summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFlorian Müllner <fmuellner@gnome.org>2021-07-19 00:01:24 +0200
committerFlorian Müllner <fmuellner@gnome.org>2021-07-19 00:03:33 +0200
commit952865a86ebb08f97263cfdbfe38b7adc20e4560 (patch)
tree1f9347628656210b03ceee4fae83beb21491d1eb /src
parent7862f143937e43dca0513af3a24dabfb4d0db4fc (diff)
downloadmutter-master.tar.gz
Replace contents with redirect messagemaster
The default development branch is now `main`. This commit only exists on `master` to point people towards that. See https://gitlab.gnome.org/GNOME/glib/-/issues/2348 for details.
Diffstat (limited to 'src')
-rw-r--r--src/backends/edid-parse.c542
-rw-r--r--src/backends/edid.h193
-rw-r--r--src/backends/gsm-inhibitor-flag.h36
-rw-r--r--src/backends/meta-backend-private.h203
-rw-r--r--src/backends/meta-backend-types.h69
-rw-r--r--src/backends/meta-backend.c1663
-rw-r--r--src/backends/meta-barrier-private.h66
-rw-r--r--src/backends/meta-barrier.c365
-rw-r--r--src/backends/meta-crtc-mode.c200
-rw-r--r--src/backends/meta-crtc-mode.h93
-rw-r--r--src/backends/meta-crtc.c246
-rw-r--r--src/backends/meta-crtc.h77
-rw-r--r--src/backends/meta-cursor-renderer.c492
-rw-r--r--src/backends/meta-cursor-renderer.h82
-rw-r--r--src/backends/meta-cursor-sprite-xcursor.c371
-rw-r--r--src/backends/meta-cursor-sprite-xcursor.h43
-rw-r--r--src/backends/meta-cursor-tracker-private.h56
-rw-r--r--src/backends/meta-cursor-tracker.c514
-rw-r--r--src/backends/meta-cursor.c240
-rw-r--r--src/backends/meta-cursor.h85
-rw-r--r--src/backends/meta-dbus-session-watcher.c237
-rw-r--r--src/backends/meta-dbus-session-watcher.h52
-rw-r--r--src/backends/meta-display-config-shared.h39
-rw-r--r--src/backends/meta-dnd-private.h41
-rw-r--r--src/backends/meta-egl-ext.h103
-rw-r--r--src/backends/meta-egl.c1154
-rw-r--r--src/backends/meta-egl.h272
-rw-r--r--src/backends/meta-gles3-table.h36
-rw-r--r--src/backends/meta-gles3.c163
-rw-r--r--src/backends/meta-gles3.h83
-rw-r--r--src/backends/meta-gpu.c226
-rw-r--r--src/backends/meta-gpu.h72
-rw-r--r--src/backends/meta-idle-manager.c379
-rw-r--r--src/backends/meta-idle-manager.h39
-rw-r--r--src/backends/meta-idle-monitor-private.h53
-rw-r--r--src/backends/meta-idle-monitor.c530
-rw-r--r--src/backends/meta-input-device-private.h48
-rw-r--r--src/backends/meta-input-device.c138
-rw-r--r--src/backends/meta-input-mapper-private.h52
-rw-r--r--src/backends/meta-input-mapper.c986
-rw-r--r--src/backends/meta-input-settings-dummy.c295
-rw-r--r--src/backends/meta-input-settings-dummy.h34
-rw-r--r--src/backends/meta-input-settings-private.h204
-rw-r--r--src/backends/meta-input-settings.c1762
-rw-r--r--src/backends/meta-keymap-utils.c56
-rw-r--r--src/backends/meta-keymap-utils.h28
-rw-r--r--src/backends/meta-logical-monitor.c343
-rw-r--r--src/backends/meta-logical-monitor.h107
-rw-r--r--src/backends/meta-monitor-config-manager.c1899
-rw-r--r--src/backends/meta-monitor-config-manager.h201
-rw-r--r--src/backends/meta-monitor-config-migration.c1233
-rw-r--r--src/backends/meta-monitor-config-migration.h41
-rw-r--r--src/backends/meta-monitor-config-store.c1683
-rw-r--r--src/backends/meta-monitor-config-store.h60
-rw-r--r--src/backends/meta-monitor-manager-dummy.c816
-rw-r--r--src/backends/meta-monitor-manager-dummy.h48
-rw-r--r--src/backends/meta-monitor-manager-private.h439
-rw-r--r--src/backends/meta-monitor-manager.c3471
-rw-r--r--src/backends/meta-monitor-transform.c128
-rw-r--r--src/backends/meta-monitor-transform.h74
-rw-r--r--src/backends/meta-monitor.c1988
-rw-r--r--src/backends/meta-monitor.h280
-rw-r--r--src/backends/meta-orientation-manager.c335
-rw-r--r--src/backends/meta-orientation-manager.h44
-rw-r--r--src/backends/meta-output.c465
-rw-r--r--src/backends/meta-output.h192
-rw-r--r--src/backends/meta-pointer-constraint.c146
-rw-r--r--src/backends/meta-pointer-constraint.h77
-rw-r--r--src/backends/meta-profiler.c203
-rw-r--r--src/backends/meta-profiler.h41
-rw-r--r--src/backends/meta-remote-access-controller-private.h38
-rw-r--r--src/backends/meta-remote-access-controller.c283
-rw-r--r--src/backends/meta-remote-desktop-session.c1725
-rw-r--r--src/backends/meta-remote-desktop-session.h60
-rw-r--r--src/backends/meta-remote-desktop.c342
-rw-r--r--src/backends/meta-remote-desktop.h54
-rw-r--r--src/backends/meta-renderer-view.c247
-rw-r--r--src/backends/meta-renderer-view.h34
-rw-r--r--src/backends/meta-renderer.c405
-rw-r--r--src/backends/meta-renderer.h78
-rw-r--r--src/backends/meta-screen-cast-area-stream-src.c652
-rw-r--r--src/backends/meta-screen-cast-area-stream-src.h37
-rw-r--r--src/backends/meta-screen-cast-area-stream.c181
-rw-r--r--src/backends/meta-screen-cast-area-stream.h49
-rw-r--r--src/backends/meta-screen-cast-monitor-stream-src.c793
-rw-r--r--src/backends/meta-screen-cast-monitor-stream-src.h40
-rw-r--r--src/backends/meta-screen-cast-monitor-stream.c295
-rw-r--r--src/backends/meta-screen-cast-monitor-stream.h50
-rw-r--r--src/backends/meta-screen-cast-session.c825
-rw-r--r--src/backends/meta-screen-cast-session.h72
-rw-r--r--src/backends/meta-screen-cast-stream-src.c1237
-rw-r--r--src/backends/meta-screen-cast-stream-src.h117
-rw-r--r--src/backends/meta-screen-cast-stream.c383
-rw-r--r--src/backends/meta-screen-cast-stream.h74
-rw-r--r--src/backends/meta-screen-cast-virtual-stream-src.c612
-rw-r--r--src/backends/meta-screen-cast-virtual-stream-src.h38
-rw-r--r--src/backends/meta-screen-cast-virtual-stream.c121
-rw-r--r--src/backends/meta-screen-cast-virtual-stream.h40
-rw-r--r--src/backends/meta-screen-cast-window-stream-src.c614
-rw-r--r--src/backends/meta-screen-cast-window-stream-src.h37
-rw-r--r--src/backends/meta-screen-cast-window-stream.c285
-rw-r--r--src/backends/meta-screen-cast-window-stream.h46
-rw-r--r--src/backends/meta-screen-cast-window.c99
-rw-r--r--src/backends/meta-screen-cast-window.h93
-rw-r--r--src/backends/meta-screen-cast.c385
-rw-r--r--src/backends/meta-screen-cast.h69
-rw-r--r--src/backends/meta-settings-private.h81
-rw-r--r--src/backends/meta-settings.c559
-rw-r--r--src/backends/meta-stage-impl-private.h76
-rw-r--r--src/backends/meta-stage-impl.c756
-rw-r--r--src/backends/meta-stage-private.h79
-rw-r--r--src/backends/meta-stage-view-private.h51
-rw-r--r--src/backends/meta-stage-view.c204
-rw-r--r--src/backends/meta-stage.c485
-rw-r--r--src/backends/meta-viewport-info.c223
-rw-r--r--src/backends/meta-viewport-info.h61
-rw-r--r--src/backends/meta-virtual-monitor.c238
-rw-r--r--src/backends/meta-virtual-monitor.h71
-rw-r--r--src/backends/native/dbus-utils.c107
-rw-r--r--src/backends/native/dbus-utils.h32
-rwxr-xr-xsrc/backends/native/gen-default-modes.py127
-rw-r--r--src/backends/native/meta-backend-native-private.h35
-rw-r--r--src/backends/native/meta-backend-native-types.h41
-rw-r--r--src/backends/native/meta-backend-native.c768
-rw-r--r--src/backends/native/meta-backend-native.h55
-rw-r--r--src/backends/native/meta-barrier-native.c652
-rw-r--r--src/backends/native/meta-barrier-native.h52
-rw-r--r--src/backends/native/meta-clutter-backend-native.c111
-rw-r--r--src/backends/native/meta-clutter-backend-native.h38
-rw-r--r--src/backends/native/meta-cogl-utils.c85
-rw-r--r--src/backends/native/meta-cogl-utils.h38
-rw-r--r--src/backends/native/meta-crtc-kms.c386
-rw-r--r--src/backends/native/meta-crtc-kms.h83
-rw-r--r--src/backends/native/meta-crtc-mode-kms.c81
-rw-r--r--src/backends/native/meta-crtc-mode-kms.h39
-rw-r--r--src/backends/native/meta-crtc-mode-virtual.c70
-rw-r--r--src/backends/native/meta-crtc-mode-virtual.h34
-rw-r--r--src/backends/native/meta-crtc-native.c44
-rw-r--r--src/backends/native/meta-crtc-native.h41
-rw-r--r--src/backends/native/meta-crtc-virtual.c60
-rw-r--r--src/backends/native/meta-crtc-virtual.h32
-rw-r--r--src/backends/native/meta-cursor-renderer-native.c1878
-rw-r--r--src/backends/native/meta-cursor-renderer-native.h42
-rw-r--r--src/backends/native/meta-device-pool-private.h35
-rw-r--r--src/backends/native/meta-device-pool.c390
-rw-r--r--src/backends/native/meta-device-pool.h68
-rw-r--r--src/backends/native/meta-drm-buffer-dumb.c287
-rw-r--r--src/backends/native/meta-drm-buffer-dumb.h45
-rw-r--r--src/backends/native/meta-drm-buffer-gbm.c474
-rw-r--r--src/backends/native/meta-drm-buffer-gbm.h49
-rw-r--r--src/backends/native/meta-drm-buffer-import.c209
-rw-r--r--src/backends/native/meta-drm-buffer-import.h55
-rw-r--r--src/backends/native/meta-drm-buffer-private.h64
-rw-r--r--src/backends/native/meta-drm-buffer.c296
-rw-r--r--src/backends/native/meta-drm-buffer.h53
-rw-r--r--src/backends/native/meta-gpu-kms.c422
-rw-r--r--src/backends/native/meta-gpu-kms.h74
-rw-r--r--src/backends/native/meta-input-device-native.c1599
-rw-r--r--src/backends/native/meta-input-device-native.h162
-rw-r--r--src/backends/native/meta-input-device-tool-native.c183
-rw-r--r--src/backends/native/meta-input-device-tool-native.h90
-rw-r--r--src/backends/native/meta-input-settings-native.c876
-rw-r--r--src/backends/native/meta-input-settings-native.h56
-rw-r--r--src/backends/native/meta-input-thread.h33
-rw-r--r--src/backends/native/meta-keymap-native.c152
-rw-r--r--src/backends/native/meta-keymap-native.h43
-rw-r--r--src/backends/native/meta-kms-connector-private.h54
-rw-r--r--src/backends/native/meta-kms-connector.c700
-rw-r--r--src/backends/native/meta-kms-connector.h77
-rw-r--r--src/backends/native/meta-kms-crtc-private.h51
-rw-r--r--src/backends/native/meta-kms-crtc.c399
-rw-r--r--src/backends/native/meta-kms-crtc.h79
-rw-r--r--src/backends/native/meta-kms-device-private.h36
-rw-r--r--src/backends/native/meta-kms-device.c439
-rw-r--r--src/backends/native/meta-kms-device.h69
-rw-r--r--src/backends/native/meta-kms-impl-device-atomic.c1202
-rw-r--r--src/backends/native/meta-kms-impl-device-atomic.h29
-rw-r--r--src/backends/native/meta-kms-impl-device-dummy.c127
-rw-r--r--src/backends/native/meta-kms-impl-device-dummy.h30
-rw-r--r--src/backends/native/meta-kms-impl-device-simple.c1678
-rw-r--r--src/backends/native/meta-kms-impl-device-simple.h29
-rw-r--r--src/backends/native/meta-kms-impl-device.c1070
-rw-r--r--src/backends/native/meta-kms-impl-device.h178
-rw-r--r--src/backends/native/meta-kms-impl.c204
-rw-r--r--src/backends/native/meta-kms-impl.h52
-rw-r--r--src/backends/native/meta-kms-mode-private.h34
-rw-r--r--src/backends/native/meta-kms-mode.c143
-rw-r--r--src/backends/native/meta-kms-mode.h47
-rw-r--r--src/backends/native/meta-kms-page-flip-private.h65
-rw-r--r--src/backends/native/meta-kms-page-flip.c288
-rw-r--r--src/backends/native/meta-kms-plane-private.h64
-rw-r--r--src/backends/native/meta-kms-plane.c537
-rw-r--r--src/backends/native/meta-kms-plane.h65
-rw-r--r--src/backends/native/meta-kms-private.h65
-rw-r--r--src/backends/native/meta-kms-types.h75
-rw-r--r--src/backends/native/meta-kms-update-private.h157
-rw-r--r--src/backends/native/meta-kms-update.c645
-rw-r--r--src/backends/native/meta-kms-update.h181
-rw-r--r--src/backends/native/meta-kms-utils.c103
-rw-r--r--src/backends/native/meta-kms-utils.h43
-rw-r--r--src/backends/native/meta-kms.c754
-rw-r--r--src/backends/native/meta-kms.h74
-rw-r--r--src/backends/native/meta-launcher.c410
-rw-r--r--src/backends/native/meta-launcher.h40
-rw-r--r--src/backends/native/meta-monitor-manager-native.c825
-rw-r--r--src/backends/native/meta-monitor-manager-native.h49
-rw-r--r--src/backends/native/meta-onscreen-native.c2137
-rw-r--r--src/backends/native/meta-onscreen-native.h59
-rw-r--r--src/backends/native/meta-output-kms.c414
-rw-r--r--src/backends/native/meta-output-kms.h55
-rw-r--r--src/backends/native/meta-output-native.c43
-rw-r--r--src/backends/native/meta-output-native.h39
-rw-r--r--src/backends/native/meta-output-virtual.c80
-rw-r--r--src/backends/native/meta-output-virtual.h36
-rw-r--r--src/backends/native/meta-pointer-constraint-native.c694
-rw-r--r--src/backends/native/meta-pointer-constraint-native.h46
-rw-r--r--src/backends/native/meta-renderer-native-gles3.c160
-rw-r--r--src/backends/native/meta-renderer-native-gles3.h40
-rw-r--r--src/backends/native/meta-renderer-native-private.h115
-rw-r--r--src/backends/native/meta-renderer-native.c2264
-rw-r--r--src/backends/native/meta-renderer-native.h71
-rw-r--r--src/backends/native/meta-seat-impl.c3542
-rw-r--r--src/backends/native/meta-seat-impl.h254
-rw-r--r--src/backends/native/meta-seat-native.c634
-rw-r--r--src/backends/native/meta-seat-native.h133
-rw-r--r--src/backends/native/meta-stage-native.c191
-rw-r--r--src/backends/native/meta-stage-native.h37
-rw-r--r--src/backends/native/meta-udev.c274
-rw-r--r--src/backends/native/meta-udev.h49
-rw-r--r--src/backends/native/meta-virtual-input-device-native.c1110
-rw-r--r--src/backends/native/meta-virtual-input-device-native.h31
-rw-r--r--src/backends/native/meta-virtual-monitor-native.c80
-rw-r--r--src/backends/native/meta-virtual-monitor-native.h45
-rw-r--r--src/backends/native/meta-xkb-utils.c137
-rw-r--r--src/backends/native/meta-xkb-utils.h43
-rw-r--r--src/backends/x11/cm/meta-backend-x11-cm.c550
-rw-r--r--src/backends/x11/cm/meta-backend-x11-cm.h31
-rw-r--r--src/backends/x11/cm/meta-cursor-sprite-xfixes.c231
-rw-r--r--src/backends/x11/cm/meta-cursor-sprite-xfixes.h36
-rw-r--r--src/backends/x11/cm/meta-renderer-x11-cm.c113
-rw-r--r--src/backends/x11/cm/meta-renderer-x11-cm.h42
-rw-r--r--src/backends/x11/meta-backend-x11.c996
-rw-r--r--src/backends/x11/meta-backend-x11.h63
-rw-r--r--src/backends/x11/meta-barrier-x11.c212
-rw-r--r--src/backends/x11/meta-barrier-x11.h42
-rw-r--r--src/backends/x11/meta-clutter-backend-x11.c745
-rw-r--r--src/backends/x11/meta-clutter-backend-x11.h96
-rw-r--r--src/backends/x11/meta-crtc-xrandr.c308
-rw-r--r--src/backends/x11/meta-crtc-xrandr.h57
-rw-r--r--src/backends/x11/meta-cursor-renderer-x11.c114
-rw-r--r--src/backends/x11/meta-cursor-renderer-x11.h52
-rw-r--r--src/backends/x11/meta-cursor-tracker-x11.c186
-rw-r--r--src/backends/x11/meta-cursor-tracker-x11.h34
-rw-r--r--src/backends/x11/meta-event-x11.c114
-rw-r--r--src/backends/x11/meta-event-x11.h33
-rw-r--r--src/backends/x11/meta-gpu-xrandr.c277
-rw-r--r--src/backends/x11/meta-gpu-xrandr.h42
-rw-r--r--src/backends/x11/meta-input-device-tool-x11.c56
-rw-r--r--src/backends/x11/meta-input-device-tool-x11.h51
-rw-r--r--src/backends/x11/meta-input-device-x11.c795
-rw-r--r--src/backends/x11/meta-input-device-x11.h102
-rw-r--r--src/backends/x11/meta-input-settings-x11.c948
-rw-r--r--src/backends/x11/meta-input-settings-x11.h49
-rw-r--r--src/backends/x11/meta-keymap-x11.c949
-rw-r--r--src/backends/x11/meta-keymap-x11.h61
-rw-r--r--src/backends/x11/meta-monitor-manager-xrandr.c1151
-rw-r--r--src/backends/x11/meta-monitor-manager-xrandr.h41
-rw-r--r--src/backends/x11/meta-output-xrandr.c987
-rw-r--r--src/backends/x11/meta-output-xrandr.h52
-rw-r--r--src/backends/x11/meta-renderer-x11.c107
-rw-r--r--src/backends/x11/meta-renderer-x11.h42
-rw-r--r--src/backends/x11/meta-seat-x11.c2422
-rw-r--r--src/backends/x11/meta-seat-x11.h44
-rw-r--r--src/backends/x11/meta-stage-x11.c853
-rw-r--r--src/backends/x11/meta-stage-x11.h96
-rw-r--r--src/backends/x11/meta-virtual-input-device-x11.c253
-rw-r--r--src/backends/x11/meta-virtual-input-device-x11.h31
-rw-r--r--src/backends/x11/meta-xkb-a11y-x11.c339
-rw-r--r--src/backends/x11/meta-xkb-a11y-x11.h39
-rw-r--r--src/backends/x11/nested/meta-backend-x11-nested.c320
-rw-r--r--src/backends/x11/nested/meta-backend-x11-nested.h40
-rw-r--r--src/backends/x11/nested/meta-cursor-renderer-x11-nested.c91
-rw-r--r--src/backends/x11/nested/meta-cursor-renderer-x11-nested.h38
-rw-r--r--src/backends/x11/nested/meta-renderer-x11-nested.c248
-rw-r--r--src/backends/x11/nested/meta-renderer-x11-nested.h37
-rw-r--r--src/backends/x11/nested/meta-stage-x11-nested.c236
-rw-r--r--src/backends/x11/nested/meta-stage-x11-nested.h35
-rw-r--r--src/compositor/README70
-rw-r--r--src/compositor/clutter-utils.c188
-rw-r--r--src/compositor/clutter-utils.h40
-rw-r--r--src/compositor/cogl-utils.c114
-rw-r--r--src/compositor/cogl-utils.h39
-rw-r--r--src/compositor/compositor-private.h101
-rw-r--r--src/compositor/compositor.c1581
-rw-r--r--src/compositor/meta-background-actor-private.h10
-rw-r--r--src/compositor/meta-background-actor.c218
-rw-r--r--src/compositor/meta-background-content-private.h16
-rw-r--r--src/compositor/meta-background-content.c1312
-rw-r--r--src/compositor/meta-background-group.c66
-rw-r--r--src/compositor/meta-background-image.c370
-rw-r--r--src/compositor/meta-background-private.h14
-rw-r--r--src/compositor/meta-background.c1018
-rw-r--r--src/compositor/meta-compositor-native.c151
-rw-r--r--src/compositor/meta-compositor-native.h33
-rw-r--r--src/compositor/meta-compositor-server.c100
-rw-r--r--src/compositor/meta-compositor-server.h38
-rw-r--r--src/compositor/meta-compositor-x11.c530
-rw-r--r--src/compositor/meta-compositor-x11.h39
-rw-r--r--src/compositor/meta-cullable.c245
-rw-r--r--src/compositor/meta-cullable.h61
-rw-r--r--src/compositor/meta-dnd-actor-private.h48
-rw-r--r--src/compositor/meta-dnd-actor.c242
-rw-r--r--src/compositor/meta-dnd.c336
-rw-r--r--src/compositor/meta-feedback-actor-private.h70
-rw-r--r--src/compositor/meta-feedback-actor.c285
-rw-r--r--src/compositor/meta-later-private.h28
-rw-r--r--src/compositor/meta-later.c352
-rw-r--r--src/compositor/meta-module.c193
-rw-r--r--src/compositor/meta-module.h55
-rw-r--r--src/compositor/meta-plugin-manager.c419
-rw-r--r--src/compositor/meta-plugin-manager.h105
-rw-r--r--src/compositor/meta-plugin.c223
-rw-r--r--src/compositor/meta-shadow-factory.c1066
-rw-r--r--src/compositor/meta-shaped-texture-private.h76
-rw-r--r--src/compositor/meta-shaped-texture.c1676
-rw-r--r--src/compositor/meta-surface-actor-wayland.c198
-rw-r--r--src/compositor/meta-surface-actor-wayland.h63
-rw-r--r--src/compositor/meta-surface-actor-x11.c422
-rw-r--r--src/compositor/meta-surface-actor-x11.h62
-rw-r--r--src/compositor/meta-surface-actor.c698
-rw-r--r--src/compositor/meta-surface-actor.h72
-rw-r--r--src/compositor/meta-sync-ring.c592
-rw-r--r--src/compositor/meta-sync-ring.h13
-rw-r--r--src/compositor/meta-texture-tower.c484
-rw-r--r--src/compositor/meta-texture-tower.h68
-rw-r--r--src/compositor/meta-window-actor-private.h102
-rw-r--r--src/compositor/meta-window-actor-wayland.c171
-rw-r--r--src/compositor/meta-window-actor-wayland.h37
-rw-r--r--src/compositor/meta-window-actor-x11.c1693
-rw-r--r--src/compositor/meta-window-actor-x11.h47
-rw-r--r--src/compositor/meta-window-actor.c1559
-rw-r--r--src/compositor/meta-window-group-private.h23
-rw-r--r--src/compositor/meta-window-group.c222
-rw-r--r--src/compositor/meta-window-shape.c259
-rw-r--r--src/compositor/plugins/default.c923
-rw-r--r--src/compositor/plugins/meson.build20
-rw-r--r--src/compositor/region-utils.c458
-rw-r--r--src/compositor/region-utils.h119
-rw-r--r--src/core/bell.c209
-rw-r--r--src/core/bell.h43
-rw-r--r--src/core/boxes-private.h288
-rw-r--r--src/core/boxes.c2183
-rw-r--r--src/core/constraints.c1878
-rw-r--r--src/core/constraints.h39
-rw-r--r--src/core/delete.c124
-rw-r--r--src/core/display-private.h434
-rw-r--r--src/core/display.c3852
-rw-r--r--src/core/edge-resistance.c1310
-rw-r--r--src/core/edge-resistance.h40
-rw-r--r--src/core/events.c509
-rw-r--r--src/core/events.h31
-rw-r--r--src/core/frame.c427
-rw-r--r--src/core/frame.h85
-rw-r--r--src/core/keybindings-private.h160
-rw-r--r--src/core/keybindings.c4578
-rw-r--r--src/core/meta-accel-parse.c358
-rw-r--r--src/core/meta-accel-parse.h44
-rw-r--r--src/core/meta-anonymous-file.c368
-rw-r--r--src/core/meta-anonymous-file.h53
-rw-r--r--src/core/meta-border.c154
-rw-r--r--src/core/meta-border.h84
-rw-r--r--src/core/meta-clipboard-manager.c179
-rw-r--r--src/core/meta-clipboard-manager.h30
-rw-r--r--src/core/meta-close-dialog-default-private.h37
-rw-r--r--src/core/meta-close-dialog-default.c281
-rw-r--r--src/core/meta-close-dialog.c144
-rw-r--r--src/core/meta-context-main.c702
-rw-r--r--src/core/meta-context-main.h31
-rw-r--r--src/core/meta-context-private.h63
-rw-r--r--src/core/meta-context.c568
-rw-r--r--src/core/meta-fraction.c134
-rw-r--r--src/core/meta-fraction.h31
-rw-r--r--src/core/meta-gesture-tracker-private.h70
-rw-r--r--src/core/meta-gesture-tracker.c581
-rw-r--r--src/core/meta-inhibit-shortcuts-dialog-default-private.h34
-rw-r--r--src/core/meta-inhibit-shortcuts-dialog-default.c132
-rw-r--r--src/core/meta-inhibit-shortcuts-dialog.c103
-rw-r--r--src/core/meta-launch-context.c269
-rw-r--r--src/core/meta-pad-action-mapper.c860
-rw-r--r--src/core/meta-pad-action-mapper.h46
-rw-r--r--src/core/meta-private-enums.h31
-rw-r--r--src/core/meta-selection-private.h32
-rw-r--r--src/core/meta-selection-source-memory.c128
-rw-r--r--src/core/meta-selection-source-remote.c144
-rw-r--r--src/core/meta-selection-source-remote.h43
-rw-r--r--src/core/meta-selection-source.c166
-rw-r--r--src/core/meta-selection.c415
-rw-r--r--src/core/meta-sound-player.c296
-rw-r--r--src/core/meta-workspace-manager-private.h96
-rw-r--r--src/core/meta-workspace-manager.c1060
-rw-r--r--src/core/mutter.c97
-rw-r--r--src/core/place.c942
-rw-r--r--src/core/place.h39
-rw-r--r--src/core/prefs-private.h26
-rw-r--r--src/core/prefs.c2229
-rw-r--r--src/core/restart-helper.c84
-rw-r--r--src/core/restart.c201
-rw-r--r--src/core/stack-tracker.c1293
-rw-r--r--src/core/stack-tracker.h87
-rw-r--r--src/core/stack.c1340
-rw-r--r--src/core/stack.h406
-rw-r--r--src/core/startup-notification-private.h52
-rw-r--r--src/core/startup-notification.c696
-rw-r--r--src/core/util-private.h61
-rw-r--r--src/core/util.c796
-rw-r--r--src/core/window-private.h888
-rw-r--r--src/core/window.c8665
-rw-r--r--src/core/workspace-private.h103
-rw-r--r--src/core/workspace.c1477
-rw-r--r--src/libmutter.pc.in14
-rw-r--r--src/meson.build1102
-rw-r--r--src/meta-private-enum-types.c.in39
-rw-r--r--src/meta-private-enum-types.h.in25
-rw-r--r--src/meta/barrier.h124
-rw-r--r--src/meta/boxes.h159
-rw-r--r--src/meta/common.h553
-rw-r--r--src/meta/compositor-mutter.h60
-rw-r--r--src/meta/compositor.h165
-rw-r--r--src/meta/display.h315
-rw-r--r--src/meta/group.h65
-rw-r--r--src/meta/keybindings.h46
-rw-r--r--src/meta/main.h50
-rw-r--r--src/meta/meson.build75
-rw-r--r--src/meta/meta-backend.h76
-rw-r--r--src/meta/meta-background-actor.h50
-rw-r--r--src/meta/meta-background-content.h74
-rw-r--r--src/meta/meta-background-group.h26
-rw-r--r--src/meta/meta-background-image.h69
-rw-r--r--src/meta/meta-background.h74
-rw-r--r--src/meta/meta-close-dialog.h65
-rw-r--r--src/meta/meta-context.h101
-rw-r--r--src/meta/meta-cursor-tracker.h63
-rw-r--r--src/meta/meta-dnd.h34
-rw-r--r--src/meta/meta-enum-types.c.in39
-rw-r--r--src/meta/meta-enum-types.h.in27
-rw-r--r--src/meta/meta-enums.h30
-rw-r--r--src/meta/meta-idle-monitor.h56
-rw-r--r--src/meta/meta-inhibit-shortcuts-dialog.h55
-rw-r--r--src/meta/meta-later.h53
-rw-r--r--src/meta/meta-launch-context.h39
-rw-r--r--src/meta/meta-monitor-manager.h68
-rw-r--r--src/meta/meta-plugin.h370
-rw-r--r--src/meta/meta-remote-access-controller.h63
-rw-r--r--src/meta/meta-selection-source-memory.h39
-rw-r--r--src/meta/meta-selection-source.h85
-rw-r--r--src/meta/meta-selection.h70
-rw-r--r--src/meta/meta-settings.h34
-rw-r--r--src/meta/meta-shadow-factory.h135
-rw-r--r--src/meta/meta-shaped-texture.h60
-rw-r--r--src/meta/meta-sound-player.h46
-rw-r--r--src/meta/meta-stage.h34
-rw-r--r--src/meta/meta-startup-notification.h76
-rw-r--r--src/meta/meta-wayland-client.h67
-rw-r--r--src/meta/meta-window-actor.h67
-rw-r--r--src/meta/meta-window-group.h16
-rw-r--r--src/meta/meta-window-shape.h76
-rw-r--r--src/meta/meta-workspace-manager.h78
-rw-r--r--src/meta/meta-x11-display.h73
-rw-r--r--src/meta/meta-x11-errors.h41
-rw-r--r--src/meta/prefs.h485
-rw-r--r--src/meta/theme.h41
-rw-r--r--src/meta/types.h49
-rw-r--r--src/meta/util.h236
-rw-r--r--src/meta/window.h449
-rw-r--r--src/meta/workspace.h73
-rw-r--r--src/org.freedesktop.login1.xml46
-rw-r--r--src/org.gnome.Mutter.DisplayConfig.xml473
-rw-r--r--src/org.gnome.Mutter.IdleMonitor.xml37
-rw-r--r--src/org.gnome.Mutter.RemoteDesktop.xml351
-rw-r--r--src/org.gnome.Mutter.ScreenCast.xml220
-rw-r--r--src/tests/README93
-rw-r--r--src/tests/anonymous-file.c282
-rw-r--r--src/tests/boxes-tests.c1389
-rw-r--r--src/tests/boxes-tests.h23
-rw-r--r--src/tests/clutter-test-utils.c473
-rw-r--r--src/tests/clutter-test-utils.h174
-rw-r--r--src/tests/clutter/README38
-rw-r--r--src/tests/clutter/accessibility/cally-atkcomponent-example.c95
-rw-r--r--src/tests/clutter/accessibility/cally-atkeditabletext-example.c266
-rw-r--r--src/tests/clutter/accessibility/cally-atkevents-example.c194
-rw-r--r--src/tests/clutter/accessibility/cally-atktext-example.c253
-rw-r--r--src/tests/clutter/accessibility/cally-clone-example.c112
-rw-r--r--src/tests/clutter/accessibility/cally-examples-util.c148
-rw-r--r--src/tests/clutter/accessibility/cally-examples-util.h26
-rw-r--r--src/tests/clutter/accessibility/meson.build39
-rw-r--r--src/tests/clutter/clutter-1.0.suppressions165
-rw-r--r--src/tests/clutter/conform/actor-clone.c68
-rw-r--r--src/tests/clutter/conform/actor-destroy.c200
-rw-r--r--src/tests/clutter/conform/actor-graph.c552
-rw-r--r--src/tests/clutter/conform/actor-invariants.c368
-rw-r--r--src/tests/clutter/conform/actor-iter.c220
-rw-r--r--src/tests/clutter/conform/actor-layout.c98
-rw-r--r--src/tests/clutter/conform/actor-meta.c42
-rw-r--r--src/tests/clutter/conform/actor-offscreen-redirect.c452
-rw-r--r--src/tests/clutter/conform/actor-paint-opacity.c151
-rw-r--r--src/tests/clutter/conform/actor-pick.c231
-rw-r--r--src/tests/clutter/conform/actor-pivot-point.c52
-rw-r--r--src/tests/clutter/conform/actor-shader-effect.c301
-rw-r--r--src/tests/clutter/conform/actor-size.c218
-rw-r--r--src/tests/clutter/conform/binding-pool.c311
-rw-r--r--src/tests/clutter/conform/cally-text.c338
-rw-r--r--src/tests/clutter/conform/color.c321
-rw-r--r--src/tests/clutter/conform/frame-clock-timeline.c209
-rw-r--r--src/tests/clutter/conform/frame-clock.c846
-rw-r--r--src/tests/clutter/conform/interval.c119
-rw-r--r--src/tests/clutter/conform/meson.build79
-rw-r--r--src/tests/clutter/conform/path.c740
-rw-r--r--src/tests/clutter/conform/script-parser.c303
-rw-r--r--src/tests/clutter/conform/scripts/test-script-child.json21
-rw-r--r--src/tests/clutter/conform/scripts/test-script-interval.json16
-rw-r--r--src/tests/clutter/conform/scripts/test-script-margin.json22
-rw-r--r--src/tests/clutter/conform/scripts/test-script-model.json17
-rw-r--r--src/tests/clutter/conform/scripts/test-script-named-object.json44
-rw-r--r--src/tests/clutter/conform/scripts/test-script-object-property.json13
-rw-r--r--src/tests/clutter/conform/scripts/test-script-single.json10
-rw-r--r--src/tests/clutter/conform/scripts/test-script-timeline-markers.json16
-rw-r--r--src/tests/clutter/conform/text-cache.c299
-rw-r--r--src/tests/clutter/conform/text.c564
-rw-r--r--src/tests/clutter/conform/texture-fbo.c227
-rw-r--r--src/tests/clutter/conform/timeline-interpolate.c211
-rw-r--r--src/tests/clutter/conform/timeline-progress.c117
-rw-r--r--src/tests/clutter/conform/timeline-rewind.c102
-rw-r--r--src/tests/clutter/conform/timeline.c365
-rw-r--r--src/tests/clutter/conform/units.c133
-rw-r--r--src/tests/clutter/interactive/light0.pngbin1559 -> 0 bytes
-rw-r--r--src/tests/clutter/interactive/meson.build74
-rwxr-xr-xsrc/tests/clutter/interactive/meson/gen-test-unit-names.sh14
-rw-r--r--src/tests/clutter/interactive/redhand.pngbin8250 -> 0 bytes
-rw-r--r--src/tests/clutter/interactive/redhand_alpha.pngbin2360 -> 0 bytes
-rw-r--r--src/tests/clutter/interactive/test-actors.c264
-rw-r--r--src/tests/clutter/interactive/test-animation.c131
-rw-r--r--src/tests/clutter/interactive/test-bind-constraint.c258
-rw-r--r--src/tests/clutter/interactive/test-binding-pool.c326
-rw-r--r--src/tests/clutter/interactive/test-cairo-clock.c125
-rw-r--r--src/tests/clutter/interactive/test-cairo-flowers.c261
-rw-r--r--src/tests/clutter/interactive/test-cogl-multitexture.c254
-rw-r--r--src/tests/clutter/interactive/test-cogl-offscreen.c353
-rw-r--r--src/tests/clutter/interactive/test-cogl-point-sprites.c282
-rw-r--r--src/tests/clutter/interactive/test-cogl-shader-glsl.c350
-rw-r--r--src/tests/clutter/interactive/test-cogl-tex-convert.c245
-rw-r--r--src/tests/clutter/interactive/test-cogl-tex-polygon.c455
-rw-r--r--src/tests/clutter/interactive/test-cogl-tex-tile.c235
-rw-r--r--src/tests/clutter/interactive/test-content.c242
-rw-r--r--src/tests/clutter/interactive/test-devices.c234
-rw-r--r--src/tests/clutter/interactive/test-easing.c252
-rw-r--r--src/tests/clutter/interactive/test-events.c477
-rw-r--r--src/tests/clutter/interactive/test-grab.c283
-rw-r--r--src/tests/clutter/interactive/test-image.c261
-rw-r--r--src/tests/clutter/interactive/test-keyframe-transition.c115
-rw-r--r--src/tests/clutter/interactive/test-layout.c684
-rw-r--r--src/tests/clutter/interactive/test-main.c227
-rw-r--r--src/tests/clutter/interactive/test-path-constraint.c138
-rw-r--r--src/tests/clutter/interactive/test-rotate-zoom.c100
-rw-r--r--src/tests/clutter/interactive/test-script.c154
-rw-r--r--src/tests/clutter/interactive/test-script.json54
-rw-r--r--src/tests/clutter/interactive/test-shader-effects.c88
-rw-r--r--src/tests/clutter/interactive/test-stage-sizing.c89
-rw-r--r--src/tests/clutter/interactive/test-state-script.c46
-rw-r--r--src/tests/clutter/interactive/test-swipe-action.c199
-rw-r--r--src/tests/clutter/interactive/test-text-field.c339
-rw-r--r--src/tests/clutter/interactive/test-text.c102
-rw-r--r--src/tests/clutter/interactive/test-touch-events.c185
-rwxr-xr-xsrc/tests/clutter/interactive/wrapper.sh.in15
-rw-r--r--src/tests/clutter/meson.build11
-rw-r--r--src/tests/clutter/micro-bench/meson.build31
-rw-r--r--src/tests/clutter/micro-bench/test-cogl-perf.c150
-rw-r--r--src/tests/clutter/micro-bench/test-picking.c119
-rw-r--r--src/tests/clutter/micro-bench/test-random-text.c106
-rw-r--r--src/tests/clutter/micro-bench/test-text-perf.c190
-rw-r--r--src/tests/clutter/micro-bench/test-text.c123
-rwxr-xr-xsrc/tests/clutter/performance/create-report.rb179
-rw-r--r--src/tests/clutter/performance/joblist27
-rwxr-xr-xsrc/tests/clutter/performance/makejobs.rb24
-rw-r--r--src/tests/clutter/performance/meson.build34
-rw-r--r--src/tests/clutter/performance/test-common.h144
-rw-r--r--src/tests/clutter/performance/test-picking.c109
-rw-r--r--src/tests/clutter/performance/test-text-perf.c166
-rw-r--r--src/tests/clutter/test-utils.h30
-rw-r--r--src/tests/headless-start-test.c180
-rw-r--r--src/tests/kms-utils-unit-tests.c267
-rw-r--r--src/tests/meson.build351
-rw-r--r--src/tests/meta-backend-test.c95
-rw-r--r--src/tests/meta-backend-test.h37
-rw-r--r--src/tests/meta-context-test.c333
-rw-r--r--src/tests/meta-gpu-test.c55
-rw-r--r--src/tests/meta-gpu-test.h26
-rw-r--r--src/tests/meta-monitor-manager-test.c490
-rw-r--r--src/tests/meta-monitor-manager-test.h81
-rw-r--r--src/tests/meta-ref-test.c610
-rw-r--r--src/tests/meta-ref-test.h39
-rw-r--r--src/tests/meta-test-utils-private.h26
-rw-r--r--src/tests/meta-test-utils.c567
-rw-r--r--src/tests/meta-test-utils.h100
-rw-r--r--src/tests/meta-test/meson.build9
-rw-r--r--src/tests/meta-test/meta-context-test.h56
-rw-r--r--src/tests/meta-wayland-test-driver.c160
-rw-r--r--src/tests/meta-wayland-test-driver.h30
-rw-r--r--src/tests/migration/basic-new.xml78
-rw-r--r--src/tests/migration/basic-old.xml72
-rw-r--r--src/tests/migration/first-rotated-new.xml44
-rw-r--r--src/tests/migration/first-rotated-old.xml37
-rw-r--r--src/tests/migration/oneoff-new-finished.xml31
-rw-r--r--src/tests/migration/oneoff-new.xml31
-rw-r--r--src/tests/migration/oneoff-old.xml26
-rw-r--r--src/tests/migration/rotated-new-finished.xml27
-rw-r--r--src/tests/migration/rotated-new.xml27
-rw-r--r--src/tests/migration/rotated-old.xml21
-rw-r--r--src/tests/migration/tiled-new.xml23
-rw-r--r--src/tests/migration/tiled-old.xml37
-rw-r--r--src/tests/migration/wiggle-new-discarded.xml2
-rw-r--r--src/tests/migration/wiggle-new-finished.xml27
-rw-r--r--src/tests/migration/wiggle-new.xml27
-rw-r--r--src/tests/migration/wiggle-old.xml21
-rw-r--r--src/tests/monitor-config-migration-unit-tests.c136
-rw-r--r--src/tests/monitor-config-migration-unit-tests.h25
-rw-r--r--src/tests/monitor-configs/first-rotated.xml47
-rw-r--r--src/tests/monitor-configs/fractional-scale.xml23
-rw-r--r--src/tests/monitor-configs/high-precision-fractional-scale.xml23
-rw-r--r--src/tests/monitor-configs/interlaced.xml23
-rw-r--r--src/tests/monitor-configs/lid-scale.xml23
-rw-r--r--src/tests/monitor-configs/lid-switch.xml91
-rw-r--r--src/tests/monitor-configs/mirrored.xml35
-rw-r--r--src/tests/monitor-configs/non-preferred-tiled-custom-resolution.xml22
-rw-r--r--src/tests/monitor-configs/oneoff.xml31
-rw-r--r--src/tests/monitor-configs/primary.xml40
-rw-r--r--src/tests/monitor-configs/scale.xml23
-rw-r--r--src/tests/monitor-configs/second-rotated-tiled.xml43
-rw-r--r--src/tests/monitor-configs/second-rotated.xml43
-rw-r--r--src/tests/monitor-configs/single.xml22
-rw-r--r--src/tests/monitor-configs/tiled-custom-resolution.xml23
-rw-r--r--src/tests/monitor-configs/tiled.xml23
-rw-r--r--src/tests/monitor-configs/underscanning.xml23
-rw-r--r--src/tests/monitor-configs/vertical.xml39
-rw-r--r--src/tests/monitor-store-unit-tests.c864
-rw-r--r--src/tests/monitor-store-unit-tests.h25
-rw-r--r--src/tests/monitor-test-utils.c780
-rw-r--r--src/tests/monitor-test-utils.h206
-rw-r--r--src/tests/monitor-transform-tests.c101
-rw-r--r--src/tests/monitor-transform-tests.h23
-rw-r--r--src/tests/monitor-unit-tests.c5868
-rw-r--r--src/tests/monitor-unit-tests.h36
-rw-r--r--src/tests/mutter-all.test.in6
-rw-r--r--src/tests/native-headless.c47
-rw-r--r--src/tests/native-persistent-virtual-monitor.c100
-rw-r--r--src/tests/native-screen-cast.c86
-rw-r--r--src/tests/native-screen-cast.h26
-rw-r--r--src/tests/native-virtual-monitor.c135
-rw-r--r--src/tests/native-virtual-monitor.h26
-rw-r--r--src/tests/ref-test-sanity.c148
-rw-r--r--src/tests/ref-tests/backends_native_virtual-monitor_create_0.ref.pngbin3509 -> 0 bytes
-rw-r--r--src/tests/ref-tests/backends_native_virtual-monitor_create_1.ref.pngbin2610 -> 0 bytes
-rw-r--r--src/tests/ref-tests/tests_ref-test_sanity_0.ref.pngbin6749 -> 0 bytes
-rw-r--r--src/tests/ref-tests/tests_ref-test_sanity_1.ref.pngbin5402 -> 0 bytes
-rw-r--r--src/tests/screen-cast-client.c572
-rw-r--r--src/tests/stacking/basic-wayland.metatest22
-rw-r--r--src/tests/stacking/basic-x11.metatest19
-rw-r--r--src/tests/stacking/client-side-decorated.metatest22
-rw-r--r--src/tests/stacking/closed-transient-no-default-focus.metatest29
-rw-r--r--src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest23
-rw-r--r--src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest30
-rw-r--r--src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest37
-rw-r--r--src/tests/stacking/closed-transient-no-input-parent.metatest31
-rw-r--r--src/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest44
-rw-r--r--src/tests/stacking/closed-transient-no-input-parents.metatest47
-rw-r--r--src/tests/stacking/closed-transient-only-take-focus-parents.metatest36
-rw-r--r--src/tests/stacking/closed-transient.metatest19
-rw-r--r--src/tests/stacking/default-size.metatest36
-rw-r--r--src/tests/stacking/fullscreen-maximize.metatest73
-rw-r--r--src/tests/stacking/map-fixed-size.metatest75
-rw-r--r--src/tests/stacking/minimized.metatest18
-rw-r--r--src/tests/stacking/mixed-windows.metatest26
-rw-r--r--src/tests/stacking/modals.metatest32
-rw-r--r--src/tests/stacking/override-redirect.metatest19
-rw-r--r--src/tests/stacking/restore-position.metatest73
-rw-r--r--src/tests/stacking/restore-size.metatest95
-rw-r--r--src/tests/stacking/set-override-redirect-parent.metatest37
-rw-r--r--src/tests/stacking/set-parent-exported.metatest15
-rw-r--r--src/tests/stacking/set-parent.metatest14
-rw-r--r--src/tests/stacking/unmaximize-new-size.metatest22
-rw-r--r--src/tests/stage-view-tests.c1171
-rw-r--r--src/tests/test-client.c944
-rw-r--r--src/tests/test-runner.c1202
-rw-r--r--src/tests/unit-tests.c258
-rw-r--r--src/tests/unit-tests.h25
-rw-r--r--src/tests/wayland-test-clients/invalid-subsurfaces.c165
-rw-r--r--src/tests/wayland-test-clients/invalid-xdg-shell-actions.c280
-rw-r--r--src/tests/wayland-test-clients/meson.build70
-rw-r--r--src/tests/wayland-test-clients/subsurface-remap-toplevel.c397
-rw-r--r--src/tests/wayland-test-clients/test-driver.xml13
-rw-r--r--src/tests/wayland-test-clients/wayland-test-client-utils.c88
-rw-r--r--src/tests/wayland-test-clients/wayland-test-client-utils.h8
-rw-r--r--src/tests/wayland-test-clients/xdg-apply-limits.c408
-rw-r--r--src/tests/wayland-unit-tests.c264
-rw-r--r--src/tests/wayland-unit-tests.h25
-rw-r--r--src/ui/frames.c1869
-rw-r--r--src/ui/frames.h148
-rw-r--r--src/ui/theme-private.h281
-rw-r--r--src/ui/theme.c1397
-rw-r--r--src/ui/ui.c281
-rw-r--r--src/ui/ui.h79
-rw-r--r--src/wayland/meta-cursor-sprite-wayland.c75
-rw-r--r--src/wayland/meta-cursor-sprite-wayland.h35
-rw-r--r--src/wayland/meta-pointer-confinement-wayland.c267
-rw-r--r--src/wayland/meta-pointer-confinement-wayland.h56
-rw-r--r--src/wayland/meta-pointer-lock-wayland.c104
-rw-r--r--src/wayland/meta-pointer-lock-wayland.h42
-rw-r--r--src/wayland/meta-selection-source-wayland-private.h39
-rw-r--r--src/wayland/meta-selection-source-wayland.c170
-rw-r--r--src/wayland/meta-wayland-activation.c333
-rw-r--r--src/wayland/meta-wayland-activation.h32
-rw-r--r--src/wayland/meta-wayland-actor-surface.c460
-rw-r--r--src/wayland/meta-wayland-actor-surface.h54
-rw-r--r--src/wayland/meta-wayland-buffer.c852
-rw-r--r--src/wayland/meta-wayland-buffer.h96
-rw-r--r--src/wayland/meta-wayland-client.c335
-rw-r--r--src/wayland/meta-wayland-cursor-surface.c401
-rw-r--r--src/wayland/meta-wayland-cursor-surface.h52
-rw-r--r--src/wayland/meta-wayland-data-device-primary-legacy.c359
-rw-r--r--src/wayland/meta-wayland-data-device-primary-legacy.h55
-rw-r--r--src/wayland/meta-wayland-data-device-primary.c358
-rw-r--r--src/wayland/meta-wayland-data-device-primary.h55
-rw-r--r--src/wayland/meta-wayland-data-device.c1147
-rw-r--r--src/wayland/meta-wayland-data-device.h91
-rw-r--r--src/wayland/meta-wayland-data-offer-primary-legacy.c139
-rw-r--r--src/wayland/meta-wayland-data-offer-primary-legacy.h31
-rw-r--r--src/wayland/meta-wayland-data-offer-primary.c139
-rw-r--r--src/wayland/meta-wayland-data-offer-primary.h31
-rw-r--r--src/wayland/meta-wayland-data-offer.c327
-rw-r--r--src/wayland/meta-wayland-data-offer.h51
-rw-r--r--src/wayland/meta-wayland-data-source-primary-legacy.c117
-rw-r--r--src/wayland/meta-wayland-data-source-primary-legacy.h37
-rw-r--r--src/wayland/meta-wayland-data-source-primary.c117
-rw-r--r--src/wayland/meta-wayland-data-source-primary.h37
-rw-r--r--src/wayland/meta-wayland-data-source.c523
-rw-r--r--src/wayland/meta-wayland-data-source.h112
-rw-r--r--src/wayland/meta-wayland-dma-buf.c784
-rw-r--r--src/wayland/meta-wayland-dma-buf.h56
-rw-r--r--src/wayland/meta-wayland-dnd-surface.c152
-rw-r--r--src/wayland/meta-wayland-dnd-surface.h31
-rw-r--r--src/wayland/meta-wayland-egl-stream.c367
-rw-r--r--src/wayland/meta-wayland-egl-stream.h54
-rw-r--r--src/wayland/meta-wayland-gtk-shell.c565
-rw-r--r--src/wayland/meta-wayland-gtk-shell.h31
-rw-r--r--src/wayland/meta-wayland-inhibit-shortcuts-dialog.c187
-rw-r--r--src/wayland/meta-wayland-inhibit-shortcuts-dialog.h31
-rw-r--r--src/wayland/meta-wayland-inhibit-shortcuts.c188
-rw-r--r--src/wayland/meta-wayland-inhibit-shortcuts.h39
-rw-r--r--src/wayland/meta-wayland-input-device.c129
-rw-r--r--src/wayland/meta-wayland-input-device.h48
-rw-r--r--src/wayland/meta-wayland-keyboard.c873
-rw-r--r--src/wayland/meta-wayland-keyboard.h140
-rw-r--r--src/wayland/meta-wayland-legacy-xdg-shell.c2105
-rw-r--r--src/wayland/meta-wayland-legacy-xdg-shell.h53
-rw-r--r--src/wayland/meta-wayland-outputs.c750
-rw-r--r--src/wayland/meta-wayland-outputs.h55
-rw-r--r--src/wayland/meta-wayland-pointer-constraints.c1201
-rw-r--r--src/wayland/meta-wayland-pointer-constraints.h47
-rw-r--r--src/wayland/meta-wayland-pointer-gesture-pinch.c166
-rw-r--r--src/wayland/meta-wayland-pointer-gesture-pinch.h39
-rw-r--r--src/wayland/meta-wayland-pointer-gesture-swipe.c162
-rw-r--r--src/wayland/meta-wayland-pointer-gesture-swipe.h39
-rw-r--r--src/wayland/meta-wayland-pointer-gestures.c83
-rw-r--r--src/wayland/meta-wayland-pointer-gestures.h32
-rw-r--r--src/wayland/meta-wayland-pointer.c1370
-rw-r--r--src/wayland/meta-wayland-pointer.h158
-rw-r--r--src/wayland/meta-wayland-popup.c308
-rw-r--r--src/wayland/meta-wayland-popup.h62
-rw-r--r--src/wayland/meta-wayland-presentation-time-private.h67
-rw-r--r--src/wayland/meta-wayland-presentation-time.c417
-rw-r--r--src/wayland/meta-wayland-private.h107
-rw-r--r--src/wayland/meta-wayland-region.c105
-rw-r--r--src/wayland/meta-wayland-region.h41
-rw-r--r--src/wayland/meta-wayland-seat.c556
-rw-r--r--src/wayland/meta-wayland-seat.h87
-rw-r--r--src/wayland/meta-wayland-shell-surface.c380
-rw-r--r--src/wayland/meta-wayland-shell-surface.h68
-rw-r--r--src/wayland/meta-wayland-subsurface.c612
-rw-r--r--src/wayland/meta-wayland-subsurface.h58
-rw-r--r--src/wayland/meta-wayland-surface.c2133
-rw-r--r--src/wayland/meta-wayland-surface.h399
-rw-r--r--src/wayland/meta-wayland-tablet-cursor-surface.c43
-rw-r--r--src/wayland/meta-wayland-tablet-cursor-surface.h33
-rw-r--r--src/wayland/meta-wayland-tablet-manager.c244
-rw-r--r--src/wayland/meta-wayland-tablet-manager.h53
-rw-r--r--src/wayland/meta-wayland-tablet-pad-group.c385
-rw-r--r--src/wayland/meta-wayland-tablet-pad-group.h73
-rw-r--r--src/wayland/meta-wayland-tablet-pad-ring.c206
-rw-r--r--src/wayland/meta-wayland-tablet-pad-ring.h59
-rw-r--r--src/wayland/meta-wayland-tablet-pad-strip.c205
-rw-r--r--src/wayland/meta-wayland-tablet-pad-strip.h59
-rw-r--r--src/wayland/meta-wayland-tablet-pad.c563
-rw-r--r--src/wayland/meta-wayland-tablet-pad.h81
-rw-r--r--src/wayland/meta-wayland-tablet-seat.c571
-rw-r--r--src/wayland/meta-wayland-tablet-seat.h81
-rw-r--r--src/wayland/meta-wayland-tablet-tool.c912
-rw-r--r--src/wayland/meta-wayland-tablet-tool.h87
-rw-r--r--src/wayland/meta-wayland-tablet.c129
-rw-r--r--src/wayland/meta-wayland-tablet.h58
-rw-r--r--src/wayland/meta-wayland-text-input-legacy.c633
-rw-r--r--src/wayland/meta-wayland-text-input-legacy.h43
-rw-r--r--src/wayland/meta-wayland-text-input.c766
-rw-r--r--src/wayland/meta-wayland-text-input.h47
-rw-r--r--src/wayland/meta-wayland-touch.c616
-rw-r--r--src/wayland/meta-wayland-touch.h78
-rw-r--r--src/wayland/meta-wayland-types.h66
-rw-r--r--src/wayland/meta-wayland-versions.h63
-rw-r--r--src/wayland/meta-wayland-viewporter.c237
-rw-r--r--src/wayland/meta-wayland-viewporter.h30
-rw-r--r--src/wayland/meta-wayland-window-configuration.c131
-rw-r--r--src/wayland/meta-wayland-window-configuration.h70
-rw-r--r--src/wayland/meta-wayland-wl-shell.c777
-rw-r--r--src/wayland/meta-wayland-wl-shell.h33
-rw-r--r--src/wayland/meta-wayland-xdg-foreign.c462
-rw-r--r--src/wayland/meta-wayland-xdg-foreign.h34
-rw-r--r--src/wayland/meta-wayland-xdg-shell.c2437
-rw-r--r--src/wayland/meta-wayland-xdg-shell.h53
-rw-r--r--src/wayland/meta-wayland.c741
-rw-r--r--src/wayland/meta-wayland.h95
-rw-r--r--src/wayland/meta-window-wayland.c1195
-rw-r--r--src/wayland/meta-window-wayland.h80
-rw-r--r--src/wayland/meta-window-xwayland.c305
-rw-r--r--src/wayland/meta-window-xwayland.h34
-rw-r--r--src/wayland/meta-xwayland-dnd-private.h34
-rw-r--r--src/wayland/meta-xwayland-dnd.c991
-rw-r--r--src/wayland/meta-xwayland-grab-keyboard.c346
-rw-r--r--src/wayland/meta-xwayland-grab-keyboard.h41
-rw-r--r--src/wayland/meta-xwayland-private.h59
-rw-r--r--src/wayland/meta-xwayland-surface.c257
-rw-r--r--src/wayland/meta-xwayland-surface.h38
-rw-r--r--src/wayland/meta-xwayland.c1417
-rw-r--r--src/wayland/meta-xwayland.h53
-rw-r--r--src/wayland/protocol/gtk-primary-selection.xml225
-rw-r--r--src/wayland/protocol/gtk-shell.xml90
-rw-r--r--src/wayland/protocol/gtk-text-input.xml302
-rw-r--r--src/x11/atomnames.h186
-rw-r--r--src/x11/events.c1936
-rw-r--r--src/x11/events.h31
-rw-r--r--src/x11/group-private.h41
-rw-r--r--src/x11/group-props.c235
-rw-r--r--src/x11/group-props.h37
-rw-r--r--src/x11/group.c332
-rw-r--r--src/x11/iconcache.c575
-rw-r--r--src/x11/iconcache.h75
-rw-r--r--src/x11/meta-selection-source-x11-private.h44
-rw-r--r--src/x11/meta-selection-source-x11.c275
-rw-r--r--src/x11/meta-startup-notification-x11.c377
-rw-r--r--src/x11/meta-startup-notification-x11.h44
-rw-r--r--src/x11/meta-x11-display-private.h261
-rw-r--r--src/x11/meta-x11-display.c2320
-rw-r--r--src/x11/meta-x11-errors.c65
-rw-r--r--src/x11/meta-x11-selection-input-stream-private.h54
-rw-r--r--src/x11/meta-x11-selection-input-stream.c572
-rw-r--r--src/x11/meta-x11-selection-output-stream-private.h47
-rw-r--r--src/x11/meta-x11-selection-output-stream.c686
-rw-r--r--src/x11/meta-x11-selection-private.h34
-rw-r--r--src/x11/meta-x11-selection.c551
-rw-r--r--src/x11/meta-x11-stack-private.h33
-rw-r--r--src/x11/meta-x11-stack.c355
-rw-r--r--src/x11/meta-x11-window-control.c265
-rw-r--r--src/x11/meta-x11-window-control.h81
-rw-r--r--src/x11/mutter-Xatomtype.h136
-rw-r--r--src/x11/session.c1860
-rw-r--r--src/x11/session.h90
-rw-r--r--src/x11/window-props.c2012
-rw-r--r--src/x11/window-props.h95
-rw-r--r--src/x11/window-x11-private.h89
-rw-r--r--src/x11/window-x11.c4223
-rw-r--r--src/x11/window-x11.h103
-rw-r--r--src/x11/xprops.c1126
-rw-r--r--src/x11/xprops.h196
880 files changed, 0 insertions, 265156 deletions
diff --git a/src/backends/edid-parse.c b/src/backends/edid-parse.c
deleted file mode 100644
index a7b9fd225..000000000
--- a/src/backends/edid-parse.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * 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
deleted file mode 100644
index f07fd9e55..000000000
--- a/src/backends/edid.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/* 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
deleted file mode 100644
index 40698f96a..000000000
--- a/src/backends/gsm-inhibitor-flag.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 81104e2d0..000000000
--- a/src/backends/meta-backend-private.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/* -*- 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-mapper-private.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/meta-context-private.h"
-#include "core/util-private.h"
-
-#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 * (* get_cursor_renderer) (MetaBackend *backend,
- ClutterInputDevice *device);
- MetaCursorTracker * (* create_cursor_tracker) (MetaBackend *backend);
- MetaRenderer * (* create_renderer) (MetaBackend *backend,
- GError **error);
- MetaInputSettings * (* get_input_settings) (MetaBackend *backend);
-
- ClutterSeat * (* create_default_seat) (MetaBackend *backend,
- GError **error);
-
- 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_pointer_constraint) (MetaBackend *backend,
- MetaPointerConstraint *constraint);
-};
-
-void meta_backend_destroy (MetaBackend *backend);
-
-void meta_backend_prepare_shutdown (MetaBackend *backend);
-
-ClutterBackend * meta_backend_get_clutter_backend (MetaBackend *backend);
-
-ClutterSeat * meta_backend_get_default_seat (MetaBackend *bakcend);
-
-MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend,
- ClutterInputDevice *device);
-
-MetaIdleManager * meta_backend_get_idle_manager (MetaBackend *backend);
-
-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_for_device (MetaBackend *backend,
- ClutterInputDevice *device);
-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);
-
-MetaScreenCast * meta_backend_get_screen_cast (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_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);
-
-MetaInputMapper *meta_backend_get_input_mapper (MetaBackend *backend);
-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
-
-void meta_backend_add_hw_cursor_inhibitor (MetaBackend *backend,
- MetaHwCursorInhibitor *inhibitor);
-
-void meta_backend_remove_hw_cursor_inhibitor (MetaBackend *backend,
- MetaHwCursorInhibitor *inhibitor);
-
-gboolean meta_backend_is_hw_cursors_inhibited (MetaBackend *backend);
-
-#endif /* META_BACKEND_PRIVATE_H */
diff --git a/src/backends/meta-backend-types.h b/src/backends/meta-backend-types.h
deleted file mode 100644
index c5e46d87a..000000000
--- a/src/backends/meta-backend-types.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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 _MetaBackend MetaBackend;
-
-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 _MetaCrtcAssignment MetaCrtcAssignment;
-typedef struct _MetaOutputAssignment MetaOutputAssignment;
-
-typedef struct _MetaTileInfo MetaTileInfo;
-
-typedef struct _MetaRenderer MetaRenderer;
-typedef struct _MetaRendererView MetaRendererView;
-
-typedef struct _MetaRemoteDesktop MetaRemoteDesktop;
-typedef struct _MetaScreenCast MetaScreenCast;
-typedef struct _MetaScreenCastSession MetaScreenCastSession;
-typedef struct _MetaScreenCastStream MetaScreenCastStream;
-
-typedef struct _MetaVirtualMonitor MetaVirtualMonitor;
-typedef struct _MetaVirtualMonitorInfo MetaVirtualMonitorInfo;
-
-typedef struct _MetaIdleManager MetaIdleManager;
-
-#ifdef HAVE_REMOTE_DESKTOP
-typedef struct _MetaRemoteDesktop MetaRemoteDesktop;
-#endif
-
-#endif /* META_BACKEND_TYPE_H */
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
deleted file mode 100644
index d4cd5d10f..000000000
--- a/src/backends/meta-backend.c
+++ /dev/null
@@ -1,1663 +0,0 @@
-/* -*- 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 with 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-renderer.h"
-#include "backends/meta-cursor-tracker-private.h"
-#include "backends/meta-idle-manager.h"
-#include "backends/meta-idle-monitor-private.h"
-#include "backends/meta-input-mapper-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 "clutter/clutter-seat-private.h"
-#include "core/meta-context-private.h"
-#include "meta/main.h"
-#include "meta/meta-backend.h"
-#include "meta/meta-context.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
-{
- PROP_0,
-
- PROP_CONTEXT,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS];
-
-enum
-{
- KEYMAP_CHANGED,
- KEYMAP_LAYOUT_GROUP_CHANGED,
- LAST_DEVICE_CHANGED,
- LID_IS_CLOSED_CHANGED,
- GPU_ADDED,
- PREPARE_SHUTDOWN,
-
- 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
-{
- MetaContext *context;
-
- MetaMonitorManager *monitor_manager;
- MetaOrientationManager *orientation_manager;
- MetaCursorTracker *cursor_tracker;
- MetaInputMapper *input_mapper;
- MetaIdleManager *idle_manager;
- 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_PROFILER
- MetaProfiler *profiler;
-#endif
-
-#ifdef HAVE_LIBWACOM
- WacomDeviceDatabase *wacom_db;
-#endif
-
- ClutterBackend *clutter_backend;
- ClutterSeat *default_seat;
- ClutterActor *stage;
-
- GList *gpus;
- GList *hw_cursor_inhibitors;
-
- gboolean is_pointer_position_initialized;
-
- guint device_update_idle_id;
-
- 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;
-};
-typedef struct _MetaBackendPrivate MetaBackendPrivate;
-
-typedef struct _MetaBackendSource MetaBackendSource;
-
-struct _MetaBackendSource
-{
- GSource parent;
- MetaBackend *backend;
-};
-
-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_dispose (GObject *object)
-{
- MetaBackend *backend = META_BACKEND (object);
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-
- _backend = NULL;
-
- g_clear_pointer (&priv->cursor_tracker, meta_cursor_tracker_destroy);
- g_clear_object (&priv->current_device);
- g_clear_object (&priv->monitor_manager);
- g_clear_object (&priv->orientation_manager);
-#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);
- priv->sleep_signal_id = 0;
- }
-
- if (priv->upower_watch_id)
- {
- g_bus_unwatch_name (priv->upower_watch_id);
- priv->upower_watch_id = 0;
- }
-
- 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_clear_object (&priv->settings);
-
-#ifdef HAVE_PROFILER
- g_clear_object (&priv->profiler);
-#endif
-
- g_clear_pointer (&priv->default_seat, clutter_seat_destroy);
- g_clear_pointer (&priv->stage, clutter_actor_destroy);
- g_clear_pointer (&priv->clutter_backend, clutter_backend_destroy);
- g_clear_pointer (&priv->idle_manager, meta_idle_manager_free);
- g_clear_object (&priv->renderer);
- g_clear_list (&priv->gpus, g_object_unref);
-
- G_OBJECT_CLASS (meta_backend_parent_class)->dispose (object);
-}
-
-void
-meta_backend_destroy (MetaBackend *backend)
-{
- g_object_run_dispose (G_OBJECT (backend));
- g_object_unref (backend);
-}
-
-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);
-}
-
-static gboolean
-should_have_cursor_renderer (ClutterInputDevice *device)
-{
- switch (clutter_input_device_get_device_type (device))
- {
- case CLUTTER_POINTER_DEVICE:
- if (clutter_input_device_get_device_mode (device) ==
- CLUTTER_INPUT_MODE_LOGICAL)
- return TRUE;
-
- return FALSE;
- case CLUTTER_TABLET_DEVICE:
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-static void
-update_cursors (MetaBackend *backend)
-{
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
- ClutterSeat *seat = clutter_backend_get_default_seat (priv->clutter_backend);
- MetaCursorRenderer *cursor_renderer;
- ClutterInputDevice *pointer, *device;
- GList *devices, *l;
-
- pointer = clutter_seat_get_pointer (seat);
- devices = clutter_seat_list_devices (seat);
- devices = g_list_prepend (devices, pointer);
-
- for (l = devices; l; l = l->next)
- {
- device = l->data;
-
- if (!should_have_cursor_renderer (device))
- continue;
-
- cursor_renderer = meta_backend_get_cursor_renderer_for_device (backend,
- device);
- if (cursor_renderer)
- meta_cursor_renderer_force_update (cursor_renderer);
- }
-
- g_list_free (devices);
-}
-
-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_seat_query_state (seat, device, NULL, &point, NULL))
- {
- /* 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;
- }
- }
-
- update_cursors (backend);
-}
-
-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_LOGICAL)
- 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 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);
- ClutterInputDeviceType device_type;
-
- if (clutter_input_device_get_device_mode (device) ==
- CLUTTER_INPUT_MODE_LOGICAL)
- return;
-
- device_type = clutter_input_device_get_device_type (device);
-
- if (device_type == CLUTTER_TOUCHSCREEN_DEVICE)
- meta_cursor_tracker_set_pointer_visible (priv->cursor_tracker, FALSE);
- else if (device_type == CLUTTER_POINTER_DEVICE &&
- !clutter_seat_has_touchscreen (seat))
- meta_cursor_tracker_set_pointer_visible (priv->cursor_tracker, TRUE);
-
- if (device_type == CLUTTER_TOUCHSCREEN_DEVICE ||
- 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)
- meta_input_mapper_add_device (priv->input_mapper, device);
-}
-
-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);
-
- if (clutter_input_device_get_device_mode (device) ==
- CLUTTER_INPUT_MODE_LOGICAL)
- return;
-
- meta_input_mapper_remove_device (priv->input_mapper, 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 = clutter_seat_has_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
-input_mapper_device_mapped_cb (MetaInputMapper *mapper,
- ClutterInputDevice *device,
- float matrix[6],
- MetaInputSettings *input_settings)
-{
- meta_input_settings_set_device_matrix (input_settings, device, matrix);
-}
-
-static void
-input_mapper_device_enabled_cb (MetaInputMapper *mapper,
- ClutterInputDevice *device,
- gboolean enabled,
- MetaInputSettings *input_settings)
-{
- meta_input_settings_set_device_enabled (input_settings, device, enabled);
-}
-
-static void
-input_mapper_device_aspect_ratio_cb (MetaInputMapper *mapper,
- ClutterInputDevice *device,
- double aspect_ratio,
- MetaInputSettings *input_settings)
-{
- meta_input_settings_set_device_aspect_ratio (input_settings, device, aspect_ratio);
-}
-
-static void
-on_stage_shown_cb (MetaBackend *backend)
-{
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
- ClutterSeat *seat = clutter_backend_get_default_seat (priv->clutter_backend);
- g_autoptr (GList) devices = NULL;
- const GList *l;
-
- 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_LOGICAL)
- continue;
-
- if (clutter_input_device_get_device_type (device) !=
- CLUTTER_POINTER_DEVICE)
- continue;
-
- meta_cursor_tracker_set_pointer_visible (priv->cursor_tracker, TRUE);
- break;
- }
-}
-
-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);
- MetaInputSettings *input_settings;
-
- priv->stage = meta_stage_new (backend);
- clutter_actor_realize (priv->stage);
- META_BACKEND_GET_CLASS (backend)->select_stage_events (backend);
- g_signal_connect_object (priv->stage, "show",
- G_CALLBACK (on_stage_shown_cb), backend,
- G_CONNECT_SWAPPED);
-
- meta_monitor_manager_setup (priv->monitor_manager);
-
- meta_backend_sync_screen_size (backend);
-
- priv->idle_manager = meta_idle_manager_new (backend);
-
- 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_mapper = meta_input_mapper_new ();
-
- input_settings = meta_backend_get_input_settings (backend);
-
- if (input_settings)
- {
- g_signal_connect (priv->input_mapper, "device-mapped",
- G_CALLBACK (input_mapper_device_mapped_cb),
- input_settings);
- g_signal_connect (priv->input_mapper, "device-enabled",
- G_CALLBACK (input_mapper_device_enabled_cb),
- input_settings);
- g_signal_connect (priv->input_mapper, "device-aspect-ratio",
- G_CALLBACK (input_mapper_device_aspect_ratio_cb),
- input_settings);
- }
-
-#ifdef HAVE_REMOTE_DESKTOP
- 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 (backend,
- priv->dbus_session_watcher);
- priv->remote_access_controller =
- meta_remote_access_controller_new (priv->remote_desktop, priv->screen_cast);
-#endif /* HAVE_REMOTE_DESKTOP */
-
- if (!meta_monitor_manager_is_headless (priv->monitor_manager))
- {
- reset_pointer_position (backend);
- priv->is_pointer_position_initialized = TRUE;
- }
-
- meta_monitor_manager_post_init (priv->monitor_manager);
-}
-
-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;
-}
-
-static MetaCursorTracker *
-meta_backend_real_create_cursor_tracker (MetaBackend *backend)
-{
- return g_object_new (META_TYPE_CURSOR_TRACKER,
- "backend", backend,
- NULL);
-}
-
-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_manager_reset_idle_time (priv->idle_manager);
-}
-
-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);
-
- g_assert (priv->context);
-
-#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_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaBackend *backend = META_BACKEND (object);
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-
- switch (prop_id)
- {
- case PROP_CONTEXT:
- priv->context = g_value_get_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_backend_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaBackend *backend = META_BACKEND (object);
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-
- switch (prop_id)
- {
- case PROP_CONTEXT:
- g_value_set_object (value, priv->context);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_backend_class_init (MetaBackendClass *klass)
-{
- const gchar *mutter_stage_views;
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->dispose = meta_backend_dispose;
- object_class->constructed = meta_backend_constructed;
- object_class->set_property = meta_backend_set_property;
- object_class->get_property = meta_backend_get_property;
-
- klass->post_init = meta_backend_real_post_init;
- 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;
- klass->create_cursor_tracker = meta_backend_real_create_cursor_tracker;
-
- obj_props[PROP_CONTEXT] =
- g_param_spec_object ("context",
- "context",
- "MetaContext",
- META_TYPE_CONTEXT,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, N_PROPS, obj_props);
-
- 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);
- signals[PREPARE_SHUTDOWN] =
- g_signal_new ("prepare-shutdown",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
- 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)
-{
- 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)
-{
- MetaBackend *backend = user_data;
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
- gboolean suspending;
-
- g_variant_get (parameters, "(b)", &suspending);
- if (suspending)
- return;
-
- meta_idle_manager_reset_idle_time (priv->idle_manager);
-}
-
-static void
-system_bus_gotten_cb (GObject *object,
- GAsyncResult *res,
- gpointer user_data)
-{
- MetaBackend *backend = user_data;
- MetaBackendPrivate *priv;
- GDBusConnection *bus;
-
- bus = g_bus_get_finish (res, NULL);
- if (!bus)
- return;
-
- priv = meta_backend_get_instance_private (backend);
- 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,
- backend,
- NULL);
-}
-
-/* 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)
-{
- MetaBackendSource *backend_source = (MetaBackendSource *) source;
- ClutterEvent *event = clutter_event_get ();
-
- if (event)
- {
- event->any.stage =
- CLUTTER_STAGE (meta_backend_get_stage (backend_source->backend));
- 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 ClutterSeat *
-meta_backend_create_default_seat (MetaBackend *backend,
- GError **error)
-{
- return META_BACKEND_GET_CLASS (backend)->create_default_seat (backend, error);
-}
-
-static gboolean
-init_clutter (MetaBackend *backend,
- GError **error)
-{
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
- MetaBackendSource *backend_source;
- 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;
- }
-
- priv->default_seat = meta_backend_create_default_seat (backend, error);
- if (!priv->default_seat)
- return FALSE;
-
- source = g_source_new (&clutter_source_funcs, sizeof (MetaBackendSource));
- backend_source = (MetaBackendSource *) source;
- backend_source->backend = backend;
- 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 =
- META_BACKEND_GET_CLASS (backend)->create_cursor_tracker (backend);
-
- 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 meta_idle_manager_get_monitor (priv->idle_manager, device);
-}
-
-/**
- * meta_backend_get_core_idle_monitor:
- *
- * Returns: (transfer none): the #MetaIdleMonitor that tracks server-global
- * idle time for all devices.
- */
-MetaIdleMonitor *
-meta_backend_get_core_idle_monitor (MetaBackend *backend)
-{
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-
- return meta_idle_manager_get_core_monitor (priv->idle_manager);
-}
-
-/**
- * meta_backend_get_idle_manager: (skip)
- */
-MetaIdleManager *
-meta_backend_get_idle_manager (MetaBackend *backend)
-{
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-
- return priv->idle_manager;
-}
-
-/**
- * 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);
- ClutterInputDevice *pointer;
- ClutterSeat *seat;
-
- seat = clutter_backend_get_default_seat (priv->clutter_backend);
- pointer = clutter_seat_get_pointer (seat);
-
- return meta_backend_get_cursor_renderer_for_device (backend, pointer);
-}
-
-MetaCursorRenderer *
-meta_backend_get_cursor_renderer_for_device (MetaBackend *backend,
- ClutterInputDevice *device)
-{
- g_return_val_if_fail (META_IS_BACKEND (backend), NULL);
- g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
- g_return_val_if_fail (clutter_input_device_get_device_type (device) !=
- CLUTTER_KEYBOARD_DEVICE, NULL);
-
- return META_BACKEND_GET_CLASS (backend)->get_cursor_renderer (backend,
- device);
-}
-
-/**
- * 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;
-}
-
-/**
- * meta_backend_get_screen_cast: (skip)
- */
-MetaScreenCast *
-meta_backend_get_screen_cast (MetaBackend *backend)
-{
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-
- return priv->screen_cast;
-}
-#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_get_context:
- * @backend: the #MetaBackend
- *
- * Returns: (transfer none): The #MetaContext
- */
-MetaContext *
-meta_backend_get_context (MetaBackend *backend)
-{
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-
- return priv->context;
-}
-
-/**
- * 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);
-}
-
-/**
- * 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;
-}
-
-ClutterSeat *
-meta_backend_get_default_seat (MetaBackend *backend)
-{
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-
- return priv->default_seat;
-}
-
-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_LOGICAL)
- 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 @constraint 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);
-
- META_BACKEND_GET_CLASS (backend)->set_pointer_constraint (backend, constraint);
- g_set_object (&priv->client_pointer_constraint, 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_backend_prepare_shutdown (MetaBackend *backend)
-{
- g_signal_emit (backend, signals[PREPARE_SHUTDOWN], 0);
-}
-
-/**
- * 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;
-}
-
-MetaInputMapper *
-meta_backend_get_input_mapper (MetaBackend *backend)
-{
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-
- return priv->input_mapper;
-}
-
-MetaInputSettings *
-meta_backend_get_input_settings (MetaBackend *backend)
-{
- return META_BACKEND_GET_CLASS (backend)->get_input_settings (backend);
-}
-
-/**
- * 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
-
-void
-meta_backend_add_hw_cursor_inhibitor (MetaBackend *backend,
- MetaHwCursorInhibitor *inhibitor)
-{
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-
- priv->hw_cursor_inhibitors = g_list_prepend (priv->hw_cursor_inhibitors,
- inhibitor);
-}
-
-void
-meta_backend_remove_hw_cursor_inhibitor (MetaBackend *backend,
- MetaHwCursorInhibitor *inhibitor)
-{
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
-
- priv->hw_cursor_inhibitors = g_list_remove (priv->hw_cursor_inhibitors,
- inhibitor);
-}
-
-gboolean
-meta_backend_is_hw_cursors_inhibited (MetaBackend *backend)
-{
- MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
- GList *l;
-
- for (l = priv->hw_cursor_inhibitors; l; l = l->next)
- {
- MetaHwCursorInhibitor *inhibitor = l->data;
-
- if (meta_hw_cursor_inhibitor_is_cursor_inhibited (inhibitor))
- return TRUE;
- }
-
- return FALSE;
-}
diff --git a/src/backends/meta-barrier-private.h b/src/backends/meta-barrier-private.h
deleted file mode 100644
index d0483e43c..000000000
--- a/src/backends/meta-barrier-private.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- 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
deleted file mode 100644
index d924d0ab3..000000000
--- a/src/backends/meta-barrier.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/* -*- 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);
- g_return_if_fail (priv->border.line.a.x >= 0);
- g_return_if_fail (priv->border.line.a.y >= 0);
- g_return_if_fail (priv->border.line.b.x >= 0);
- g_return_if_fail (priv->border.line.b.y >= 0);
-
-#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_free (event);
-}
-
-G_DEFINE_BOXED_TYPE (MetaBarrierEvent,
- meta_barrier_event,
- meta_barrier_event_ref,
- meta_barrier_event_unref)
diff --git a/src/backends/meta-crtc-mode.c b/src/backends/meta-crtc-mode.c
deleted file mode 100644
index 6d2de4b74..000000000
--- a/src/backends/meta-crtc-mode.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2017-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.
- */
-
-#include "config.h"
-
-#include "backends/meta-crtc-mode.h"
-
-enum
-{
- PROP_0,
-
- PROP_ID,
- PROP_NAME,
- PROP_INFO,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS];
-
-typedef struct _MetaCrtcModePrivate
-{
- uint64_t id;
- char *name;
- MetaCrtcModeInfo *info;
-} MetaCrtcModePrivate;
-
-G_DEFINE_TYPE_WITH_PRIVATE (MetaCrtcMode, meta_crtc_mode, G_TYPE_OBJECT)
-
-G_DEFINE_BOXED_TYPE (MetaCrtcModeInfo, meta_crtc_mode_info,
- meta_crtc_mode_info_ref,
- meta_crtc_mode_info_unref)
-
-MetaCrtcModeInfo *
-meta_crtc_mode_info_new (void)
-{
- MetaCrtcModeInfo *crtc_mode_info;
-
- crtc_mode_info = g_new0 (MetaCrtcModeInfo, 1);
- g_ref_count_init (&crtc_mode_info->ref_count);
-
- return crtc_mode_info;
-}
-
-MetaCrtcModeInfo *
-meta_crtc_mode_info_ref (MetaCrtcModeInfo *crtc_mode_info)
-{
- g_ref_count_inc (&crtc_mode_info->ref_count);
- return crtc_mode_info;
-}
-
-void
-meta_crtc_mode_info_unref (MetaCrtcModeInfo *crtc_mode_info)
-{
- if (g_ref_count_dec (&crtc_mode_info->ref_count))
- g_free (crtc_mode_info);
-}
-
-uint64_t
-meta_crtc_mode_get_id (MetaCrtcMode *crtc_mode)
-{
- MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode);
-
- return priv->id;
-}
-
-const char *
-meta_crtc_mode_get_name (MetaCrtcMode *crtc_mode)
-{
- MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode);
-
- return priv->name;
-}
-
-const MetaCrtcModeInfo *
-meta_crtc_mode_get_info (MetaCrtcMode *crtc_mode)
-{
- MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode);
-
- return priv->info;
-}
-
-static void
-meta_crtc_mode_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaCrtcMode *crtc_mode = META_CRTC_MODE (object);
- MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode);
-
- switch (prop_id)
- {
- case PROP_ID:
- priv->id = g_value_get_uint64 (value);
- break;
- case PROP_NAME:
- priv->name = g_value_dup_string (value);
- break;
- case PROP_INFO:
- priv->info = meta_crtc_mode_info_ref (g_value_get_boxed (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-meta_crtc_mode_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaCrtcMode *crtc_mode = META_CRTC_MODE (object);
- MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode);
-
- switch (prop_id)
- {
- case PROP_ID:
- g_value_set_uint64 (value, priv->id);
- break;
- case PROP_NAME:
- g_value_set_string (value, priv->name);
- break;
- case PROP_INFO:
- g_value_set_boxed (value, priv->info);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-meta_crtc_mode_finalize (GObject *object)
-{
- MetaCrtcMode *crtc_mode = META_CRTC_MODE (object);
- MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode);
-
- g_clear_pointer (&priv->name, g_free);
- g_clear_pointer (&priv->info, meta_crtc_mode_info_unref);
-
- 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->set_property = meta_crtc_mode_set_property;
- object_class->get_property = meta_crtc_mode_get_property;
- object_class->finalize = meta_crtc_mode_finalize;
-
- obj_props[PROP_ID] =
- g_param_spec_uint64 ("id",
- "id",
- "CRTC mode id",
- 0, UINT64_MAX, 0,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- obj_props[PROP_NAME] =
- g_param_spec_string ("name",
- "name",
- "Name of CRTC mode",
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- obj_props[PROP_INFO] =
- g_param_spec_boxed ("info",
- "info",
- "MetaOutputInfo",
- META_TYPE_CRTC_MODE_INFO,
- 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-crtc-mode.h b/src/backends/meta-crtc-mode.h
deleted file mode 100644
index 2ac90e408..000000000
--- a/src/backends/meta-crtc-mode.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2017-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.
- */
-
-#ifndef META_CRTC_MODE_H
-#define META_CRTC_MODE_H
-
-#include <glib-object.h>
-#include <stdint.h>
-
-#include "core/util-private.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 _MetaCrtcModeInfo
-{
- grefcount ref_count;
-
- int width;
- int height;
- float refresh_rate;
- int64_t vblank_duration_us;
- MetaCrtcModeFlag flags;
-} MetaCrtcModeInfo;
-
-#define META_TYPE_CRTC_MODE (meta_crtc_mode_get_type ())
-META_EXPORT_TEST
-G_DECLARE_DERIVABLE_TYPE (MetaCrtcMode, meta_crtc_mode,
- META, CRTC_MODE,
- GObject)
-
-struct _MetaCrtcModeClass
-{
- GObjectClass parent_class;
-};
-
-#define META_TYPE_CRTC_MODE_INFO (meta_crtc_mode_info_get_type ())
-GType meta_crtc_mode_info_get_type (void);
-
-META_EXPORT_TEST
-MetaCrtcModeInfo * meta_crtc_mode_info_new (void);
-
-META_EXPORT_TEST
-MetaCrtcModeInfo * meta_crtc_mode_info_ref (MetaCrtcModeInfo *crtc_mode_info);
-
-META_EXPORT_TEST
-void meta_crtc_mode_info_unref (MetaCrtcModeInfo *crtc_mode_info);
-
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaCrtcModeInfo, meta_crtc_mode_info_unref)
-
-uint64_t meta_crtc_mode_get_id (MetaCrtcMode *crtc_mode);
-
-const char * meta_crtc_mode_get_name (MetaCrtcMode *crtc_mode);
-
-META_EXPORT_TEST
-const MetaCrtcModeInfo * meta_crtc_mode_get_info (MetaCrtcMode *crtc_mode);
-
-#endif /* META_CRTC_MODE_H */
diff --git a/src/backends/meta-crtc.c b/src/backends/meta-crtc.c
deleted file mode 100644
index 09f9199d5..000000000
--- a/src/backends/meta-crtc.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * 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"
-
-#include "backends/meta-gpu.h"
-
-enum
-{
- PROP_0,
-
- PROP_ID,
- PROP_GPU,
- PROP_ALL_TRANSFORMS,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS];
-
-typedef struct _MetaCrtcPrivate
-{
- uint64_t id;
-
- MetaGpu *gpu;
-
- MetaMonitorTransform all_transforms;
-
- GList *outputs;
- MetaCrtcConfig *config;
-} MetaCrtcPrivate;
-
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaCrtc, meta_crtc, G_TYPE_OBJECT)
-
-uint64_t
-meta_crtc_get_id (MetaCrtc *crtc)
-{
- MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
-
- return priv->id;
-}
-
-MetaGpu *
-meta_crtc_get_gpu (MetaCrtc *crtc)
-{
- MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
-
- return priv->gpu;
-}
-
-const GList *
-meta_crtc_get_outputs (MetaCrtc *crtc)
-{
- MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
-
- return priv->outputs;
-}
-
-void
-meta_crtc_assign_output (MetaCrtc *crtc,
- MetaOutput *output)
-{
- MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
-
- priv->outputs = g_list_append (priv->outputs, output);
-}
-
-void
-meta_crtc_unassign_output (MetaCrtc *crtc,
- MetaOutput *output)
-{
- MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
-
- g_return_if_fail (g_list_find (priv->outputs, output));
-
- priv->outputs = g_list_remove (priv->outputs, output);
-}
-
-MetaMonitorTransform
-meta_crtc_get_all_transforms (MetaCrtc *crtc)
-{
- MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
-
- return priv->all_transforms;
-}
-
-void
-meta_crtc_set_config (MetaCrtc *crtc,
- graphene_rect_t *layout,
- MetaCrtcMode *mode,
- MetaMonitorTransform transform)
-{
- MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
- MetaCrtcConfig *config;
-
- meta_crtc_unset_config (crtc);
-
- config = g_new0 (MetaCrtcConfig, 1);
- config->layout = *layout;
- config->mode = mode;
- config->transform = transform;
-
- priv->config = config;
-}
-
-void
-meta_crtc_unset_config (MetaCrtc *crtc)
-{
- MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
-
- g_clear_pointer (&priv->config, g_free);
-}
-
-const MetaCrtcConfig *
-meta_crtc_get_config (MetaCrtc *crtc)
-{
- MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
-
- return priv->config;
-}
-
-static void
-meta_crtc_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaCrtc *crtc = META_CRTC (object);
- MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
-
- switch (prop_id)
- {
- case PROP_ID:
- priv->id = g_value_get_uint64 (value);
- break;
- case PROP_GPU:
- priv->gpu = g_value_get_object (value);
- break;
- case PROP_ALL_TRANSFORMS:
- priv->all_transforms = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-meta_crtc_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaCrtc *crtc = META_CRTC (object);
- MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
-
- switch (prop_id)
- {
- case PROP_ID:
- g_value_set_uint64 (value, priv->id);
- break;
- case PROP_GPU:
- g_value_set_object (value, priv->gpu);
- break;
- case PROP_ALL_TRANSFORMS:
- g_value_set_uint (value, priv->all_transforms);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-meta_crtc_finalize (GObject *object)
-{
- MetaCrtc *crtc = META_CRTC (object);
- MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
-
- g_clear_pointer (&priv->config, g_free);
- g_clear_pointer (&priv->outputs, g_list_free);
-
- G_OBJECT_CLASS (meta_crtc_parent_class)->finalize (object);
-}
-
-static void
-meta_crtc_init (MetaCrtc *crtc)
-{
- MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
-
- priv->all_transforms = META_MONITOR_ALL_TRANSFORMS;
-}
-
-static void
-meta_crtc_class_init (MetaCrtcClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->set_property = meta_crtc_set_property;
- object_class->get_property = meta_crtc_get_property;
- object_class->finalize = meta_crtc_finalize;
-
- obj_props[PROP_ID] =
- g_param_spec_uint64 ("id",
- "id",
- "CRTC id",
- 0, UINT64_MAX, 0,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- obj_props[PROP_GPU] =
- g_param_spec_object ("gpu",
- "gpu",
- "MetaGpu",
- META_TYPE_GPU,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- obj_props[PROP_ALL_TRANSFORMS] =
- g_param_spec_uint ("all-transforms",
- "all-transforms",
- "All transforms",
- 0,
- META_MONITOR_ALL_TRANSFORMS,
- META_MONITOR_ALL_TRANSFORMS,
- 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-crtc.h b/src/backends/meta-crtc.h
deleted file mode 100644
index f6a3bc136..000000000
--- a/src/backends/meta-crtc.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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-crtc-mode.h"
-#include "backends/meta-monitor-transform.h"
-#include "core/util-private.h"
-#include "meta/boxes.h"
-
-typedef struct _MetaCrtcConfig
-{
- graphene_rect_t layout;
- MetaMonitorTransform transform;
- MetaCrtcMode *mode;
-} MetaCrtcConfig;
-
-#define META_TYPE_CRTC (meta_crtc_get_type ())
-META_EXPORT_TEST
-G_DECLARE_DERIVABLE_TYPE (MetaCrtc, meta_crtc, META, CRTC, GObject)
-
-struct _MetaCrtcClass
-{
- GObjectClass parent_class;
-};
-
-META_EXPORT_TEST
-uint64_t meta_crtc_get_id (MetaCrtc *crtc);
-
-META_EXPORT_TEST
-MetaGpu * meta_crtc_get_gpu (MetaCrtc *crtc);
-
-META_EXPORT_TEST
-const GList * meta_crtc_get_outputs (MetaCrtc *crtc);
-
-void meta_crtc_assign_output (MetaCrtc *crtc,
- MetaOutput *output);
-
-META_EXPORT_TEST
-void meta_crtc_unassign_output (MetaCrtc *crtc,
- MetaOutput *output);
-
-MetaMonitorTransform meta_crtc_get_all_transforms (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);
-
-META_EXPORT_TEST
-const MetaCrtcConfig * meta_crtc_get_config (MetaCrtc *crtc);
-
-#endif /* META_CRTC_H */
diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c
deleted file mode 100644
index 3353b17d3..000000000
--- a/src/backends/meta-cursor-renderer.c
+++ /dev/null
@@ -1,492 +0,0 @@
-/* -*- 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-backend-private.h"
-#include "backends/meta-logical-monitor.h"
-#include "backends/meta-stage-private.h"
-#include "clutter/clutter.h"
-#include "clutter/clutter-mutter.h"
-#include "cogl/cogl.h"
-#include "core/boxes-private.h"
-#include "meta/meta-backend.h"
-#include "meta/util.h"
-
-G_DEFINE_INTERFACE (MetaHwCursorInhibitor, meta_hw_cursor_inhibitor,
- G_TYPE_OBJECT)
-
-enum
-{
- PROP_0,
-
- PROP_BACKEND,
- PROP_DEVICE,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS];
-
-struct _MetaCursorRendererPrivate
-{
- MetaBackend *backend;
-
- float current_x;
- float current_y;
-
- ClutterInputDevice *device;
- MetaCursorSprite *displayed_cursor;
- MetaCursorSprite *overlay_cursor;
-
- MetaOverlay *stage_overlay;
- gboolean handled_by_backend;
- gulong after_paint_handler_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);
-
-gboolean
-meta_hw_cursor_inhibitor_is_cursor_inhibited (MetaHwCursorInhibitor *inhibitor)
-{
- MetaHwCursorInhibitorInterface *iface =
- META_HW_CURSOR_INHIBITOR_GET_IFACE (inhibitor);
-
- return iface->is_cursor_inhibited (inhibitor);
-}
-
-static void
-meta_hw_cursor_inhibitor_default_init (MetaHwCursorInhibitorInterface *iface)
-{
-}
-
-void
-meta_cursor_renderer_emit_painted (MetaCursorRenderer *renderer,
- MetaCursorSprite *cursor_sprite,
- ClutterStageView *stage_view)
-{
- g_signal_emit (renderer, signals[CURSOR_PAINTED], 0, cursor_sprite, stage_view);
-}
-
-static void
-align_cursor_position (MetaCursorRenderer *renderer,
- graphene_rect_t *rect)
-{
- MetaCursorRendererPrivate *priv =
- meta_cursor_renderer_get_instance_private (renderer);
- ClutterActor *stage = meta_backend_get_stage (priv->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);
-}
-
-void
-meta_cursor_renderer_update_stage_overlay (MetaCursorRenderer *renderer,
- MetaCursorSprite *cursor_sprite)
-{
- MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
- ClutterActor *stage = meta_backend_get_stage (priv->backend);
- CoglTexture *texture;
- graphene_rect_t rect = GRAPHENE_RECT_INIT_ZERO;
-
- g_set_object (&priv->overlay_cursor, cursor_sprite);
-
- 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)
- texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
- else
- texture = NULL;
-
- meta_overlay_set_visible (priv->stage_overlay, !priv->handled_by_backend);
- meta_stage_update_cursor_overlay (META_STAGE (stage), priv->stage_overlay,
- texture, &rect);
-}
-
-static void
-meta_cursor_renderer_after_paint (ClutterStage *stage,
- ClutterStageView *stage_view,
- MetaCursorRenderer *renderer)
-{
- MetaCursorRendererPrivate *priv =
- meta_cursor_renderer_get_instance_private (renderer);
-
- if (priv->displayed_cursor && !priv->handled_by_backend)
- {
- graphene_rect_t rect;
- MetaRectangle view_layout;
- graphene_rect_t view_rect;
-
- rect = meta_cursor_renderer_calculate_rect (renderer,
- priv->displayed_cursor);
- clutter_stage_view_get_layout (stage_view, &view_layout);
- view_rect = meta_rectangle_to_graphene_rect (&view_layout);
- if (graphene_rect_intersection (&rect, &view_rect, NULL))
- {
- meta_cursor_renderer_emit_painted (renderer,
- priv->displayed_cursor,
- stage_view);
- }
- }
-}
-
-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_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object);
- MetaCursorRendererPrivate *priv =
- meta_cursor_renderer_get_instance_private (renderer);
-
- switch (prop_id)
- {
- case PROP_BACKEND:
- g_value_set_object (value, priv->backend);
- break;
- case PROP_DEVICE:
- g_value_set_object (value, priv->device);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_cursor_renderer_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object);
- MetaCursorRendererPrivate *priv =
- meta_cursor_renderer_get_instance_private (renderer);
-
- switch (prop_id)
- {
- case PROP_BACKEND:
- priv->backend = g_value_get_object (value);
- break;
- case PROP_DEVICE:
- priv->device = g_value_get_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_cursor_renderer_finalize (GObject *object)
-{
- MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object);
- MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
- ClutterActor *stage = meta_backend_get_stage (priv->backend);
-
- if (priv->stage_overlay)
- meta_stage_remove_cursor_overlay (META_STAGE (stage), priv->stage_overlay);
-
- g_clear_signal_handler (&priv->after_paint_handler_id, stage);
-
- g_clear_object (&priv->displayed_cursor);
- g_clear_object (&priv->overlay_cursor);
-
- G_OBJECT_CLASS (meta_cursor_renderer_parent_class)->finalize (object);
-}
-
-static void
-meta_cursor_renderer_constructed (GObject *object)
-{
- MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object);
- MetaCursorRendererPrivate *priv =
- meta_cursor_renderer_get_instance_private (renderer);
- ClutterActor *stage;
-
- stage = meta_backend_get_stage (priv->backend);
- priv->after_paint_handler_id =
- g_signal_connect (stage, "after-paint",
- G_CALLBACK (meta_cursor_renderer_after_paint),
- renderer);
-
- G_OBJECT_CLASS (meta_cursor_renderer_parent_class)->constructed (object);
-}
-
-static void
-meta_cursor_renderer_class_init (MetaCursorRendererClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->get_property = meta_cursor_renderer_get_property;
- object_class->set_property = meta_cursor_renderer_set_property;
- object_class->finalize = meta_cursor_renderer_finalize;
- object_class->constructed = meta_cursor_renderer_constructed;
- klass->update_cursor = meta_cursor_renderer_real_update_cursor;
-
- 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);
- obj_props[PROP_DEVICE] =
- g_param_spec_object ("device",
- "device",
- "Input device",
- CLUTTER_TYPE_INPUT_DEVICE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, N_PROPS, obj_props);
-
- signals[CURSOR_PAINTED] = g_signal_new ("cursor-painted",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 2,
- G_TYPE_POINTER,
- CLUTTER_TYPE_STAGE_VIEW);
-}
-
-static void
-meta_cursor_renderer_init (MetaCursorRenderer *renderer)
-{
-}
-
-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 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.0f;
-
- cursor_rect = meta_cursor_renderer_calculate_rect (cursor_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);
-
- if (!graphene_rect_intersection (&cursor_rect,
- &logical_monitor_rect,
- NULL))
- continue;
-
- highest_scale = MAX (highest_scale, logical_monitor->scale);
- }
-
- return highest_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;
-
- if (cursor_sprite)
- {
- float scale = find_highest_logical_monitor_scale (priv->backend,
- cursor_sprite);
- meta_cursor_sprite_prepare_at (cursor_sprite,
- MAX (1, scale),
- (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;
-
- meta_cursor_renderer_update_stage_overlay (renderer, cursor_sprite);
-}
-
-MetaCursorRenderer *
-meta_cursor_renderer_new (MetaBackend *backend,
- ClutterInputDevice *device)
-{
- return g_object_new (META_TYPE_CURSOR_RENDERER,
- "backend", backend,
- "device", device,
- 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;
- g_set_object (&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_update_position (MetaCursorRenderer *renderer)
-{
- MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
- graphene_point_t pos;
-
- clutter_seat_query_state (clutter_input_device_get_seat (priv->device),
- priv->device, NULL, &pos, NULL);
- priv->current_x = pos.x;
- priv->current_y = pos.y;
-
- meta_cursor_renderer_update_cursor (renderer, priv->displayed_cursor);
-}
-
-MetaCursorSprite *
-meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
-{
- MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
-
- return priv->overlay_cursor;
-}
-
-gboolean
-meta_cursor_renderer_is_overlay_visible (MetaCursorRenderer *renderer)
-{
- MetaCursorRendererPrivate *priv =
- meta_cursor_renderer_get_instance_private (renderer);
-
- if (!priv->stage_overlay)
- return FALSE;
-
- return meta_overlay_is_visible (priv->stage_overlay);
-}
-
-ClutterInputDevice *
-meta_cursor_renderer_get_input_device (MetaCursorRenderer *renderer)
-{
- MetaCursorRendererPrivate *priv =
- meta_cursor_renderer_get_instance_private (renderer);
-
- return priv->device;
-}
diff --git a/src/backends/meta-cursor-renderer.h b/src/backends/meta-cursor-renderer.h
deleted file mode 100644
index f6de01bfb..000000000
--- a/src/backends/meta-cursor-renderer.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- 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_inhibited) (MetaHwCursorInhibitor *inhibitor);
-};
-
-gboolean meta_hw_cursor_inhibitor_is_cursor_inhibited (MetaHwCursorInhibitor *inhibitor);
-
-#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 (MetaBackend *backend,
- ClutterInputDevice *device);
-
-void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
- MetaCursorSprite *cursor_sprite);
-
-void meta_cursor_renderer_update_position (MetaCursorRenderer *renderer);
-void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer);
-
-MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
-
-gboolean meta_cursor_renderer_is_overlay_visible (MetaCursorRenderer *renderer);
-
-graphene_rect_t meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
- MetaCursorSprite *cursor_sprite);
-
-void meta_cursor_renderer_emit_painted (MetaCursorRenderer *renderer,
- MetaCursorSprite *cursor_sprite,
- ClutterStageView *stage_view);
-ClutterInputDevice * meta_cursor_renderer_get_input_device (MetaCursorRenderer *renderer);
-
-void meta_cursor_renderer_update_stage_overlay (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
deleted file mode 100644
index 5284f28ea..000000000
--- a/src/backends/meta-cursor-sprite-xcursor.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * 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_BLANK:
- case META_CURSOR_NONE:
- case META_CURSOR_LAST:
- break;
- }
-
- g_assert_not_reached ();
- return NULL;
-}
-
-static Cursor
-create_blank_cursor (Display *xdisplay)
-{
- Pixmap pixmap;
- XColor color;
- Cursor cursor;
- XGCValues gc_values;
- GC gc;
-
- pixmap = XCreatePixmap (xdisplay, DefaultRootWindow (xdisplay), 1, 1, 1);
-
- gc_values.foreground = BlackPixel (xdisplay, DefaultScreen (xdisplay));
- gc = XCreateGC (xdisplay, pixmap, GCForeground, &gc_values);
-
- XFillRectangle (xdisplay, pixmap, gc, 0, 0, 1, 1);
-
- color.pixel = 0;
- color.red = color.blue = color.green = 0;
-
- cursor = XCreatePixmapCursor (xdisplay, pixmap, pixmap, &color, &color, 1, 1);
-
- XFreeGC (xdisplay, gc);
- XFreePixmap (xdisplay, pixmap);
-
- return cursor;
-}
-
-static XcursorImages *
-create_blank_cursor_images (void)
-{
- XcursorImages *images;
-
- images = XcursorImagesCreate (1);
- images->images[0] = XcursorImageCreate (1, 1);
-
- images->images[0]->xhot = 0;
- images->images[0]->yhot = 0;
- memset (images->images[0]->pixels, 0, sizeof(int32_t));
-
- return images;
-}
-
-MetaCursor
-meta_cursor_sprite_xcursor_get_cursor (MetaCursorSpriteXcursor *sprite_xcursor)
-{
- return sprite_xcursor->cursor;
-}
-
-Cursor
-meta_create_x_cursor (Display *xdisplay,
- MetaCursor cursor)
-{
- if (cursor == META_CURSOR_BLANK)
- return create_blank_cursor (xdisplay);
-
- return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor));
-}
-
-static XcursorImages *
-load_cursor_on_client (MetaCursor cursor, int scale)
-{
- XcursorImages *xcursor_images;
- int fallback_size;
-
- if (cursor == META_CURSOR_BLANK)
- return create_blank_cursor_images ();
-
- 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_once ("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", 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
deleted file mode 100644
index dbc927484..000000000
--- a/src/backends/meta-cursor-sprite-xcursor.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 2d8d38042..000000000
--- a/src/backends/meta-cursor-tracker-private.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- 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 "meta/meta-cursor-tracker.h"
-
-struct _MetaCursorTrackerClass
-{
- GObjectClass parent_class;
-
- void (* set_force_track_position) (MetaCursorTracker *tracker,
- gboolean is_enabled);
- MetaCursorSprite * (* get_sprite) (MetaCursorTracker *tracker);
-};
-
-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_invalidate_position (MetaCursorTracker *tracker);
-
-void meta_cursor_tracker_track_position (MetaCursorTracker *tracker);
-
-void meta_cursor_tracker_untrack_position (MetaCursorTracker *tracker);
-
-MetaBackend * meta_cursor_tracker_get_backend (MetaCursorTracker *tracker);
-
-void meta_cursor_tracker_notify_cursor_changed (MetaCursorTracker *tracker);
-
-void meta_cursor_tracker_destroy (MetaCursorTracker *tracker);
-
-#endif
diff --git a/src/backends/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c
deleted file mode 100644
index 24776e266..000000000
--- a/src/backends/meta-cursor-tracker.c
+++ /dev/null
@@ -1,514 +0,0 @@
-/* -*- 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 <string.h>
-
-#include "backends/meta-backend-private.h"
-#include "cogl/cogl.h"
-#include "core/display-private.h"
-#include "clutter/clutter.h"
-#include "meta/main.h"
-#include "meta/util.h"
-
-enum
-{
- PROP_0,
-
- PROP_BACKEND,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS];
-
-typedef struct _MetaCursorTrackerPrivate
-{
- MetaBackend *backend;
-
- gboolean is_showing;
-
- int track_position_count;
-
- float x;
- float y;
-
- 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;
-} MetaCursorTrackerPrivate;
-
-G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorTracker, meta_cursor_tracker,
- G_TYPE_OBJECT)
-
-enum
-{
- CURSOR_CHANGED,
- POSITION_INVALIDATED,
- VISIBILITY_CHANGED,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-void
-meta_cursor_tracker_notify_cursor_changed (MetaCursorTracker *tracker)
-{
- g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
-}
-
-static void
-cursor_texture_updated (MetaCursorSprite *cursor,
- MetaCursorTracker *tracker)
-{
- g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
-}
-
-static gboolean
-update_displayed_cursor (MetaCursorTracker *tracker)
-{
- MetaCursorTrackerPrivate *priv =
- meta_cursor_tracker_get_instance_private (tracker);
- MetaDisplay *display = meta_get_display ();
- MetaCursorSprite *cursor = NULL;
-
- if (display && meta_display_windows_are_interactable (display) &&
- priv->has_window_cursor)
- cursor = priv->window_cursor;
- else
- cursor = priv->root_cursor;
-
- if (priv->displayed_cursor == cursor)
- return FALSE;
-
- if (priv->displayed_cursor)
- {
- g_signal_handlers_disconnect_by_func (priv->displayed_cursor,
- cursor_texture_updated,
- tracker);
- }
-
- g_set_object (&priv->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)
-{
- MetaCursorTrackerPrivate *priv =
- meta_cursor_tracker_get_instance_private (tracker);
- MetaCursorSprite *cursor = NULL;
-
- if (priv->is_showing)
- cursor = priv->displayed_cursor;
-
- return g_set_object (&priv->effective_cursor, cursor);
-}
-
-static void
-change_cursor_renderer (MetaCursorTracker *tracker)
-{
- MetaCursorTrackerPrivate *priv =
- meta_cursor_tracker_get_instance_private (tracker);
- MetaCursorRenderer *cursor_renderer =
- meta_backend_get_cursor_renderer (priv->backend);
-
- meta_cursor_renderer_set_cursor (cursor_renderer, priv->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_real_set_force_track_position (MetaCursorTracker *tracker,
- gboolean is_enabled)
-{
-}
-
-static MetaCursorSprite *
-meta_cursor_tracker_real_get_sprite (MetaCursorTracker *tracker)
-{
- MetaCursorTrackerPrivate *priv =
- meta_cursor_tracker_get_instance_private (tracker);
-
- return priv->displayed_cursor;
-}
-
-void
-meta_cursor_tracker_destroy (MetaCursorTracker *tracker)
-{
- g_object_run_dispose (G_OBJECT (tracker));
- g_object_unref (tracker);
-}
-
-static void
-meta_cursor_tracker_init (MetaCursorTracker *tracker)
-{
- MetaCursorTrackerPrivate *priv =
- meta_cursor_tracker_get_instance_private (tracker);
-
- priv->is_showing = FALSE;
- priv->x = -1.0;
- priv->y = -1.0;
-}
-
-static void
-meta_cursor_tracker_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaCursorTracker *tracker = META_CURSOR_TRACKER (object);
- MetaCursorTrackerPrivate *priv =
- meta_cursor_tracker_get_instance_private (tracker);
-
- 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_cursor_tracker_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaCursorTracker *tracker = META_CURSOR_TRACKER (object);
- MetaCursorTrackerPrivate *priv =
- meta_cursor_tracker_get_instance_private (tracker);
-
- 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_cursor_tracker_dispose (GObject *object)
-{
- MetaCursorTracker *tracker = META_CURSOR_TRACKER (object);
- MetaCursorTrackerPrivate *priv =
- meta_cursor_tracker_get_instance_private (tracker);
-
- g_clear_object (&priv->effective_cursor);
- g_clear_object (&priv->displayed_cursor);
- g_clear_object (&priv->root_cursor);
-
- G_OBJECT_CLASS (meta_cursor_tracker_parent_class)->dispose (object);
-}
-
-static void
-meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->get_property = meta_cursor_tracker_get_property;
- object_class->set_property = meta_cursor_tracker_set_property;
- object_class->dispose = meta_cursor_tracker_dispose;
-
- klass->set_force_track_position =
- meta_cursor_tracker_real_set_force_track_position;
- klass->get_sprite =
- meta_cursor_tracker_real_get_sprite;
-
- 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);
-
- 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);
-
- signals[POSITION_INVALIDATED] = g_signal_new ("position-invalidated",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
- 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)
-{
- MetaCursorTrackerPrivate *priv =
- meta_cursor_tracker_get_instance_private (tracker);
-
- g_clear_object (&priv->window_cursor);
- if (cursor_sprite)
- priv->window_cursor = g_object_ref (cursor_sprite);
- priv->has_window_cursor = has_cursor;
- sync_cursor (tracker);
-}
-
-/**
- * meta_cursor_tracker_get_sprite:
- *
- * Returns: (transfer none):
- */
-CoglTexture *
-meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
-{
- MetaCursorSprite *cursor_sprite;
-
- cursor_sprite = META_CURSOR_TRACKER_GET_CLASS (tracker)->get_sprite (tracker);
-
- if (!cursor_sprite)
- return NULL;
-
- meta_cursor_sprite_realize_texture (cursor_sprite);
- return meta_cursor_sprite_get_cogl_texture (cursor_sprite);
-}
-
-/**
- * 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));
-
- cursor_sprite = META_CURSOR_TRACKER_GET_CLASS (tracker)->get_sprite (tracker);
-
- 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)
-{
- MetaCursorTrackerPrivate *priv =
- meta_cursor_tracker_get_instance_private (tracker);
-
- g_clear_object (&priv->root_cursor);
- if (cursor_sprite)
- priv->root_cursor = g_object_ref (cursor_sprite);
-
- sync_cursor (tracker);
-}
-
-void
-meta_cursor_tracker_invalidate_position (MetaCursorTracker *tracker)
-{
- g_signal_emit (tracker, signals[POSITION_INVALIDATED], 0);
-}
-
-void
-meta_cursor_tracker_get_pointer (MetaCursorTracker *tracker,
- graphene_point_t *coords,
- ClutterModifierType *mods)
-{
- ClutterSeat *seat;
- ClutterInputDevice *cdevice;
-
- seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
- cdevice = clutter_seat_get_pointer (seat);
-
- clutter_seat_query_state (seat, cdevice, NULL, coords, mods);
-}
-
-void
-meta_cursor_tracker_track_position (MetaCursorTracker *tracker)
-{
- MetaCursorTrackerPrivate *priv =
- meta_cursor_tracker_get_instance_private (tracker);
-
- priv->track_position_count++;
- if (priv->track_position_count == 1)
- {
- MetaCursorTrackerClass *klass =
- META_CURSOR_TRACKER_GET_CLASS (tracker);
-
- klass->set_force_track_position (tracker, TRUE);
- }
-}
-
-void
-meta_cursor_tracker_untrack_position (MetaCursorTracker *tracker)
-{
- MetaCursorTrackerPrivate *priv =
- meta_cursor_tracker_get_instance_private (tracker);
-
- g_return_if_fail (priv->track_position_count > 0);
-
- priv->track_position_count--;
- if (priv->track_position_count == 0)
- {
- MetaCursorTrackerClass *klass =
- META_CURSOR_TRACKER_GET_CLASS (tracker);
-
- klass->set_force_track_position (tracker, FALSE);
- }
-}
-
-gboolean
-meta_cursor_tracker_get_pointer_visible (MetaCursorTracker *tracker)
-{
- MetaCursorTrackerPrivate *priv =
- meta_cursor_tracker_get_instance_private (tracker);
-
- return priv->is_showing;
-}
-
-void
-meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
- gboolean visible)
-{
- MetaCursorTrackerPrivate *priv =
- meta_cursor_tracker_get_instance_private (tracker);
-
- if (visible == priv->is_showing)
- return;
- priv->is_showing = visible;
-
- sync_cursor (tracker);
-
- g_signal_emit (tracker, signals[VISIBILITY_CHANGED], 0);
-}
-MetaBackend *
-meta_cursor_tracker_get_backend (MetaCursorTracker *tracker)
-{
- MetaCursorTrackerPrivate *priv =
- meta_cursor_tracker_get_instance_private (tracker);
-
- return priv->backend;
-}
diff --git a/src/backends/meta-cursor.c b/src/backends/meta-cursor.c
deleted file mode 100644
index d0fb2ba68..000000000
--- a/src/backends/meta-cursor.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/* -*- 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,
- float best_scale,
- int x,
- int y)
-{
- g_signal_emit (sprite, signals[PREPARE_AT], 0, best_scale, x, y);
-}
-
-void
-meta_cursor_sprite_realize_texture (MetaCursorSprite *sprite)
-{
- META_CURSOR_SPRITE_GET_CLASS (sprite)->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, 3,
- G_TYPE_FLOAT,
- 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
deleted file mode 100644
index a65e128c4..000000000
--- a/src/backends/meta-cursor.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- 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,
- float best_scale,
- 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
deleted file mode 100644
index a885b423b..000000000
--- a/src/backends/meta-dbus-session-watcher.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 06d3e1ff9..000000000
--- a/src/backends/meta-dbus-session-watcher.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- 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
deleted file mode 100644
index f037dac83..000000000
--- a/src/backends/meta-display-config-shared.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 0cfb3d788..000000000
--- a/src/backends/meta-dnd-private.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- 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
deleted file mode 100644
index db0b74f76..000000000
--- a/src/backends/meta-egl-ext.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 0d3f8c95d..000000000
--- a/src/backends/meta-egl.c
+++ /dev/null
@@ -1,1154 +0,0 @@
-/* -*- 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;
-
- PFNEGLBINDWAYLANDDISPLAYWL eglBindWaylandDisplayWL;
- 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;
-}
-
-gboolean
-meta_egl_bind_api (MetaEgl *egl,
- EGLenum api,
- GError **error)
-{
- if (!eglBindAPI (api))
- {
- 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_bind_wayland_display (MetaEgl *egl,
- EGLDisplay display,
- struct wl_display *wayland_display,
- GError **error)
-{
- if (!is_egl_proc_valid (egl->eglBindWaylandDisplayWL, error))
- return FALSE;
-
- if (!egl->eglBindWaylandDisplayWL (display, wayland_display))
- {
- 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 (eglBindWaylandDisplayWL);
- 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
deleted file mode 100644
index e108e714a..000000000
--- a/src/backends/meta-egl.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/* -*- 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);
-
-gboolean meta_egl_bind_api (MetaEgl *egl,
- EGLenum api,
- 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_bind_wayland_display (MetaEgl *egl,
- EGLDisplay display,
- struct wl_display *wayland_display,
- 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
deleted file mode 100644
index 4cc866060..000000000
--- a/src/backends/meta-gles3-table.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 727b3c125..000000000
--- a/src/backends/meta-gles3.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 89206cc8f..000000000
--- a/src/backends/meta-gles3.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- 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
deleted file mode 100644
index ce4353bf0..000000000
--- a/src/backends/meta-gpu.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/* -*- 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;
- const MetaOutputInfo *output_info = meta_output_get_info (output);
-
- if (output_info->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
deleted file mode 100644
index 9d12f95a7..000000000
--- a/src/backends/meta-gpu.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- 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-manager.c b/src/backends/meta-idle-manager.c
deleted file mode 100644
index 92ba0a237..000000000
--- a/src/backends/meta-idle-manager.c
+++ /dev/null
@@ -1,379 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright 2013-2021 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-manager.h"
-
-#include "backends/meta-idle-monitor-private.h"
-#include "clutter/clutter.h"
-#include "meta/main.h"
-#include "meta/meta-context.h"
-#include "meta/meta-idle-monitor.h"
-#include "meta/util.h"
-
-#include "meta-dbus-idle-monitor.h"
-
-typedef struct _MetaIdleManager
-{
- MetaBackend *backend;
- guint dbus_name_id;
-
- GHashTable *device_monitors;
-} MetaIdleManager;
-
-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_manager_reset_idle_time (meta_idle_monitor_get_manager (monitor));
- 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_free (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_new0 (DBusWatch, 1);
- 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 (skeleton, "handle-add-idle-watch",
- G_CALLBACK (handle_add_idle_watch), monitor);
- g_signal_connect (skeleton, "handle-add-user-active-watch",
- G_CALLBACK (handle_add_user_active_watch), monitor);
- g_signal_connect (skeleton, "handle-remove-watch",
- G_CALLBACK (handle_remove_watch), monitor);
- g_signal_connect (skeleton, "handle-reset-idletime",
- G_CALLBACK (handle_reset_idletime), monitor);
- g_signal_connect (skeleton, "handle-get-idletime",
- G_CALLBACK (handle_get_idletime), monitor);
-
- 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)
-{
- MetaIdleManager *manager = user_data;
- GDBusObjectManagerServer *object_manager;
- MetaIdleMonitor *monitor;
- char *path;
-
- object_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_manager_get_core_monitor (manager);
- path = g_strdup ("/org/gnome/Mutter/IdleMonitor/Core");
- create_monitor_skeleton (object_manager, monitor, path);
- g_free (path);
-
- g_dbus_object_manager_server_set_connection (object_manager, connection);
-}
-
-static void
-on_name_acquired (GDBusConnection *connection,
- const char *name,
- gpointer user_data)
-{
- meta_verbose ("Acquired name %s", name);
-}
-
-static void
-on_name_lost (GDBusConnection *connection,
- const char *name,
- gpointer user_data)
-{
- meta_verbose ("Lost or failed to acquire name %s", name);
-}
-
-MetaIdleMonitor *
-meta_idle_manager_get_monitor (MetaIdleManager *idle_manager,
- ClutterInputDevice *device)
-{
- return g_hash_table_lookup (idle_manager->device_monitors, device);
-}
-
-MetaIdleMonitor *
-meta_idle_manager_get_core_monitor (MetaIdleManager *idle_manager)
-{
- 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));
-}
-
-void
-meta_idle_manager_reset_idle_time (MetaIdleManager *idle_manager)
-{
- MetaIdleMonitor *core_monitor;
-
- core_monitor = meta_idle_manager_get_core_monitor (idle_manager);
- meta_idle_monitor_reset_idletime (core_monitor);
-}
-
-static void
-create_device_monitor (MetaIdleManager *idle_manager,
- ClutterInputDevice *device)
-{
- MetaIdleMonitor *idle_monitor;
-
- if (g_hash_table_contains (idle_manager->device_monitors, device))
- return;
-
- idle_monitor = meta_idle_monitor_new (idle_manager, device);
- g_hash_table_insert (idle_manager->device_monitors, device, idle_monitor);
-}
-
-static void
-on_device_added (ClutterSeat *seat,
- ClutterInputDevice *device,
- gpointer user_data)
-{
- MetaIdleManager *idle_manager = user_data;
-
- create_device_monitor (idle_manager, device);
-}
-
-static void
-on_device_removed (ClutterSeat *seat,
- ClutterInputDevice *device,
- gpointer user_data)
-{
- MetaIdleManager *idle_manager = user_data;
-
- g_hash_table_remove (idle_manager->device_monitors, device);
-}
-
-static void
-create_device_monitors (MetaIdleManager *idle_manager,
- ClutterSeat *seat)
-{
- GList *l, *devices;
-
- create_device_monitor (idle_manager, clutter_seat_get_pointer (seat));
- create_device_monitor (idle_manager, clutter_seat_get_keyboard (seat));
-
- devices = clutter_seat_list_devices (seat);
- for (l = devices; l; l = l->next)
- {
- ClutterInputDevice *device = l->data;
-
- create_device_monitor (idle_manager, device);
- }
-
- g_list_free (devices);
-}
-
-MetaIdleManager *
-meta_idle_manager_new (MetaBackend *backend)
-{
- MetaContext *context = meta_backend_get_context (backend);
- ClutterSeat *seat = meta_backend_get_default_seat (backend);
- MetaIdleManager *idle_manager;
-
- idle_manager = g_new0 (MetaIdleManager, 1);
- idle_manager->backend = backend;
-
- idle_manager->dbus_name_id =
- g_bus_own_name (G_BUS_TYPE_SESSION,
- "org.gnome.Mutter.IdleMonitor",
- G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
- (meta_context_is_replacing (context) ?
- G_BUS_NAME_OWNER_FLAGS_REPLACE :
- G_BUS_NAME_OWNER_FLAGS_NONE),
- on_bus_acquired,
- on_name_acquired,
- on_name_lost,
- idle_manager,
- NULL);
-
- idle_manager->device_monitors =
- g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_object_unref);
- g_signal_connect (seat, "device-added",
- G_CALLBACK (on_device_added), idle_manager);
- g_signal_connect_after (seat, "device-removed",
- G_CALLBACK (on_device_removed), idle_manager);
- create_device_monitors (idle_manager, seat);
-
- return idle_manager;
-}
-
-void
-meta_idle_manager_free (MetaIdleManager *idle_manager)
-{
- g_clear_pointer (&idle_manager->device_monitors, g_hash_table_destroy);
- g_bus_unown_name (idle_manager->dbus_name_id);
- g_free (idle_manager);
-}
diff --git a/src/backends/meta-idle-manager.h b/src/backends/meta-idle-manager.h
deleted file mode 100644
index c2a998feb..000000000
--- a/src/backends/meta-idle-manager.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2021 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_MANAGER_H
-#define META_IDLE_MANAGER_H
-
-#include "backends/meta-backend-types.h"
-#include "clutter/clutter.h"
-
-typedef struct _MetaIdleMonitor MetaIdleMonitor;
-typedef struct _MetaIdleManager MetaIdleManager;
-
-MetaIdleMonitor * meta_idle_manager_get_monitor (MetaIdleManager *idle_manager,
- ClutterInputDevice *device);
-
-MetaIdleMonitor * meta_idle_manager_get_core_monitor (MetaIdleManager *idle_manager);
-
-void meta_idle_manager_reset_idle_time (MetaIdleManager *idle_manager);
-
-MetaIdleManager * meta_idle_manager_new (MetaBackend *backend);
-
-void meta_idle_manager_free (MetaIdleManager *idle_manager);
-
-#endif /* META_IDLE_MANAGER_H */
diff --git a/src/backends/meta-idle-monitor-private.h b/src/backends/meta-idle-monitor-private.h
deleted file mode 100644
index 6d4387876..000000000
--- a/src/backends/meta-idle-monitor-private.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- 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 _MetaIdleMonitorClass
-{
- GObjectClass parent_class;
-};
-
-void meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor);
-
-MetaIdleManager * meta_idle_monitor_get_manager (MetaIdleMonitor *monitor);
-
-MetaIdleMonitor * meta_idle_monitor_new (MetaIdleManager *idle_manager,
- ClutterInputDevice *device);
-
-#endif /* META_IDLE_MONITOR_PRIVATE_H */
diff --git a/src/backends/meta-idle-monitor.c b/src/backends/meta-idle-monitor.c
deleted file mode 100644
index df924d4dd..000000000
--- a/src/backends/meta-idle-monitor.c
+++ /dev/null
@@ -1,530 +0,0 @@
-/* -*- 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 "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];
-
-struct _MetaIdleMonitor
-{
- GObject parent;
-
- MetaIdleManager *idle_manager;
- GDBusProxy *session_proxy;
- gboolean inhibited;
- GHashTable *watches;
- ClutterInputDevice *device;
- int64_t last_event_time;
-};
-
-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_free (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);
- }
-}
-
-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_new0 (MetaIdleMonitorWatch, 1);
-
- 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);
-}
-
-MetaIdleManager *
-meta_idle_monitor_get_manager (MetaIdleMonitor *monitor)
-{
- return monitor->idle_manager;
-}
-
-MetaIdleMonitor *
-meta_idle_monitor_new (MetaIdleManager *idle_manager,
- ClutterInputDevice *device)
-{
- MetaIdleMonitor *monitor;
-
- monitor = g_object_new (META_TYPE_IDLE_MONITOR,
- "device", device,
- NULL);
- monitor->idle_manager = idle_manager;
-
- return monitor;
-}
diff --git a/src/backends/meta-input-device-private.h b/src/backends/meta-input-device-private.h
deleted file mode 100644
index a2cbd4864..000000000
--- a/src/backends/meta-input-device-private.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 24f6ef9ae..000000000
--- a/src/backends/meta-input-device.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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)
-{
-#ifdef HAVE_LIBWACOM
- MetaInputDevice *input_device;
- WacomDeviceDatabase *wacom_db;
- MetaInputDevicePrivate *priv;
- const char *node;
-#endif
-
- G_OBJECT_CLASS (meta_input_device_parent_class)->constructed (object);
-
-#ifdef HAVE_LIBWACOM
- input_device = META_INPUT_DEVICE (object);
- 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
deleted file mode 100644
index 63d480dba..000000000
--- a/src/backends/meta-input-mapper-private.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- 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 "backends/meta-backend-types.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);
-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);
-
-GSettings * meta_input_mapper_get_tablet_settings (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
deleted file mode 100644
index ffbe2dd37..000000000
--- a/src/backends/meta-input-mapper.c
+++ /dev/null
@@ -1,986 +0,0 @@
-/* -*- 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 "backends/meta-input-device-private.h"
-#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;
-typedef struct _DeviceMatch DeviceMatch;
-
-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_EDID_VENDOR, /* EDID vendor match, eg. "WAC" for Wacom */
- META_MATCH_EDID_PARTIAL, /* Partial EDID model match, eg. "Cintiq" */
- META_MATCH_EDID_FULL, /* Full EDID model match, eg. "Cintiq 12WX" */
- META_MATCH_SIZE, /* Size from input device and output match */
- META_MATCH_IS_BUILTIN, /* Output is builtin, applies mainly to system-integrated devices */
- META_MATCH_CONFIG, /* Specified by config */
- N_OUTPUT_MATCHES
-} MetaOutputMatchType;
-
-struct _MetaMapperInputInfo
-{
- ClutterInputDevice *device;
- MetaInputMapper *mapper;
- MetaMapperOutputInfo *output;
- GSettings *settings;
- guint builtin : 1;
-};
-
-struct _MetaMapperOutputInfo
-{
- MetaLogicalMonitor *logical_monitor;
- GList *input_devices;
- MetaInputCapabilityFlags attached_caps;
-};
-
-struct _MappingHelper
-{
- GArray *device_maps;
-};
-
-struct _DeviceMatch
-{
- MetaMonitor *monitor;
- uint32_t score;
-};
-
-struct _DeviceCandidates
-{
- MetaMapperInputInfo *input;
-
- GArray *matches; /* Array of DeviceMatch */
-
- int best;
-};
-
-enum
-{
- DEVICE_MAPPED,
- DEVICE_ENABLED,
- DEVICE_ASPECT_RATIO,
- N_SIGNALS
-};
-
-static guint signals[N_SIGNALS] = { 0, };
-
-static void mapper_output_info_remove_input (MetaMapperOutputInfo *output,
- MetaMapperInputInfo *input);
-
-static void mapper_recalculate_input (MetaInputMapper *mapper,
- MetaMapperInputInfo *input);
-
-G_DEFINE_TYPE (MetaInputMapper, meta_input_mapper, G_TYPE_OBJECT)
-
-static GSettings *
-get_device_settings (ClutterInputDevice *device)
-{
- const char *group, *schema, *vendor, *product;
- ClutterInputDeviceType type;
- GSettings *settings;
- char *path;
-
- type = clutter_input_device_get_device_type (device);
-
- if (type == CLUTTER_TOUCHSCREEN_DEVICE)
- {
- group = "touchscreens";
- schema = "org.gnome.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.gnome.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/gnome/desktop/peripherals/%s/%s:%s/",
- group, vendor, product);
-
- settings = g_settings_new_with_path (schema, path);
- g_free (path);
-
- return settings;
-}
-
-static void
-settings_output_changed_cb (GSettings *settings,
- const char *key,
- MetaMapperInputInfo *info)
-{
- if (info->output != NULL)
- mapper_output_info_remove_input (info->output, info);
-
- mapper_recalculate_input (info->mapper, info);
-}
-
-static MetaMapperInputInfo *
-mapper_input_info_new (ClutterInputDevice *device,
- MetaInputMapper *mapper)
-{
- MetaMapperInputInfo *info;
-
- info = g_new0 (MetaMapperInputInfo, 1);
- info->mapper = mapper;
- info->device = device;
- info->settings = get_device_settings (device);
-
- g_signal_connect (info->settings, "changed::output",
- G_CALLBACK (settings_output_changed_cb), info);
-
- return info;
-}
-
-static void
-mapper_input_info_free (MetaMapperInputInfo *info)
-{
- g_signal_handlers_disconnect_by_func (info->settings, settings_output_changed_cb, info);
- g_object_unref (info->settings);
- 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)
-{
- MetaInputMapper *mapper = input->mapper;
- float matrix[6] = { 1, 0, 0, 0, 1, 0 };
- double aspect_ratio;
- int width, height;
-
- if (input->output == output)
- return;
-
- input->output = output;
-
- if (output && monitor)
- {
- meta_monitor_manager_get_monitor_matrix (mapper->monitor_manager,
- monitor,
- output->logical_monitor,
- matrix);
- meta_monitor_get_current_resolution (monitor, &width, &height);
- }
- else
- {
- meta_monitor_manager_get_screen_size (mapper->monitor_manager,
- &width, &height);
- }
-
- aspect_ratio = (double) width / height;
-
- g_signal_emit (input->mapper, signals[DEVICE_MAPPED], 0,
- input->device, matrix);
- g_signal_emit (input->mapper, signals[DEVICE_ASPECT_RATIO], 0,
- input->device, aspect_ratio);
-}
-
-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
-clear_candidates (DeviceCandidates *candidates)
-{
- g_clear_pointer (&candidates->matches, g_array_unref);
-}
-
-static void
-mapping_helper_init (MappingHelper *helper)
-{
- helper->device_maps = g_array_new (FALSE, FALSE, sizeof (DeviceCandidates));
- g_array_set_clear_func (helper->device_maps,
- (GDestroyNotify) clear_candidates);
-}
-
-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);
- if (!node)
- return FALSE;
-
- 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
-match_size (MetaMapperInputInfo *input,
- MetaMonitor *monitor)
-{
- double w_diff, h_diff;
- int o_width, o_height;
- double i_width, i_height;
-
- if (!input_device_get_physical_size (input->mapper, input->device,
- &i_width, &i_height))
- return FALSE;
-
- 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));
-
- return w_diff < MAX_SIZE_MATCH_DIFF && h_diff < MAX_SIZE_MATCH_DIFF;
-}
-
-static gboolean
-match_builtin (MetaInputMapper *mapper,
- MetaMonitor *monitor)
-{
- return monitor == meta_monitor_manager_get_laptop_panel (mapper->monitor_manager);
-}
-
-static gboolean
-match_config (MetaMapperInputInfo *info,
- MetaMonitor *monitor)
-{
- gboolean match = FALSE;
- char **edid;
- guint n_values;
-
- edid = g_settings_get_strv (info->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 (info->device));
- goto out;
- }
-
- if (!*edid[0] && !*edid[1] && !*edid[2])
- goto out;
-
- match = (g_strcmp0 (meta_monitor_get_vendor (monitor), edid[0]) == 0 &&
- g_strcmp0 (meta_monitor_get_product (monitor), edid[1]) == 0 &&
- g_strcmp0 (meta_monitor_get_serial (monitor), edid[2]) == 0);
-
- out:
- g_strfreev (edid);
-
- return match;
-}
-
-static int
-sort_by_score (DeviceMatch *match1,
- DeviceMatch *match2)
-{
- return (int) match1->score - match2->score;
-}
-
-static void
-guess_candidates (MetaInputMapper *mapper,
- MetaMapperInputInfo *input,
- DeviceCandidates *info)
-{
- GList *monitors, *l;
- gboolean builtin = FALSE;
- gboolean integrated = TRUE;
-
-#ifdef HAVE_LIBWACOM
- if (clutter_input_device_get_device_type (input->device) != CLUTTER_TOUCHSCREEN_DEVICE)
- {
- WacomDevice *wacom_device;
- WacomIntegrationFlags flags = 0;
-
- wacom_device =
- meta_input_device_get_wacom_device (META_INPUT_DEVICE (input->device));
-
- if (wacom_device)
- {
- flags = libwacom_get_integration_flags (wacom_device);
-
- integrated = (flags & (WACOM_DEVICE_INTEGRATED_SYSTEM |
- WACOM_DEVICE_INTEGRATED_DISPLAY)) != 0;
- builtin = (flags & WACOM_DEVICE_INTEGRATED_SYSTEM) != 0;
- }
- }
-#endif
-
- monitors = meta_monitor_manager_get_monitors (mapper->monitor_manager);
-
- for (l = monitors; l; l = l->next)
- {
- MetaOutputMatchType edid_match;
- DeviceMatch match = { l->data, 0 };
-
- g_assert (META_IS_MONITOR (l->data));
-
- if (match_edid (input, l->data, &edid_match))
- match.score |= 1 << edid_match;
-
- if (integrated && match_size (input, l->data))
- match.score |= 1 << META_MATCH_SIZE;
-
- if (builtin && match_builtin (mapper, l->data))
- match.score |= 1 << META_MATCH_IS_BUILTIN;
-
- if (match_config (input, l->data))
- match.score |= 1 << META_MATCH_CONFIG;
-
- if (match.score > 0)
- g_array_append_val (info->matches, match);
- }
-
- if (info->matches->len == 0)
- {
- DeviceMatch match = { 0 };
-
- match.monitor =
- meta_monitor_manager_get_laptop_panel (mapper->monitor_manager);
-
- if (match.monitor != NULL)
- g_array_append_val (info->matches, match);
-
- info->best = 0;
- }
- else
- {
- DeviceMatch *best;
-
- g_array_sort (info->matches, (GCompareFunc) sort_by_score);
- best = &g_array_index (info->matches, DeviceMatch, 0);
- info->best = best->score;
- }
-}
-
-static void
-mapping_helper_add (MappingHelper *helper,
- MetaMapperInputInfo *input,
- MetaInputMapper *mapper)
-{
- DeviceCandidates info = { 0, };
- guint i, pos = 0;
-
- info.input = input;
- info.matches = g_array_new (FALSE, TRUE, sizeof (DeviceMatch));
-
- 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, j;
-
- /* Now, decide which input claims which output */
- for (i = 0; i < helper->device_maps->len; i++)
- {
- DeviceCandidates *info;
-
- info = &g_array_index (helper->device_maps, DeviceCandidates, i);
- g_debug ("Applying mapping %d to input device '%s', capabilities %x", i,
- clutter_input_device_get_device_name (info->input->device),
- mapper_input_info_get_caps (info->input));
-
- for (j = 0; j < info->matches->len; j++)
- {
- MetaLogicalMonitor *logical_monitor;
- MetaMapperOutputInfo *output;
- MetaMonitor *monitor;
- DeviceMatch *match;
-
- match = &g_array_index (info->matches, DeviceMatch, j);
- g_debug ("Output candidate '%s', score %x",
- meta_monitor_get_display_name (match->monitor),
- match->score);
-
- monitor = match->monitor;
- logical_monitor = meta_monitor_get_logical_monitor (monitor);
- 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;
-
- g_debug ("Matched input '%s' with output '%s'",
- clutter_input_device_get_device_name (info->input->device),
- meta_monitor_get_display_name (match->monitor));
- mapper_output_info_add_input (output, info->input, monitor);
- 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_power_save_mode_changed_cb (MetaMonitorManager *monitor_manager,
- MetaInputMapper *mapper)
-{
- ClutterInputDevice *device;
- MetaLogicalMonitor *logical_monitor;
- MetaMonitor *builtin;
- MetaPowerSave power_save_mode;
- gboolean on;
-
- power_save_mode =
- meta_monitor_manager_get_power_save_mode (mapper->monitor_manager);
- on = power_save_mode == META_POWER_SAVE_ON;
-
- builtin = meta_monitor_manager_get_laptop_panel (monitor_manager);
- if (!builtin)
- return;
-
- logical_monitor = meta_monitor_get_logical_monitor (builtin);
- if (!logical_monitor)
- return;
-
- device =
- meta_input_mapper_get_logical_monitor_device (mapper,
- logical_monitor,
- CLUTTER_TOUCHSCREEN_DEVICE);
- if (!device)
- return;
-
- g_signal_emit (mapper, signals[DEVICE_ENABLED], 0, device, on);
-}
-
-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);
- g_signal_connect (mapper->monitor_manager, "power-save-mode-changed",
- G_CALLBACK (input_mapper_power_save_mode_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, 2,
- CLUTTER_TYPE_INPUT_DEVICE,
- G_TYPE_POINTER);
- signals[DEVICE_ENABLED] =
- g_signal_new ("device-enabled",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 2,
- CLUTTER_TYPE_INPUT_DEVICE,
- G_TYPE_BOOLEAN);
- signals[DEVICE_ASPECT_RATIO] =
- g_signal_new ("device-aspect-ratio",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 2,
- CLUTTER_TYPE_INPUT_DEVICE,
- G_TYPE_DOUBLE);
-}
-
-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)
-{
- 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);
- 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;
-}
-
-static ClutterInputDevice *
-find_grouped_pen (ClutterInputDevice *device)
-{
- GList *l, *devices;
- ClutterInputDeviceType device_type;
- ClutterInputDevice *pen = NULL;
- ClutterSeat *seat;
-
- device_type = clutter_input_device_get_device_type (device);
-
- if (device_type == CLUTTER_TABLET_DEVICE ||
- device_type == CLUTTER_PEN_DEVICE)
- return device;
-
- seat = clutter_input_device_get_seat (device);
- devices = clutter_seat_list_devices (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_mapper_get_device_logical_monitor (MetaInputMapper *mapper,
- ClutterInputDevice *device)
-{
- MetaMapperOutputInfo *output;
- MetaLogicalMonitor *logical_monitor;
- GHashTableIter iter;
- GList *l;
-
- if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE)
- {
- device = find_grouped_pen (device);
- if (!device)
- return NULL;
- }
-
- 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;
-}
-
-GSettings *
-meta_input_mapper_get_tablet_settings (MetaInputMapper *mapper,
- ClutterInputDevice *device)
-{
- MetaMapperInputInfo *input;
-
- g_return_val_if_fail (META_IS_INPUT_MAPPER (mapper), NULL);
- g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
-
- input = g_hash_table_lookup (mapper->input_devices, device);
- if (!input)
- return NULL;
-
- return input->settings;
-}
diff --git a/src/backends/meta-input-settings-dummy.c b/src/backends/meta-input-settings-dummy.c
deleted file mode 100644
index 74e6f429c..000000000
--- a/src/backends/meta-input-settings-dummy.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright 2021 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, see <http://www.gnu.org/licenses/>.
- *
- * Author: Marco Trevisan <marco.trevisan@canonical.com>
- */
-
-#include "backends/meta-input-settings-dummy.h"
-
-G_DEFINE_TYPE (MetaInputSettingsDummy,
- meta_input_settings_dummy,
- META_TYPE_INPUT_SETTINGS)
-
-static void
-meta_input_settings_dummy_set_send_events (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopDeviceSendEvents mode)
-{
-}
-
-static void
-meta_input_settings_dummy_set_matrix (MetaInputSettings *settings,
- ClutterInputDevice *device,
- const float matrix[6])
-{
-}
-
-static void
-meta_input_settings_dummy_set_speed (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gdouble speed)
-{
-}
-
-static void
-meta_input_settings_dummy_set_left_handed (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean enabled)
-{
-}
-
-static void
-meta_input_settings_dummy_set_tap_enabled (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean enabled)
-{
-}
-
-static void
-meta_input_settings_dummy_set_tap_button_map (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopTouchpadTapButtonMap mode)
-{
-}
-
-static void
-meta_input_settings_dummy_set_tap_and_drag_enabled (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean enabled)
-{
-}
-
-static void
-meta_input_settings_dummy_set_tap_and_drag_lock_enabled (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean enabled)
-{
-}
-
-static void
-meta_input_settings_dummy_set_disable_while_typing (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean enabled)
-{
-}
-
-static void
-meta_input_settings_dummy_set_invert_scroll (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean inverted)
-{
-}
-
-static void
-meta_input_settings_dummy_set_edge_scroll (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean enabled)
-{
-}
-
-static void
-meta_input_settings_dummy_set_two_finger_scroll (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean enabled)
-{
-}
-
-static void
-meta_input_settings_dummy_set_scroll_button (MetaInputSettings *settings,
- ClutterInputDevice *device,
- guint button,
- gboolean button_lock)
-{
-}
-
-
-static void
-meta_input_settings_dummy_set_click_method (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopTouchpadClickMethod mode)
-{
-}
-
-
-static void
-meta_input_settings_dummy_set_keyboard_repeat (MetaInputSettings *settings,
- gboolean repeat,
- guint delay,
- guint interval)
-{
-}
-
-
-static void
-meta_input_settings_dummy_set_tablet_mapping (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopTabletMapping mapping)
-{
-}
-
-static void
-meta_input_settings_dummy_set_tablet_aspect_ratio (MetaInputSettings *settings,
- ClutterInputDevice *device,
- double ratio)
-{
-}
-
-static void
-meta_input_settings_dummy_set_tablet_area (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gdouble padding_left,
- gdouble padding_right,
- gdouble padding_top,
- gdouble padding_bottom)
-{
-}
-
-
-static void
-meta_input_settings_dummy_set_mouse_accel_profile (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopPointerAccelProfile profile)
-{
-}
-
-static void
-meta_input_settings_dummy_set_trackball_accel_profile (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopPointerAccelProfile profile)
-{
-}
-
-
-static void
-meta_input_settings_dummy_set_stylus_pressure (MetaInputSettings *settings,
- ClutterInputDevice *device,
- ClutterInputDeviceTool *tool,
- const gint32 curve[4])
-{
-}
-
-static void
-meta_input_settings_dummy_set_stylus_button_map (MetaInputSettings *settings,
- ClutterInputDevice *device,
- ClutterInputDeviceTool *tool,
- GDesktopStylusButtonAction primary,
- GDesktopStylusButtonAction secondary,
- GDesktopStylusButtonAction tertiary)
-{
-}
-
-
-static void
-meta_input_settings_dummy_set_mouse_middle_click_emulation (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean enabled)
-{
-}
-
-static void
-meta_input_settings_dummy_set_touchpad_middle_click_emulation (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean enabled)
-{
-}
-
-static void
-meta_input_settings_dummy_set_trackball_middle_click_emulation (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean enabled)
-{
-}
-
-static gboolean
-meta_input_settings_dummy_has_two_finger_scroll (MetaInputSettings *settings,
- ClutterInputDevice *device)
-{
- return FALSE;
-}
-static gboolean
-meta_input_settings_dummy_is_trackball_device (MetaInputSettings *settings,
- ClutterInputDevice *device)
-{
- return FALSE;
-}
-
-static void
-meta_input_settings_dummy_init (MetaInputSettingsDummy *input_settings)
-{
-}
-
-static void
-meta_input_settings_dummy_class_init (MetaInputSettingsDummyClass *klass)
-{
- MetaInputSettingsClass *input_settings_class = META_INPUT_SETTINGS_CLASS (klass);
-
- input_settings_class->set_send_events =
- meta_input_settings_dummy_set_send_events;
- input_settings_class->set_matrix =
- meta_input_settings_dummy_set_matrix;
- input_settings_class->set_speed =
- meta_input_settings_dummy_set_speed;
- input_settings_class->set_left_handed =
- meta_input_settings_dummy_set_left_handed;
- input_settings_class->set_tap_enabled =
- meta_input_settings_dummy_set_tap_enabled;
- input_settings_class->set_tap_button_map =
- meta_input_settings_dummy_set_tap_button_map;
- input_settings_class->set_tap_and_drag_enabled =
- meta_input_settings_dummy_set_tap_and_drag_enabled;
- input_settings_class->set_tap_and_drag_lock_enabled =
- meta_input_settings_dummy_set_tap_and_drag_lock_enabled;
- input_settings_class->set_disable_while_typing =
- meta_input_settings_dummy_set_disable_while_typing;
- input_settings_class->set_invert_scroll =
- meta_input_settings_dummy_set_invert_scroll;
- input_settings_class->set_edge_scroll =
- meta_input_settings_dummy_set_edge_scroll;
- input_settings_class->set_two_finger_scroll =
- meta_input_settings_dummy_set_two_finger_scroll;
- input_settings_class->set_scroll_button =
- meta_input_settings_dummy_set_scroll_button;
- input_settings_class->set_click_method =
- meta_input_settings_dummy_set_click_method;
- input_settings_class->set_keyboard_repeat =
- meta_input_settings_dummy_set_keyboard_repeat;
- input_settings_class->set_tablet_mapping =
- meta_input_settings_dummy_set_tablet_mapping;
- input_settings_class->set_tablet_aspect_ratio =
- meta_input_settings_dummy_set_tablet_aspect_ratio;
- input_settings_class->set_tablet_area =
- meta_input_settings_dummy_set_tablet_area;
- input_settings_class->set_mouse_accel_profile =
- meta_input_settings_dummy_set_mouse_accel_profile;
- input_settings_class->set_trackball_accel_profile =
- meta_input_settings_dummy_set_trackball_accel_profile;
- input_settings_class->set_stylus_pressure =
- meta_input_settings_dummy_set_stylus_pressure;
- input_settings_class->set_stylus_button_map =
- meta_input_settings_dummy_set_stylus_button_map;
- input_settings_class->set_mouse_middle_click_emulation =
- meta_input_settings_dummy_set_mouse_middle_click_emulation;
- input_settings_class->set_touchpad_middle_click_emulation =
- meta_input_settings_dummy_set_touchpad_middle_click_emulation;
- input_settings_class->set_trackball_middle_click_emulation =
- meta_input_settings_dummy_set_trackball_middle_click_emulation;
- input_settings_class->has_two_finger_scroll =
- meta_input_settings_dummy_has_two_finger_scroll;
- input_settings_class->is_trackball_device =
- meta_input_settings_dummy_is_trackball_device;
-}
diff --git a/src/backends/meta-input-settings-dummy.h b/src/backends/meta-input-settings-dummy.h
deleted file mode 100644
index 9d91dc15d..000000000
--- a/src/backends/meta-input-settings-dummy.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright 2021 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, see <http://www.gnu.org/licenses/>.
- *
- * Author: Marco Trevisan <marco.trevisan@canonical.com>
- */
-
-#pragma once
-
-#include "backends/meta-input-settings-private.h"
-
-#define META_TYPE_INPUT_SETTINGS_DUMMY (meta_input_settings_dummy_get_type ())
-
-G_DECLARE_DERIVABLE_TYPE (MetaInputSettingsDummy, meta_input_settings_dummy,
- META, INPUT_SETTINGS_DUMMY, MetaInputSettings);
-
-struct _MetaInputSettingsDummyClass
-{
- MetaInputSettingsClass parent_class;
-};
diff --git a/src/backends/meta-input-settings-private.h b/src/backends/meta-input-settings-private.h
deleted file mode 100644
index 42ee0e0e6..000000000
--- a/src/backends/meta-input-settings-private.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/* -*- 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 <gdesktop-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)
-
-typedef enum
-{
- META_A11Y_KEYBOARD_ENABLED = 1 << 0,
- META_A11Y_TIMEOUT_ENABLED = 1 << 1,
- META_A11Y_MOUSE_KEYS_ENABLED = 1 << 2,
- META_A11Y_SLOW_KEYS_ENABLED = 1 << 3,
- META_A11Y_SLOW_KEYS_BEEP_PRESS = 1 << 4,
- META_A11Y_SLOW_KEYS_BEEP_ACCEPT = 1 << 5,
- META_A11Y_SLOW_KEYS_BEEP_REJECT = 1 << 6,
- META_A11Y_BOUNCE_KEYS_ENABLED = 1 << 7,
- META_A11Y_BOUNCE_KEYS_BEEP_REJECT = 1 << 8,
- META_A11Y_TOGGLE_KEYS_ENABLED = 1 << 9,
- META_A11Y_STICKY_KEYS_ENABLED = 1 << 10,
- META_A11Y_STICKY_KEYS_TWO_KEY_OFF = 1 << 11,
- META_A11Y_STICKY_KEYS_BEEP = 1 << 12,
- META_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13,
-} MetaKeyboardA11yFlags;
-
-/**
- * MetaKbdA11ySettings:
- *
- * The #MetaKbdA11ySettings structure contains keyboard accessibility
- * settings
- *
- */
-typedef struct _MetaKbdA11ySettings
-{
- MetaKeyboardA11yFlags controls;
- int slowkeys_delay;
- int debounce_delay;
- int timeout_delay;
- int mousekeys_init_delay;
- int mousekeys_max_speed;
- int mousekeys_accel_time;
-} MetaKbdA11ySettings;
-
-struct _MetaInputSettingsClass
-{
- GObjectClass parent_class;
-
- void (* set_send_events) (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopDeviceSendEvents mode);
- void (* set_matrix) (MetaInputSettings *settings,
- ClutterInputDevice *device,
- const float 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_button_map) (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopTouchpadTapButtonMap mode);
- void (* set_tap_and_drag_enabled) (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean enabled);
- void (* set_tap_and_drag_lock_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,
- gboolean button_lock);
-
- void (* set_click_method) (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopTouchpadClickMethod mode);
-
- void (* set_keyboard_repeat) (MetaInputSettings *settings,
- gboolean repeat,
- guint delay,
- guint interval);
-
- void (* set_tablet_mapping) (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopTabletMapping mapping);
- void (* set_tablet_aspect_ratio) (MetaInputSettings *settings,
- ClutterInputDevice *device,
- double ratio);
- 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,
- GDesktopPointerAccelProfile profile);
- void (* set_trackball_accel_profile) (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopPointerAccelProfile 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,
- GDesktopStylusButtonAction primary,
- GDesktopStylusButtonAction secondary,
- GDesktopStylusButtonAction 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);
-};
-
-void meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings,
- gboolean numlock_state);
-gboolean meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settings);
-
-void meta_input_settings_set_device_matrix (MetaInputSettings *input_settings,
- ClutterInputDevice *device,
- float matrix[6]);
-void meta_input_settings_set_device_enabled (MetaInputSettings *input_settings,
- ClutterInputDevice *device,
- gboolean enabled);
-void meta_input_settings_set_device_aspect_ratio (MetaInputSettings *input_settings,
- ClutterInputDevice *device,
- double aspect_ratio);
-
-void meta_input_settings_get_kbd_a11y_settings (MetaInputSettings *input_settings,
- MetaKbdA11ySettings *a11y_settings);
-
-void meta_input_settings_add_device (MetaInputSettings *input_settings,
- ClutterInputDevice *device);
-void meta_input_settings_remove_device (MetaInputSettings *input_settings,
- ClutterInputDevice *device);
-void meta_input_settings_notify_tool_change (MetaInputSettings *input_settings,
- ClutterInputDevice *device,
- ClutterInputDeviceTool *tool);
-void meta_input_settings_notify_kbd_a11y_change (MetaInputSettings *input_settings,
- MetaKeyboardA11yFlags new_flags,
- MetaKeyboardA11yFlags what_changed);
-
-#endif /* META_INPUT_SETTINGS_PRIVATE_H */
diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c
deleted file mode 100644
index 16618608b..000000000
--- a/src/backends/meta-input-settings.c
+++ /dev/null
@@ -1,1762 +0,0 @@
-/* -*- 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;
- double aspect_ratio;
-};
-
-struct _MetaInputSettingsPrivate
-{
- ClutterSeat *seat;
- gulong monitors_changed_id;
-
- GSettings *mouse_settings;
- GSettings *touchpad_settings;
- GSettings *trackball_settings;
- GSettings *keyboard_settings;
- GSettings *keyboard_a11y_settings;
-
- GList *devices;
- GHashTable *mappable_devices;
-
- GHashTable *current_tools;
-
- GHashTable *two_finger_devices;
-
- MetaKbdA11ySettings kbd_a11y_settings;
-};
-
-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);
-
-G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettings, meta_input_settings, G_TYPE_OBJECT)
-
-enum
-{
- KBD_A11Y_CHANGED,
- N_SIGNALS
-};
-
-static guint signals[N_SIGNALS] = { 0 };
-
-static GSList *
-meta_input_settings_get_devices (MetaInputSettings *settings,
- ClutterInputDeviceType type)
-{
- MetaInputSettingsPrivate *priv;
- GList *l;
- GSList *list = NULL;
-
- priv = meta_input_settings_get_instance_private (settings);
-
- for (l = priv->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_LOGICAL)
- list = g_slist_prepend (list, device);
- }
-
- 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->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_pointer (&priv->mappable_devices, g_hash_table_unref);
- g_clear_pointer (&priv->current_tools, g_hash_table_unref);
-
- 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;
- GDesktopTouchpadHandedness 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 G_DESKTOP_TOUCHPAD_HANDEDNESS_RIGHT:
- enabled = FALSE;
- break;
- case G_DESKTOP_TOUCHPAD_HANDEDNESS_LEFT:
- enabled = TRUE;
- break;
- case G_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
- {
- GDesktopTouchpadHandedness 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 == G_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,
- GDesktopPointerAccelProfile 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)
-{
- GDesktopPointerAccelProfile 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;
-
- for (l = priv->devices; l; l = l->next)
- {
- device = l->data;
-
- if (clutter_input_device_get_device_mode (device) ==
- CLUTTER_INPUT_MODE_LOGICAL)
- continue;
-
- do_update_pointer_accel_profile (input_settings, settings,
- device, profile);
- }
- }
-}
-
-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_button_map (MetaInputSettings *input_settings,
- ClutterInputDevice *device)
-{
- MetaInputSettingsClass *input_settings_class;
- GDesktopTouchpadTapButtonMap 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, "tap-button-map");
-
- if (device)
- {
- settings_device_set_uint_setting (input_settings, device,
- input_settings_class->set_tap_button_map,
- method);
- }
- else
- {
- settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
- (ConfigUintFunc) input_settings_class->set_tap_button_map,
- method);
- }
-}
-
-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_tap_and_drag_lock_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-lock");
-
- if (device)
- {
- settings_device_set_bool_setting (input_settings, device,
- input_settings_class->set_tap_and_drag_lock_enabled,
- enabled);
- }
- else
- {
- settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
- NULL,
- input_settings_class->set_tap_and_drag_lock_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;
- GDesktopTouchpadClickMethod 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;
- GDesktopDeviceSendEvents 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;
- gboolean button_lock;
-
- 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");
- button_lock = g_settings_get_boolean (priv->trackball_settings, "scroll-wheel-emulation-button-lock");
-
- if (device)
- {
- input_settings_class->set_scroll_button (input_settings, device, button, button_lock);
- }
- else if (!device)
- {
- GList *l;
-
- for (l = priv->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, button_lock);
- }
- }
-}
-
-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 void
-update_tablet_keep_aspect (MetaInputSettings *input_settings,
- GSettings *settings,
- ClutterInputDevice *device)
-{
- MetaInputSettingsPrivate *priv;
- MetaInputSettingsClass *input_settings_class;
- DeviceMappingInfo *info;
- gboolean keep_aspect;
- double aspect_ratio;
-
- 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;
-
- priv = meta_input_settings_get_instance_private (input_settings);
-
- info = g_hash_table_lookup (priv->mappable_devices, device);
- if (!info)
- 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
-
- keep_aspect = g_settings_get_boolean (settings, "keep-aspect");
-
- if (keep_aspect)
- aspect_ratio = info->aspect_ratio;
- else
- aspect_ratio = 0;
-
- input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
- input_settings_class->set_tablet_aspect_ratio (input_settings, device, aspect_ratio);
-}
-
-static void
-update_tablet_mapping (MetaInputSettings *input_settings,
- GSettings *settings,
- ClutterInputDevice *device)
-{
- MetaInputSettingsClass *input_settings_class;
- GDesktopTabletMapping 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);
-}
-
-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-button-map") == 0)
- update_touchpad_tap_button_map (input_settings, NULL);
- else if (strcmp (key, "tap-and-drag") == 0)
- update_touchpad_tap_and_drag_enabled (input_settings, NULL);
- else if (strcmp (key, "tap-and-drag-lock") == 0)
- update_touchpad_tap_and_drag_lock_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 ||
- strcmp (key, "scroll-wheel-emulation-button-lock") == 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);
- }
-}
-
-static void
-mapped_device_changed_cb (GSettings *settings,
- const gchar *key,
- DeviceMappingInfo *info)
-{
- 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;
-
- 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;
- MetaKeyboardA11yFlags flag;
-} keyboard_a11y_settings_flags_pair[] = {
- { "enable", META_A11Y_KEYBOARD_ENABLED },
- { "timeout-enable", META_A11Y_TIMEOUT_ENABLED },
- { "mousekeys-enable", META_A11Y_MOUSE_KEYS_ENABLED },
- { "slowkeys-enable", META_A11Y_SLOW_KEYS_ENABLED },
- { "slowkeys-beep-press", META_A11Y_SLOW_KEYS_BEEP_PRESS },
- { "slowkeys-beep-accept", META_A11Y_SLOW_KEYS_BEEP_ACCEPT },
- { "slowkeys-beep-reject", META_A11Y_SLOW_KEYS_BEEP_REJECT },
- { "bouncekeys-enable", META_A11Y_BOUNCE_KEYS_ENABLED },
- { "bouncekeys-beep-reject", META_A11Y_BOUNCE_KEYS_BEEP_REJECT },
- { "togglekeys-enable", META_A11Y_TOGGLE_KEYS_ENABLED },
- { "stickykeys-enable", META_A11Y_STICKY_KEYS_ENABLED },
- { "stickykeys-modifier-beep", META_A11Y_STICKY_KEYS_BEEP },
- { "stickykeys-two-key-off", META_A11Y_STICKY_KEYS_TWO_KEY_OFF },
- { "feature-state-change-beep", META_A11Y_FEATURE_STATE_CHANGE_BEEP },
-};
-
-static void
-load_keyboard_a11y_settings (MetaInputSettings *input_settings)
-{
- MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings);
- MetaKbdA11ySettings kbd_a11y_settings = { 0 };
- guint i;
-
- 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");
-
- priv->kbd_a11y_settings = kbd_a11y_settings;
- g_signal_emit (input_settings, signals[KBD_A11Y_CHANGED], 0, &priv->kbd_a11y_settings);
-}
-
-void
-meta_input_settings_notify_kbd_a11y_change (MetaInputSettings *input_settings,
- MetaKeyboardA11yFlags new_flags,
- MetaKeyboardA11yFlags what_changed)
-{
- 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);
-}
-
-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.gnome.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.gnome.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/gnome/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/gnome/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/gnome/desktop/peripherals/stylus/%" G_GINT64_MODIFIER "x/",
- serial);
- }
-
- tool_settings =
- g_settings_new_with_path ("org.gnome.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 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_free (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_new0 (DeviceMappingInfo, 1);
- 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_button_map (input_settings, device);
- update_touchpad_tap_and_drag_enabled (input_settings, device);
- update_touchpad_tap_and_drag_lock_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);
-
- 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;
- GDesktopStylusButtonAction 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);
-}
-
-void
-meta_input_settings_add_device (MetaInputSettings *input_settings,
- ClutterInputDevice *device)
-{
- MetaInputSettingsPrivate *priv =
- meta_input_settings_get_instance_private (input_settings);
-
- if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_LOGICAL)
- return;
-
- priv->devices = g_list_prepend (priv->devices, device);
- evaluate_two_finger_scrolling (input_settings, device);
-
- apply_device_settings (input_settings, device);
- check_add_mappable_device (input_settings, device);
-}
-
-void
-meta_input_settings_remove_device (MetaInputSettings *input_settings,
- ClutterInputDevice *device)
-{
- MetaInputSettingsPrivate *priv;
-
- priv = meta_input_settings_get_instance_private (input_settings);
- 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);
-
- priv->devices = g_list_remove (priv->devices, device);
-}
-
-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);
-}
-
-void
-meta_input_settings_notify_tool_change (MetaInputSettings *input_settings,
- ClutterInputDevice *device,
- ClutterInputDeviceTool *tool)
-{
- 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;
-
- priv = meta_input_settings_get_instance_private (input_settings);
-
- for (l = priv->devices; l; l = l->next)
- {
- ClutterInputDevice *device = l->data;
-
- if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_LOGICAL)
- continue;
-
- check_add_mappable_device (input_settings, device);
- }
-}
-
-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);
-
- load_keyboard_a11y_settings (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");
-
- signals[KBD_A11Y_CHANGED] =
- g_signal_new ("kbd-a11y-changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, NULL,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
-
-}
-
-static void
-meta_input_settings_init (MetaInputSettings *settings)
-{
- MetaInputSettingsPrivate *priv;
-
- priv = meta_input_settings_get_instance_private (settings);
-
- priv->mouse_settings = g_settings_new ("org.gnome.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.gnome.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.gnome.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.gnome.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.gnome.desktop.a11y.keyboard");
- g_signal_connect (priv->keyboard_a11y_settings, "changed",
- G_CALLBACK (meta_input_keyboard_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->two_finger_devices = g_hash_table_new (NULL, NULL);
-}
-
-void
-meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings,
- gboolean numlock_state)
-{
- MetaInputSettingsPrivate *priv;
-
- priv = meta_input_settings_get_instance_private (input_settings);
-
- if (!g_settings_get_boolean (priv->keyboard_settings, "remember-numlock-state"))
- return;
-
- if (numlock_state == g_settings_get_boolean (priv->keyboard_settings, "numlock-state"))
- return;
-
- g_settings_set_boolean (priv->keyboard_settings, "numlock-state", numlock_state);
-}
-
-gboolean
-meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settings)
-{
- MetaInputSettingsPrivate *priv;
- gboolean numlock_state = FALSE;
-
- priv = meta_input_settings_get_instance_private (input_settings);
-
- if (g_settings_get_boolean (priv->keyboard_settings, "remember-numlock-state"))
- numlock_state = g_settings_get_boolean (priv->keyboard_settings, "numlock-state");
-
- return numlock_state;
-}
-
-void
-meta_input_settings_set_device_matrix (MetaInputSettings *input_settings,
- ClutterInputDevice *device,
- float matrix[6])
-{
- g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings));
- g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
-
- META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_matrix (input_settings,
- device,
- matrix);
-}
-
-void
-meta_input_settings_set_device_enabled (MetaInputSettings *input_settings,
- ClutterInputDevice *device,
- gboolean enabled)
-{
- GDesktopDeviceSendEvents mode;
-
- g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings));
- g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
-
- mode = enabled ?
- G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED :
- G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED;
-
- META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_send_events (input_settings,
- device,
- mode);
-}
-
-void
-meta_input_settings_set_device_aspect_ratio (MetaInputSettings *input_settings,
- ClutterInputDevice *device,
- double aspect_ratio)
-{
- MetaInputSettingsPrivate *priv;
- DeviceMappingInfo *info;
-
- g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings));
- g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
-
- priv = meta_input_settings_get_instance_private (input_settings);
-
- info = g_hash_table_lookup (priv->mappable_devices, device);
- if (!info)
- return;
-
- info->aspect_ratio = aspect_ratio;
- update_tablet_keep_aspect (input_settings, info->settings, device);
-}
-
-void
-meta_input_settings_get_kbd_a11y_settings (MetaInputSettings *input_settings,
- MetaKbdA11ySettings *a11y_settings)
-{
- MetaInputSettingsPrivate *priv;
-
- g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings));
-
- priv = meta_input_settings_get_instance_private (input_settings);
-
- *a11y_settings = priv->kbd_a11y_settings;
-}
diff --git a/src/backends/meta-keymap-utils.c b/src/backends/meta-keymap-utils.c
deleted file mode 100644
index 123eb2303..000000000
--- a/src/backends/meta-keymap-utils.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Utilities for use with libxkbcommon
- *
- * Copyright 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 "backends/meta-keymap-utils.h"
-
-#include <glib.h>
-#include <limits.h>
-
-struct xkb_context *
-meta_create_xkb_context (void)
-{
- struct xkb_context *ctx;
- char xdg[PATH_MAX] = {0};
- const char *env;
-
- /*
- * We can only append search paths in libxkbcommon, so we start with an
- * empty set, then add the XDG dir, then add the default search paths.
- */
- ctx = xkb_context_new (XKB_CONTEXT_NO_DEFAULT_INCLUDES);
-
- env = g_getenv ("XDG_CONFIG_HOME");
- if (env)
- {
- g_snprintf (xdg, sizeof xdg, "%s/xkb", env);
- }
- else if ((env = g_getenv ("HOME")))
- {
- g_snprintf (xdg, sizeof xdg, "%s/.config/xkb", env);
- }
-
- if (env)
- xkb_context_include_path_append (ctx, xdg);
- xkb_context_include_path_append_default (ctx);
-
- return ctx;
-}
diff --git a/src/backends/meta-keymap-utils.h b/src/backends/meta-keymap-utils.h
deleted file mode 100644
index 3806824e4..000000000
--- a/src/backends/meta-keymap-utils.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Utilities for use with libxkbcommon
- *
- * Copyright 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/>.
- */
-
-#ifndef META_KEYMAP_UTILS_H
-#define META_KEYMAP_UTILS_H
-
-#include <xkbcommon/xkbcommon.h>
-
-struct xkb_context * meta_create_xkb_context (void);
-
-#endif /* META_KEYMAP_UTILS_H */
diff --git a/src/backends/meta-logical-monitor.c b/src/backends/meta-logical-monitor.c
deleted file mode 100644
index b562e5acb..000000000
--- a/src/backends/meta-logical-monitor.c
+++ /dev/null
@@ -1,343 +0,0 @@
-/* -*- 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 = meta_output_get_id (main_output);
- 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;
- MetaCrtc *crtc;
- const MetaCrtcConfig *crtc_config;
- MetaMonitorTransform transform;
-
- main_output = meta_monitor_get_main_output (monitor);
- crtc = meta_output_get_assigned_crtc (main_output);
- crtc_config = meta_crtc_get_config (crtc);
- transform = crtc_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 = meta_output_get_id (main_output);
- 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 &&
- meta_output_is_presentation (output));
- }
- }
-
- 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
deleted file mode 100644
index d5ef1da83..000000000
--- a/src/backends/meta-logical-monitor.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -*- 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 extended, 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);
-
-META_EXPORT_TEST
-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
deleted file mode 100644
index 0253e072f..000000000
--- a/src/backends/meta-monitor-config-manager.c
+++ /dev/null
@@ -1,1899 +0,0 @@
-/* -*- 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_assignment_free (MetaCrtcAssignment *assignment);
-
-static void
-meta_output_assignment_free (MetaOutputAssignment *assignment);
-
-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++)
- {
- uint64_t id;
-
- id = g_array_index (reserved_crtcs, uint64_t, i);
- if (id == meta_crtc_get_id (crtc))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-is_crtc_assigned (MetaCrtc *crtc,
- GPtrArray *crtc_assignments)
-{
- unsigned int i;
-
- for (i = 0; i < crtc_assignments->len; i++)
- {
- MetaCrtcAssignment *assigned_crtc_assignment =
- g_ptr_array_index (crtc_assignments, i);
-
- if (assigned_crtc_assignment->crtc == crtc)
- return TRUE;
- }
-
- return FALSE;
-}
-
-static MetaCrtc *
-find_unassigned_crtc (MetaOutput *output,
- GPtrArray *crtc_assignments,
- GArray *reserved_crtcs)
-{
- MetaCrtc *crtc;
- const MetaOutputInfo *output_info;
- unsigned int i;
-
- crtc = meta_output_get_assigned_crtc (output);
- if (crtc && !is_crtc_assigned (crtc, crtc_assignments))
- return crtc;
-
- output_info = meta_output_get_info (output);
-
- /* then try to assign a CRTC that wasn't used */
- for (i = 0; i < output_info->n_possible_crtcs; i++)
- {
- crtc = output_info->possible_crtcs[i];
-
- if (is_crtc_assigned (crtc, crtc_assignments))
- 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_info->n_possible_crtcs; i++)
- {
- crtc = output_info->possible_crtcs[i];
-
- if (is_crtc_assigned (crtc, crtc_assignments))
- continue;
-
- return crtc;
- }
-
- return NULL;
-}
-
-typedef struct
-{
- MetaMonitorManager *monitor_manager;
- MetaMonitorsConfig *config;
- MetaLogicalMonitorConfig *logical_monitor_config;
- MetaMonitorConfig *monitor_config;
- GPtrArray *crtc_assignments;
- GPtrArray *output_assignments;
- 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;
- const MetaCrtcModeInfo *crtc_mode_info;
- graphene_rect_t crtc_layout;
- MetaCrtcAssignment *crtc_assignment;
- MetaOutputAssignment *output_assignment;
- 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_assignments,
- 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;
-
- 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;
- }
-
- crtc_mode = monitor_crtc_mode->crtc_mode;
- crtc_mode_info = meta_crtc_mode_get_info (monitor_crtc_mode->crtc_mode);
-
- if (meta_monitor_transform_is_rotated (crtc_transform))
- {
- width = crtc_mode_info->height / scale;
- height = crtc_mode_info->width / scale;
- }
- else
- {
- width = crtc_mode_info->width / scale;
- height = crtc_mode_info->height / scale;
- }
-
- crtc_layout = GRAPHENE_RECT_INIT (x_offset + (crtc_x / scale),
- y_offset + (crtc_y / scale),
- width,
- height);
-
- crtc_assignment = g_new0 (MetaCrtcAssignment, 1);
- *crtc_assignment = (MetaCrtcAssignment) {
- .crtc = crtc,
- .mode = crtc_mode,
- .layout = crtc_layout,
- .transform = crtc_hw_transform,
- .outputs = g_ptr_array_new ()
- };
- g_ptr_array_add (crtc_assignment->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_assignment = g_new0 (MetaOutputAssignment, 1);
- *output_assignment = (MetaOutputAssignment) {
- .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_assignments, crtc_assignment);
- g_ptr_array_add (data->output_assignments, output_assignment);
-
- return TRUE;
-}
-
-static gboolean
-assign_monitor_crtcs (MetaMonitorManager *manager,
- MetaMonitorsConfig *config,
- MetaLogicalMonitorConfig *logical_monitor_config,
- MetaMonitorConfig *monitor_config,
- GPtrArray *crtc_assignments,
- GPtrArray *output_assignments,
- 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_assignments = crtc_assignments,
- .output_assignments = output_assignments,
- .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_assignments,
- GPtrArray *output_assignments,
- 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_assignments, output_assignments,
- reserved_crtcs, error))
- return FALSE;
- }
-
- return TRUE;
-}
-
-gboolean
-meta_monitor_config_manager_assign (MetaMonitorManager *manager,
- MetaMonitorsConfig *config,
- GPtrArray **out_crtc_assignments,
- GPtrArray **out_output_assignments,
- GError **error)
-{
- GPtrArray *crtc_assignments;
- GPtrArray *output_assignments;
- GArray *reserved_crtcs;
- GList *l;
-
- crtc_assignments =
- g_ptr_array_new_with_free_func ((GDestroyNotify) meta_crtc_assignment_free);
- output_assignments =
- g_ptr_array_new_with_free_func ((GDestroyNotify) meta_output_assignment_free);
- reserved_crtcs = g_array_new (FALSE, FALSE, sizeof (uint64_t));
-
- 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)
- {
- uint64_t crtc_id = meta_crtc_get_id (crtc);
-
- g_array_append_val (reserved_crtcs, 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_assignments, output_assignments,
- reserved_crtcs, error))
- {
- g_ptr_array_free (crtc_assignments, TRUE);
- g_ptr_array_free (output_assignments, TRUE);
- g_array_free (reserved_crtcs, TRUE);
- return FALSE;
- }
- }
-
- g_array_free (reserved_crtcs, TRUE);
-
- *out_crtc_assignments = crtc_assignments;
- *out_output_assignments = output_assignments;
-
- 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)
-} 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_memdup2 (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 MetaLogicalMonitorConfig *
-create_preferred_logical_monitor_config (MetaMonitorManager *monitor_manager,
- MetaMonitor *monitor,
- int x,
- int y,
- 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,
- 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_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;
- int x;
- GList *monitors;
- GList *l;
- MetaMonitorsConfig *monitors_config;
-
- primary_monitor = find_primary_monitor (monitor_manager);
- if (!primary_monitor)
- return NULL;
-
- layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
-
- primary_logical_monitor_config =
- create_preferred_logical_monitor_config (monitor_manager,
- primary_monitor,
- 0, 0,
- 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,
- primary_logical_monitor_config,
- layout_mode);
- logical_monitor_configs = g_list_append (logical_monitor_configs,
- logical_monitor_config);
-
- x += logical_monitor_config->layout.width;
- }
-
- monitors_config = meta_monitors_config_new (monitor_manager,
- logical_monitor_configs,
- layout_mode,
- META_MONITORS_CONFIG_FLAG_NONE);
-
- if (monitors_config)
- meta_monitors_config_set_switch_config (monitors_config, META_MONITOR_SWITCH_CONFIG_ALL_LINEAR);
-
- return monitors_config;
-}
-
-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;
-
- primary_monitor = find_primary_monitor (monitor_manager);
- if (!primary_monitor)
- return NULL;
-
- layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
-
- primary_logical_monitor_config =
- create_preferred_logical_monitor_config (monitor_manager,
- primary_monitor,
- 0, 0,
- 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;
- 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);
-
- primary_logical_monitor_config =
- create_preferred_logical_monitor_config (monitor_manager,
- primary_monitor,
- x, y,
- 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,
- 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);
- }
-
- 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_memdup2 (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_memdup2 (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);
-}
-
-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;
- MetaMonitorsConfig *monitors_config;
-
- 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, 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);
- monitors_config = meta_monitors_config_new (monitor_manager,
- logical_monitor_configs,
- layout_mode,
- META_MONITORS_CONFIG_FLAG_NONE);
-
- if (monitors_config)
- meta_monitors_config_set_switch_config (monitors_config, META_MONITOR_SWITCH_CONFIG_ALL_MIRROR);
-
- return monitors_config;
-}
-
-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;
- MetaLogicalMonitorLayoutMode layout_mode;
- GList *monitors;
- GList *l;
- MetaMonitorsConfig *monitors_config;
-
- layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
-
- 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,
- 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;
- }
-
- if (!logical_monitor_configs)
- return NULL;
-
- monitors_config = meta_monitors_config_new (monitor_manager,
- logical_monitor_configs,
- layout_mode,
- META_MONITORS_CONFIG_FLAG_NONE);
-
- if (monitors_config)
- meta_monitors_config_set_switch_config (monitors_config, META_MONITOR_SWITCH_CONFIG_EXTERNAL);
-
- return monitors_config;
-}
-
-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;
- MetaMonitorsConfig *monitors_config;
-
- monitor = meta_monitor_manager_get_laptop_panel (monitor_manager);
- if (!monitor)
- return NULL;
-
- layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
-
- primary_logical_monitor_config =
- create_preferred_logical_monitor_config (monitor_manager,
- monitor,
- 0, 0,
- NULL,
- layout_mode);
- primary_logical_monitor_config->is_primary = TRUE;
- logical_monitor_configs = g_list_append (NULL,
- primary_logical_monitor_config);
-
- monitors_config = meta_monitors_config_new (monitor_manager,
- logical_monitor_configs,
- layout_mode,
- META_MONITORS_CONFIG_FLAG_NONE);
-
- if (monitors_config)
- meta_monitors_config_set_switch_config (monitors_config, META_MONITOR_SWITCH_CONFIG_BUILTIN);
-
- return monitors_config;
-}
-
-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;
- }
-
- 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)
-{
- if (monitor_config->monitor_spec)
- 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_assignment_free (MetaCrtcAssignment *assignment)
-{
- g_ptr_array_free (assignment->outputs, TRUE);
- g_free (assignment);
-}
-
-static void
-meta_output_assignment_free (MetaOutputAssignment *assignment)
-{
- g_free (assignment);
-}
-
-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,
- 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_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
deleted file mode 100644
index 86756a7e3..000000000
--- a/src/backends/meta-monitor-config-manager.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/* -*- 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_assignments,
- GPtrArray **output_assignments,
- 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);
-
-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,
- 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
deleted file mode 100644
index d619dc433..000000000
--- a/src/backends/meta-monitor-config-migration.c
+++ /dev/null
@@ -1,1233 +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
- * 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;
-
- 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;
- float scale;
-
- 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;
- }
-
- scale = meta_monitor_calculate_mode_scale (monitor, monitor_mode);
-
- logical_monitor_config->scale = scale;
- }
-
- config->layout_mode =
- meta_monitor_manager_get_default_layout_mode (monitor_manager);
- 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
deleted file mode 100644
index 7b338ace2..000000000
--- a/src/backends/meta-monitor-config-migration.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 4dd357a15..000000000
--- a/src/backends/meta-monitor-config-store.c
+++ /dev/null
@@ -1,1683 +0,0 @@
-/* -*- 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,
- 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_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;
-
- 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);
-
- 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,
- error))
- return;
-
- if (!meta_verify_logical_monitor_config (logical_monitor_config,
- layout_mode,
- store->monitor_manager,
- 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)
-{
- char *escaped;
-
- g_string_append_printf (buffer, "%s<monitorspec>\n", indentation);
-
- escaped = g_markup_escape_text (monitor_spec->connector, -1);
- g_string_append_printf (buffer, "%s <connector>%s</connector>\n",
- indentation,
- escaped);
- g_free (escaped);
-
- escaped = g_markup_escape_text (monitor_spec->vendor, -1);
- g_string_append_printf (buffer, "%s <vendor>%s</vendor>\n",
- indentation,
- escaped);
- g_free (escaped);
-
- escaped = g_markup_escape_text (monitor_spec->product, -1);
- g_string_append_printf (buffer, "%s <product>%s</product>\n",
- indentation,
- escaped);
- g_free (escaped);
-
- escaped = g_markup_escape_text (monitor_spec->serial, -1);
- g_string_append_printf (buffer, "%s <serial>%s</serial>\n",
- indentation,
- escaped);
- g_free (escaped);
-
- 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", 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",
- 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 configuration.",
- 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
deleted file mode 100644
index 92c24ecaa..000000000
--- a/src/backends/meta-monitor-config-store.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- 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
deleted file mode 100644
index d08fb022b..000000000
--- a/src/backends/meta-monitor-manager-dummy.c
+++ /dev/null
@@ -1,816 +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
- * 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/main.h"
-#include "meta/util.h"
-
-#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;
-};
-
-struct _MetaOutputDummy
-{
- MetaOutput parent;
-
- float scale;
-};
-
-struct _MetaCrtcDummy
-{
- MetaCrtc parent;
-};
-
-G_DEFINE_TYPE (MetaOutputDummy, meta_output_dummy, META_TYPE_OUTPUT)
-G_DEFINE_TYPE (MetaCrtcDummy, meta_crtc_dummy, META_TYPE_CRTC)
-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)
-
-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)
-{
- g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL;
-
- crtc_mode_info = meta_crtc_mode_info_new ();
- crtc_mode_info->width = spec->width;
- crtc_mode_info->height = spec->height;
- crtc_mode_info->refresh_rate = spec->refresh_rate;
-
- return g_object_new (META_TYPE_CRTC_MODE,
- "id", (uint64_t) mode_id,
- "info", crtc_mode_info,
- NULL);
-}
-
-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;
- g_autoptr (MetaOutputInfo) output_info = NULL;
- 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;
-
- 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_memdup2 (&default_specs[i], sizeof (CrtcModeSpec));
- mode_specs = g_list_prepend (mode_specs, spec);
- }
- }
-
- if (!mode_specs)
- {
- g_warning ("Cannot create dummy output: No valid mode specs.");
- meta_exit (META_EXIT_ERROR);
- }
-
- 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_DUMMY,
- "id", (uint64_t) g_list_length (*crtcs) + 1,
- "gpu", gpu,
- NULL);
- *crtcs = g_list_append (*crtcs, crtc);
-
- number = g_list_length (*outputs) + 1;
-
- output_info = meta_output_info_new ();
- output_info->name = g_strdup_printf ("LVDS%d", number);
- output_info->vendor = g_strdup ("MetaProducts Inc.");
- output_info->product = g_strdup ("MetaMonitor");
- output_info->serial = g_strdup_printf ("0xC0FFEE-%d", number);
- output_info->width_mm = 222;
- output_info->height_mm = 125;
- output_info->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
- output_info->preferred_mode = g_list_last (*modes)->data;
- output_info->n_possible_clones = 0;
- output_info->connector_type = META_CONNECTOR_TYPE_LVDS;
-
- output_info->modes = g_new0 (MetaCrtcMode *, n_mode_specs);
- for (l = new_modes, i = 0; l; l = l->next, i++)
- {
- MetaCrtcMode *mode = l->data;
-
- output_info->modes[i] = mode;
- }
- output_info->n_modes = n_mode_specs;
- output_info->possible_crtcs = g_new0 (MetaCrtc *, 1);
- output_info->possible_crtcs[0] = g_list_last (*crtcs)->data;
- output_info->n_possible_crtcs = 1;
-
- output = g_object_new (META_TYPE_OUTPUT_DUMMY,
- "id", (uint64_t) number,
- "gpu", gpu,
- "info", output_info,
- NULL);
- output_dummy = META_OUTPUT_DUMMY (output);
- output_dummy->scale = scale;
-
- *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_DUMMY,
- "id", (uint64_t) g_list_length (*crtcs) + i + 1,
- "gpu", gpu,
- NULL);
- 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;
- const MetaCrtcModeInfo *preferred_mode_info;
- unsigned int j;
- unsigned int number;
- g_autoptr (MetaOutputInfo) output_info = NULL;
- GList *l;
-
- /* Arbitrary ID unique for this output */
- number = g_list_length (*outputs) + 1;
-
- preferred_mode = g_list_last (*modes)->data;
- preferred_mode_info = meta_crtc_mode_get_info (preferred_mode);
-
- output_info = meta_output_info_new ();
-
- output_info->name = g_strdup_printf ("LVDS%d", number);
- output_info->vendor = g_strdup ("MetaProducts Inc.");
- output_info->product = g_strdup ("MetaMonitor");
- output_info->serial = g_strdup_printf ("0xC0FFEE-%d", number);
- output_info->suggested_x = -1;
- output_info->suggested_y = -1;
- output_info->width_mm = 222;
- output_info->height_mm = 125;
- output_info->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
- output_info->preferred_mode = preferred_mode;
- output_info->n_possible_clones = 0;
- output_info->connector_type = META_CONNECTOR_TYPE_LVDS;
- output_info->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_info->width,
- .tile_h = preferred_mode_info->height
- },
-
- output_info->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_info->modes[j] = mode;
- }
- output_info->n_modes = G_N_ELEMENTS (mode_specs);
-
- output_info->possible_crtcs = g_new0 (MetaCrtc *, n_tiles);
- for (l = new_crtcs, j = 0; l; l = l->next, j++)
- {
- MetaCrtc *crtc = l->data;
-
- output_info->possible_crtcs[j] = crtc;
- }
- output_info->n_possible_crtcs = n_tiles;
-
- output = g_object_new (META_TYPE_OUTPUT_DUMMY,
- "id", (uint64_t) number,
- "gpu", gpu,
- "info", output_info,
- NULL);
- output_dummy = META_OUTPUT_DUMMY (output);
- output_dummy->scale = scale;
-
- *outputs = g_list_append (*outputs, output);
- }
-}
-
-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;
- const char *tiled_monitors_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).");
- 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_str = g_getenv ("MUTTER_DEBUG_TILED_DUMMY_MONITORS");
- tiled_monitors = g_strcmp0 (tiled_monitors_str, "1") == 0;
-
- 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,
- MetaCrtcAssignment **crtcs,
- unsigned int n_crtcs,
- MetaOutputAssignment **outputs,
- unsigned int n_outputs)
-{
- g_autoptr (GList) to_configure_outputs = NULL;
- g_autoptr (GList) to_configure_crtcs = NULL;
- unsigned i;
-
- to_configure_outputs = g_list_copy (meta_gpu_get_outputs (get_gpu (manager)));
- to_configure_crtcs = g_list_copy (meta_gpu_get_crtcs (get_gpu (manager)));
-
- for (i = 0; i < n_crtcs; i++)
- {
- MetaCrtcAssignment *crtc_assignment = crtcs[i];
- MetaCrtc *crtc = crtc_assignment->crtc;
-
- to_configure_crtcs = g_list_remove (to_configure_crtcs, crtc);
-
- if (crtc_assignment->mode == NULL)
- {
- meta_crtc_unset_config (crtc);
- }
- else
- {
- unsigned int j;
-
- meta_crtc_set_config (crtc,
- &crtc_assignment->layout,
- crtc_assignment->mode,
- crtc_assignment->transform);
-
- for (j = 0; j < crtc_assignment->outputs->len; j++)
- {
- MetaOutput *output;
- MetaOutputAssignment *output_assignment;
-
- output = ((MetaOutput**) crtc_assignment->outputs->pdata)[j];
-
- to_configure_outputs = g_list_remove (to_configure_outputs,
- output);
-
- output_assignment = meta_find_output_assignment (outputs,
- n_outputs,
- output);
- meta_output_assign_crtc (output, crtc, output_assignment);
- }
- }
- }
-
- g_list_foreach (to_configure_crtcs,
- (GFunc) meta_crtc_unset_config,
- NULL);
- g_list_foreach (to_configure_outputs,
- (GFunc) meta_output_unassign_crtc,
- NULL);
-}
-
-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_assignments;
- GPtrArray *output_assignments;
-
- 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_assignments,
- &output_assignments,
- error))
- return FALSE;
-
- if (method == META_MONITORS_CONFIG_METHOD_VERIFY)
- {
- g_ptr_array_free (crtc_assignments, TRUE);
- g_ptr_array_free (output_assignments, TRUE);
- return TRUE;
- }
-
- apply_crtc_assignments (manager,
- (MetaCrtcAssignment **) crtc_assignments->pdata,
- crtc_assignments->len,
- (MetaOutputAssignment **) output_assignments->pdata,
- output_assignments->len);
-
- g_ptr_array_free (crtc_assignments, TRUE);
- g_ptr_array_free (output_assignments, 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,
- MetaMonitor *monitor,
- MetaMonitorMode *monitor_mode)
-{
- MetaOutput *output;
- MetaOutputDummy *output_dummy;
-
- output = meta_monitor_get_main_output (monitor);
- output_dummy = META_OUTPUT_DUMMY (output);
-
- 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:
- 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 (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;
-}
-
-static void
-meta_output_dummy_init (MetaOutputDummy *output_dummy)
-{
- output_dummy->scale = 1;
-}
-
-static void
-meta_output_dummy_class_init (MetaOutputDummyClass *klass)
-{
-}
-
-static void
-meta_crtc_dummy_init (MetaCrtcDummy *crtc_dummy)
-{
-}
-
-static void
-meta_crtc_dummy_class_init (MetaCrtcDummyClass *klass)
-{
-}
diff --git a/src/backends/meta-monitor-manager-dummy.h b/src/backends/meta-monitor-manager-dummy.h
deleted file mode 100644
index 72244166e..000000000
--- a/src/backends/meta-monitor-manager-dummy.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- 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-crtc.h"
-#include "backends/meta-gpu.h"
-#include "backends/meta-monitor-manager-private.h"
-#include "backends/meta-output.h"
-
-#define META_TYPE_OUTPUT_DUMMY (meta_output_dummy_get_type ())
-G_DECLARE_FINAL_TYPE (MetaOutputDummy, meta_output_dummy,
- META, OUTPUT_DUMMY,
- MetaOutput)
-
-#define META_TYPE_CRTC_DUMMY (meta_crtc_dummy_get_type ())
-G_DECLARE_FINAL_TYPE (MetaCrtcDummy, meta_crtc_dummy,
- META, CRTC_DUMMY,
- MetaCrtc)
-
-#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
deleted file mode 100644
index 60c1e9082..000000000
--- a/src/backends/meta-monitor-manager-private.h
+++ /dev/null
@@ -1,439 +0,0 @@
-/* -*- 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.
- * Copyright (C) 2020 NVIDIA 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, 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 <libgnome-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 "backends/meta-viewport-info.h"
-#include "core/util-private.h"
-#include "meta/display.h"
-#include "meta/meta-monitor-manager.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)
-} 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
-} MetaLogicalMonitorLayoutMode;
-
-/*
- * MetaCrtcAssignment:
- *
- * A representation of a CRTC configuration, generated by
- * MetaMonitorConfigManager.
- */
-struct _MetaCrtcAssignment
-{
- MetaCrtc *crtc;
- MetaCrtcMode *mode;
- graphene_rect_t layout;
- MetaMonitorTransform transform;
- GPtrArray *outputs;
-};
-
-/*
- * MetaOutputAssignment:
- *
- * A representation of a connector configuration, generated by
- * MetaMonitorConfigManager.
- */
-struct _MetaOutputAssignment
-{
- MetaOutput *output;
- gboolean is_primary;
- gboolean is_presentation;
- gboolean is_underscanning;
-};
-
-/*
- * MetaOutputCtm:
- *
- * A 3x3 color transform matrix in the fixed-point S31.32 sign-magnitude format
- * used by DRM.
- */
-typedef struct _MetaOutputCtm
-{
- uint64_t matrix[9];
-} MetaOutputCtm;
-
-#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))
-
-typedef struct _MetaDBusDisplayConfig MetaDBusDisplayConfig;
-
-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 *logical_monitors;
- MetaLogicalMonitor *primary_logical_monitor;
-
- int dbus_name_id;
-
- int persistent_timeout_id;
-
- guint panel_orientation_managed : 1;
-
- 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.
- *
- * @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.
- *
- * @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().
- * @set_output_ctm: vfunc for meta_monitor_manager_output_set_ctm()
- *
- * The base class for a #MetaMonitorManager.
- */
-struct _MetaMonitorManagerClass
-{
- GObjectClass parent_class;
-
- GBytes * (* read_edid) (MetaMonitorManager *manager,
- MetaOutput *output);
-
- void (* read_current_state) (MetaMonitorManager *manager);
-
- void (* ensure_initial_config) (MetaMonitorManager *manager);
-
- gboolean (* apply_monitors_config) (MetaMonitorManager *manager,
- MetaMonitorsConfig *config,
- MetaMonitorsConfigMethod method,
- GError **error);
-
- void (* set_power_save_mode) (MetaMonitorManager *manager,
- MetaPowerSave power_save);
-
- void (* change_backlight) (MetaMonitorManager *manager,
- MetaOutput *output,
- int backlight);
-
- void (* get_crtc_gamma) (MetaMonitorManager *manager,
- MetaCrtc *crtc,
- size_t *size,
- unsigned short **red,
- unsigned short **green,
- unsigned short **blue);
- void (* set_crtc_gamma) (MetaMonitorManager *manager,
- MetaCrtc *crtc,
- size_t size,
- unsigned short *red,
- unsigned short *green,
- unsigned short *blue);
-
- void (* tiled_monitor_added) (MetaMonitorManager *manager,
- MetaMonitor *monitor);
-
- void (* tiled_monitor_removed) (MetaMonitorManager *manager,
- MetaMonitor *monitor);
-
- gboolean (* is_transform_handled) (MetaMonitorManager *manager,
- MetaCrtc *crtc,
- MetaMonitorTransform transform);
-
- float (* calculate_monitor_mode_scale) (MetaMonitorManager *manager,
- MetaMonitor *monitor,
- MetaMonitorMode *monitor_mode);
-
- float * (* calculate_supported_scales) (MetaMonitorManager *manager,
- MetaLogicalMonitorLayoutMode layout_mode,
- MetaMonitor *monitor,
- MetaMonitorMode *monitor_mode,
- int *n_supported_scales);
-
- MetaMonitorManagerCapability (* get_capabilities) (MetaMonitorManager *manager);
-
- gboolean (* get_max_screen_size) (MetaMonitorManager *manager,
- int *width,
- int *height);
-
- MetaLogicalMonitorLayoutMode (* get_default_layout_mode) (MetaMonitorManager *manager);
-
- void (* set_output_ctm) (MetaOutput *output,
- const MetaOutputCtm *ctm);
-
- MetaVirtualMonitor * (* create_virtual_monitor) (MetaMonitorManager *manager,
- const MetaVirtualMonitorInfo *info,
- GError **error);
-};
-
-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);
-
-gboolean meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager);
-
-void meta_monitor_manager_read_current_state (MetaMonitorManager *manager);
-
-void meta_monitor_manager_reconfigure (MetaMonitorManager *manager);
-
-META_EXPORT_TEST
-void meta_monitor_manager_reload (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,
- 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);
-
-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);
-
-META_EXPORT_TEST
-MetaVirtualMonitor * meta_monitor_manager_create_virtual_monitor (MetaMonitorManager *manager,
- const MetaVirtualMonitorInfo *info,
- GError **error);
-
-META_EXPORT_TEST
-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);
-
-static inline MetaOutputAssignment *
-meta_find_output_assignment (MetaOutputAssignment **outputs,
- unsigned int n_outputs,
- MetaOutput *output)
-{
- unsigned int i;
-
- for (i = 0; i < n_outputs; i++)
- {
- MetaOutputAssignment *output_assignment = outputs[i];
-
- if (output == output_assignment->output)
- return output_assignment;
- }
-
- return NULL;
-}
-
-void meta_monitor_manager_post_init (MetaMonitorManager *manager);
-
-MetaViewportInfo * meta_monitor_manager_get_viewports (MetaMonitorManager *manager);
-
-GList * meta_monitor_manager_get_virtual_monitors (MetaMonitorManager *manager);
-
-#endif /* META_MONITOR_MANAGER_PRIVATE_H */
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
deleted file mode 100644
index e6d50bd99..000000000
--- a/src/backends/meta-monitor-manager.c
+++ /dev/null
@@ -1,3471 +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
- * Copyright (C) 2013 Red Hat Inc.
- * Copyright (C) 2020 NVIDIA 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, 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/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/meta-virtual-monitor.h"
-#include "backends/x11/meta-monitor-manager-xrandr.h"
-#include "clutter/clutter.h"
-#include "core/util-private.h"
-#include "meta/main.h"
-#include "meta/meta-x11-errors.h"
-
-#include "meta-dbus-display-config.h"
-
-#define DEFAULT_DISPLAY_CONFIGURATION_TIMEOUT 20
-
-enum
-{
- PROP_0,
-
- PROP_BACKEND,
- PROP_PANEL_ORIENTATION_MANAGED,
-
- 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;
- gboolean initial_orient_change_done;
-
- GList *virtual_monitors;
-
- gboolean shutting_down;
-} 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 MetaMonitor *
-meta_monitor_manager_get_active_monitor (MetaMonitorManager *manager);
-
-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)
-{
- const MetaOutputInfo *output_info = meta_output_get_info (output);
-
- return (output_info->tile_info.loc_h_tile == 0 &&
- output_info->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);
-}
-
-static float
-derive_configured_global_scale (MetaMonitorManager *manager,
- MetaMonitorsConfig *config)
-{
- MetaLogicalMonitorConfig *logical_monitor_config;
-
- logical_monitor_config = config->logical_monitor_configs->data;
-
- return logical_monitor_config->scale;
-}
-
-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,
- monitor,
- monitor_mode);
-}
-
-static float
-derive_calculated_global_scale (MetaMonitorManager *manager)
-{
- MetaMonitor *monitor = NULL;
-
- monitor = meta_monitor_manager_get_primary_monitor (manager);
-
- if (!monitor || !meta_monitor_is_active (monitor))
- monitor = meta_monitor_manager_get_active_monitor (manager);
-
- if (!monitor)
- return 1.0;
-
- return calculate_monitor_scale (manager, monitor);
-}
-
-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 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 = global_scale;
- else 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);
-}
-
-static void
-prepare_shutdown (MetaBackend *backend,
- MetaMonitorManager *manager)
-{
- MetaMonitorManagerPrivate *priv =
- meta_monitor_manager_get_instance_private (manager);
-
- priv->shutting_down = TRUE;
-}
-
-/**
- * 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,
- MetaMonitor *monitor,
- MetaMonitorMode *monitor_mode)
-{
- MetaMonitorManagerClass *manager_class =
- META_MONITOR_MANAGER_GET_CLASS (manager);
-
- return manager_class->calculate_monitor_mode_scale (manager,
- monitor,
- monitor_mode);
-}
-
-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
-on_virtual_monitor_destroyed (MetaVirtualMonitor *virtual_monitor,
- MetaMonitorManager *manager)
-{
- MetaMonitorManagerPrivate *priv =
- meta_monitor_manager_get_instance_private (manager);
- MetaOutput *output;
-
- output = meta_virtual_monitor_get_output (virtual_monitor);
- g_message ("Removed virtual monitor %s", meta_output_get_name (output));
- priv->virtual_monitors = g_list_remove (priv->virtual_monitors,
- virtual_monitor);
-
- if (!priv->shutting_down)
- meta_monitor_manager_reload (manager);
-}
-
-MetaVirtualMonitor *
-meta_monitor_manager_create_virtual_monitor (MetaMonitorManager *manager,
- const MetaVirtualMonitorInfo *info,
- GError **error)
-{
- MetaMonitorManagerPrivate *priv =
- meta_monitor_manager_get_instance_private (manager);
- MetaMonitorManagerClass *manager_class =
- META_MONITOR_MANAGER_GET_CLASS (manager);
- MetaVirtualMonitor *virtual_monitor;
- MetaOutput *output;
-
- if (!manager_class->create_virtual_monitor)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- "Backend doesn't support creating virtual monitors");
- return NULL;
- }
-
- virtual_monitor = manager_class->create_virtual_monitor (manager, info,
- error);
- if (!virtual_monitor)
- return NULL;
-
- g_signal_connect (virtual_monitor, "destroy",
- G_CALLBACK (on_virtual_monitor_destroyed),
- manager);
-
- priv->virtual_monitors = g_list_append (priv->virtual_monitors,
- virtual_monitor);
-
- output = meta_virtual_monitor_get_output (virtual_monitor);
- g_message ("Added virtual monitor %s", meta_output_get_name (output));
-
- return virtual_monitor;
-}
-
-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 ||
- !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;
-
- 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)
- {
- config = meta_monitor_config_manager_get_stored (manager->config_manager);
- 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 (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
-handle_orientation_change (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);
-}
-
-/*
- * Special case for tablets with a native portrait mode and a keyboard dock,
- * where the device gets docked in landscape mode. For this combo to work
- * properly with mutter starting while the tablet is docked, we need to take
- * the accelerometer reported orientation into account (at mutter startup)
- * even if there is a tablet-mode-switch which indicates that the device is
- * NOT in tablet-mode (because it is docked).
- */
-static gboolean
-handle_initial_orientation_change (MetaOrientationManager *orientation_manager,
- MetaMonitorManager *manager)
-{
- ClutterBackend *clutter_backend;
- ClutterSeat *seat;
- MetaMonitor *monitor;
- MetaMonitorMode *mode;
- int width, height;
-
- clutter_backend = meta_backend_get_clutter_backend (manager->backend);
- seat = clutter_backend_get_default_seat (clutter_backend);
-
- /*
- * This is a workaround to ignore the tablet mode switch on the initial config
- * of devices with a native portrait mode panel. The touchscreen and
- * accelerometer requirements for applying the orientation must still be met.
- */
- if (!clutter_seat_has_touchscreen (seat) ||
- !meta_orientation_manager_has_accelerometer (orientation_manager))
- return FALSE;
-
- /* Check for a portrait mode panel */
- monitor = meta_monitor_manager_get_laptop_panel (manager);
- if (!monitor)
- return FALSE;
-
- mode = meta_monitor_get_preferred_mode (monitor);
- meta_monitor_mode_get_resolution (mode, &width, &height);
- if (width > height)
- return FALSE;
-
- handle_orientation_change (orientation_manager, manager);
- return TRUE;
-}
-
-static void
-orientation_changed (MetaOrientationManager *orientation_manager,
- MetaMonitorManager *manager)
-{
- MetaMonitorManagerPrivate *priv =
- meta_monitor_manager_get_instance_private (manager);
-
- if (!priv->initial_orient_change_done)
- {
- priv->initial_orient_change_done = TRUE;
- if (handle_initial_orientation_change (orientation_manager, manager))
- return;
- }
-
- if (!manager->panel_orientation_managed)
- return;
-
- handle_orientation_change (orientation_manager, manager);
-}
-
-static void
-experimental_features_changed (MetaSettings *settings,
- MetaExperimentalFeature old_experimental_features,
- MetaMonitorManager *manager)
-{
- gboolean was_stage_views_scaled;
- gboolean is_stage_views_scaled;
- 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);
-
- if (is_stage_views_scaled != was_stage_views_scaled)
- should_reconfigure = TRUE;
-
- if (should_reconfigure)
- meta_monitor_manager_reconfigure (manager);
-
- meta_settings_update_ui_scaling_factor (settings);
-}
-
-static void
-update_panel_orientation_managed (MetaMonitorManager *manager)
-{
- MetaOrientationManager *orientation_manager;
- ClutterBackend *clutter_backend;
- ClutterSeat *seat;
- gboolean panel_orientation_managed;
-
- clutter_backend = meta_backend_get_clutter_backend (manager->backend);
- seat = clutter_backend_get_default_seat (clutter_backend);
-
- orientation_manager = meta_backend_get_orientation_manager (manager->backend);
-
- panel_orientation_managed =
- (clutter_seat_get_touch_mode (seat) &&
- meta_orientation_manager_has_accelerometer (orientation_manager));
-
- if (manager->panel_orientation_managed == panel_orientation_managed)
- return;
-
- manager->panel_orientation_managed = panel_orientation_managed;
- g_object_notify_by_pspec (G_OBJECT (manager),
- obj_props[PROP_PANEL_ORIENTATION_MANAGED]);
-
- meta_dbus_display_config_set_panel_orientation_managed (manager->display_config,
- manager->panel_orientation_managed);
-
- /* The orientation may have changed while it was unmanaged */
- if (panel_orientation_managed)
- handle_orientation_change (orientation_manager, manager);
-}
-
-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 (meta_backend_get_orientation_manager (backend),
- "notify::has-accelerometer",
- G_CALLBACK (update_panel_orientation_managed), manager,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (backend,
- "lid-is-closed-changed",
- G_CALLBACK (lid_is_closed_changed),
- manager, 0);
-
- g_signal_connect (backend, "prepare-shutdown",
- G_CALLBACK (prepare_shutdown),
- manager);
-
- 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);
- MetaMonitorManagerPrivate *priv =
- meta_monitor_manager_get_instance_private (manager);
-
- g_list_free_full (manager->logical_monitors, g_object_unref);
-
- g_warn_if_fail (!priv->virtual_monitors);
-
- 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;
- case PROP_PANEL_ORIENTATION_MANAGED:
- 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;
- case PROP_PANEL_ORIENTATION_MANAGED:
- g_value_set_boolean (value, manager->panel_orientation_managed);
- 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);
-
- obj_props[PROP_PANEL_ORIENTATION_MANAGED] =
- g_param_spec_boolean ("panel-orientation-managed",
- "Panel orientation managed",
- "Panel orientation is managed",
- FALSE,
- G_PARAM_READABLE |
- G_PARAM_EXPLICIT_NOTIFY |
- 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;
- const MetaCrtcConfig *crtc_config;
-
- g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au"));
- for (j = 0; j <= META_MONITOR_TRANSFORM_FLIPPED_270; j++)
- {
- if (meta_crtc_get_all_transforms (crtc) & (1 << j))
- g_variant_builder_add (&transforms, "u", j);
- }
-
- crtc_config = meta_crtc_get_config (crtc);
- 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) meta_crtc_get_id (crtc),
- (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) meta_crtc_get_id (crtc),
- 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;
- const MetaOutputInfo *output_info = meta_output_get_info (output);
- GVariantBuilder crtcs, modes, clones, properties;
- GBytes *edid;
- MetaCrtc *crtc;
- int crtc_index;
- int backlight;
- int min_backlight_step;
- gboolean is_primary;
- gboolean is_presentation;
- const char * connector_type_name;
- gboolean is_underscanning;
- gboolean supports_underscanning;
- gboolean supports_color_transform;
-
- g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au"));
- for (j = 0; j < output_info->n_possible_crtcs; j++)
- {
- MetaCrtc *possible_crtc = output_info->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_info->n_modes; j++)
- {
- unsigned mode_index;
-
- mode_index = g_list_index (combined_modes, output_info->modes[j]);
- g_variant_builder_add (&modes, "u", mode_index);
- }
-
- g_variant_builder_init (&clones, G_VARIANT_TYPE ("au"));
- for (j = 0; j < output_info->n_possible_clones; j++)
- {
- unsigned int possible_clone_index;
-
- possible_clone_index = g_list_index (combined_outputs,
- output_info->possible_clones[j]);
- g_variant_builder_add (&clones, "u", possible_clone_index);
- }
-
- backlight = meta_output_get_backlight (output);
- min_backlight_step =
- output_info->backlight_max - output_info->backlight_min
- ? 100 / (output_info->backlight_max - output_info->backlight_min)
- : -1;
- is_primary = meta_output_is_primary (output);
- is_presentation = meta_output_is_presentation (output);
- is_underscanning = meta_output_is_underscanning (output);
- connector_type_name = get_connector_type_name (output_info->connector_type);
- supports_underscanning = output_info->supports_underscanning;
- supports_color_transform = output_info->supports_color_transform;
-
- g_variant_builder_init (&properties, G_VARIANT_TYPE ("a{sv}"));
- g_variant_builder_add (&properties, "{sv}", "vendor",
- g_variant_new_string (output_info->vendor));
- g_variant_builder_add (&properties, "{sv}", "product",
- g_variant_new_string (output_info->product));
- g_variant_builder_add (&properties, "{sv}", "serial",
- g_variant_new_string (output_info->serial));
- g_variant_builder_add (&properties, "{sv}", "width-mm",
- g_variant_new_int32 (output_info->width_mm));
- g_variant_builder_add (&properties, "{sv}", "height-mm",
- g_variant_new_int32 (output_info->height_mm));
- g_variant_builder_add (&properties, "{sv}", "display-name",
- g_variant_new_string (output_info->name));
- g_variant_builder_add (&properties, "{sv}", "backlight",
- g_variant_new_int32 (backlight));
- g_variant_builder_add (&properties, "{sv}", "min-backlight-step",
- g_variant_new_int32 (min_backlight_step));
- g_variant_builder_add (&properties, "{sv}", "primary",
- g_variant_new_boolean (is_primary));
- g_variant_builder_add (&properties, "{sv}", "presentation",
- g_variant_new_boolean (is_presentation));
- g_variant_builder_add (&properties, "{sv}", "connector-type",
- g_variant_new_string (connector_type_name));
- g_variant_builder_add (&properties, "{sv}", "underscanning",
- g_variant_new_boolean (is_underscanning));
- g_variant_builder_add (&properties, "{sv}", "supports-underscanning",
- g_variant_new_boolean (supports_underscanning));
- g_variant_builder_add (&properties, "{sv}", "supports-color-transform",
- g_variant_new_boolean (supports_color_transform));
-
- 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_info->tile_info.group_id)
- {
- GVariant *tile_variant;
-
- tile_variant = g_variant_new ("(uuuuuuuu)",
- output_info->tile_info.group_id,
- output_info->tile_info.flags,
- output_info->tile_info.max_h_tiles,
- output_info->tile_info.max_v_tiles,
- output_info->tile_info.loc_h_tile,
- output_info->tile_info.loc_v_tile,
- output_info->tile_info.tile_w,
- output_info->tile_info.tile_h);
- g_variant_builder_add (&properties, "{sv}", "tile", tile_variant);
- }
-
- 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 */
- meta_output_get_id (output),
- crtc_index,
- &crtcs,
- meta_output_get_name (output),
- &modes,
- &clones,
- &properties);
- }
-
- for (l = combined_modes, i = 0; l; l = l->next, i++)
- {
- MetaCrtcMode *mode = l->data;
- const MetaCrtcModeInfo *crtc_mode_info =
- meta_crtc_mode_get_info (mode);
-
- g_variant_builder_add (&mode_builder, "(uxuudu)",
- i, /* ID */
- (int64_t) meta_crtc_mode_get_id (mode),
- (uint32_t) crtc_mode_info->width,
- (uint32_t) crtc_mode_info->height,
- (double) crtc_mode_info->refresh_rate,
- (uint32_t) crtc_mode_info->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_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;
-
- 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);
-}
-
-#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;
-
- 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,
- 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}"));
- 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));
- }
-
- 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
-
-gboolean
-meta_monitor_manager_is_scale_supported (MetaMonitorManager *manager,
- MetaLogicalMonitorLayoutMode layout_mode,
- MetaMonitor *monitor,
- MetaMonitorMode *monitor_mode,
- float 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 (supported_scales[i] == 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 (manager,
- config->layout_mode,
- 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:
- 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 (!meta_verify_logical_monitor_config (logical_monitor_config,
- layout_mode,
- manager,
- 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:
- 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;
-
- 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;
- }
-
- logical_monitor_configs = g_list_append (logical_monitor_configs,
- logical_monitor_config);
- }
-
- 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;
- const MetaOutputInfo *output_info;
- int new_backlight;
-
- 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;
- }
-
- output_info = meta_output_get_info (output);
- if (meta_output_get_backlight (output) == -1 ||
- (output_info->backlight_min == 0 &&
- output_info->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);
-
- new_backlight = meta_output_get_backlight (output);
- meta_dbus_display_config_complete_change_backlight (skeleton,
- invocation,
- new_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 gboolean
-meta_monitor_manager_handle_set_output_ctm (MetaDBusDisplayConfig *skeleton,
- GDBusMethodInvocation *invocation,
- guint serial,
- guint output_id,
- GVariant *ctm_var,
- MetaMonitorManager *manager)
-{
- MetaMonitorManagerClass *klass;
- GList *combined_outputs;
- MetaOutput *output;
- MetaOutputCtm ctm;
- int i;
-
- 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_id >= 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_id);
- g_list_free (combined_outputs);
-
- if (g_variant_n_children (ctm_var) != 9)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_INVALID_ARGS,
- "Unexpected color transform matrix variant length");
- return TRUE;
- }
-
- for (i = 0; i < 9; i++)
- {
- GVariant *tmp = g_variant_get_child_value (ctm_var, i);
- ctm.matrix[i] = g_variant_get_uint64 (tmp);
- g_variant_unref (tmp);
- }
-
- klass = META_MONITOR_MANAGER_GET_CLASS (manager);
- if (klass->set_output_ctm)
- klass->set_output_ctm (output, &ctm);
- meta_dbus_display_config_complete_set_output_ctm (skeleton, invocation);
-
- 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);
- g_signal_connect_object (manager->display_config, "handle-set-output-ctm",
- G_CALLBACK (meta_monitor_manager_handle_set_output_ctm),
- 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", 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", name);
-}
-
-static void
-initialize_dbus_interface (MetaMonitorManager *manager)
-{
- MetaContext *context = meta_backend_get_context (manager->backend);
-
- manager->dbus_name_id =
- g_bus_own_name (G_BUS_TYPE_SESSION,
- "org.gnome.Mutter.DisplayConfig",
- G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
- (meta_context_is_replacing (context) ?
- G_BUS_NAME_OWNER_FLAGS_REPLACE :
- G_BUS_NAME_OWNER_FLAGS_NONE),
- 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);
-}
-
-static MetaMonitor *
-meta_monitor_manager_get_active_monitor (MetaMonitorManager *manager)
-{
- return find_monitor (manager, meta_monitor_is_active);
-}
-
-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
-destroy_monitor (MetaMonitor *monitor)
-{
- g_object_run_dispose (G_OBJECT (monitor));
- g_object_unref (monitor);
-}
-
-static void
-rebuild_monitors (MetaMonitorManager *manager)
-{
- GList *gpus;
- GList *l;
-
- if (manager->monitors)
- {
- g_list_free_full (manager->monitors, (GDestroyNotify) destroy_monitor);
- 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;
- const MetaOutputInfo *output_info = meta_output_get_info (output);
-
- if (output_info->tile_info.group_id)
- {
- if (is_main_tiled_monitor_output (output))
- {
- MetaMonitorTiled *monitor_tiled;
-
- monitor_tiled = meta_monitor_tiled_new (manager, output);
- manager->monitors = g_list_append (manager->monitors,
- monitor_tiled);
- }
- }
- else
- {
- MetaMonitorNormal *monitor_normal;
-
- monitor_normal = meta_monitor_normal_new (manager, output);
- manager->monitors = g_list_append (manager->monitors,
- monitor_normal);
- }
- }
- }
-
- for (l = meta_monitor_manager_get_virtual_monitors (manager); l; l = l->next)
- {
- MetaVirtualMonitor *virtual_monitor = l->data;
- MetaOutput *output = meta_virtual_monitor_get_output (virtual_monitor);
- MetaMonitorNormal *monitor_normal;
-
- monitor_normal = meta_monitor_normal_new (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_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
-
- meta_monitor_manager_rebuild_logical_monitors_derived (manager, config);
-}
-
-void
-meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager,
- MetaMonitorsConfig *config)
-{
- GList *old_logical_monitors;
-
- meta_monitor_manager_update_monitor_modes_derived (manager);
-
- 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_monitor_manager_reconfigure (MetaMonitorManager *manager)
-{
- meta_monitor_manager_ensure_configured (manager);
-}
-
-void
-meta_monitor_manager_reload (MetaMonitorManager *manager)
-{
- meta_monitor_manager_read_current_state (manager);
- meta_monitor_manager_reconfigure (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);
-}
-
-gboolean
-meta_monitor_manager_get_panel_orientation_managed (MetaMonitorManager *manager)
-{
- g_return_val_if_fail (META_IS_MONITOR_MANAGER (manager), FALSE);
-
- return manager->panel_orientation_managed;
-}
-
-void
-meta_monitor_manager_post_init (MetaMonitorManager *manager)
-{
- ClutterBackend *clutter_backend;
- ClutterSeat *seat;
-
- clutter_backend = meta_backend_get_clutter_backend (manager->backend);
- seat = clutter_backend_get_default_seat (clutter_backend);
-
- g_signal_connect_object (seat, "notify::touch-mode",
- G_CALLBACK (update_panel_orientation_managed), manager,
- G_CONNECT_SWAPPED);
-}
-
-MetaViewportInfo *
-meta_monitor_manager_get_viewports (MetaMonitorManager *manager)
-{
- MetaViewportInfo *info;
- GArray *views, *scales;
- GList *logical_monitors, *l;
-
- views = g_array_new (FALSE, FALSE, sizeof (cairo_rectangle_int_t));
- scales = g_array_new (FALSE, FALSE, sizeof (float));
-
- logical_monitors = meta_monitor_manager_get_logical_monitors (manager);
-
- for (l = logical_monitors; l; l = l->next)
- {
- MetaLogicalMonitor *logical_monitor = l->data;
- cairo_rectangle_int_t rect;
- float scale;
-
- rect = logical_monitor->rect;
- g_array_append_val (views, rect);
-
- scale = logical_monitor->scale;
- g_array_append_val (scales, scale);
- }
-
- info = meta_viewport_info_new ((cairo_rectangle_int_t *) views->data,
- (float *) scales->data,
- views->len,
- meta_is_stage_views_scaled ());
- g_array_unref (views);
- g_array_unref (scales);
-
- return info;
-}
-
-GList *
-meta_monitor_manager_get_virtual_monitors (MetaMonitorManager *manager)
-{
- MetaMonitorManagerPrivate *priv =
- meta_monitor_manager_get_instance_private (manager);
-
- return priv->virtual_monitors;
-}
diff --git a/src/backends/meta-monitor-transform.c b/src/backends/meta-monitor-transform.c
deleted file mode 100644
index d6b1f8b45..000000000
--- a/src/backends/meta-monitor-transform.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 6113f3a5a..000000000
--- a/src/backends/meta-monitor-transform.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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)
-#define META_MONITOR_ALL_TRANSFORMS ((1 << META_MONITOR_N_TRANSFORMS) - 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 (transform >= META_MONITOR_TRANSFORM_FLIPPED);
-}
-
-META_EXPORT_TEST
-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
deleted file mode 100644
index e02f8ed45..000000000
--- a/src/backends/meta-monitor.c
+++ /dev/null
@@ -1,1988 +0,0 @@
-/* -*- 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
-{
- MetaBackend *backend;
-
- 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 extended, 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 const MetaOutputInfo *
-meta_monitor_get_main_output_info (MetaMonitor *monitor)
-{
- MetaOutput *output = meta_monitor_get_main_output (monitor);
-
- return meta_output_get_info (output);
-}
-
-static void
-meta_monitor_generate_spec (MetaMonitor *monitor)
-{
- MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
- const MetaOutputInfo *output_info =
- meta_monitor_get_main_output_info (monitor);
- MetaMonitorSpec *monitor_spec;
-
- monitor_spec = g_new0 (MetaMonitorSpec, 1);
- *monitor_spec = (MetaMonitorSpec) {
- .connector = g_strdup (output_info->name),
- .vendor = g_strdup (output_info->vendor),
- .product = g_strdup (output_info->product),
- .serial = g_strdup (output_info->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);
- }
-}
-
-MetaBackend *
-meta_monitor_get_backend (MetaMonitor *monitor)
-{
- MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
-
- return priv->backend;
-}
-
-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 meta_output_is_primary (output);
-}
-
-gboolean
-meta_monitor_supports_underscanning (MetaMonitor *monitor)
-{
- const MetaOutputInfo *output_info =
- meta_monitor_get_main_output_info (monitor);
-
- return output_info->supports_underscanning;
-}
-
-gboolean
-meta_monitor_is_underscanning (MetaMonitor *monitor)
-{
- MetaOutput *output;
-
- output = meta_monitor_get_main_output (monitor);
-
- return meta_output_is_underscanning (output);
-}
-
-gboolean
-meta_monitor_is_laptop_panel (MetaMonitor *monitor)
-{
- const MetaOutputInfo *output_info =
- meta_monitor_get_main_output_info (monitor);
-
- switch (output_info->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)
-{
- const MetaOutputInfo *output_info =
- meta_monitor_get_main_output_info (monitor);
-
- *width_mm = output_info->width_mm;
- *height_mm = output_info->height_mm;
-}
-
-CoglSubpixelOrder
-meta_monitor_get_subpixel_order (MetaMonitor *monitor)
-{
- const MetaOutputInfo *output_info =
- meta_monitor_get_main_output_info (monitor);
-
- return output_info->subpixel_order;
-}
-
-const char *
-meta_monitor_get_connector (MetaMonitor *monitor)
-{
- const MetaOutputInfo *output_info =
- meta_monitor_get_main_output_info (monitor);
-
- return output_info->name;
-}
-
-const char *
-meta_monitor_get_vendor (MetaMonitor *monitor)
-{
- const MetaOutputInfo *output_info =
- meta_monitor_get_main_output_info (monitor);
-
- return output_info->vendor;
-}
-
-const char *
-meta_monitor_get_product (MetaMonitor *monitor)
-{
- const MetaOutputInfo *output_info =
- meta_monitor_get_main_output_info (monitor);
-
- return output_info->product;
-}
-
-const char *
-meta_monitor_get_serial (MetaMonitor *monitor)
-{
- const MetaOutputInfo *output_info =
- meta_monitor_get_main_output_info (monitor);
-
- return output_info->serial;
-}
-
-MetaConnectorType
-meta_monitor_get_connector_type (MetaMonitor *monitor)
-{
- const MetaOutputInfo *output_info =
- meta_monitor_get_main_output_info (monitor);
-
- return output_info->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_foreach (priv->outputs, (GFunc) meta_output_unset_monitor, NULL);
- 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)
-{
- const MetaOutputInfo *output_info =
- meta_monitor_get_main_output_info (monitor);
- const MetaCrtcModeInfo *crtc_mode_info =
- meta_crtc_mode_get_info (crtc_mode);
-
- if (meta_monitor_transform_is_rotated (output_info->panel_orientation_transform))
- {
- int temp = width;
- width = height;
- height = temp;
- }
-
- return (MetaMonitorModeSpec) {
- .width = width,
- .height = height,
- .refresh_rate = crtc_mode_info->refresh_rate,
- .flags = crtc_mode_info->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;
- const MetaOutputInfo *output_info;
- MetaCrtcMode *preferred_mode;
- MetaCrtcModeFlag preferred_mode_flags;
- unsigned int i;
-
- output = meta_monitor_get_main_output (monitor);
- output_info = meta_output_get_info (output);
- preferred_mode = output_info->preferred_mode;
- preferred_mode_flags = meta_crtc_mode_get_info (preferred_mode)->flags;
-
- for (i = 0; i < output_info->n_modes; i++)
- {
- MetaCrtcMode *crtc_mode = output_info->modes[i];
- const MetaCrtcModeInfo *crtc_mode_info =
- meta_crtc_mode_get_info (crtc_mode);
- MetaCrtc *crtc;
- MetaMonitorMode *mode;
- gboolean replace;
-
- mode = g_new0 (MetaMonitorMode, 1);
- mode->monitor = monitor;
- mode->spec = meta_monitor_create_spec (monitor,
- crtc_mode_info->width,
- crtc_mode_info->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_info->flags == preferred_mode_flags;
-
- if (!meta_monitor_add_mode (monitor, mode, replace))
- {
- g_assert (crtc_mode != output_info->preferred_mode);
- meta_monitor_mode_free (mode);
- continue;
- }
-
- if (crtc_mode == output_info->preferred_mode)
- monitor_priv->preferred_mode = mode;
-
- crtc = meta_output_get_assigned_crtc (output);
- if (crtc)
- {
- const MetaCrtcConfig *crtc_config;
-
- crtc_config = meta_crtc_get_config (crtc);
- if (crtc_config && crtc_mode == crtc_config->mode)
- monitor_priv->current_mode = mode;
- }
- }
-}
-
-MetaMonitorNormal *
-meta_monitor_normal_new (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->backend = meta_monitor_manager_get_backend (monitor_manager);
-
- monitor_priv->outputs = g_list_append (NULL, g_object_ref (output));
- meta_output_set_monitor (output, monitor);
-
- monitor_priv->winsys_id = meta_output_get_id (output);
- 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;
- const MetaCrtcConfig *crtc_config;
-
- output = meta_monitor_get_main_output (monitor);
- crtc = meta_output_get_assigned_crtc (output);
- crtc_config = meta_crtc_get_config (crtc);
-
- 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)
-{
- const MetaOutputInfo *output_info =
- meta_monitor_get_main_output_info (monitor);
-
- if (!output_info->hotplug_mode_update)
- return FALSE;
-
- if (output_info->suggested_x < 0 && output_info->suggested_y < 0)
- return FALSE;
-
- *x = output_info->suggested_x;
- *y = output_info->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;
- const MetaOutputInfo *output_info = meta_output_get_info (output);
- const MetaOutputInfo *origin_output_info;
-
- if (output_info->tile_info.group_id != monitor_tiled->tile_group_id)
- continue;
-
- origin_output_info = meta_output_get_info (monitor_tiled->origin_output);
- g_warn_if_fail (output_info->subpixel_order ==
- origin_output_info->subpixel_order);
-
- monitor_priv->outputs = g_list_append (monitor_priv->outputs,
- g_object_ref (output));
-
- meta_output_set_monitor (output, META_MONITOR (monitor_tiled));
- }
-}
-
-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);
- const MetaOutputInfo *output_info = meta_output_get_info (output);
- GList *l;
- int x = 0;
- int y = 0;
-
- for (l = monitor_priv->outputs; l; l = l->next)
- {
- const MetaOutputInfo *other_output_info = meta_output_get_info (l->data);
-
- switch (crtc_transform)
- {
- case META_MONITOR_TRANSFORM_NORMAL:
- case META_MONITOR_TRANSFORM_FLIPPED:
- if ((other_output_info->tile_info.loc_v_tile ==
- output_info->tile_info.loc_v_tile) &&
- (other_output_info->tile_info.loc_h_tile <
- output_info->tile_info.loc_h_tile))
- x += other_output_info->tile_info.tile_w;
- if ((other_output_info->tile_info.loc_h_tile ==
- output_info->tile_info.loc_h_tile) &&
- (other_output_info->tile_info.loc_v_tile <
- output_info->tile_info.loc_v_tile))
- y += other_output_info->tile_info.tile_h;
- break;
- case META_MONITOR_TRANSFORM_180:
- case META_MONITOR_TRANSFORM_FLIPPED_180:
- if ((other_output_info->tile_info.loc_v_tile ==
- output_info->tile_info.loc_v_tile) &&
- (other_output_info->tile_info.loc_h_tile >
- output_info->tile_info.loc_h_tile))
- x += other_output_info->tile_info.tile_w;
- if ((other_output_info->tile_info.loc_h_tile ==
- output_info->tile_info.loc_h_tile) &&
- (other_output_info->tile_info.loc_v_tile >
- output_info->tile_info.loc_v_tile))
- y += other_output_info->tile_info.tile_h;
- break;
- case META_MONITOR_TRANSFORM_270:
- case META_MONITOR_TRANSFORM_FLIPPED_270:
- if ((other_output_info->tile_info.loc_v_tile ==
- output_info->tile_info.loc_v_tile) &&
- (other_output_info->tile_info.loc_h_tile >
- output_info->tile_info.loc_h_tile))
- y += other_output_info->tile_info.tile_w;
- if ((other_output_info->tile_info.loc_h_tile ==
- output_info->tile_info.loc_h_tile) &&
- (other_output_info->tile_info.loc_v_tile >
- output_info->tile_info.loc_v_tile))
- x += other_output_info->tile_info.tile_h;
- break;
- case META_MONITOR_TRANSFORM_90:
- case META_MONITOR_TRANSFORM_FLIPPED_90:
- if ((other_output_info->tile_info.loc_v_tile ==
- output_info->tile_info.loc_v_tile) &&
- (other_output_info->tile_info.loc_h_tile <
- output_info->tile_info.loc_h_tile))
- y += other_output_info->tile_info.tile_w;
- if ((other_output_info->tile_info.loc_h_tile ==
- output_info->tile_info.loc_h_tile) &&
- (other_output_info->tile_info.loc_v_tile <
- output_info->tile_info.loc_v_tile))
- x += other_output_info->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)
- {
- const MetaOutputInfo *output_info = meta_output_get_info (l->data);
-
- if (output_info->tile_info.loc_v_tile == 0)
- width += output_info->tile_info.tile_w;
-
- if (output_info->tile_info.loc_h_tile == 0)
- height += output_info->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;
- const MetaCrtcConfig *crtc_config;
-
- crtc = meta_output_get_assigned_crtc (output);
- crtc_config = crtc ? meta_crtc_get_config (crtc) : NULL;
-
- 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)
-{
- const MetaOutputInfo *output_info = meta_output_get_info (output);
- const MetaCrtcModeInfo *crtc_mode_info = meta_crtc_mode_get_info (crtc_mode);
-
- return (crtc_mode_info->width == (int) output_info->tile_info.tile_w &&
- crtc_mode_info->height == (int) output_info->tile_info.tile_h);
-}
-
-static MetaCrtcMode *
-find_tiled_crtc_mode (MetaOutput *output,
- MetaCrtcMode *reference_crtc_mode)
-{
- const MetaOutputInfo *output_info = meta_output_get_info (output);
- const MetaCrtcModeInfo *reference_crtc_mode_info =
- meta_crtc_mode_get_info (reference_crtc_mode);
- MetaCrtcMode *crtc_mode;
- unsigned int i;
-
- crtc_mode = output_info->preferred_mode;
- if (is_crtc_mode_tiled (output, crtc_mode))
- return crtc_mode;
-
- for (i = 0; i < output_info->n_modes; i++)
- {
- const MetaCrtcModeInfo *crtc_mode_info;
-
- crtc_mode = output_info->modes[i];
- crtc_mode_info = meta_crtc_mode_get_info (crtc_mode);
-
- if (!is_crtc_mode_tiled (output, crtc_mode))
- continue;
-
- if (crtc_mode_info->refresh_rate != reference_crtc_mode_info->refresh_rate)
- continue;
-
- if (crtc_mode_info->flags != reference_crtc_mode_info->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;
- const MetaOutputInfo *output_info = meta_output_get_info (output);
- 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", meta_output_get_name (output));
- 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_info->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;
- const MetaOutputInfo *main_output_info;
- GList *tiled_modes = NULL;
- unsigned int i;
- MetaMonitorMode *best_mode = NULL;
- GList *l;
-
- main_output = meta_monitor_get_main_output (META_MONITOR (monitor_tiled));
- main_output_info = meta_output_get_info (main_output);
-
- for (i = 0; i < main_output_info->n_modes; i++)
- {
- MetaCrtcMode *reference_crtc_mode = main_output_info->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;
- const MetaCrtcModeInfo *crtc_mode_info;
- 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;
-
- crtc_mode_info = meta_crtc_mode_get_info (crtc_mode);
- mode->parent.spec = meta_monitor_create_spec (monitor,
- crtc_mode_info->width,
- crtc_mode_info->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)
-{
- const MetaOutputInfo *output_info = meta_output_get_info (output);
- int count;
- unsigned int i;
-
- count = 0;
- for (i = 0; i < output_info->n_modes; i++)
- {
- MetaCrtcMode *crtc_mode = output_info->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;
- const MetaOutputInfo *main_output_info;
- unsigned int i;
-
- main_output = meta_monitor_get_main_output (monitor);
- main_output_info = meta_output_get_info (main_output);
-
- for (i = 0; i < main_output_info->n_modes; i++)
- {
- MetaCrtcMode *crtc_mode = main_output_info->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_info->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 (MetaMonitorManager *monitor_manager,
- MetaOutput *output)
-{
- const MetaOutputInfo *output_info = meta_output_get_info (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->backend = meta_monitor_manager_get_backend (monitor_manager);
-
- monitor_tiled->tile_group_id = output_info->tile_info.group_id;
- monitor_priv->winsys_id = meta_output_get_id (output);
-
- monitor_tiled->origin_output = output;
- add_tiled_monitor_outputs (meta_output_get_gpu (output), 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;
- const MetaCrtcConfig *crtc_config;
- const graphene_rect_t *crtc_layout;
-
- crtc = meta_output_get_assigned_crtc (output);
- if (!crtc)
- continue;
-
- crtc_config = meta_crtc_get_config (crtc);
- 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 && meta_crtc_get_config (crtc)));
-}
-
-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)
-{
- 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)
-{
- 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);
-}
-
-static gboolean
-is_logical_size_large_enough (int width,
- int height)
-{
- return width * height >= MINIMUM_LOGICAL_AREA;
-}
-
-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;
- scaled_w = width / scale;
- scaled_h = height / scale;
-
- if (scale < MINIMUM_SCALE_FACTOR ||
- scale > MAXIMUM_SCALE_FACTOR ||
- !is_logical_size_large_enough (floorf (scaled_w), floorf (scaled_h)))
- goto out;
-
- if (floorf (scaled_w) == scaled_w && floorf (scaled_h) == scaled_h)
- return scale;
-
- i = 0;
- found_one = FALSE;
- base_scaled_w = floorf (scaled_w);
-
- 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) &&
- fmodf (scale_value, 1.0) != 0.0)
- {
- continue;
- }
-
- 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;
-}
-
-MetaMonitorCrtcMode *
-meta_monitor_get_crtc_mode_for_output (MetaMonitor *monitor,
- MetaMonitorMode *mode,
- MetaOutput *output)
-{
- 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->output == output)
- return monitor_crtc_mode;
- }
-
- g_warn_if_reached ();
- return NULL;
-}
-
-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
deleted file mode 100644
index 341657ae3..000000000
--- a/src/backends/meta-monitor.h
+++ /dev/null
@@ -1,280 +0,0 @@
-/* -*- 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),
-} MetaMonitorScalesConstraint;
-
-#define META_TYPE_MONITOR (meta_monitor_get_type ())
-META_EXPORT_TEST
-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)
-
-MetaMonitorTiled * meta_monitor_tiled_new (MetaMonitorManager *monitor_manager,
- MetaOutput *output);
-
-MetaMonitorNormal * meta_monitor_normal_new (MetaMonitorManager *monitor_manager,
- MetaOutput *output);
-
-MetaMonitorSpec * meta_monitor_get_spec (MetaMonitor *monitor);
-
-MetaBackend * meta_monitor_get_backend (MetaMonitor *monitor);
-
-META_EXPORT_TEST
-gboolean meta_monitor_is_active (MetaMonitor *monitor);
-
-META_EXPORT_TEST
-MetaOutput * meta_monitor_get_main_output (MetaMonitor *monitor);
-
-gboolean meta_monitor_is_primary (MetaMonitor *monitor);
-
-gboolean meta_monitor_supports_underscanning (MetaMonitor *monitor);
-
-gboolean meta_monitor_is_underscanning (MetaMonitor *monitor);
-
-gboolean meta_monitor_is_laptop_panel (MetaMonitor *monitor);
-
-gboolean meta_monitor_is_same_as (MetaMonitor *monitor,
- MetaMonitor *other_monitor);
-
-META_EXPORT_TEST
-GList * meta_monitor_get_outputs (MetaMonitor *monitor);
-
-void meta_monitor_get_current_resolution (MetaMonitor *monitor,
- int *width,
- int *height);
-
-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);
-
-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);
-
-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);
-
-MetaMonitorCrtcMode * meta_monitor_get_crtc_mode_for_output (MetaMonitor *monitor,
- MetaMonitorMode *mode,
- MetaOutput *output);
-
-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
deleted file mode 100644
index 52a1d1de6..000000000
--- a/src/backends/meta-orientation-manager.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/* -*- 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];
-
-enum
-{
- PROP_0,
-
- PROP_HAS_ACCELEROMETER,
-
- PROP_LAST
-};
-
-static GParamSpec *props[PROP_LAST];
-
-struct _MetaOrientationManager
-{
- GObject parent_instance;
-
- GCancellable *cancellable;
-
- guint iio_watch_id;
- GDBusProxy *iio_proxy;
- MetaOrientation prev_orientation;
- MetaOrientation curr_orientation;
- guint has_accel : 1;
-
- GSettings *settings;
-};
-
-G_DEFINE_TYPE (MetaOrientationManager, meta_orientation_manager, G_TYPE_OBJECT)
-
-#define CONF_SCHEMA "org.gnome.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)
-{
- GVariant *v;
-
- self->curr_orientation = META_ORIENTATION_UNDEFINED;
-
- if (!self->iio_proxy)
- {
- self->has_accel = FALSE;
- return;
- }
-
- v = g_dbus_proxy_get_cached_property (self->iio_proxy, "HasAccelerometer");
- if (v)
- {
- self->has_accel = !!g_variant_get_boolean (v);
- g_variant_unref (v);
- }
-
- if (self->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)
-{
- gboolean had_accel = self->has_accel;
-
- read_iio_proxy (self);
-
- if (had_accel != self->has_accel)
- g_object_notify_by_pspec (G_OBJECT (self), props[PROP_HAS_ACCELEROMETER]);
-
- if (g_settings_get_boolean (self->settings, ORIENTATION_LOCK_KEY))
- return;
-
- 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_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaOrientationManager *self = META_ORIENTATION_MANAGER (object);
-
- switch (prop_id)
- {
- case PROP_HAS_ACCELEROMETER:
- g_value_set_boolean (value, self->has_accel);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-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;
- gobject_class->get_property = meta_orientation_manager_get_property;
-
- 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);
-
- props[PROP_HAS_ACCELEROMETER] =
- g_param_spec_boolean ("has-accelerometer",
- "Has accelerometer",
- "Has accelerometer",
- FALSE,
- G_PARAM_READABLE |
- G_PARAM_EXPLICIT_NOTIFY |
- G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (gobject_class, PROP_LAST, props);
-}
-
-MetaOrientation
-meta_orientation_manager_get_orientation (MetaOrientationManager *self)
-{
- return self->curr_orientation;
-}
-
-gboolean
-meta_orientation_manager_has_accelerometer (MetaOrientationManager *self)
-{
- return self->has_accel;
-}
diff --git a/src/backends/meta-orientation-manager.h b/src/backends/meta-orientation-manager.h
deleted file mode 100644
index 9ae87957d..000000000
--- a/src/backends/meta-orientation-manager.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- 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);
-
-gboolean meta_orientation_manager_has_accelerometer (MetaOrientationManager *self);
-
-#endif /* META_ORIENTATION_MANAGER_H */
diff --git a/src/backends/meta-output.c b/src/backends/meta-output.c
deleted file mode 100644
index 432697d6d..000000000
--- a/src/backends/meta-output.c
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * 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/edid.h"
-#include "backends/meta-output.h"
-
-#include "backends/meta-crtc.h"
-
-enum
-{
- PROP_0,
-
- PROP_ID,
- PROP_GPU,
- PROP_INFO,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS];
-
-typedef struct _MetaOutputPrivate
-{
- uint64_t id;
-
- MetaGpu *gpu;
-
- MetaOutputInfo *info;
-
- MetaMonitor *monitor;
-
- /* The CRTC driving this output, NULL if the output is not enabled */
- MetaCrtc *crtc;
-
- gboolean is_primary;
- gboolean is_presentation;
-
- gboolean is_underscanning;
-
- int backlight;
-} MetaOutputPrivate;
-
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaOutput, meta_output, G_TYPE_OBJECT)
-
-G_DEFINE_BOXED_TYPE (MetaOutputInfo, meta_output_info,
- meta_output_info_ref,
- meta_output_info_unref)
-
-MetaOutputInfo *
-meta_output_info_new (void)
-{
- MetaOutputInfo *output_info;
-
- output_info = g_new0 (MetaOutputInfo, 1);
- g_ref_count_init (&output_info->ref_count);
-
- return output_info;
-}
-
-MetaOutputInfo *
-meta_output_info_ref (MetaOutputInfo *output_info)
-{
- g_ref_count_inc (&output_info->ref_count);
- return output_info;
-}
-
-void
-meta_output_info_unref (MetaOutputInfo *output_info)
-{
- if (g_ref_count_dec (&output_info->ref_count))
- {
- g_free (output_info->name);
- g_free (output_info->vendor);
- g_free (output_info->product);
- g_free (output_info->serial);
- g_free (output_info->modes);
- g_free (output_info->possible_crtcs);
- g_free (output_info->possible_clones);
- g_free (output_info);
- }
-}
-
-uint64_t
-meta_output_get_id (MetaOutput *output)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- return priv->id;
-}
-
-MetaGpu *
-meta_output_get_gpu (MetaOutput *output)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- return priv->gpu;
-}
-
-MetaMonitor *
-meta_output_get_monitor (MetaOutput *output)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- g_warn_if_fail (priv->monitor);
-
- return priv->monitor;
-}
-
-void
-meta_output_set_monitor (MetaOutput *output,
- MetaMonitor *monitor)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- g_warn_if_fail (!priv->monitor);
-
- priv->monitor = monitor;
-}
-
-void
-meta_output_unset_monitor (MetaOutput *output)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- g_warn_if_fail (priv->monitor);
-
- priv->monitor = NULL;
-}
-
-const char *
-meta_output_get_name (MetaOutput *output)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- return priv->info->name;
-}
-
-gboolean
-meta_output_is_primary (MetaOutput *output)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- return priv->is_primary;
-}
-
-gboolean
-meta_output_is_presentation (MetaOutput *output)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- return priv->is_presentation;
-}
-
-gboolean
-meta_output_is_underscanning (MetaOutput *output)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- return priv->is_underscanning;
-}
-
-void
-meta_output_set_backlight (MetaOutput *output,
- int backlight)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- priv->backlight = backlight;
-}
-
-int
-meta_output_get_backlight (MetaOutput *output)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- return priv->backlight;
-}
-
-void
-meta_output_add_possible_clone (MetaOutput *output,
- MetaOutput *possible_clone)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
- MetaOutputInfo *output_info = priv->info;
-
- output_info->n_possible_clones++;
- output_info->possible_clones = g_renew (MetaOutput *,
- output_info->possible_clones,
- output_info->n_possible_clones);
- output_info->possible_clones[output_info->n_possible_clones - 1] =
- possible_clone;
-}
-
-const MetaOutputInfo *
-meta_output_get_info (MetaOutput *output)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- return priv->info;
-}
-
-void
-meta_output_assign_crtc (MetaOutput *output,
- MetaCrtc *crtc,
- const MetaOutputAssignment *output_assignment)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- g_assert (crtc);
-
- meta_output_unassign_crtc (output);
-
- g_set_object (&priv->crtc, crtc);
-
- meta_crtc_assign_output (crtc, output);
-
- priv->is_primary = output_assignment->is_primary;
- priv->is_presentation = output_assignment->is_presentation;
- priv->is_underscanning = output_assignment->is_underscanning;
-}
-
-void
-meta_output_unassign_crtc (MetaOutput *output)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- if (priv->crtc)
- {
- meta_crtc_unassign_output (priv->crtc, output);
- g_clear_object (&priv->crtc);
- }
-
- priv->is_primary = FALSE;
- priv->is_presentation = FALSE;
-}
-
-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)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
- MetaMonitorTransform panel_orientation_transform;
-
- panel_orientation_transform = priv->info->panel_orientation_transform;
- return meta_monitor_transform_transform (transform,
- panel_orientation_transform);
-}
-
-MetaMonitorTransform
-meta_output_crtc_to_logical_transform (MetaOutput *output,
- MetaMonitorTransform transform)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
- MetaMonitorTransform inverted_panel_orientation_transform;
-
- inverted_panel_orientation_transform =
- meta_monitor_transform_invert (priv->info->panel_orientation_transform);
- return meta_monitor_transform_transform (transform,
- inverted_panel_orientation_transform);
-}
-
-void
-meta_output_info_parse_edid (MetaOutputInfo *output_info,
- GBytes *edid)
-{
- MonitorInfo *parsed_edid;
- size_t len;
-
- if (!edid)
- goto out;
-
- parsed_edid = decode_edid (g_bytes_get_data (edid, &len));
-
- if (parsed_edid)
- {
- output_info->vendor = g_strndup (parsed_edid->manufacturer_code, 4);
- if (!g_utf8_validate (output_info->vendor, -1, NULL))
- g_clear_pointer (&output_info->vendor, g_free);
-
- output_info->product = g_strndup (parsed_edid->dsc_product_name, 14);
- if (!g_utf8_validate (output_info->product, -1, NULL) ||
- output_info->product[0] == '\0')
- {
- g_clear_pointer (&output_info->product, g_free);
- output_info->product = g_strdup_printf ("0x%04x", (unsigned) parsed_edid->product_code);
- }
-
- output_info->serial = g_strndup (parsed_edid->dsc_serial_number, 14);
- if (!g_utf8_validate (output_info->serial, -1, NULL) ||
- output_info->serial[0] == '\0')
- {
- g_clear_pointer (&output_info->serial, g_free);
- output_info->serial = g_strdup_printf ("0x%08x", parsed_edid->serial_number);
- }
-
- g_free (parsed_edid);
- }
-
- out:
- if (!output_info->vendor)
- output_info->vendor = g_strdup ("unknown");
- if (!output_info->product)
- output_info->product = g_strdup ("unknown");
- if (!output_info->serial)
- output_info->serial = g_strdup ("unknown");
-}
-
-gboolean
-meta_output_is_laptop (MetaOutput *output)
-{
- const MetaOutputInfo *output_info = meta_output_get_info (output);
-
- switch (output_info->connector_type)
- {
- case META_CONNECTOR_TYPE_eDP:
- case META_CONNECTOR_TYPE_LVDS:
- case META_CONNECTOR_TYPE_DSI:
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-static void
-meta_output_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaOutput *output = META_OUTPUT (object);
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- switch (prop_id)
- {
- case PROP_ID:
- priv->id = g_value_get_uint64 (value);
- break;
- case PROP_GPU:
- priv->gpu = g_value_get_object (value);
- break;
- case PROP_INFO:
- priv->info = meta_output_info_ref (g_value_get_boxed (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-meta_output_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaOutput *output = META_OUTPUT (object);
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- switch (prop_id)
- {
- case PROP_ID:
- g_value_set_uint64 (value, priv->id);
- break;
- case PROP_GPU:
- g_value_set_object (value, priv->gpu);
- break;
- case PROP_INFO:
- g_value_set_boxed (value, priv->info);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-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);
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- g_clear_pointer (&priv->info, meta_output_info_unref);
-
- G_OBJECT_CLASS (meta_output_parent_class)->finalize (object);
-}
-
-static void
-meta_output_init (MetaOutput *output)
-{
- MetaOutputPrivate *priv = meta_output_get_instance_private (output);
-
- priv->backlight = -1;
-}
-
-static void
-meta_output_class_init (MetaOutputClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->set_property = meta_output_set_property;
- object_class->get_property = meta_output_get_property;
- object_class->dispose = meta_output_dispose;
- object_class->finalize = meta_output_finalize;
-
- obj_props[PROP_ID] =
- g_param_spec_uint64 ("id",
- "id",
- "CRTC id",
- 0, UINT64_MAX, 0,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- obj_props[PROP_GPU] =
- g_param_spec_object ("gpu",
- "gpu",
- "MetaGpu",
- META_TYPE_GPU,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- obj_props[PROP_INFO] =
- g_param_spec_boxed ("info",
- "info",
- "MetaOutputInfo",
- META_TYPE_OUTPUT_INFO,
- 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-output.h b/src/backends/meta-output.h
deleted file mode 100644
index b96c118d8..000000000
--- a/src/backends/meta-output.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2017 Red Hat
- * Copyright (C) 2020 NVIDIA 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_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
-{
- uint32_t group_id;
- uint32_t flags;
- uint32_t max_h_tiles;
- uint32_t max_v_tiles;
- uint32_t loc_h_tile;
- uint32_t loc_v_tile;
- uint32_t tile_w;
- uint32_t tile_h;
-};
-
-/* The first 17 matches the values in drm_mode.h, the ones starting with
- * 1000 do not. */
-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,
-
- META_CONNECTOR_TYPE_META = 1000,
-} MetaConnectorType;
-
-typedef struct _MetaOutputInfo
-{
- grefcount ref_count;
-
- 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_min;
- int backlight_max;
-
- gboolean supports_underscanning;
- gboolean supports_color_transform;
-
- /*
- * Get a new preferred mode on hotplug events, to handle dynamic guest
- * resizing.
- */
- gboolean hotplug_mode_update;
- int suggested_x;
- int suggested_y;
-
- MetaTileInfo tile_info;
-} MetaOutputInfo;
-
-#define META_TYPE_OUTPUT_INFO (meta_output_info_get_type ())
-META_EXPORT_TEST
-GType meta_output_info_get_type (void);
-
-META_EXPORT_TEST
-MetaOutputInfo * meta_output_info_new (void);
-
-META_EXPORT_TEST
-MetaOutputInfo * meta_output_info_ref (MetaOutputInfo *output_info);
-
-META_EXPORT_TEST
-void meta_output_info_unref (MetaOutputInfo *output_info);
-
-META_EXPORT_TEST
-void meta_output_info_parse_edid (MetaOutputInfo *output_info,
- GBytes *edid);
-
-gboolean meta_output_is_laptop (MetaOutput *output);
-
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaOutputInfo, meta_output_info_unref)
-
-#define META_TYPE_OUTPUT (meta_output_get_type ())
-META_EXPORT_TEST
-G_DECLARE_DERIVABLE_TYPE (MetaOutput, meta_output, META, OUTPUT, GObject)
-
-struct _MetaOutputClass
-{
- GObjectClass parent_class;
-};
-
-META_EXPORT_TEST
-uint64_t meta_output_get_id (MetaOutput *output);
-
-META_EXPORT_TEST
-MetaGpu * meta_output_get_gpu (MetaOutput *output);
-
-META_EXPORT_TEST
-MetaMonitor * meta_output_get_monitor (MetaOutput *output);
-
-void meta_output_set_monitor (MetaOutput *output,
- MetaMonitor *monitor);
-
-void meta_output_unset_monitor (MetaOutput *output);
-
-const char * meta_output_get_name (MetaOutput *output);
-
-META_EXPORT_TEST
-gboolean meta_output_is_primary (MetaOutput *output);
-
-META_EXPORT_TEST
-gboolean meta_output_is_presentation (MetaOutput *output);
-
-META_EXPORT_TEST
-gboolean meta_output_is_underscanning (MetaOutput *output);
-
-void meta_output_set_backlight (MetaOutput *output,
- int backlight);
-
-int meta_output_get_backlight (MetaOutput *output);
-
-void meta_output_add_possible_clone (MetaOutput *output,
- MetaOutput *possible_clone);
-
-META_EXPORT_TEST
-const MetaOutputInfo * meta_output_get_info (MetaOutput *output);
-
-META_EXPORT_TEST
-void meta_output_assign_crtc (MetaOutput *output,
- MetaCrtc *crtc,
- const MetaOutputAssignment *output_assignment);
-
-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
deleted file mode 100644
index 7682b14b0..000000000
--- a/src/backends/meta-pointer-constraint.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/* -*- 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"
-
-#ifdef HAVE_NATIVE_BACKEND
-#include "backends/native/meta-backend-native.h"
-#include "backends/native/meta-pointer-constraint-native.h"
-#endif
-
-#include <glib-object.h>
-
-struct _MetaPointerConstraint
-{
- GObject parent_instance;
- cairo_region_t *region;
-};
-
-G_DEFINE_TYPE (MetaPointerConstraint, meta_pointer_constraint, G_TYPE_OBJECT);
-
-G_DEFINE_TYPE (MetaPointerConstraintImpl, meta_pointer_constraint_impl,
- G_TYPE_OBJECT);
-
-static void
-meta_pointer_constraint_finalize (GObject *object)
-{
- MetaPointerConstraint *constraint = META_POINTER_CONSTRAINT (object);
-
- g_clear_pointer (&constraint->region, cairo_region_destroy);
-
- G_OBJECT_CLASS (meta_pointer_constraint_parent_class)->finalize (object);
-}
-
-static void
-meta_pointer_constraint_init (MetaPointerConstraint *constraint)
-{
-}
-
-static void
-meta_pointer_constraint_class_init (MetaPointerConstraintClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = meta_pointer_constraint_finalize;
-}
-
-
-MetaPointerConstraint *
-meta_pointer_constraint_new (const cairo_region_t *region)
-{
- MetaPointerConstraint *constraint;
-
- constraint = g_object_new (META_TYPE_POINTER_CONSTRAINT, NULL);
- constraint->region = cairo_region_copy (region);
-
- return constraint;
-}
-
-cairo_region_t *
-meta_pointer_constraint_get_region (MetaPointerConstraint *constraint)
-{
- return constraint->region;
-}
-
-static void
-meta_pointer_constraint_impl_init (MetaPointerConstraintImpl *constraint_impl)
-{
-}
-
-static void
-meta_pointer_constraint_impl_class_init (MetaPointerConstraintImplClass *klass)
-{
-}
-
-/**
- * meta_pointer_constraint_impl_constrain:
- * @constraint_impl: a #MetaPointerConstraintImpl.
- * @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_impl_constrain (MetaPointerConstraintImpl *constraint_impl,
- ClutterInputDevice *device,
- uint32_t time,
- float prev_x,
- float prev_y,
- float *x,
- float *y)
-{
- META_POINTER_CONSTRAINT_IMPL_GET_CLASS (constraint_impl)->constrain (constraint_impl,
- device,
- time,
- prev_x, prev_y,
- x, y);
-}
-
-void
-meta_pointer_constraint_impl_ensure_constrained (MetaPointerConstraintImpl *constraint_impl,
- ClutterInputDevice *device)
-{
- META_POINTER_CONSTRAINT_IMPL_GET_CLASS (constraint_impl)->ensure_constrained (constraint_impl,
- device);
-}
diff --git a/src/backends/meta-pointer-constraint.h b/src/backends/meta-pointer-constraint.h
deleted file mode 100644
index b47eda490..000000000
--- a/src/backends/meta-pointer-constraint.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- 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_FINAL_TYPE (MetaPointerConstraint, meta_pointer_constraint,
- META, POINTER_CONSTRAINT, GObject);
-
-MetaPointerConstraint * meta_pointer_constraint_new (const cairo_region_t *region);
-cairo_region_t * meta_pointer_constraint_get_region (MetaPointerConstraint *constraint);
-
-#define META_TYPE_POINTER_CONSTRAINT_IMPL (meta_pointer_constraint_impl_get_type ())
-G_DECLARE_DERIVABLE_TYPE (MetaPointerConstraintImpl, meta_pointer_constraint_impl,
- META, POINTER_CONSTRAINT_IMPL, GObject);
-
-/**
- * MetaPointerConstraintImplClass:
- * @constrain: the virtual function pointer for
- * meta_pointer_constraint_impl_constrain().
- */
-struct _MetaPointerConstraintImplClass
-{
- GObjectClass parent_class;
-
- void (* constrain) (MetaPointerConstraintImpl *constraint_impl,
- ClutterInputDevice *device,
- uint32_t time,
- float prev_x,
- float prev_y,
- float *x,
- float *y);
- void (* ensure_constrained) (MetaPointerConstraintImpl *constraint_impl,
- ClutterInputDevice *device);
-};
-
-void meta_pointer_constraint_impl_constrain (MetaPointerConstraintImpl *constraint_impl,
- ClutterInputDevice *device,
- uint32_t time,
- float prev_x,
- float prev_y,
- float *x,
- float *y);
-void meta_pointer_constraint_impl_ensure_constrained (MetaPointerConstraintImpl *constraint_impl,
- ClutterInputDevice *device);
-
-G_END_DECLS
-
-#endif /* META_POINTER_CONSTRAINT_H */
diff --git a/src/backends/meta-profiler.c b/src/backends/meta-profiler.c
deleted file mode 100644
index 7a18b85ce..000000000
--- a/src/backends/meta-profiler.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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", 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", 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
deleted file mode 100644
index aa0d72640..000000000
--- a/src/backends/meta-profiler.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 8c8a319c4..000000000
--- a/src/backends/meta-remote-access-controller-private.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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 "backends/meta-backend-types.h"
-#include "meta/meta-remote-access-controller.h"
-
-MetaRemoteAccessController * meta_remote_access_controller_new (MetaRemoteDesktop *remote_desktop,
- MetaScreenCast *screen_cast);
-
-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
deleted file mode 100644
index b2ac93d88..000000000
--- a/src/backends/meta-remote-access-controller.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * 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"
-
-#ifdef HAVE_REMOTE_DESKTOP
-#include "backends/meta-remote-desktop.h"
-#include "backends/meta-screen-cast.h"
-#endif
-
-enum
-{
- HANDLE_STOPPED,
-
- N_HANDLE_SIGNALS
-};
-
-static int handle_signals[N_HANDLE_SIGNALS];
-
-enum
-{
- PROP_0,
-
- PROP_IS_RECORDING,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS];
-
-enum
-{
- CONTROLLER_NEW_HANDLE,
-
- N_CONTROLLER_SIGNALS
-};
-
-static int controller_signals[N_CONTROLLER_SIGNALS];
-
-typedef struct _MetaRemoteAccessHandlePrivate
-{
- gboolean has_stopped;
-
- gboolean disable_animations;
-
- gboolean is_recording;
-} MetaRemoteAccessHandlePrivate;
-
-G_DEFINE_TYPE_WITH_PRIVATE (MetaRemoteAccessHandle,
- meta_remote_access_handle,
- G_TYPE_OBJECT)
-
-struct _MetaRemoteAccessController
-{
- GObject parent;
-
- MetaRemoteDesktop *remote_desktop;
- MetaScreenCast *screen_cast;
-};
-
-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);
-}
-
-/**
- * meta_remote_access_controller_inhibit_remote_access:
- * @controller: a #MetaRemoteAccessController
- *
- * Inhibits remote access sessions from being created and running. Any active
- * remote access session will be terminated.
- */
-void
-meta_remote_access_controller_inhibit_remote_access (MetaRemoteAccessController *controller)
-{
-#ifdef HAVE_REMOTE_DESKTOP
- meta_remote_desktop_inhibit (controller->remote_desktop);
- meta_screen_cast_inhibit (controller->screen_cast);
-#endif
-}
-
-/**
- * meta_remote_access_controller_uninhibit_remote_access:
- * @controller: a #MetaRemoteAccessController
- *
- * Uninhibits remote access sessions from being created and running. If this was
- * the last inhibitation that was inhibited, new remote access sessions can now
- * be created.
- */
-void
-meta_remote_access_controller_uninhibit_remote_access (MetaRemoteAccessController *controller)
-{
-#ifdef HAVE_REMOTE_DESKTOP
- meta_screen_cast_uninhibit (controller->screen_cast);
- meta_remote_desktop_uninhibit (controller->remote_desktop);
-#endif
-}
-
-MetaRemoteAccessController *
-meta_remote_access_controller_new (MetaRemoteDesktop *remote_desktop,
- MetaScreenCast *screen_cast)
-{
- MetaRemoteAccessController *remote_access_controller;
-
- remote_access_controller = g_object_new (META_TYPE_REMOTE_ACCESS_CONTROLLER,
- NULL);
- remote_access_controller->remote_desktop = remote_desktop;
- remote_access_controller->screen_cast = screen_cast;
-
- return remote_access_controller;
-}
-
-static void
-meta_remote_access_handle_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaRemoteAccessHandle *handle = META_REMOTE_ACCESS_HANDLE (object);
- MetaRemoteAccessHandlePrivate *priv =
- meta_remote_access_handle_get_instance_private (handle);
-
- switch (prop_id)
- {
- case PROP_IS_RECORDING:
- g_value_set_boolean (value, priv->is_recording);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_remote_access_handle_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaRemoteAccessHandle *handle = META_REMOTE_ACCESS_HANDLE (object);
- MetaRemoteAccessHandlePrivate *priv =
- meta_remote_access_handle_get_instance_private (handle);
-
- switch (prop_id)
- {
- case PROP_IS_RECORDING:
- priv->is_recording = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_remote_access_handle_init (MetaRemoteAccessHandle *handle)
-{
-}
-
-static void
-meta_remote_access_handle_class_init (MetaRemoteAccessHandleClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->get_property = meta_remote_access_handle_get_property;
- object_class->set_property = meta_remote_access_handle_set_property;
-
- 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);
-
- obj_props[PROP_IS_RECORDING] =
- g_param_spec_boolean ("is-recording",
- "is-recording",
- "Is a screen recording",
- FALSE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, N_PROPS, obj_props);
-}
-
-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
deleted file mode 100644
index e15bd63de..000000000
--- a/src/backends/meta-remote-desktop-session.c
+++ /dev/null
@@ -1,1725 +0,0 @@
-/* -*- 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 <fcntl.h>
-#include <gio/gunixfdlist.h>
-#include <gio/gunixoutputstream.h>
-#include <glib-unix.h>
-#include <linux/input.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <xkbcommon/xkbcommon.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 "core/display-private.h"
-#include "core/meta-selection-private.h"
-#include "core/meta-selection-source-remote.h"
-#include "meta/meta-backend.h"
-
-#include "meta-dbus-remote-desktop.h"
-
-#define META_REMOTE_DESKTOP_SESSION_DBUS_PATH "/org/gnome/Mutter/RemoteDesktop/Session"
-
-#define TRANSFER_REQUEST_CLEANUP_TIMEOUT_MS (s2ms (15))
-
-typedef enum _MetaRemoteDesktopNotifyAxisFlags
-{
- META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_NONE = 0,
- META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_FINISH = 1 << 0,
- META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_WHEEL = 1 << 1,
- META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_FINGER = 1 << 2,
- META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_CONTINUOUS = 1 << 3,
-} MetaRemoteDesktopNotifyAxisFlags;
-
-typedef struct _SelectionReadData
-{
- MetaRemoteDesktopSession *session;
- GOutputStream *stream;
- GCancellable *cancellable;
-} SelectionReadData;
-
-struct _MetaRemoteDesktopSession
-{
- MetaDBusRemoteDesktopSessionSkeleton parent;
-
- MetaRemoteDesktop *remote_desktop;
-
- GDBusConnection *connection;
- 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;
-
- gboolean is_clipboard_enabled;
- gulong owner_changed_handler_id;
- SelectionReadData *read_data;
- unsigned int transfer_serial;
- MetaSelectionSourceRemote *current_source;
- GHashTable *transfer_requests;
- guint transfer_request_timeout_id;
-};
-
-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->started;
-}
-
-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 void
-ensure_virtual_device (MetaRemoteDesktopSession *session,
- ClutterInputDeviceType device_type)
-{
- MetaRemoteDesktop *remote_desktop = session->remote_desktop;
- MetaBackend *backend = meta_remote_desktop_get_backend (remote_desktop);
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
- ClutterVirtualInputDevice **virtual_device_ptr = NULL;
-
- switch (device_type)
- {
- case CLUTTER_POINTER_DEVICE:
- virtual_device_ptr = &session->virtual_pointer;
- break;
- case CLUTTER_KEYBOARD_DEVICE:
- virtual_device_ptr = &session->virtual_keyboard;
- break;
- case CLUTTER_TOUCHSCREEN_DEVICE:
- virtual_device_ptr = &session->virtual_touchscreen;
- break;
- default:
- g_assert_not_reached ();
- }
-
- g_assert (virtual_device_ptr);
-
- if (*virtual_device_ptr)
- return;
-
- *virtual_device_ptr = clutter_seat_create_virtual_device (seat, device_type);
-}
-
-static gboolean
-meta_remote_desktop_session_start (MetaRemoteDesktopSession *session,
- GError **error)
-{
- g_assert (!session->started);
-
- if (session->screen_cast_session)
- {
- if (!meta_screen_cast_session_start (session->screen_cast_session, error))
- return FALSE;
- }
-
- 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)
-{
- MetaBackend *backend = meta_remote_desktop_get_backend (remote_desktop);
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
- ClutterKeymap *keymap = clutter_seat_get_keymap (seat);
- GDBusInterfaceSkeleton *interface_skeleton;
- MetaRemoteDesktopSession *session;
-
- session = g_object_new (META_TYPE_REMOTE_DESKTOP_SESSION, NULL);
-
- session->remote_desktop = remote_desktop;
- session->peer_name = g_strdup (peer_name);
-
- interface_skeleton = G_DBUS_INTERFACE_SKELETON (session);
- session->connection = meta_remote_desktop_get_connection (remote_desktop);
- if (!g_dbus_interface_skeleton_export (interface_skeleton,
- session->connection,
- session->object_path,
- error))
- {
- g_object_unref (session);
- return NULL;
- }
-
- g_object_bind_property (keymap, "caps-lock-state",
- session, "caps-lock-state",
- G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
- g_object_bind_property (keymap, "num-lock-state",
- session, "num-lock-state",
- G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
-
- 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)
- {
- ensure_virtual_device (session, CLUTTER_KEYBOARD_DEVICE);
- state = CLUTTER_KEY_STATE_PRESSED;
- }
- else
- {
- if (!session->virtual_keyboard)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Invalid key event");
- return TRUE;
- }
-
- 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)
- {
- ensure_virtual_device (session, CLUTTER_KEYBOARD_DEVICE);
- state = CLUTTER_KEY_STATE_PRESSED;
- }
- else
- {
- if (!session->virtual_keyboard)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Invalid key event");
- return TRUE;
- }
-
- 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)
- {
- ensure_virtual_device (session, CLUTTER_POINTER_DEVICE);
- state = CLUTTER_BUTTON_STATE_PRESSED;
- }
- else
- {
- if (!session->virtual_pointer)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Invalid button event");
- return TRUE;
- }
-
- 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
-clutter_scroll_source_from_axis_flags (MetaRemoteDesktopNotifyAxisFlags axis_flags,
- ClutterScrollSource *scroll_source)
-{
- MetaRemoteDesktopNotifyAxisFlags scroll_mask;
-
- scroll_mask = META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_WHEEL |
- META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_FINGER |
- META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_CONTINUOUS;
-
- switch (axis_flags & scroll_mask)
- {
- case META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_WHEEL:
- *scroll_source = CLUTTER_SCROLL_SOURCE_WHEEL;
- return TRUE;
- case META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_NONE:
- case META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_FINGER:
- *scroll_source = CLUTTER_SCROLL_SOURCE_FINGER;
- return TRUE;
- case META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_SOURCE_CONTINUOUS:
- *scroll_source = CLUTTER_SCROLL_SOURCE_CONTINUOUS;
- return TRUE;
- }
-
- return FALSE;
-}
-
-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;
- ClutterScrollSource scroll_source;
-
- if (!meta_remote_desktop_session_check_can_notify (session, invocation))
- return TRUE;
-
- if (!clutter_scroll_source_from_axis_flags (flags, &scroll_source))
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Invalid scroll source");
- return TRUE;
- }
-
- if (flags & META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_FINISH)
- {
- finish_flags |= (CLUTTER_SCROLL_FINISHED_HORIZONTAL |
- CLUTTER_SCROLL_FINISHED_VERTICAL);
- }
-
- ensure_virtual_device (session, CLUTTER_POINTER_DEVICE);
-
- clutter_virtual_input_device_notify_scroll_continuous (session->virtual_pointer,
- CLUTTER_CURRENT_TIME,
- dx, dy,
- scroll_source,
- 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;
- }
-
- ensure_virtual_device (session, CLUTTER_POINTER_DEVICE);
-
- /*
- * 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;
-
- ensure_virtual_device (session, CLUTTER_POINTER_DEVICE);
-
- 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;
- }
-
- ensure_virtual_device (session, CLUTTER_POINTER_DEVICE);
-
- if (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);
- }
- else
- {
- meta_topic (META_DEBUG_REMOTE_DESKTOP,
- "Dropping early absolute pointer motion (%f, %f)", x, 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 (slot > CLUTTER_VIRTUAL_INPUT_DEVICE_MAX_TOUCH_SLOTS)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Touch slot out of range");
- 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;
- }
-
- ensure_virtual_device (session, CLUTTER_TOUCHSCREEN_DEVICE);
-
- if (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);
- }
- else
- {
- meta_topic (META_DEBUG_REMOTE_DESKTOP,
- "Dropping early touch down (%f, %f)", x, 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 (slot > CLUTTER_VIRTUAL_INPUT_DEVICE_MAX_TOUCH_SLOTS)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Touch slot out of range");
- 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;
- }
-
- if (!session->virtual_touchscreen)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Invalid touch point");
- return TRUE;
- }
-
- if (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);
- }
- else
- {
- meta_topic (META_DEBUG_REMOTE_DESKTOP,
- "Dropping early touch motion (%f, %f)", x, 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;
-
- if (slot > CLUTTER_VIRTUAL_INPUT_DEVICE_MAX_TOUCH_SLOTS)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Touch slot out of range");
- return TRUE;
- }
-
- if (!session->virtual_touchscreen)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Invalid touch point");
- 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 MetaSelectionSourceRemote *
-create_remote_desktop_source (MetaRemoteDesktopSession *session,
- GVariant *mime_types_variant,
- GError **error)
-{
- GVariantIter iter;
- char *mime_type;
- GList *mime_types = NULL;
-
- g_variant_iter_init (&iter, mime_types_variant);
- if (g_variant_iter_n_children (&iter) == 0)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
- "No mime types in mime types list");
- return NULL;
- }
-
- while (g_variant_iter_next (&iter, "s", &mime_type))
- mime_types = g_list_prepend (mime_types, mime_type);
-
- mime_types = g_list_reverse (mime_types);
-
- return meta_selection_source_remote_new (session, mime_types);
-}
-
-static const char *
-mime_types_to_string (char **formats,
- char *buf,
- int buf_len)
-{
- g_autofree char *mime_types_string = NULL;
- int len;
-
- if (!formats)
- return "N\\A";
-
- mime_types_string = g_strjoinv (",", formats);
- len = strlen (mime_types_string);
- strncpy (buf, mime_types_string, buf_len - 1);
- if (len >= buf_len - 1)
- buf[buf_len - 2] = '*';
- buf[buf_len - 1] = '\0';
-
- return buf;
-}
-
-static gboolean
-is_own_source (MetaRemoteDesktopSession *session,
- MetaSelectionSource *source)
-{
- return source && source == META_SELECTION_SOURCE (session->current_source);
-}
-
-static GVariant *
-generate_owner_changed_variant (char **mime_types_array,
- gboolean is_own_source)
-{
- GVariantBuilder builder;
-
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
- if (mime_types_array)
- {
- g_variant_builder_add (&builder, "{sv}", "mime-types",
- g_variant_new ("(^as)", mime_types_array));
- g_variant_builder_add (&builder, "{sv}", "session-is-owner",
- g_variant_new_boolean (is_own_source));
- }
-
- return g_variant_builder_end (&builder);
-}
-
-static void
-emit_owner_changed (MetaRemoteDesktopSession *session,
- MetaSelectionSource *owner)
-{
- char log_buf[255];
- g_autofree char **mime_types_array = NULL;
- GList *l;
- int i;
- GVariant *options_variant;
- const char *object_path;
-
- if (owner)
- {
- GList *mime_types;
-
- mime_types = meta_selection_source_get_mimetypes (owner);
- mime_types_array = g_new0 (char *, g_list_length (mime_types) + 1);
- for (l = meta_selection_source_get_mimetypes (owner), i = 0;
- l;
- l = l->next, i++)
- mime_types_array[i] = l->data;
- }
-
- meta_topic (META_DEBUG_REMOTE_DESKTOP,
- "Clipboard owner changed, owner: %p (%s, is own? %s), mime types: [%s], "
- "notifying %s",
- owner,
- owner ? g_type_name_from_instance ((GTypeInstance *) owner)
- : "NULL",
- is_own_source (session, owner) ? "yes" : "no",
- mime_types_to_string (mime_types_array, log_buf,
- G_N_ELEMENTS (log_buf)),
- session->peer_name);
-
- options_variant =
- generate_owner_changed_variant (mime_types_array,
- is_own_source (session, owner));
-
- object_path = g_dbus_interface_skeleton_get_object_path (
- G_DBUS_INTERFACE_SKELETON (session));
- g_dbus_connection_emit_signal (session->connection,
- NULL,
- object_path,
- "org.gnome.Mutter.RemoteDesktop.Session",
- "SelectionOwnerChanged",
- g_variant_new ("(@a{sv})", options_variant),
- NULL);
-}
-
-static void
-on_selection_owner_changed (MetaSelection *selection,
- MetaSelectionType selection_type,
- MetaSelectionSource *owner,
- MetaRemoteDesktopSession *session)
-{
- if (selection_type != META_SELECTION_CLIPBOARD)
- return;
-
- emit_owner_changed (session, owner);
-}
-
-static gboolean
-handle_enable_clipboard (MetaDBusRemoteDesktopSession *skeleton,
- GDBusMethodInvocation *invocation,
- GVariant *arg_options)
-{
- MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
- GVariant *mime_types_variant;
- g_autoptr (GError) error = NULL;
- MetaDisplay *display = meta_get_display ();
- MetaSelection *selection = meta_display_get_selection (display);
- g_autoptr (MetaSelectionSourceRemote) source_remote = NULL;
-
- meta_topic (META_DEBUG_REMOTE_DESKTOP,
- "Enable clipboard for %s",
- g_dbus_method_invocation_get_sender (invocation));
-
- if (session->is_clipboard_enabled)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Already enabled");
- return TRUE;
- }
-
- mime_types_variant = g_variant_lookup_value (arg_options,
- "mime-types",
- G_VARIANT_TYPE_STRING_ARRAY);
- if (mime_types_variant)
- {
- source_remote = create_remote_desktop_source (session,
- mime_types_variant,
- &error);
- if (!source_remote)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Invalid mime type list: %s",
- error->message);
- return TRUE;
- }
- }
-
- if (source_remote)
- {
- meta_topic (META_DEBUG_REMOTE_DESKTOP,
- "Setting remote desktop clipboard source: %p from %s",
- source_remote, session->peer_name);
-
- g_set_object (&session->current_source, source_remote);
- meta_selection_set_owner (selection,
- META_SELECTION_CLIPBOARD,
- META_SELECTION_SOURCE (source_remote));
- }
- else
- {
- MetaSelectionSource *owner;
-
- owner = meta_selection_get_current_owner (selection,
- META_SELECTION_CLIPBOARD);
-
- if (owner)
- emit_owner_changed (session, owner);
- }
-
- session->is_clipboard_enabled = TRUE;
- session->owner_changed_handler_id =
- g_signal_connect (selection, "owner-changed",
- G_CALLBACK (on_selection_owner_changed),
- session);
-
- meta_dbus_remote_desktop_session_complete_enable_clipboard (skeleton,
- invocation);
-
- return TRUE;
-}
-
-static gboolean
-cancel_transfer_request (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- GTask *task = G_TASK (value);
- MetaRemoteDesktopSession *session = user_data;
-
- meta_selection_source_remote_cancel_transfer (session->current_source,
- task);
-
- return TRUE;
-}
-
-static void
-meta_remote_desktop_session_cancel_transfer_requests (MetaRemoteDesktopSession *session)
-{
- g_return_if_fail (session->current_source);
-
- g_hash_table_foreach_remove (session->transfer_requests,
- cancel_transfer_request,
- session);
-}
-
-static gboolean
-transfer_request_cleanup_timout (gpointer user_data)
-{
- MetaRemoteDesktopSession *session = user_data;
-
- meta_topic (META_DEBUG_REMOTE_DESKTOP,
- "Cancel unanswered SelectionTransfer requests for %s, "
- "waited for %.02f seconds already",
- session->peer_name,
- TRANSFER_REQUEST_CLEANUP_TIMEOUT_MS / 1000.0);
-
- meta_remote_desktop_session_cancel_transfer_requests (session);
-
- session->transfer_request_timeout_id = 0;
- return G_SOURCE_REMOVE;
-}
-
-static void
-reset_current_selection_source (MetaRemoteDesktopSession *session)
-{
- MetaDisplay *display = meta_get_display ();
- MetaSelection *selection = meta_display_get_selection (display);
-
- if (!session->current_source)
- return;
-
- meta_selection_unset_owner (selection,
- META_SELECTION_CLIPBOARD,
- META_SELECTION_SOURCE (session->current_source));
- meta_remote_desktop_session_cancel_transfer_requests (session);
- g_clear_handle_id (&session->transfer_request_timeout_id, g_source_remove);
- g_clear_object (&session->current_source);
-}
-
-static void
-cancel_selection_read (MetaRemoteDesktopSession *session)
-{
- if (!session->read_data)
- return;
-
- g_cancellable_cancel (session->read_data->cancellable);
- session->read_data->session = NULL;
- session->read_data = NULL;
-}
-
-static gboolean
-handle_disable_clipboard (MetaDBusRemoteDesktopSession *skeleton,
- GDBusMethodInvocation *invocation)
-{
- MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
- MetaDisplay *display = meta_get_display ();
- MetaSelection *selection = meta_display_get_selection (display);
-
- meta_topic (META_DEBUG_REMOTE_DESKTOP,
- "Disable clipboard for %s",
- g_dbus_method_invocation_get_sender (invocation));
-
- if (!session->is_clipboard_enabled)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Was not enabled");
- return TRUE;
- }
-
- g_clear_signal_handler (&session->owner_changed_handler_id, selection);
- reset_current_selection_source (session);
- cancel_selection_read (session);
-
- meta_dbus_remote_desktop_session_complete_disable_clipboard (skeleton,
- invocation);
-
- return TRUE;
-}
-
-static gboolean
-handle_set_selection (MetaDBusRemoteDesktopSession *skeleton,
- GDBusMethodInvocation *invocation,
- GVariant *arg_options)
-{
- MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
- g_autoptr (GVariant) mime_types_variant = NULL;
- g_autoptr (GError) error = NULL;
-
- if (!session->is_clipboard_enabled)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Clipboard not enabled");
- return TRUE;
- }
-
- if (session->current_source)
- {
- meta_remote_desktop_session_cancel_transfer_requests (session);
- g_clear_handle_id (&session->transfer_request_timeout_id,
- g_source_remove);
- }
-
- mime_types_variant = g_variant_lookup_value (arg_options,
- "mime-types",
- G_VARIANT_TYPE_STRING_ARRAY);
- if (mime_types_variant)
- {
- g_autoptr (MetaSelectionSourceRemote) source_remote = NULL;
- MetaDisplay *display = meta_get_display ();
-
- source_remote = create_remote_desktop_source (session,
- mime_types_variant,
- &error);
- if (!source_remote)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Invalid format list: %s",
- error->message);
- return TRUE;
- }
-
- meta_topic (META_DEBUG_REMOTE_DESKTOP,
- "Set selection for %s to %p",
- g_dbus_method_invocation_get_sender (invocation),
- source_remote);
-
- g_set_object (&session->current_source, source_remote);
- meta_selection_set_owner (meta_display_get_selection (display),
- META_SELECTION_CLIPBOARD,
- META_SELECTION_SOURCE (source_remote));
- }
- else
- {
- meta_topic (META_DEBUG_REMOTE_DESKTOP,
- "Unset selection for %s",
- g_dbus_method_invocation_get_sender (invocation));
-
- reset_current_selection_source (session);
- }
-
- meta_dbus_remote_desktop_session_complete_set_selection (skeleton,
- invocation);
-
- return TRUE;
-}
-
-static void
-reset_transfer_cleanup_timeout (MetaRemoteDesktopSession *session)
-{
- g_clear_handle_id (&session->transfer_request_timeout_id, g_source_remove);
- session->transfer_request_timeout_id =
- g_timeout_add (TRANSFER_REQUEST_CLEANUP_TIMEOUT_MS,
- transfer_request_cleanup_timout,
- session);
-}
-
-void
-meta_remote_desktop_session_request_transfer (MetaRemoteDesktopSession *session,
- const char *mime_type,
- GTask *task)
-{
- const char *object_path;
-
- session->transfer_serial++;
-
- meta_topic (META_DEBUG_REMOTE_DESKTOP,
- "Emit SelectionTransfer ('%s', %u) for %s",
- mime_type,
- session->transfer_serial,
- session->peer_name);
-
- g_hash_table_insert (session->transfer_requests,
- GUINT_TO_POINTER (session->transfer_serial),
- task);
- reset_transfer_cleanup_timeout (session);
-
- object_path = g_dbus_interface_skeleton_get_object_path (
- G_DBUS_INTERFACE_SKELETON (session));
- g_dbus_connection_emit_signal (session->connection,
- NULL,
- object_path,
- "org.gnome.Mutter.RemoteDesktop.Session",
- "SelectionTransfer",
- g_variant_new ("(su)",
- mime_type,
- session->transfer_serial),
- NULL);
-}
-
-static gboolean
-handle_selection_write (MetaDBusRemoteDesktopSession *skeleton,
- GDBusMethodInvocation *invocation,
- GUnixFDList *fd_list_in,
- unsigned int serial)
-{
- MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
- g_autoptr (GError) error = NULL;
- int pipe_fds[2];
- g_autoptr (GUnixFDList) fd_list = NULL;
- int fd_idx;
- GVariant *fd_variant;
- GTask *task;
-
- meta_topic (META_DEBUG_REMOTE_DESKTOP,
- "Write selection for %s",
- g_dbus_method_invocation_get_sender (invocation));
-
- if (!session->is_clipboard_enabled)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Clipboard not enabled");
- return TRUE;
- }
-
- if (!session->current_source)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "No current selection owned");
- return TRUE;
- }
-
- if (!g_hash_table_steal_extended (session->transfer_requests,
- GUINT_TO_POINTER (serial),
- NULL,
- (gpointer *) &task))
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Transfer serial %u doesn't match "
- "any transfer request",
- serial);
- return TRUE;
- }
-
- if (!g_unix_open_pipe (pipe_fds, FD_CLOEXEC, &error))
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Failed open pipe: %s",
- error->message);
- return TRUE;
- }
-
- if (!g_unix_set_fd_nonblocking (pipe_fds[0], TRUE, &error))
- {
- close (pipe_fds[0]);
- close (pipe_fds[1]);
-
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Failed to make pipe non-blocking: %s",
- error->message);
- return TRUE;
- }
-
- fd_list = g_unix_fd_list_new ();
-
- fd_idx = g_unix_fd_list_append (fd_list, pipe_fds[1], NULL);
- close (pipe_fds[1]);
- fd_variant = g_variant_new_handle (fd_idx);
-
- meta_selection_source_remote_complete_transfer (session->current_source,
- pipe_fds[0],
- task);
-
- meta_dbus_remote_desktop_session_complete_selection_write (skeleton,
- invocation,
- fd_list,
- fd_variant);
-
- return TRUE;
-}
-
-static gboolean
-handle_selection_write_done (MetaDBusRemoteDesktopSession *skeleton,
- GDBusMethodInvocation *invocation,
- unsigned int arg_serial,
- gboolean arg_success)
-{
- MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
-
- meta_topic (META_DEBUG_REMOTE_DESKTOP,
- "Write selection done for %s",
- g_dbus_method_invocation_get_sender (invocation));
-
- if (!session->is_clipboard_enabled)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Clipboard not enabled");
- return TRUE;
- }
-
- meta_dbus_remote_desktop_session_complete_selection_write_done (skeleton,
- invocation);
-
- return TRUE;
-}
-
-static void
-transfer_cb (MetaSelection *selection,
- GAsyncResult *res,
- SelectionReadData *read_data)
-{
- g_autoptr (GError) error = NULL;
-
- if (!meta_selection_transfer_finish (selection, res, &error))
- {
- g_warning ("Could not fetch selection data "
- "for remote desktop session: %s",
- error->message);
- }
-
- if (read_data->session)
- {
- meta_topic (META_DEBUG_REMOTE_DESKTOP, "Finished selection transfer for %s",
- read_data->session->peer_name);
- }
-
- g_output_stream_close (read_data->stream, NULL, NULL);
- g_clear_object (&read_data->stream);
- g_clear_object (&read_data->cancellable);
-
- if (read_data->session)
- read_data->session->read_data = NULL;
-
- g_free (read_data);
-}
-
-static gboolean
-handle_selection_read (MetaDBusRemoteDesktopSession *skeleton,
- GDBusMethodInvocation *invocation,
- GUnixFDList *fd_list_in,
- const char *mime_type)
-{
- MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
- MetaDisplay *display = meta_get_display ();
- MetaSelection *selection = meta_display_get_selection (display);
- MetaSelectionSource *source;
- g_autoptr (GError) error = NULL;
- int pipe_fds[2];
- g_autoptr (GUnixFDList) fd_list = NULL;
- int fd_idx;
- GVariant *fd_variant;
- SelectionReadData *read_data;
-
- meta_topic (META_DEBUG_REMOTE_DESKTOP,
- "Read selection for %s",
- g_dbus_method_invocation_get_sender (invocation));
-
- if (!session->is_clipboard_enabled)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Clipboard not enabled");
- return TRUE;
- }
-
- source = meta_selection_get_current_owner (selection,
- META_SELECTION_CLIPBOARD);
- if (!source)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FILE_NOT_FOUND,
- "No selection owner available");
- return TRUE;
- }
-
- if (is_own_source (session, source))
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Tried to read own selection");
- return TRUE;
- }
-
- if (session->read_data)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_LIMITS_EXCEEDED,
- "Tried to read in parallel");
- return TRUE;
- }
-
- if (!g_unix_open_pipe (pipe_fds, FD_CLOEXEC, &error))
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Failed open pipe: %s",
- error->message);
- return TRUE;
- }
-
- if (!g_unix_set_fd_nonblocking (pipe_fds[0], TRUE, &error))
- {
- close (pipe_fds[0]);
- close (pipe_fds[1]);
-
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Failed to make pipe non-blocking: %s",
- error->message);
- return TRUE;
- }
-
- fd_list = g_unix_fd_list_new ();
-
- fd_idx = g_unix_fd_list_append (fd_list, pipe_fds[0], NULL);
- close (pipe_fds[0]);
- fd_variant = g_variant_new_handle (fd_idx);
-
- session->read_data = read_data = g_new0 (SelectionReadData, 1);
- read_data->session = session;
- read_data->stream = g_unix_output_stream_new (pipe_fds[1], TRUE);
- read_data->cancellable = g_cancellable_new ();
- meta_selection_transfer_async (selection,
- META_SELECTION_CLIPBOARD,
- mime_type,
- -1,
- read_data->stream,
- read_data->cancellable,
- (GAsyncReadyCallback) transfer_cb,
- read_data);
-
- meta_dbus_remote_desktop_session_complete_selection_read (skeleton,
- invocation,
- fd_list,
- fd_variant);
-
- 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;
- iface->handle_enable_clipboard = handle_enable_clipboard;
- iface->handle_disable_clipboard = handle_disable_clipboard;
- iface->handle_set_selection = handle_set_selection;
- iface->handle_selection_write = handle_selection_write;
- iface->handle_selection_write_done = handle_selection_write_done;
- iface->handle_selection_read = handle_selection_read;
-}
-
-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);
- MetaDisplay *display = meta_get_display ();
- MetaSelection *selection = meta_display_get_selection (display);
-
- g_assert (!meta_remote_desktop_session_is_running (session));
-
- g_clear_signal_handler (&session->owner_changed_handler_id, selection);
- reset_current_selection_source (session);
- cancel_selection_read (session);
- g_hash_table_unref (session->transfer_requests);
-
- 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);
-
- session->transfer_requests = g_hash_table_new (NULL, NULL);
-}
-
-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
deleted file mode 100644
index 7af9c4897..000000000
--- a/src/backends/meta-remote-desktop-session.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- 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_request_transfer (MetaRemoteDesktopSession *session,
- const char *mime_type,
- GTask *task);
-
-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
deleted file mode 100644
index f0a499818..000000000
--- a/src/backends/meta-remote-desktop.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/* -*- 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;
-
- MetaBackend *backend;
- int dbus_name_id;
-
- int inhibit_count;
-
- 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));
-
-void
-meta_remote_desktop_inhibit (MetaRemoteDesktop *remote_desktop)
-{
- remote_desktop->inhibit_count++;
- if (remote_desktop->inhibit_count == 1)
- {
- GHashTableIter iter;
- gpointer key, value;
-
- g_hash_table_iter_init (&iter, remote_desktop->sessions);
- while (g_hash_table_iter_next (&iter, &key, &value))
- {
- MetaRemoteDesktopSession *session = value;
-
- g_hash_table_iter_steal (&iter);
- meta_remote_desktop_session_close (session);
- }
- }
-}
-
-void
-meta_remote_desktop_uninhibit (MetaRemoteDesktop *remote_desktop)
-{
- g_return_if_fail (remote_desktop->inhibit_count > 0);
-
- remote_desktop->inhibit_count--;
-}
-
-MetaBackend *
-meta_remote_desktop_get_backend (MetaRemoteDesktop *remote_desktop)
-{
- return remote_desktop->backend;
-}
-
-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;
-
- if (remote_desktop->inhibit_count > 0)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_ACCESS_DENIED,
- "Session creation inhibited");
-
- return TRUE;
- }
-
- 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", error->message);
-}
-
-static void
-on_name_acquired (GDBusConnection *connection,
- const char *name,
- gpointer user_data)
-{
- g_info ("Acquired name %s", name);
-}
-
-static void
-on_name_lost (GDBusConnection *connection,
- const char *name,
- gpointer user_data)
-{
- g_warning ("Lost or failed to acquire name %s", 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
-on_prepare_shutdown (MetaBackend *backend,
- MetaRemoteDesktop *remote_desktop)
-{
- GHashTableIter iter;
- gpointer value;
-
- g_hash_table_iter_init (&iter, remote_desktop->sessions);
- while (g_hash_table_iter_next (&iter, NULL, &value))
- {
- MetaRemoteDesktopSession *session = value;
-
- g_hash_table_iter_steal (&iter);
- meta_remote_desktop_session_close (session);
- }
-}
-
-static void
-meta_remote_desktop_finalize (GObject *object)
-{
- MetaRemoteDesktop *remote_desktop = META_REMOTE_DESKTOP (object);
-
- if (remote_desktop->dbus_name_id != 0)
- g_bus_unown_name (remote_desktop->dbus_name_id);
-
- g_assert (g_hash_table_size (remote_desktop->sessions) == 0);
- g_hash_table_destroy (remote_desktop->sessions);
-
- G_OBJECT_CLASS (meta_remote_desktop_parent_class)->finalize (object);
-}
-
-MetaRemoteDesktop *
-meta_remote_desktop_new (MetaBackend *backend,
- MetaDbusSessionWatcher *session_watcher)
-{
- MetaRemoteDesktop *remote_desktop;
-
- remote_desktop = g_object_new (META_TYPE_REMOTE_DESKTOP, NULL);
- remote_desktop->backend = backend;
- remote_desktop->session_watcher = session_watcher;
-
- g_signal_connect (backend, "prepare-shutdown",
- G_CALLBACK (on_prepare_shutdown),
- remote_desktop);
-
- 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
deleted file mode 100644
index 3a7f38563..000000000
--- a/src/backends/meta-remote-desktop.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- 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-backend-types.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)
-
-void meta_remote_desktop_inhibit (MetaRemoteDesktop *remote_desktop);
-
-void meta_remote_desktop_uninhibit (MetaRemoteDesktop *remote_desktop);
-
-MetaBackend * meta_remote_desktop_get_backend (MetaRemoteDesktop *remote_desktop);
-
-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 (MetaBackend *backend,
- MetaDbusSessionWatcher *session_watcher);
-
-#endif /* META_REMOTE_DESKTOP_H */
diff --git a/src/backends/meta-renderer-view.c b/src/backends/meta-renderer-view.c
deleted file mode 100644
index 55617fc68..000000000
--- a/src/backends/meta-renderer-view.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * 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-crtc.h"
-#include "backends/meta-renderer.h"
-#include "clutter/clutter-mutter.h"
-#include "compositor/region-utils.h"
-
-enum
-{
- PROP_0,
-
- PROP_TRANSFORM,
- PROP_CRTC,
-
- PROP_LAST
-};
-
-static GParamSpec *obj_props[PROP_LAST];
-
-struct _MetaRendererView
-{
- MetaStageView parent;
-
- MetaMonitorTransform transform;
-
- MetaCrtc *crtc;
-};
-
-G_DEFINE_TYPE (MetaRendererView, meta_renderer_view,
- META_TYPE_STAGE_VIEW)
-
-MetaMonitorTransform
-meta_renderer_view_get_transform (MetaRendererView *view)
-{
- return view->transform;
-}
-
-MetaCrtc *
-meta_renderer_view_get_crtc (MetaRendererView *view)
-{
- return view->crtc;
-}
-
-static void
-meta_renderer_view_get_offscreen_transformation_matrix (ClutterStageView *view,
- graphene_matrix_t *matrix)
-{
- MetaRendererView *renderer_view = META_RENDERER_VIEW (view);
-
- graphene_matrix_init_identity (matrix);
-
- switch (renderer_view->transform)
- {
- case META_MONITOR_TRANSFORM_NORMAL:
- break;
- case META_MONITOR_TRANSFORM_90:
- graphene_matrix_translate (matrix, &GRAPHENE_POINT3D_INIT (0, -1, 0));
- graphene_matrix_rotate (matrix, 90, graphene_vec3_z_axis ());
- break;
- case META_MONITOR_TRANSFORM_180:
- graphene_matrix_translate (matrix, &GRAPHENE_POINT3D_INIT (-1, -1, 0));
- graphene_matrix_rotate (matrix, 180, graphene_vec3_z_axis ());
- break;
- case META_MONITOR_TRANSFORM_270:
- graphene_matrix_translate (matrix, &GRAPHENE_POINT3D_INIT (-1, 0, 0));
- graphene_matrix_rotate (matrix, 270, graphene_vec3_z_axis ());
- break;
- case META_MONITOR_TRANSFORM_FLIPPED:
- graphene_matrix_translate (matrix, &GRAPHENE_POINT3D_INIT (-1, 0, 0));
- graphene_matrix_scale (matrix, -1, 1, 1);
- break;
- case META_MONITOR_TRANSFORM_FLIPPED_90:
- graphene_matrix_rotate (matrix, 90, graphene_vec3_z_axis ());
- graphene_matrix_scale (matrix, -1, 1, 1);
- break;
- case META_MONITOR_TRANSFORM_FLIPPED_180:
- graphene_matrix_translate (matrix, &GRAPHENE_POINT3D_INIT (0, -1, 0));
- graphene_matrix_rotate (matrix, 180, graphene_vec3_z_axis ());
- graphene_matrix_scale (matrix, -1, 1, 1);
- break;
- case META_MONITOR_TRANSFORM_FLIPPED_270:
- graphene_matrix_translate (matrix, &GRAPHENE_POINT3D_INIT (-1, -1, 0));
- graphene_matrix_rotate (matrix, 270, graphene_vec3_z_axis ());
- graphene_matrix_scale (matrix, -1, 1, 1);
- break;
- }
-}
-
-static void
-meta_renderer_view_setup_offscreen_blit_pipeline (ClutterStageView *view,
- CoglPipeline *pipeline)
-{
- graphene_matrix_t matrix;
-
- meta_renderer_view_get_offscreen_transformation_matrix (view, &matrix);
- cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
-}
-
-static void
-meta_renderer_view_transform_rect_to_onscreen (ClutterStageView *view,
- const cairo_rectangle_int_t *src_rect,
- int dst_width,
- int dst_height,
- cairo_rectangle_int_t *dst_rect)
-{
- MetaRendererView *renderer_view = META_RENDERER_VIEW (view);
- MetaMonitorTransform inverted_transform;
-
- inverted_transform =
- meta_monitor_transform_invert (renderer_view->transform);
- return meta_rectangle_transform (src_rect,
- inverted_transform,
- dst_width,
- dst_height,
- dst_rect);
-}
-
-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;
- case PROP_CRTC:
- g_value_set_object (value, view->crtc);
- 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;
- case PROP_CRTC:
- view->crtc = g_value_get_object (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;
- view_class->transform_rect_to_onscreen =
- meta_renderer_view_transform_rect_to_onscreen;
-
- 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);
-
- obj_props[PROP_CRTC] =
- g_param_spec_object ("crtc",
- "MetaCrtc",
- "MetaCrtc",
- META_TYPE_CRTC,
- 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
deleted file mode 100644
index 3f21c7c48..000000000
--- a/src/backends/meta-renderer-view.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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 "backends/meta-stage-impl-private.h"
-#include "backends/meta-stage-view-private.h"
-
-#define META_TYPE_RENDERER_VIEW (meta_renderer_view_get_type ())
-G_DECLARE_FINAL_TYPE (MetaRendererView, meta_renderer_view,
- META, RENDERER_VIEW,
- MetaStageView)
-
-MetaMonitorTransform meta_renderer_view_get_transform (MetaRendererView *view);
-
-MetaCrtc *meta_renderer_view_get_crtc (MetaRendererView *view);
-
-#endif /* META_RENDERER_VIEW_H */
diff --git a/src/backends/meta-renderer.c b/src/backends/meta-renderer.c
deleted file mode 100644
index 8808a52ef..000000000
--- a/src/backends/meta-renderer.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/* -*- 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;
- gboolean is_paused;
-} 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;
- MetaRendererView *view;
-
- view = meta_renderer_create_view (renderer, logical_monitor, output, crtc);
- meta_renderer_add_view (renderer, 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_clear_list (&priv->views, (GDestroyNotify) clutter_stage_view_destroy);
-
- logical_monitors =
- meta_monitor_manager_get_logical_monitors (monitor_manager);
-
- for (l = logical_monitors; l; l = l->next)
- {
- MetaLogicalMonitor *logical_monitor = l->data;
-
- if (meta_logical_monitor_is_primary (logical_monitor))
- {
- ClutterBackend *clutter_backend;
- float scale;
-
- clutter_backend = meta_backend_get_clutter_backend (backend);
- scale = meta_is_stage_views_scaled ()
- ? meta_logical_monitor_get_scale (logical_monitor)
- : 1.f;
-
- clutter_backend_set_fallback_resource_scale (clutter_backend, scale);
- }
-
- meta_logical_monitor_foreach_crtc (logical_monitor,
- create_crtc_view,
- renderer);
- }
-}
-
-MetaRendererView *
-meta_renderer_get_view_for_crtc (MetaRenderer *renderer,
- MetaCrtc *crtc)
-{
- MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer);
- GList *l;
-
- for (l = priv->views; l; l = l->next)
- {
- MetaRendererView *view = l->data;
-
- if (meta_renderer_view_get_crtc (view) == crtc)
- return view;
- }
-
- return NULL;
-}
-
-typedef struct _CollectViewsData
-{
- MetaRenderer *renderer;
- GList *out_views;
-} CollectViewsData;
-
-static gboolean
-collect_views (MetaMonitor *monitor,
- MetaMonitorMode *mode,
- MetaMonitorCrtcMode *monitor_crtc_mode,
- gpointer user_data,
- GError **error)
-{
- CollectViewsData *data = user_data;
- MetaCrtc *crtc;
- MetaRendererView *view;
-
- crtc = meta_output_get_assigned_crtc (monitor_crtc_mode->output);
- view = meta_renderer_get_view_for_crtc (data->renderer, crtc);
- if (!g_list_find (data->out_views, view))
- data->out_views = g_list_prepend (data->out_views, view);
-
- return TRUE;
-}
-
-static GList *
-meta_renderer_real_get_views_for_monitor (MetaRenderer *renderer,
- MetaMonitor *monitor)
-{
- CollectViewsData data = { 0 };
- MetaMonitorMode *monitor_mode;
-
- data.renderer = renderer;
-
- monitor_mode = meta_monitor_get_current_mode (monitor);
- meta_monitor_mode_foreach_crtc (monitor, monitor_mode,
- collect_views,
- &data,
- NULL);
-
- return data.out_views;
-}
-
-GList *
-meta_renderer_get_views_for_monitor (MetaRenderer *renderer,
- MetaMonitor *monitor)
-{
- return META_RENDERER_GET_CLASS (renderer)->get_views_for_monitor (renderer,
- monitor);
-}
-
-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);
-
- if (priv->is_paused)
- {
- ClutterFrameClock *frame_clock =
- clutter_stage_view_get_frame_clock (CLUTTER_STAGE_VIEW (view));
-
- clutter_frame_clock_inhibit (frame_clock);
- }
-}
-
-/**
- * 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;
-}
-
-void
-meta_renderer_pause (MetaRenderer *renderer)
-{
- MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer);
- GList *l;
-
- g_return_if_fail (!priv->is_paused);
- priv->is_paused = TRUE;
-
- for (l = priv->views; l; l = l->next)
- {
- ClutterStageView *stage_view = l->data;
- ClutterFrameClock *frame_clock =
- clutter_stage_view_get_frame_clock (stage_view);
-
- clutter_frame_clock_inhibit (frame_clock);
- }
-}
-
-void
-meta_renderer_resume (MetaRenderer *renderer)
-{
- MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer);
- GList *l;
-
- g_return_if_fail (priv->is_paused);
- priv->is_paused = FALSE;
-
- for (l = priv->views; l; l = l->next)
- {
- ClutterStageView *stage_view = l->data;
- ClutterFrameClock *frame_clock =
- clutter_stage_view_get_frame_clock (stage_view);
-
- clutter_frame_clock_uninhibit (frame_clock);
- }
-}
-
-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);
-
- return cogl_context_is_hardware_accelerated (cogl_context);
-}
-
-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_dispose (GObject *object)
-{
- MetaRenderer *renderer = META_RENDERER (object);
- MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer);
-
- g_clear_list (&priv->views, g_object_unref);
-
- G_OBJECT_CLASS (meta_renderer_parent_class)->dispose (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->dispose = meta_renderer_dispose;
-
- klass->rebuild_views = meta_renderer_real_rebuild_views;
- klass->get_views_for_monitor = meta_renderer_real_get_views_for_monitor;
-
- 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
deleted file mode 100644
index 92b0727bb..000000000
--- a/src/backends/meta-renderer.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- 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);
- GList * (* get_views_for_monitor) (MetaRenderer *renderer,
- MetaMonitor *monitor);
-};
-
-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);
-
-GList * meta_renderer_get_views_for_monitor (MetaRenderer *renderer,
- MetaMonitor *monitor);
-
-META_EXPORT_TEST
-MetaRendererView * meta_renderer_get_view_for_crtc (MetaRenderer *renderer,
- MetaCrtc *crtc);
-
-META_EXPORT_TEST
-GList * meta_renderer_get_views (MetaRenderer *renderer);
-
-gboolean meta_renderer_is_hardware_accelerated (MetaRenderer *renderer);
-
-void meta_renderer_pause (MetaRenderer *renderer);
-
-void meta_renderer_resume (MetaRenderer *renderer);
-
-#endif /* META_RENDERER_H */
diff --git a/src/backends/meta-screen-cast-area-stream-src.c b/src/backends/meta-screen-cast-area-stream-src.c
deleted file mode 100644
index aa1548101..000000000
--- a/src/backends/meta-screen-cast-area-stream-src.c
+++ /dev/null
@@ -1,652 +0,0 @@
-/*
- * 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, 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-area-stream-src.h"
-
-#include <spa/buffer/meta.h>
-
-#include "backends/meta-backend-private.h"
-#include "backends/meta-cursor-tracker-private.h"
-#include "backends/meta-screen-cast-area-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 _MetaScreenCastAreaStreamSrc
-{
- MetaScreenCastStreamSrc parent;
-
- gboolean cursor_bitmap_invalid;
- gboolean hw_cursor_inhibited;
-
- GList *watches;
-
- gulong position_invalidated_handler_id;
- gulong cursor_changed_handler_id;
-
- guint maybe_record_idle_id;
-};
-
-static void
-hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaScreenCastAreaStreamSrc,
- meta_screen_cast_area_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 (MetaScreenCastAreaStreamSrc *area_src)
-{
- MetaScreenCastStreamSrc *src;
- MetaScreenCastStream *stream;
- MetaScreenCastAreaStream *area_stream;
-
- src = META_SCREEN_CAST_STREAM_SRC (area_src);
- stream = meta_screen_cast_stream_src_get_stream (src);
- area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
-
- return meta_screen_cast_area_stream_get_stage (area_stream);
-}
-
-static MetaBackend *
-get_backend (MetaScreenCastAreaStreamSrc *area_src)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_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
-meta_screen_cast_area_stream_src_get_specs (MetaScreenCastStreamSrc *src,
- int *width,
- int *height,
- float *frame_rate)
-{
- MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
- MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
- MetaRectangle *area;
- float scale;
-
- area = meta_screen_cast_area_stream_get_area (area_stream);
- scale = meta_screen_cast_area_stream_get_scale (area_stream);
-
- *width = (int) roundf (area->width * scale);
- *height = (int) roundf (area->height * scale);
- *frame_rate = 60.0;
-
- return TRUE;
-}
-
-static gboolean
-is_cursor_in_stream (MetaScreenCastAreaStreamSrc *area_src)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
- MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
- MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
- MetaBackend *backend = get_backend (area_src);
- MetaCursorRenderer *cursor_renderer =
- meta_backend_get_cursor_renderer (backend);
- MetaRectangle *area;
- graphene_rect_t area_rect;
- MetaCursorSprite *cursor_sprite;
-
- area = meta_screen_cast_area_stream_get_area (area_stream);
- area_rect = meta_rectangle_to_graphene_rect (area);
-
- 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, &area_rect, NULL);
- }
- else
- {
- MetaCursorTracker *cursor_tracker =
- meta_backend_get_cursor_tracker (backend);
- graphene_point_t cursor_position;
-
- meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
- return graphene_rect_contains_point (&area_rect, &cursor_position);
- }
-}
-
-static gboolean
-is_redraw_queued (MetaScreenCastAreaStreamSrc *area_src)
-{
- ClutterStage *stage = get_stage (area_src);
- GList *l;
-
- for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
- {
- ClutterStageView *view = l->data;
-
- if (clutter_stage_is_redraw_queued_on_view (stage, view))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-sync_cursor_state (MetaScreenCastAreaStreamSrc *area_src)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
- MetaScreenCastRecordFlag flags;
-
- if (is_redraw_queued (area_src))
- return;
-
- flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
- meta_screen_cast_stream_src_maybe_record_frame (src, flags);
-}
-
-static void
-pointer_position_invalidated (MetaCursorTracker *cursor_tracker,
- MetaScreenCastAreaStreamSrc *area_src)
-{
- sync_cursor_state (area_src);
-}
-
-static void
-cursor_changed (MetaCursorTracker *cursor_tracker,
- MetaScreenCastAreaStreamSrc *area_src)
-{
- area_src->cursor_bitmap_invalid = TRUE;
- sync_cursor_state (area_src);
-}
-
-static void
-inhibit_hw_cursor (MetaScreenCastAreaStreamSrc *area_src)
-{
- MetaHwCursorInhibitor *inhibitor;
- MetaBackend *backend;
-
- g_return_if_fail (!area_src->hw_cursor_inhibited);
-
- backend = get_backend (area_src);
- inhibitor = META_HW_CURSOR_INHIBITOR (area_src);
- meta_backend_add_hw_cursor_inhibitor (backend, inhibitor);
-
- area_src->hw_cursor_inhibited = TRUE;
-}
-
-static void
-uninhibit_hw_cursor (MetaScreenCastAreaStreamSrc *area_src)
-{
- MetaHwCursorInhibitor *inhibitor;
- MetaBackend *backend;
-
- g_return_if_fail (area_src->hw_cursor_inhibited);
-
- backend = get_backend (area_src);
- inhibitor = META_HW_CURSOR_INHIBITOR (area_src);
- meta_backend_remove_hw_cursor_inhibitor (backend, inhibitor);
-
- area_src->hw_cursor_inhibited = FALSE;
-}
-
-static gboolean
-maybe_record_frame_on_idle (gpointer user_data)
-{
- MetaScreenCastAreaStreamSrc *area_src =
- META_SCREEN_CAST_AREA_STREAM_SRC (user_data);
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
- MetaScreenCastRecordFlag flags;
-
- area_src->maybe_record_idle_id = 0;
-
- flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
- meta_screen_cast_stream_src_maybe_record_frame (src, flags);
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-before_stage_painted (MetaStage *stage,
- ClutterStageView *view,
- ClutterPaintContext *paint_context,
- gpointer user_data)
-{
- MetaScreenCastAreaStreamSrc *area_src =
- META_SCREEN_CAST_AREA_STREAM_SRC (user_data);
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
-
- if (area_src->maybe_record_idle_id)
- return;
-
- if (!clutter_stage_view_peek_scanout (view))
- return;
-
- area_src->maybe_record_idle_id = g_idle_add (maybe_record_frame_on_idle, src);
-}
-
-static void
-stage_painted (MetaStage *stage,
- ClutterStageView *view,
- ClutterPaintContext *paint_context,
- gpointer user_data)
-{
- MetaScreenCastAreaStreamSrc *area_src =
- META_SCREEN_CAST_AREA_STREAM_SRC (user_data);
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
- MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
- MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
- const cairo_region_t *redraw_clip;
- MetaRectangle *area;
-
- if (area_src->maybe_record_idle_id)
- return;
-
- area = meta_screen_cast_area_stream_get_area (area_stream);
- redraw_clip = clutter_paint_context_get_redraw_clip (paint_context);
-
- if (redraw_clip)
- {
- switch (cairo_region_contains_rectangle (redraw_clip, area))
- {
- case CAIRO_REGION_OVERLAP_IN:
- case CAIRO_REGION_OVERLAP_PART:
- break;
- case CAIRO_REGION_OVERLAP_OUT:
- return;
- }
- }
-
- area_src->maybe_record_idle_id = g_idle_add (maybe_record_frame_on_idle, src);
-}
-
-static void
-add_view_painted_watches (MetaScreenCastAreaStreamSrc *area_src)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
- MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
- MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
- MetaBackend *backend = get_backend (area_src);
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
- ClutterStage *stage;
- MetaStage *meta_stage;
- MetaRectangle *area;
- GList *l;
-
- stage = get_stage (area_src);
- meta_stage = META_STAGE (stage);
- area = meta_screen_cast_area_stream_get_area (area_stream);
-
- 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 (area, &view_layout))
- {
- MetaStageWatch *watch;
-
- watch = meta_stage_watch_view (meta_stage,
- CLUTTER_STAGE_VIEW (view),
- META_STAGE_WATCH_BEFORE_PAINT,
- before_stage_painted,
- area_src);
-
- area_src->watches = g_list_prepend (area_src->watches, watch);
-
- watch = meta_stage_watch_view (meta_stage,
- CLUTTER_STAGE_VIEW (view),
- META_STAGE_WATCH_AFTER_ACTOR_PAINT,
- stage_painted,
- area_src);
-
- area_src->watches = g_list_prepend (area_src->watches, watch);
- }
- }
-}
-
-static void
-on_monitors_changed (MetaMonitorManager *monitor_manager,
- MetaScreenCastAreaStreamSrc *area_src)
-{
- MetaStage *stage = META_STAGE (get_stage (area_src));
- GList *l;
-
- for (l = area_src->watches; l; l = l->next)
- meta_stage_remove_watch (stage, l->data);
- g_clear_pointer (&area_src->watches, g_list_free);
-
- add_view_painted_watches (area_src);
-}
-
-static void
-meta_screen_cast_area_stream_src_enable (MetaScreenCastStreamSrc *src)
-{
- MetaScreenCastAreaStreamSrc *area_src =
- META_SCREEN_CAST_AREA_STREAM_SRC (src);
- MetaBackend *backend = get_backend (area_src);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- 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 (area_src);
-
- switch (meta_screen_cast_stream_get_cursor_mode (stream))
- {
- case META_SCREEN_CAST_CURSOR_MODE_METADATA:
- area_src->position_invalidated_handler_id =
- g_signal_connect_after (cursor_tracker, "position-invalidated",
- G_CALLBACK (pointer_position_invalidated),
- area_src);
- area_src->cursor_changed_handler_id =
- g_signal_connect_after (cursor_tracker, "cursor-changed",
- G_CALLBACK (cursor_changed),
- area_src);
- meta_cursor_tracker_track_position (cursor_tracker);
- G_GNUC_FALLTHROUGH;
- case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
- add_view_painted_watches (area_src);
- break;
- case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
- inhibit_hw_cursor (area_src);
- meta_cursor_tracker_track_position (cursor_tracker);
- add_view_painted_watches (area_src);
- break;
- }
-
- g_signal_connect_object (monitor_manager, "monitors-changed-internal",
- G_CALLBACK (on_monitors_changed),
- area_src, 0);
-
- clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
-}
-
-static void
-meta_screen_cast_area_stream_src_disable (MetaScreenCastStreamSrc *src)
-{
- MetaScreenCastAreaStreamSrc *area_src =
- META_SCREEN_CAST_AREA_STREAM_SRC (src);
- MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
- MetaBackend *backend = get_backend (area_src);
- MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
- ClutterStage *stage;
- MetaStage *meta_stage;
- GList *l;
-
- stage = get_stage (area_src);
- meta_stage = META_STAGE (stage);
-
- for (l = area_src->watches; l; l = l->next)
- {
- MetaStageWatch *watch = l->data;
-
- meta_stage_remove_watch (meta_stage, watch);
- }
- g_clear_pointer (&area_src->watches, g_list_free);
-
- if (area_src->hw_cursor_inhibited)
- uninhibit_hw_cursor (area_src);
-
- g_clear_signal_handler (&area_src->position_invalidated_handler_id,
- cursor_tracker);
- g_clear_signal_handler (&area_src->cursor_changed_handler_id,
- cursor_tracker);
-
- g_clear_handle_id (&area_src->maybe_record_idle_id, g_source_remove);
-
- switch (meta_screen_cast_stream_get_cursor_mode (stream))
- {
- case META_SCREEN_CAST_CURSOR_MODE_METADATA:
- case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
- meta_cursor_tracker_untrack_position (cursor_tracker);
- break;
- case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
- break;
- }
-}
-
-static gboolean
-meta_screen_cast_area_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
- int width,
- int height,
- int stride,
- uint8_t *data,
- GError **error)
-{
- MetaScreenCastAreaStreamSrc *area_src =
- META_SCREEN_CAST_AREA_STREAM_SRC (src);
- MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
- MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
- ClutterStage *stage;
- MetaRectangle *area;
- float scale;
- ClutterPaintFlag paint_flags = CLUTTER_PAINT_FLAG_CLEAR;
-
- stage = get_stage (area_src);
- area = meta_screen_cast_area_stream_get_area (area_stream);
- scale = meta_screen_cast_area_stream_get_scale (area_stream);
-
- switch (meta_screen_cast_stream_get_cursor_mode (stream))
- {
- case META_SCREEN_CAST_CURSOR_MODE_METADATA:
- case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
- paint_flags |= CLUTTER_PAINT_FLAG_NO_CURSORS;
- break;
- case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
- paint_flags |= CLUTTER_PAINT_FLAG_FORCE_CURSORS;
- break;
- }
-
- if (!clutter_stage_paint_to_buffer (stage, area, scale,
- data,
- stride,
- CLUTTER_CAIRO_FORMAT_ARGB32,
- paint_flags,
- error))
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-meta_screen_cast_area_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
- CoglFramebuffer *framebuffer,
- GError **error)
-{
- MetaScreenCastAreaStreamSrc *area_src =
- META_SCREEN_CAST_AREA_STREAM_SRC (src);
- MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
- MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
- MetaBackend *backend = get_backend (area_src);
- ClutterStage *stage;
- MetaRectangle *area;
- float scale;
- ClutterPaintFlag paint_flags = CLUTTER_PAINT_FLAG_CLEAR;
-
- stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
- area = meta_screen_cast_area_stream_get_area (area_stream);
- scale = meta_screen_cast_area_stream_get_scale (area_stream);
-
- switch (meta_screen_cast_stream_get_cursor_mode (stream))
- {
- case META_SCREEN_CAST_CURSOR_MODE_METADATA:
- case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
- paint_flags |= CLUTTER_PAINT_FLAG_NO_CURSORS;
- break;
- case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
- paint_flags |= CLUTTER_PAINT_FLAG_FORCE_CURSORS;
- break;
- }
- clutter_stage_paint_to_framebuffer (stage, framebuffer,
- area, scale,
- paint_flags);
-
- cogl_framebuffer_flush (framebuffer);
-
- return TRUE;
-}
-
-static void
-meta_screen_cast_area_stream_record_follow_up (MetaScreenCastStreamSrc *src)
-{
- MetaScreenCastAreaStreamSrc *area_src =
- META_SCREEN_CAST_AREA_STREAM_SRC (src);
- MetaScreenCastRecordFlag flags;
-
- g_clear_handle_id (&area_src->maybe_record_idle_id, g_source_remove);
-
- flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
- meta_screen_cast_stream_src_maybe_record_frame (src, flags);
-}
-
-static void
-meta_screen_cast_area_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
- struct spa_meta_cursor *spa_meta_cursor)
-{
- MetaScreenCastAreaStreamSrc *area_src =
- META_SCREEN_CAST_AREA_STREAM_SRC (src);
- MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
- MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
- MetaBackend *backend = get_backend (area_src);
- MetaCursorRenderer *cursor_renderer =
- meta_backend_get_cursor_renderer (backend);
- MetaCursorTracker *cursor_tracker =
- meta_backend_get_cursor_tracker (backend);
- MetaCursorSprite *cursor_sprite;
- MetaRectangle *area;
- float scale;
- graphene_point_t cursor_position;
- int x, y;
-
- cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
-
- if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) ||
- !is_cursor_in_stream (area_src))
- {
- meta_screen_cast_stream_src_unset_cursor_metadata (src,
- spa_meta_cursor);
- return;
- }
-
- area = meta_screen_cast_area_stream_get_area (area_stream);
- scale = meta_screen_cast_area_stream_get_scale (area_stream);
-
- meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
- cursor_position.x -= area->x;
- cursor_position.y -= area->y;
- cursor_position.x *= scale;
- cursor_position.y *= scale;
-
- x = (int) roundf (cursor_position.x);
- y = (int) roundf (cursor_position.y);
-
- if (area_src->cursor_bitmap_invalid)
- {
- if (cursor_sprite)
- {
- float cursor_scale;
- float metadata_scale;
-
- cursor_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite);
- metadata_scale = scale * cursor_scale;
- meta_screen_cast_stream_src_set_cursor_sprite_metadata (src,
- spa_meta_cursor,
- cursor_sprite,
- x, y,
- metadata_scale);
- }
- else
- {
- meta_screen_cast_stream_src_set_empty_cursor_sprite_metadata (src,
- spa_meta_cursor,
- x, y);
- }
-
- area_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_area_stream_src_is_cursor_inhibited (MetaHwCursorInhibitor *inhibitor)
-{
- MetaScreenCastAreaStreamSrc *area_src =
- META_SCREEN_CAST_AREA_STREAM_SRC (inhibitor);
-
- return is_cursor_in_stream (area_src);
-}
-
-static void
-hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface)
-{
- iface->is_cursor_inhibited =
- meta_screen_cast_area_stream_src_is_cursor_inhibited;
-}
-
-MetaScreenCastAreaStreamSrc *
-meta_screen_cast_area_stream_src_new (MetaScreenCastAreaStream *area_stream,
- GError **error)
-{
- return g_initable_new (META_TYPE_SCREEN_CAST_AREA_STREAM_SRC, NULL, error,
- "stream", area_stream,
- NULL);
-}
-
-static void
-meta_screen_cast_area_stream_src_init (MetaScreenCastAreaStreamSrc *area_src)
-{
- area_src->cursor_bitmap_invalid = TRUE;
-}
-
-static void
-meta_screen_cast_area_stream_src_class_init (MetaScreenCastAreaStreamSrcClass *klass)
-{
- MetaScreenCastStreamSrcClass *src_class =
- META_SCREEN_CAST_STREAM_SRC_CLASS (klass);
-
- src_class->get_specs = meta_screen_cast_area_stream_src_get_specs;
- src_class->enable = meta_screen_cast_area_stream_src_enable;
- src_class->disable = meta_screen_cast_area_stream_src_disable;
- src_class->record_to_buffer =
- meta_screen_cast_area_stream_src_record_to_buffer;
- src_class->record_to_framebuffer =
- meta_screen_cast_area_stream_src_record_to_framebuffer;
- src_class->record_follow_up =
- meta_screen_cast_area_stream_record_follow_up;
- src_class->set_cursor_metadata =
- meta_screen_cast_area_stream_src_set_cursor_metadata;
-}
diff --git a/src/backends/meta-screen-cast-area-stream-src.h b/src/backends/meta-screen-cast-area-stream-src.h
deleted file mode 100644
index 72261642c..000000000
--- a/src/backends/meta-screen-cast-area-stream-src.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- */
-
-#ifndef META_SCREEN_CAST_AREA_STREAM_SRC_H
-#define META_SCREEN_CAST_AREA_STREAM_SRC_H
-
-#include "backends/meta-screen-cast-stream-src.h"
-
-typedef struct _MetaScreenCastAreaStream MetaScreenCastAreaStream;
-
-#define META_TYPE_SCREEN_CAST_AREA_STREAM_SRC (meta_screen_cast_area_stream_src_get_type ())
-G_DECLARE_FINAL_TYPE (MetaScreenCastAreaStreamSrc,
- meta_screen_cast_area_stream_src,
- META, SCREEN_CAST_AREA_STREAM_SRC,
- MetaScreenCastStreamSrc)
-
-MetaScreenCastAreaStreamSrc * meta_screen_cast_area_stream_src_new (MetaScreenCastAreaStream *area_stream,
- GError **error);
-
-#endif /* META_SCREEN_CAST_AREA_STREAM_SRC_H */
diff --git a/src/backends/meta-screen-cast-area-stream.c b/src/backends/meta-screen-cast-area-stream.c
deleted file mode 100644
index 23d8c9828..000000000
--- a/src/backends/meta-screen-cast-area-stream.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * 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, 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-area-stream.h"
-
-#include "backends/meta-screen-cast-area-stream-src.h"
-
-struct _MetaScreenCastAreaStream
-{
- MetaScreenCastStream parent;
-
- ClutterStage *stage;
-
- MetaRectangle area;
- float scale;
-};
-
-G_DEFINE_TYPE (MetaScreenCastAreaStream,
- meta_screen_cast_area_stream,
- META_TYPE_SCREEN_CAST_STREAM)
-
-ClutterStage *
-meta_screen_cast_area_stream_get_stage (MetaScreenCastAreaStream *area_stream)
-{
- return area_stream->stage;
-}
-
-MetaRectangle *
-meta_screen_cast_area_stream_get_area (MetaScreenCastAreaStream *area_stream)
-{
- return &area_stream->area;
-}
-
-float
-meta_screen_cast_area_stream_get_scale (MetaScreenCastAreaStream *area_stream)
-{
- return area_stream->scale;
-}
-
-static gboolean
-calculate_scale (ClutterStage *stage,
- MetaRectangle *area,
- float *out_scale)
-{
- GList *l;
- float scale = 0.0;
-
- for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
- {
- ClutterStageView *stage_view = l->data;
- MetaRectangle view_layout;
-
- clutter_stage_view_get_layout (stage_view, &view_layout);
- if (meta_rectangle_overlap (area, &view_layout))
- scale = MAX (clutter_stage_view_get_scale (stage_view), scale);
- }
-
- if (scale == 0.0)
- return FALSE;
-
- *out_scale = scale;
- return TRUE;
-}
-
-MetaScreenCastAreaStream *
-meta_screen_cast_area_stream_new (MetaScreenCastSession *session,
- GDBusConnection *connection,
- MetaRectangle *area,
- ClutterStage *stage,
- MetaScreenCastCursorMode cursor_mode,
- MetaScreenCastFlag flags,
- GError **error)
-{
- MetaScreenCastAreaStream *area_stream;
- float scale;
-
- if (!calculate_scale (stage, area, &scale))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Area is off-screen");
- return NULL;
- }
-
- area_stream = g_initable_new (META_TYPE_SCREEN_CAST_AREA_STREAM,
- NULL,
- error,
- "session", session,
- "connection", connection,
- "cursor-mode", cursor_mode,
- "flags", flags,
- NULL);
- if (!area_stream)
- return NULL;
-
- area_stream->area = *area;
- area_stream->scale = scale;
- area_stream->stage = stage;
-
- return area_stream;
-}
-
-static MetaScreenCastStreamSrc *
-meta_screen_cast_area_stream_create_src (MetaScreenCastStream *stream,
- GError **error)
-{
- MetaScreenCastAreaStream *area_stream =
- META_SCREEN_CAST_AREA_STREAM (stream);
- MetaScreenCastAreaStreamSrc *area_stream_src;
-
- area_stream_src = meta_screen_cast_area_stream_src_new (area_stream,
- error);
- if (!area_stream_src)
- return NULL;
-
- return META_SCREEN_CAST_STREAM_SRC (area_stream_src);
-}
-
-static void
-meta_screen_cast_area_stream_set_parameters (MetaScreenCastStream *stream,
- GVariantBuilder *parameters_builder)
-{
- MetaScreenCastAreaStream *area_stream =
- META_SCREEN_CAST_AREA_STREAM (stream);
-
- g_variant_builder_add (parameters_builder, "{sv}",
- "size",
- g_variant_new ("(ii)",
- area_stream->area.width,
- area_stream->area.height));
-}
-
-static gboolean
-meta_screen_cast_area_stream_transform_position (MetaScreenCastStream *stream,
- double stream_x,
- double stream_y,
- double *x,
- double *y)
-{
- MetaScreenCastAreaStream *area_stream =
- META_SCREEN_CAST_AREA_STREAM (stream);
-
- *x = area_stream->area.x + (int) roundf (stream_x / area_stream->scale);
- *y = area_stream->area.y + (int) roundf (stream_y / area_stream->scale);
-
- return TRUE;
-}
-
-static void
-meta_screen_cast_area_stream_init (MetaScreenCastAreaStream *area_stream)
-{
-}
-
-static void
-meta_screen_cast_area_stream_class_init (MetaScreenCastAreaStreamClass *klass)
-{
- MetaScreenCastStreamClass *stream_class =
- META_SCREEN_CAST_STREAM_CLASS (klass);
-
- stream_class->create_src = meta_screen_cast_area_stream_create_src;
- stream_class->set_parameters = meta_screen_cast_area_stream_set_parameters;
- stream_class->transform_position = meta_screen_cast_area_stream_transform_position;
-}
diff --git a/src/backends/meta-screen-cast-area-stream.h b/src/backends/meta-screen-cast-area-stream.h
deleted file mode 100644
index b11ec1fb9..000000000
--- a/src/backends/meta-screen-cast-area-stream.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- */
-
-#ifndef META_SCREEN_CAST_AREA_STREAM_H
-#define META_SCREEN_CAST_AREA_STREAM_H
-
-#include <glib-object.h>
-
-#include "backends/meta-screen-cast-stream.h"
-#include "backends/meta-screen-cast.h"
-
-#define META_TYPE_SCREEN_CAST_AREA_STREAM (meta_screen_cast_area_stream_get_type ())
-G_DECLARE_FINAL_TYPE (MetaScreenCastAreaStream,
- meta_screen_cast_area_stream,
- META, SCREEN_CAST_AREA_STREAM,
- MetaScreenCastStream)
-
-MetaScreenCastAreaStream * meta_screen_cast_area_stream_new (MetaScreenCastSession *session,
- GDBusConnection *connection,
- MetaRectangle *area,
- ClutterStage *stage,
- MetaScreenCastCursorMode cursor_mode,
- MetaScreenCastFlag flags,
- GError **error);
-
-ClutterStage * meta_screen_cast_area_stream_get_stage (MetaScreenCastAreaStream *area_stream);
-
-MetaRectangle * meta_screen_cast_area_stream_get_area (MetaScreenCastAreaStream *area_stream);
-
-float meta_screen_cast_area_stream_get_scale (MetaScreenCastAreaStream *area_stream);
-
-#endif /* META_SCREEN_CAST_AREA_STREAM_H */
diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c
deleted file mode 100644
index b85c44fe1..000000000
--- a/src/backends/meta-screen-cast-monitor-stream-src.c
+++ /dev/null
@@ -1,793 +0,0 @@
-/* -*- 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 position_invalidated_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 gboolean
-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);
-
- return TRUE;
-}
-
-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 void
-before_stage_painted (MetaStage *stage,
- ClutterStageView *view,
- ClutterPaintContext *paint_context,
- gpointer user_data)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (user_data);
- CoglScanout *scanout;
-
- scanout = clutter_stage_view_peek_scanout (view);
- if (scanout)
- {
- 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
- {
- MetaCursorTracker *cursor_tracker =
- meta_backend_get_cursor_tracker (backend);
- graphene_point_t cursor_position;
-
- meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
- return graphene_rect_contains_point (&logical_monitor_rect,
- &cursor_position);
- }
-}
-
-static gboolean
-is_redraw_queued (MetaScreenCastMonitorStreamSrc *monitor_src)
-{
- MetaBackend *backend = get_backend (monitor_src);
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
- ClutterStage *stage = get_stage (monitor_src);
- MetaMonitor *monitor = get_monitor (monitor_src);
- g_autoptr (GList) views = NULL;
- GList *l;
-
- views = meta_renderer_get_views_for_monitor (renderer, monitor);
- for (l = views; l; l = l->next)
- {
- MetaRendererView *view = l->data;
-
- if (clutter_stage_is_redraw_queued_on_view (stage, CLUTTER_STAGE_VIEW (view)))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src);
- MetaScreenCastRecordFlag flags;
-
- if (is_redraw_queued (monitor_src))
- 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
-pointer_position_invalidated (MetaCursorTracker *cursor_tracker,
- 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 void
-inhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src)
-{
- MetaHwCursorInhibitor *inhibitor;
- MetaBackend *backend;
-
- g_return_if_fail (!monitor_src->hw_cursor_inhibited);
-
- backend = get_backend (monitor_src);
- inhibitor = META_HW_CURSOR_INHIBITOR (monitor_src);
- meta_backend_add_hw_cursor_inhibitor (backend, inhibitor);
-
- monitor_src->hw_cursor_inhibited = TRUE;
-}
-
-static void
-uninhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src)
-{
- MetaHwCursorInhibitor *inhibitor;
- MetaBackend *backend;
-
- g_return_if_fail (monitor_src->hw_cursor_inhibited);
-
- backend = get_backend (monitor_src);
- inhibitor = META_HW_CURSOR_INHIBITOR (monitor_src);
- meta_backend_remove_hw_cursor_inhibitor (backend, inhibitor);
-
- monitor_src->hw_cursor_inhibited = FALSE;
-}
-
-static void
-add_view_watches (MetaScreenCastMonitorStreamSrc *monitor_src,
- MetaStageWatchPhase watch_phase,
- MetaStageWatchFunc callback)
-{
- 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,
- callback,
- monitor_src);
-
- monitor_src->watches = g_list_prepend (monitor_src->watches, watch);
- }
- }
-}
-
-static void
-reattach_watches (MetaScreenCastMonitorStreamSrc *monitor_src)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src);
- MetaScreenCastStream *stream;
- ClutterStage *stage;
- GList *l;
-
- stream = meta_screen_cast_stream_src_get_stream (src);
- stage = get_stage (monitor_src);
-
- for (l = monitor_src->watches; l; l = l->next)
- meta_stage_remove_watch (META_STAGE (stage), l->data);
- g_clear_pointer (&monitor_src->watches, g_list_free);
-
- switch (meta_screen_cast_stream_get_cursor_mode (stream))
- {
- case META_SCREEN_CAST_CURSOR_MODE_METADATA:
- case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
- add_view_watches (monitor_src,
- META_STAGE_WATCH_BEFORE_PAINT,
- before_stage_painted);
- add_view_watches (monitor_src,
- META_STAGE_WATCH_AFTER_ACTOR_PAINT,
- stage_painted);
- break;
- case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
- add_view_watches (monitor_src,
- META_STAGE_WATCH_AFTER_PAINT,
- stage_painted);
- break;
- }
-}
-
-static void
-on_monitors_changed (MetaMonitorManager *monitor_manager,
- MetaScreenCastMonitorStreamSrc *monitor_src)
-{
- reattach_watches (monitor_src);
-}
-
-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);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
- MetaScreenCastStream *stream;
-
- 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:
- monitor_src->position_invalidated_handler_id =
- g_signal_connect_after (cursor_tracker, "position-invalidated",
- G_CALLBACK (pointer_position_invalidated),
- monitor_src);
- monitor_src->cursor_changed_handler_id =
- g_signal_connect_after (cursor_tracker, "cursor-changed",
- G_CALLBACK (cursor_changed),
- monitor_src);
- meta_cursor_tracker_track_position (cursor_tracker);
- break;
- case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
- break;
- case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
- inhibit_hw_cursor (monitor_src);
- meta_cursor_tracker_track_position (cursor_tracker);
- break;
- }
-
- reattach_watches (monitor_src);
- g_signal_connect_object (monitor_manager, "monitors-changed-internal",
- G_CALLBACK (on_monitors_changed),
- monitor_src, 0);
-
- clutter_actor_queue_redraw (CLUTTER_ACTOR (get_stage (monitor_src)));
-}
-
-static void
-meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src)
-{
- MetaScreenCastMonitorStreamSrc *monitor_src =
- META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
- MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (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->position_invalidated_handler_id,
- cursor_tracker);
- g_clear_signal_handler (&monitor_src->cursor_changed_handler_id,
- cursor_tracker);
-
- switch (meta_screen_cast_stream_get_cursor_mode (stream))
- {
- case META_SCREEN_CAST_CURSOR_MODE_METADATA:
- case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
- meta_cursor_tracker_untrack_position (cursor_tracker);
- break;
- case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
- break;
- }
-}
-
-static void
-maybe_paint_cursor_sprite (MetaScreenCastMonitorStreamSrc *monitor_src,
- int width,
- int height,
- int stride,
- uint8_t *data)
-{
- MetaBackend *backend = get_backend (monitor_src);
- MetaCursorRenderer *cursor_renderer =
- meta_backend_get_cursor_renderer (backend);
- MetaCursorSprite *cursor_sprite;
- CoglTexture *sprite_texture;
- int sprite_width, sprite_height, sprite_stride;
- float sprite_scale;
- uint8_t *sprite_data;
- cairo_surface_t *sprite_surface;
- graphene_rect_t sprite_rect;
- cairo_surface_t *surface;
- cairo_t *cr;
-
- if (!is_cursor_in_stream (monitor_src))
- return;
-
- cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
- if (!cursor_sprite)
- return;
-
- if (meta_cursor_renderer_is_overlay_visible (cursor_renderer))
- return;
-
- sprite_rect = meta_cursor_renderer_calculate_rect (cursor_renderer,
- cursor_sprite);
- sprite_texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
- sprite_width = cogl_texture_get_width (sprite_texture);
- sprite_height = cogl_texture_get_height (sprite_texture);
- sprite_stride = sprite_width * 4;
- sprite_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite);
- sprite_data = g_new0 (uint8_t, sprite_stride * sprite_height);
- cogl_texture_get_data (sprite_texture,
- CLUTTER_CAIRO_FORMAT_ARGB32,
- sprite_stride,
- sprite_data);
- sprite_surface = cairo_image_surface_create_for_data (sprite_data,
- CAIRO_FORMAT_ARGB32,
- sprite_width,
- sprite_height,
- sprite_stride);
- cairo_surface_set_device_scale (sprite_surface, sprite_scale, sprite_scale);
-
- surface = cairo_image_surface_create_for_data (data,
- CAIRO_FORMAT_ARGB32,
- width, height, stride);
-
- cr = cairo_create (surface);
- cairo_set_source_surface (cr, sprite_surface,
- sprite_rect.origin.x,
- sprite_rect.origin.y);
- cairo_paint (cr);
- cairo_destroy (cr);
- cairo_surface_destroy (sprite_surface);
- cairo_surface_destroy (surface);
- g_free (sprite_data);
-}
-
-static gboolean
-meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
- int width,
- int height,
- int stride,
- uint8_t *data,
- GError **error)
-{
- MetaScreenCastMonitorStreamSrc *monitor_src =
- META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
- MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
- ClutterStage *stage;
- MetaMonitor *monitor;
- MetaLogicalMonitor *logical_monitor;
- float scale;
-
- monitor = get_monitor (monitor_src);
- logical_monitor = meta_monitor_get_logical_monitor (monitor);
- stage = get_stage (monitor_src);
-
- if (meta_is_stage_views_scaled ())
- scale = meta_logical_monitor_get_scale (logical_monitor);
- else
- scale = 1.0;
-
- clutter_stage_capture_into (stage, &logical_monitor->rect, scale, data, stride);
-
- switch (meta_screen_cast_stream_get_cursor_mode (stream))
- {
- case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
- maybe_paint_cursor_sprite (monitor_src, width, height, stride, data);
- break;
- case META_SCREEN_CAST_CURSOR_MODE_METADATA:
- case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
- break;
- }
-
- 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;
- CoglScanout *scanout;
- MetaRectangle view_layout;
- int x, y;
-
- clutter_stage_view_get_layout (view, &view_layout);
-
- if (!meta_rectangle_overlap (&logical_monitor_layout, &view_layout))
- continue;
-
- x = (int) roundf ((view_layout.x - logical_monitor_layout.x) * view_scale);
- y = (int) roundf ((view_layout.y - logical_monitor_layout.y) * view_scale);
-
- scanout = clutter_stage_view_peek_scanout (view);
- if (scanout)
- {
- if (!cogl_scanout_blit_to_framebuffer (scanout,
- framebuffer,
- x, y,
- error))
- return FALSE;
- }
- else
- {
- view_framebuffer = clutter_stage_view_get_framebuffer (view);
- 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_flush (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);
- MetaCursorTracker *cursor_tracker =
- meta_backend_get_cursor_tracker (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 (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) ||
- !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;
-
- meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
- 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_inhibited (MetaHwCursorInhibitor *inhibitor)
-{
- 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_inhibited =
- meta_screen_cast_monitor_stream_src_is_cursor_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
deleted file mode 100644
index 7417a81e0..000000000
--- a/src/backends/meta-screen-cast-monitor-stream-src.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- 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
deleted file mode 100644
index ada9bc95f..000000000
--- a/src/backends/meta-screen-cast-monitor-stream.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/* -*- 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,
- MetaScreenCastFlag flags,
- GError **error)
-{
- MetaBackend *backend = meta_monitor_get_backend (monitor);
- 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,
- "flags", flags,
- "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 gboolean
-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;
- double scale;
-
- logical_monitor_layout =
- meta_logical_monitor_get_layout (monitor_stream->logical_monitor);
-
- if (meta_is_stage_views_scaled ())
- scale = meta_logical_monitor_get_scale (monitor_stream->logical_monitor);
- else
- scale = 1.0;
-
- *x = logical_monitor_layout.x + stream_x / scale;
- *y = logical_monitor_layout.y + stream_y / scale;
-
- return TRUE;
-}
-
-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
deleted file mode 100644
index 04c48e980..000000000
--- a/src/backends/meta-screen-cast-monitor-stream.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- 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,
- MetaScreenCastFlag flags,
- 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
deleted file mode 100644
index 60fffdea5..000000000
--- a/src/backends/meta-screen-cast-session.c
+++ /dev/null
@@ -1,825 +0,0 @@
-/* -*- 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-area-stream.h"
-#include "backends/meta-screen-cast-monitor-stream.h"
-#include "backends/meta-screen-cast-stream.h"
-#include "backends/meta-screen-cast-virtual-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;
-}
-
-MetaScreenCastSessionType
-meta_screen_cast_session_get_session_type (MetaScreenCastSession *session)
-{
- return session->session_type;
-}
-
-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;
- gboolean is_recording;
- MetaScreenCastFlag flags;
- 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;
- }
- }
-
- if (!g_variant_lookup (properties_variant, "is-recording", "b", &is_recording))
- is_recording = FALSE;
-
- stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
-
- flags = META_SCREEN_CAST_FLAG_NONE;
- if (is_recording)
- flags |= META_SCREEN_CAST_FLAG_IS_RECORDING;
-
- monitor_stream = meta_screen_cast_monitor_stream_new (session,
- connection,
- monitor,
- stage,
- cursor_mode,
- flags,
- &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;
- gboolean is_recording;
- MetaScreenCastFlag flags;
- 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;
- }
- }
-
- if (!g_variant_lookup (properties_variant, "is-recording", "b", &is_recording))
- is_recording = FALSE;
-
- interface_skeleton = G_DBUS_INTERFACE_SKELETON (skeleton);
- connection = g_dbus_interface_skeleton_get_connection (interface_skeleton);
-
- flags = META_SCREEN_CAST_FLAG_NONE;
- if (is_recording)
- flags |= META_SCREEN_CAST_FLAG_IS_RECORDING;
-
- window_stream = meta_screen_cast_window_stream_new (session,
- connection,
- window,
- cursor_mode,
- flags,
- &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 gboolean
-handle_record_area (MetaDBusScreenCastSession *skeleton,
- GDBusMethodInvocation *invocation,
- int x,
- int y,
- int width,
- int height,
- GVariant *properties_variant)
-{
- MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (skeleton);
- GDBusInterfaceSkeleton *interface_skeleton;
- GDBusConnection *connection;
- MetaBackend *backend;
- ClutterStage *stage;
- MetaScreenCastCursorMode cursor_mode;
- gboolean is_recording;
- MetaScreenCastFlag flags;
- g_autoptr (GError) error = NULL;
- MetaRectangle rect;
- MetaScreenCastAreaStream *area_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 (!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;
- }
- }
-
- if (!g_variant_lookup (properties_variant, "is-recording", "b", &is_recording))
- is_recording = FALSE;
-
- interface_skeleton = G_DBUS_INTERFACE_SKELETON (skeleton);
- connection = g_dbus_interface_skeleton_get_connection (interface_skeleton);
- backend = meta_screen_cast_get_backend (session->screen_cast);
- stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
-
- flags = META_SCREEN_CAST_FLAG_NONE;
- if (is_recording)
- flags |= META_SCREEN_CAST_FLAG_IS_RECORDING;
-
- rect = (MetaRectangle) {
- .x = x,
- .y = y,
- .width = width,
- .height = height
- };
- area_stream = meta_screen_cast_area_stream_new (session,
- connection,
- &rect,
- stage,
- cursor_mode,
- flags,
- &error);
- if (!area_stream)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Failed to record area: %s",
- error->message);
- return TRUE;
- }
-
- stream = META_SCREEN_CAST_STREAM (area_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_area (skeleton,
- invocation,
- stream_path);
-
- return TRUE;
-}
-
-static gboolean
-handle_record_virtual (MetaDBusScreenCastSession *skeleton,
- GDBusMethodInvocation *invocation,
- GVariant *properties_variant)
-{
- MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (skeleton);
- GDBusInterfaceSkeleton *interface_skeleton;
- GDBusConnection *connection;
- MetaScreenCastCursorMode cursor_mode;
- gboolean is_platform;
- MetaScreenCastFlag flags;
- g_autoptr (GError) error = NULL;
- MetaScreenCastVirtualStream *virtual_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 (!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;
- }
- }
-
- if (!g_variant_lookup (properties_variant, "is-platform", "b", &is_platform))
- is_platform = FALSE;
-
- interface_skeleton = G_DBUS_INTERFACE_SKELETON (skeleton);
- connection = g_dbus_interface_skeleton_get_connection (interface_skeleton);
-
- flags = META_SCREEN_CAST_FLAG_NONE;
- if (is_platform)
- flags |= META_SCREEN_CAST_FLAG_IS_PLATFORM;
-
- virtual_stream = meta_screen_cast_virtual_stream_new (session,
- connection,
- cursor_mode,
- flags,
- &error);
- if (!virtual_stream)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Failed to record virtual: %s",
- error->message);
- return TRUE;
- }
-
- stream = META_SCREEN_CAST_STREAM (virtual_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_virtual (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;
- iface->handle_record_area = handle_record_area;
- iface->handle_record_virtual = handle_record_virtual;
-}
-
-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 gboolean
-meta_screen_cast_session_is_recording (MetaScreenCastSession *session)
-{
- GList *l;
-
- if (!session->streams)
- return FALSE;
-
- for (l = session->streams; l; l = l->next)
- {
- MetaScreenCastStream *stream = l->data;
- MetaScreenCastFlag flags;
-
- flags = meta_screen_cast_stream_get_flags (stream);
- if (!(flags & META_SCREEN_CAST_FLAG_IS_RECORDING))
- return FALSE;
- }
-
- return TRUE;
-}
-
-static MetaScreenCastSessionHandle *
-meta_screen_cast_session_handle_new (MetaScreenCastSession *session)
-{
- MetaScreenCastSessionHandle *handle;
- gboolean is_recording;
-
- is_recording = meta_screen_cast_session_is_recording (session);
- handle = g_object_new (META_TYPE_SCREEN_CAST_SESSION_HANDLE,
- "is-recording", is_recording,
- 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
deleted file mode 100644
index 46bde5eb9..000000000
--- a/src/backends/meta-screen-cast-session.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- 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);
-
-MetaScreenCastSessionType meta_screen_cast_session_get_session_type (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
deleted file mode 100644
index c3ede8aea..000000000
--- a/src/backends/meta-screen-cast-stream-src.c
+++ /dev/null
@@ -1,1237 +0,0 @@
-/* -*- 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)
-
-#define DEFAULT_SIZE SPA_RECTANGLE (1280, 720)
-#define MIN_SIZE SPA_RECTANGLE (1, 1)
-#define MAX_SIZE SPA_RECTANGLE (16384, 16386)
-
-#define DEFAULT_FRAME_RATE SPA_FRACTION (60, 1)
-#define MIN_FRAME_RATE SPA_FRACTION (1, 1)
-#define MAX_FRAME_RATE SPA_FRACTION (1000, 1)
-
-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;
-} 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 gboolean
-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);
-
- return 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,
- int width,
- int height,
- int stride,
- uint8_t *data,
- GError **error)
-{
- MetaScreenCastStreamSrcClass *klass =
- META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
-
- return klass->record_to_buffer (src, width, height, stride, 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))
- {
- g_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);
- g_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)
- {
- int width = priv->video_format.size.width;
- int height = priv->video_format.size.height;
- int stride = priv->video_stride;
-
- return meta_screen_cast_stream_src_record_to_buffer (src,
- width,
- height,
- stride,
- 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)
- {
- meta_topic (META_DEBUG_SCREEN_CAST,
- "Couldn't dequeue a buffer from pipewire stream (node id %u), "
- "maybe your encoding is too slow?",
- pw_stream_get_node_id (priv->pipewire_stream));
- 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->video_format.size.width;
- spa_meta_video_crop->region.size.height =
- priv->video_format.size.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;
-}
-
-void
-meta_screen_cast_stream_src_close (MetaScreenCastStreamSrc *src)
-{
- 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);
- priv->emit_closed_after_dispatch = TRUE;
-}
-
-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);
- meta_screen_cast_stream_src_close (src);
- 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);
- MetaScreenCastStreamSrcClass *klass =
- META_SCREEN_CAST_STREAM_SRC_GET_CLASS (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 (384, 384)));
-
- pw_stream_update_params (priv->pipewire_stream, params, G_N_ELEMENTS (params));
-
- if (klass->notify_params_updated)
- klass->notify_params_updated (src, &priv->video_format);
-}
-
-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);
- 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);
- 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;
- spa_data[0].data = NULL;
-
- if (spa_data[0].type & (1 << SPA_DATA_DmaBuf))
- {
- dmabuf_handle =
- meta_screen_cast_create_dma_buf_handle (screen_cast,
- priv->video_format.size.width,
- priv->video_format.size.height);
- }
- else
- {
- dmabuf_handle = NULL;
- }
-
- 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);
-
- g_hash_table_insert (priv->dmabuf_handles,
- GINT_TO_POINTER (spa_data[0].fd),
- dmabuf_handle);
- }
- else
- {
- unsigned int seals;
-
- if (!(spa_data[0].type & (1 << SPA_DATA_MemFd)))
- {
- g_critical ("No supported PipeWire stream buffer data type could "
- "be negotiated");
- return;
- }
-
- /* 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)
- {
- close (spa_data[0].fd);
- spa_data[0].fd = -1;
- 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)
- {
- close (spa_data[0].fd);
- spa_data[0].fd = -1;
- 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)
- {
- g_warn_if_fail (spa_data[0].fd > 0 || !spa_data[0].data);
-
- if (spa_data[0].fd > 0)
- {
- 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));
- int width;
- int height;
- float frame_rate;
- 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;
- }
-
- if (meta_screen_cast_stream_src_get_specs (src, &width, &height, &frame_rate))
- {
- MetaFraction frame_rate_fraction;
- struct spa_fraction max_framerate;
- struct spa_fraction min_framerate;
-
- 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 (width,
- 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));
- }
- else
- {
- 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_CHOICE_RANGE_Rectangle (&DEFAULT_SIZE,
- &MIN_SIZE,
- &MAX_SIZE),
- SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction (&SPA_FRACTION (0, 1)),
- SPA_FORMAT_VIDEO_maxFramerate,
- SPA_POD_CHOICE_RANGE_Fraction (&DEFAULT_FRAME_RATE,
- &MIN_FRAME_RATE,
- &MAX_FRAME_RATE));
- }
-
- 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;
-
- g_warning ("pipewire remote error: id:%u %s", id, message);
-
- if (id == PW_ID_CORE && res == -EPIPE)
- meta_screen_cast_stream_src_close (src);
-}
-
-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
deleted file mode 100644
index 456b5bd97..000000000
--- a/src/backends/meta-screen-cast-stream-src.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -*- 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;
-
- gboolean (* 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,
- int width,
- int height,
- int stride,
- 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 (* notify_params_updated) (MetaScreenCastStreamSrc *src,
- struct spa_video_info_raw *video_format);
-};
-
-void meta_screen_cast_stream_src_close (MetaScreenCastStreamSrc *src);
-
-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
deleted file mode 100644
index b8ab5abd5..000000000
--- a/src/backends/meta-screen-cast-stream.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/* -*- 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"
-
-#include "meta-private-enum-types.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,
- PROP_FLAGS,
-};
-
-enum
-{
- CLOSED,
-
- N_SIGNALS
-};
-
-static guint signals[N_SIGNALS];
-
-typedef struct _MetaScreenCastStreamPrivate
-{
- MetaScreenCastSession *session;
-
- GDBusConnection *connection;
- char *object_path;
-
- MetaScreenCastCursorMode cursor_mode;
- MetaScreenCastFlag flags;
-
- 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;
-}
-
-MetaScreenCastStreamSrc *
-meta_screen_cast_stream_get_src (MetaScreenCastStream *stream)
-{
- MetaScreenCastStreamPrivate *priv =
- meta_screen_cast_stream_get_instance_private (stream);
-
- return priv->src;
-}
-
-gboolean
-meta_screen_cast_stream_transform_position (MetaScreenCastStream *stream,
- double stream_x,
- double stream_y,
- double *x,
- double *y)
-{
- MetaScreenCastStreamClass *klass = META_SCREEN_CAST_STREAM_GET_CLASS (stream);
-
- return klass->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;
-}
-
-MetaScreenCastFlag
-meta_screen_cast_stream_get_flags (MetaScreenCastStream *stream)
-{
- MetaScreenCastStreamPrivate *priv =
- meta_screen_cast_stream_get_instance_private (stream);
-
- return priv->flags;
-}
-
-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;
- case PROP_FLAGS:
- priv->flags = g_value_get_flags (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;
- case PROP_FLAGS:
- g_value_set_flags (value, priv->flags);
- 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 (&parameters_builder, G_VARIANT_TYPE_VARDICT);
- meta_screen_cast_stream_set_parameters (stream, &parameters_builder);
-
- parameters_variant = g_variant_builder_end (&parameters_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));
-
- g_object_class_install_property (object_class,
- PROP_FLAGS,
- g_param_spec_flags ("flags",
- "flags",
- "Screen cast flags",
- META_TYPE_SCREEN_CAST_FLAG,
- META_SCREEN_CAST_FLAG_NONE,
- 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
deleted file mode 100644
index 3424def20..000000000
--- a/src/backends/meta-screen-cast-stream.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- 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);
- gboolean (* 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);
-
-MetaScreenCastStreamSrc * meta_screen_cast_stream_get_src (MetaScreenCastStream *stream);
-
-gboolean 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);
-
-MetaScreenCastFlag meta_screen_cast_stream_get_flags (MetaScreenCastStream *stream);
-
-#endif /* META_SCREEN_CAST_STREAM_H */
diff --git a/src/backends/meta-screen-cast-virtual-stream-src.c b/src/backends/meta-screen-cast-virtual-stream-src.c
deleted file mode 100644
index 47a917da9..000000000
--- a/src/backends/meta-screen-cast-virtual-stream-src.c
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * Copyright (C) 2021 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-virtual-stream-src.h"
-
-#include "backends/meta-crtc-mode.h"
-#include "backends/meta-cursor-tracker-private.h"
-#include "backends/meta-screen-cast-session.h"
-#include "backends/meta-stage-private.h"
-#include "backends/meta-virtual-monitor.h"
-#include "core/boxes-private.h"
-
-struct _MetaScreenCastVirtualStreamSrc
-{
- MetaScreenCastStreamSrc parent;
-
- MetaVirtualMonitor *virtual_monitor;
-
- gboolean cursor_bitmap_invalid;
- gboolean hw_cursor_inhibited;
-
- MetaStageWatch *watch;
-
- gulong position_invalidated_handler_id;
- gulong cursor_changed_handler_id;
-
- gulong monitors_changed_handler_id;
-};
-
-static void
-hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaScreenCastVirtualStreamSrc,
- meta_screen_cast_virtual_stream_src,
- META_TYPE_SCREEN_CAST_STREAM_SRC,
- G_IMPLEMENT_INTERFACE (META_TYPE_HW_CURSOR_INHIBITOR,
- hw_cursor_inhibitor_iface_init))
-
-static gboolean
-meta_screen_cast_virtual_stream_src_get_specs (MetaScreenCastStreamSrc *src,
- int *width,
- int *height,
- float *frame_rate)
-{
- return FALSE;
-}
-
-static MetaBackend *
-backend_from_src (MetaScreenCastStreamSrc *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 ClutterStageView *
-view_from_src (MetaScreenCastStreamSrc *src)
-{
- MetaScreenCastVirtualStreamSrc *virtual_src =
- META_SCREEN_CAST_VIRTUAL_STREAM_SRC (src);
- MetaVirtualMonitor *virtual_monitor = virtual_src->virtual_monitor;
- MetaCrtc *crtc = meta_virtual_monitor_get_crtc (virtual_monitor);
- MetaRenderer *renderer = meta_backend_get_renderer (backend_from_src (src));
- MetaRendererView *view = meta_renderer_get_view_for_crtc (renderer, crtc);
-
- return CLUTTER_STAGE_VIEW (view);
-}
-
-static ClutterStage *
-stage_from_src (MetaScreenCastStreamSrc *src)
-{
- return CLUTTER_STAGE (meta_backend_get_stage (backend_from_src (src)));
-}
-
-static gboolean
-is_redraw_queued (MetaScreenCastVirtualStreamSrc *virtual_src)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (virtual_src);
-
- return clutter_stage_is_redraw_queued_on_view (stage_from_src (src),
- view_from_src (src));
-}
-
-ClutterStageView *
-meta_screen_cast_virtual_stream_src_get_view (MetaScreenCastVirtualStreamSrc *virtual_src)
-{
- return view_from_src (META_SCREEN_CAST_STREAM_SRC (virtual_src));
-}
-
-static void
-sync_cursor_state (MetaScreenCastVirtualStreamSrc *virtual_src)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (virtual_src);
- MetaScreenCastRecordFlag flags;
-
- if (is_redraw_queued (virtual_src))
- 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
-pointer_position_invalidated (MetaCursorTracker *cursor_tracker,
- MetaScreenCastVirtualStreamSrc *virtual_src)
-{
- sync_cursor_state (virtual_src);
-}
-
-static void
-cursor_changed (MetaCursorTracker *cursor_tracker,
- MetaScreenCastVirtualStreamSrc *virtual_src)
-{
- virtual_src->cursor_bitmap_invalid = TRUE;
- sync_cursor_state (virtual_src);
-}
-
-static void
-inhibit_hw_cursor (MetaScreenCastVirtualStreamSrc *virtual_src)
-{
- MetaHwCursorInhibitor *inhibitor;
- MetaBackend *backend;
-
- g_return_if_fail (!virtual_src->hw_cursor_inhibited);
-
- backend = backend_from_src (META_SCREEN_CAST_STREAM_SRC (virtual_src));
- inhibitor = META_HW_CURSOR_INHIBITOR (virtual_src);
- meta_backend_add_hw_cursor_inhibitor (backend, inhibitor);
-
- virtual_src->hw_cursor_inhibited = TRUE;
-}
-
-static void
-uninhibit_hw_cursor (MetaScreenCastVirtualStreamSrc *virtual_src)
-{
- MetaHwCursorInhibitor *inhibitor;
- MetaBackend *backend;
-
- g_return_if_fail (virtual_src->hw_cursor_inhibited);
-
- backend = backend_from_src (META_SCREEN_CAST_STREAM_SRC (virtual_src));
- inhibitor = META_HW_CURSOR_INHIBITOR (virtual_src);
- meta_backend_remove_hw_cursor_inhibitor (backend, inhibitor);
-
- virtual_src->hw_cursor_inhibited = FALSE;
-}
-
-static void
-actors_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 void
-add_watch (MetaScreenCastVirtualStreamSrc *virtual_src)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (virtual_src);
- MetaStage *meta_stage = META_STAGE (stage_from_src (src));
-
- g_return_if_fail (!virtual_src->watch);
-
- virtual_src->watch = meta_stage_watch_view (meta_stage,
- view_from_src (src),
- META_STAGE_WATCH_AFTER_PAINT,
- actors_painted,
- virtual_src);
-}
-
-static void
-on_monitors_changed (MetaMonitorManager *monitor_manager,
- MetaScreenCastVirtualStreamSrc *virtual_src)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (virtual_src);
- MetaStage *stage = META_STAGE (stage_from_src (src));
-
- meta_stage_remove_watch (stage, virtual_src->watch);
- virtual_src->watch = NULL;
- add_watch (virtual_src);
-}
-
-static void
-init_record_callbacks (MetaScreenCastVirtualStreamSrc *virtual_src)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (virtual_src);
- MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
- MetaBackend *backend = backend_from_src (src);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- MetaCursorTracker *cursor_tracker =
- meta_backend_get_cursor_tracker (backend);
-
- switch (meta_screen_cast_stream_get_cursor_mode (stream))
- {
- case META_SCREEN_CAST_CURSOR_MODE_METADATA:
- virtual_src->position_invalidated_handler_id =
- g_signal_connect_after (cursor_tracker, "position-invalidated",
- G_CALLBACK (pointer_position_invalidated),
- virtual_src);
- virtual_src->cursor_changed_handler_id =
- g_signal_connect_after (cursor_tracker, "cursor-changed",
- G_CALLBACK (cursor_changed),
- virtual_src);
- G_GNUC_FALLTHROUGH;
- case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
- case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
- add_watch (virtual_src);
- break;
- }
-
- if (meta_screen_cast_stream_get_cursor_mode (stream) ==
- META_SCREEN_CAST_CURSOR_MODE_EMBEDDED)
- inhibit_hw_cursor (virtual_src);
-
- virtual_src->monitors_changed_handler_id =
- g_signal_connect (monitor_manager, "monitors-changed-internal",
- G_CALLBACK (on_monitors_changed),
- virtual_src);
-}
-
-static void
-meta_screen_cast_virtual_stream_src_enable (MetaScreenCastStreamSrc *src)
-{
- MetaScreenCastVirtualStreamSrc *virtual_src =
- META_SCREEN_CAST_VIRTUAL_STREAM_SRC (src);
- MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
- MetaBackend *backend = backend_from_src (src);
- MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
-
- switch (meta_screen_cast_stream_get_cursor_mode (stream))
- {
- case META_SCREEN_CAST_CURSOR_MODE_METADATA:
- case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
- meta_cursor_tracker_track_position (cursor_tracker);
- break;
- case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
- break;
- }
-
- init_record_callbacks (virtual_src);
- clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage_from_src (src)),
- NULL);
- clutter_stage_schedule_update (stage_from_src (src));
-}
-
-static void
-meta_screen_cast_virtual_stream_src_disable (MetaScreenCastStreamSrc *src)
-{
- MetaScreenCastVirtualStreamSrc *virtual_src =
- META_SCREEN_CAST_VIRTUAL_STREAM_SRC (src);
- MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
- MetaBackend *backend = backend_from_src (src);
- MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
-
- if (virtual_src->hw_cursor_inhibited)
- uninhibit_hw_cursor (virtual_src);
-
- if (virtual_src->watch)
- {
- meta_stage_remove_watch (META_STAGE (stage_from_src (src)),
- virtual_src->watch);
- virtual_src->watch = NULL;
- }
-
- g_clear_signal_handler (&virtual_src->position_invalidated_handler_id,
- cursor_tracker);
- g_clear_signal_handler (&virtual_src->cursor_changed_handler_id,
- cursor_tracker);
-
- g_clear_signal_handler (&virtual_src->monitors_changed_handler_id,
- monitor_manager);
-
- switch (meta_screen_cast_stream_get_cursor_mode (stream))
- {
- case META_SCREEN_CAST_CURSOR_MODE_METADATA:
- case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
- meta_cursor_tracker_untrack_position (cursor_tracker);
- break;
- case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
- break;
- }
-
- g_clear_object (&virtual_src->virtual_monitor);
-}
-
-static gboolean
-meta_screen_cast_virtual_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
- int width,
- int height,
- int stride,
- uint8_t *data,
- GError **error)
-{
- clutter_stage_capture_view_into (stage_from_src (src),
- view_from_src (src),
- NULL,
- data,
- stride);
-
- return TRUE;
-}
-
-static gboolean
-meta_screen_cast_virtual_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
- CoglFramebuffer *framebuffer,
- GError **error)
-{
- ClutterStageView *view;
- CoglFramebuffer *view_framebuffer;
-
- view = view_from_src (src);
- view_framebuffer = clutter_stage_view_get_framebuffer (view);
- if (!cogl_blit_framebuffer (view_framebuffer,
- framebuffer,
- 0, 0,
- 0, 0,
- cogl_framebuffer_get_width (view_framebuffer),
- cogl_framebuffer_get_height (view_framebuffer),
- error))
- return FALSE;
-
- cogl_framebuffer_flush (framebuffer);
- return TRUE;
-}
-
-static void
-meta_screen_cast_virtual_stream_record_follow_up (MetaScreenCastStreamSrc *src)
-{
- MetaRectangle damage;
-
- clutter_stage_view_get_layout (view_from_src (src), &damage);
- damage.width = 1;
- damage.height = 1;
-
- clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage_from_src (src)),
- &damage);
-}
-
-static gboolean
-is_cursor_in_stream (MetaScreenCastVirtualStreamSrc *virtual_src)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (virtual_src);
- MetaBackend *backend = backend_from_src (src);
- MetaCursorRenderer *cursor_renderer =
- meta_backend_get_cursor_renderer (backend);
- ClutterStageView *stage_view = view_from_src (src);
- MetaRectangle view_layout;
- graphene_rect_t view_rect;
- MetaCursorSprite *cursor_sprite;
-
- clutter_stage_view_get_layout (stage_view, &view_layout);
- view_rect = meta_rectangle_to_graphene_rect (&view_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, &view_rect, NULL);
- }
- else
- {
- MetaCursorTracker *cursor_tracker =
- meta_backend_get_cursor_tracker (backend);
- graphene_point_t cursor_position;
-
- meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
- return graphene_rect_contains_point (&view_rect,
- &cursor_position);
- }
-}
-
-static void
-meta_screen_cast_virtual_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
- struct spa_meta_cursor *spa_meta_cursor)
-{
- MetaScreenCastVirtualStreamSrc *virtual_src =
- META_SCREEN_CAST_VIRTUAL_STREAM_SRC (src);
- MetaBackend *backend = backend_from_src (src);
- MetaCursorRenderer *cursor_renderer =
- meta_backend_get_cursor_renderer (backend);
- MetaCursorTracker *cursor_tracker =
- meta_backend_get_cursor_tracker (backend);
- MetaCursorSprite *cursor_sprite;
- ClutterStageView *stage_view;
- MetaRectangle view_layout;
- float view_scale;
- graphene_rect_t view_rect;
- graphene_point_t cursor_position;
- int x, y;
-
- cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
-
- if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) ||
- !is_cursor_in_stream (virtual_src))
- {
- meta_screen_cast_stream_src_unset_cursor_metadata (src,
- spa_meta_cursor);
- return;
- }
-
- stage_view = view_from_src (src);
- clutter_stage_view_get_layout (stage_view, &view_layout);
- view_rect = meta_rectangle_to_graphene_rect (&view_layout);
- view_scale = clutter_stage_view_get_scale (stage_view);
-
- meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
- cursor_position.x -= view_rect.origin.x;
- cursor_position.y -= view_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 (virtual_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);
- }
-
- virtual_src->cursor_bitmap_invalid = FALSE;
- }
- else
- {
- meta_screen_cast_stream_src_set_cursor_position_metadata (src,
- spa_meta_cursor,
- x, y);
- }
-}
-
-static MetaVirtualMonitor *
-create_virtual_monitor (MetaScreenCastVirtualStreamSrc *virtual_src,
- struct spa_video_info_raw *video_format,
- GError **error)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (virtual_src);
- MetaBackend *backend = backend_from_src (src);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- static int virtual_monitor_src_seq = 0;
- int width, height;
- float refresh_rate;
- g_autofree char *serial = NULL;
- g_autoptr (MetaVirtualMonitorInfo) info = NULL;
-
- width = video_format->size.width;
- height = video_format->size.height;
- refresh_rate = ((float) video_format->max_framerate.num /
- video_format->max_framerate.denom);
- serial = g_strdup_printf ("0x%.6x", ++virtual_monitor_src_seq);
- info = meta_virtual_monitor_info_new (width, height, refresh_rate,
- "MetaVendor",
- "Virtual remote monitor",
- serial);
- return meta_monitor_manager_create_virtual_monitor (monitor_manager,
- info,
- error);
-}
-
-static void
-ensure_virtual_monitor (MetaScreenCastVirtualStreamSrc *virtual_src,
- struct spa_video_info_raw *video_format)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (virtual_src);
- MetaBackend *backend = backend_from_src (src);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- g_autoptr (GError) error = NULL;
- MetaVirtualMonitor *virtual_monitor;
-
- virtual_monitor = virtual_src->virtual_monitor;
- if (virtual_monitor)
- {
- MetaCrtcMode *crtc_mode =
- meta_virtual_monitor_get_crtc_mode (virtual_monitor);
- const MetaCrtcModeInfo *mode_info = meta_crtc_mode_get_info (crtc_mode);
-
- if (mode_info->width == video_format->size.width &&
- mode_info->height == video_format->size.height)
- return;
-
- g_clear_object (&virtual_src->virtual_monitor);
- }
-
- virtual_monitor = create_virtual_monitor (virtual_src, video_format, &error);
- if (!virtual_monitor)
- {
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (virtual_src);
-
- g_warning ("Failed to create virtual monitor with size %dx%d: %s",
- video_format->size.width, video_format->size.height,
- error->message);
- meta_screen_cast_stream_src_close (src);
- return;
- }
- virtual_src->virtual_monitor = virtual_monitor;
-
- meta_monitor_manager_reload (monitor_manager);
-}
-
-static void
-meta_screen_cast_virtual_stream_src_notify_params_updated (MetaScreenCastStreamSrc *src,
- struct spa_video_info_raw *video_format)
-{
- MetaScreenCastVirtualStreamSrc *virtual_src =
- META_SCREEN_CAST_VIRTUAL_STREAM_SRC (src);
-
- ensure_virtual_monitor (virtual_src, video_format);
-}
-
-MetaScreenCastVirtualStreamSrc *
-meta_screen_cast_virtual_stream_src_new (MetaScreenCastVirtualStream *virtual_stream,
- GError **error)
-{
- return g_initable_new (META_TYPE_SCREEN_CAST_VIRTUAL_STREAM_SRC, NULL, error,
- "stream", virtual_stream,
- NULL);
-}
-
-static gboolean
-meta_screen_cast_virtual_stream_src_is_cursor_inhibited (MetaHwCursorInhibitor *inhibitor)
-{
- MetaScreenCastVirtualStreamSrc *virtual_src =
- META_SCREEN_CAST_VIRTUAL_STREAM_SRC (inhibitor);
-
- return is_cursor_in_stream (virtual_src);
-}
-
-static void
-hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface)
-{
- iface->is_cursor_inhibited =
- meta_screen_cast_virtual_stream_src_is_cursor_inhibited;
-}
-
-static void
-meta_screen_cast_virtual_stream_src_init (MetaScreenCastVirtualStreamSrc *virtual_src)
-{
-}
-
-static void
-meta_screen_cast_virtual_stream_src_class_init (MetaScreenCastVirtualStreamSrcClass *klass)
-{
- MetaScreenCastStreamSrcClass *src_class =
- META_SCREEN_CAST_STREAM_SRC_CLASS (klass);
-
- src_class->get_specs = meta_screen_cast_virtual_stream_src_get_specs;
- src_class->enable = meta_screen_cast_virtual_stream_src_enable;
- src_class->disable = meta_screen_cast_virtual_stream_src_disable;
- src_class->record_to_buffer =
- meta_screen_cast_virtual_stream_src_record_to_buffer;
- src_class->record_to_framebuffer =
- meta_screen_cast_virtual_stream_src_record_to_framebuffer;
- src_class->record_follow_up =
- meta_screen_cast_virtual_stream_record_follow_up;
- src_class->set_cursor_metadata =
- meta_screen_cast_virtual_stream_src_set_cursor_metadata;
- src_class->notify_params_updated =
- meta_screen_cast_virtual_stream_src_notify_params_updated;
-}
diff --git a/src/backends/meta-screen-cast-virtual-stream-src.h b/src/backends/meta-screen-cast-virtual-stream-src.h
deleted file mode 100644
index a891166bd..000000000
--- a/src/backends/meta-screen-cast-virtual-stream-src.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2021 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_VIRTUAL_STREAM_SRC_H
-#define META_SCREEN_CAST_VIRTUAL_STREAM_SRC_H
-
-#include "backends/meta-screen-cast-stream-src.h"
-#include "backends/meta-screen-cast-virtual-stream.h"
-
-#define META_TYPE_SCREEN_CAST_VIRTUAL_STREAM_SRC (meta_screen_cast_virtual_stream_src_get_type ())
-G_DECLARE_FINAL_TYPE (MetaScreenCastVirtualStreamSrc,
- meta_screen_cast_virtual_stream_src,
- META, SCREEN_CAST_VIRTUAL_STREAM_SRC,
- MetaScreenCastStreamSrc)
-
-MetaScreenCastVirtualStreamSrc * meta_screen_cast_virtual_stream_src_new (MetaScreenCastVirtualStream *virtual_stream,
- GError **error);
-
-ClutterStageView * meta_screen_cast_virtual_stream_src_get_view (MetaScreenCastVirtualStreamSrc *virtual_src);
-
-#endif /* META_SCREEN_CAST_VIRTUAL_STREAM_SRC_H */
diff --git a/src/backends/meta-screen-cast-virtual-stream.c b/src/backends/meta-screen-cast-virtual-stream.c
deleted file mode 100644
index 34dd2a00c..000000000
--- a/src/backends/meta-screen-cast-virtual-stream.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2021 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-virtual-stream.h"
-
-#include "backends/meta-screen-cast-virtual-stream-src.h"
-#include "backends/meta-virtual-monitor.h"
-
-
-struct _MetaScreenCastVirtualStream
-{
- MetaScreenCastStream parent;
-};
-
-G_DEFINE_TYPE (MetaScreenCastVirtualStream,
- meta_screen_cast_virtual_stream,
- META_TYPE_SCREEN_CAST_STREAM)
-
-MetaScreenCastVirtualStream *
-meta_screen_cast_virtual_stream_new (MetaScreenCastSession *session,
- GDBusConnection *connection,
- MetaScreenCastCursorMode cursor_mode,
- MetaScreenCastFlag flags,
- GError **error)
-{
- MetaScreenCastVirtualStream *virtual_stream;
-
- virtual_stream = g_initable_new (META_TYPE_SCREEN_CAST_VIRTUAL_STREAM,
- NULL,
- error,
- "session", session,
- "connection", connection,
- "cursor-mode", cursor_mode,
- "flags", flags,
- NULL);
- if (!virtual_stream)
- return NULL;
-
- return virtual_stream;
-}
-
-static MetaScreenCastStreamSrc *
-meta_screen_cast_virtual_stream_create_src (MetaScreenCastStream *stream,
- GError **error)
-{
- MetaScreenCastVirtualStream *virtual_stream =
- META_SCREEN_CAST_VIRTUAL_STREAM (stream);
- MetaScreenCastVirtualStreamSrc *virtual_stream_src;
-
- virtual_stream_src = meta_screen_cast_virtual_stream_src_new (virtual_stream,
- error);
- if (!virtual_stream_src)
- return NULL;
-
- return META_SCREEN_CAST_STREAM_SRC (virtual_stream_src);
-}
-
-static void
-meta_screen_cast_virtual_stream_set_parameters (MetaScreenCastStream *stream,
- GVariantBuilder *parameters_builder)
-{
-}
-
-static gboolean
-meta_screen_cast_virtual_stream_transform_position (MetaScreenCastStream *stream,
- double stream_x,
- double stream_y,
- double *x,
- double *y)
-{
- MetaScreenCastStreamSrc *src = meta_screen_cast_stream_get_src (stream);
- MetaScreenCastVirtualStreamSrc *virtual_src =
- META_SCREEN_CAST_VIRTUAL_STREAM_SRC (src);
- ClutterStageView *view;
- MetaRectangle view_layout;
-
- view = meta_screen_cast_virtual_stream_src_get_view (virtual_src);
- if (!view)
- return FALSE;
-
- clutter_stage_view_get_layout (view, &view_layout);
- *x = stream_x + view_layout.x;
- *y = stream_y + view_layout.y;
-
- return TRUE;
-}
-
-static void
-meta_screen_cast_virtual_stream_init (MetaScreenCastVirtualStream *virtual_stream)
-{
-}
-
-static void
-meta_screen_cast_virtual_stream_class_init (MetaScreenCastVirtualStreamClass *klass)
-{
- MetaScreenCastStreamClass *stream_class =
- META_SCREEN_CAST_STREAM_CLASS (klass);
-
- stream_class->create_src = meta_screen_cast_virtual_stream_create_src;
- stream_class->set_parameters = meta_screen_cast_virtual_stream_set_parameters;
- stream_class->transform_position = meta_screen_cast_virtual_stream_transform_position;
-}
diff --git a/src/backends/meta-screen-cast-virtual-stream.h b/src/backends/meta-screen-cast-virtual-stream.h
deleted file mode 100644
index 422db5e26..000000000
--- a/src/backends/meta-screen-cast-virtual-stream.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2021 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_VIRTUAL_STREAM_H
-#define META_SCREEN_CAST_VIRTUAL_STREAM_H
-
-#include "backends/meta-screen-cast-stream.h"
-
-#define META_TYPE_SCREEN_CAST_VIRTUAL_STREAM (meta_screen_cast_virtual_stream_get_type ())
-G_DECLARE_FINAL_TYPE (MetaScreenCastVirtualStream,
- meta_screen_cast_virtual_stream,
- META, SCREEN_CAST_VIRTUAL_STREAM,
- MetaScreenCastStream)
-
-MetaScreenCastVirtualStream * meta_screen_cast_virtual_stream_new (MetaScreenCastSession *session,
- GDBusConnection *connection,
- MetaScreenCastCursorMode cursor_mode,
- MetaScreenCastFlag flags,
- GError **error);
-
-MetaVirtualMonitor * meta_screen_cast_virtual_stream_get_virtual_monitor (MetaScreenCastVirtualStream *virtual_stream);
-
-#endif /* META_SCREEN_CAST_VIRTUAL_STREAM_H */
diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c
deleted file mode 100644
index 3fa932b4b..000000000
--- a/src/backends/meta-screen-cast-window-stream-src.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * 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-cursor-tracker-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 position_invalidated_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);
- MetaCursorTracker *cursor_tracker =
- meta_backend_get_cursor_tracker (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;
- meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
- 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);
- MetaCursorTracker *cursor_tracker =
- meta_backend_get_cursor_tracker (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;
- meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
- 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,
- int width,
- int height,
- int stride,
- uint8_t *data)
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
- MetaRectangle stream_rect;
- MetaScreenCastStream *stream;
-
- stream_rect = (MetaRectangle) {
- .width = width,
- .height = height,
- };
-
- 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 gboolean
-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;
-
- return TRUE;
-}
-
-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)
-
-{
- MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
- MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (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->position_invalidated_handler_id,
- cursor_tracker);
- g_clear_signal_handler (&window_src->cursor_changed_handler_id,
- cursor_tracker);
-
- switch (meta_screen_cast_stream_get_cursor_mode (stream))
- {
- case META_SCREEN_CAST_CURSOR_MODE_METADATA:
- case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
- meta_cursor_tracker_untrack_position (cursor_tracker);
- break;
- case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
- break;
- }
-}
-
-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_NONE;
- 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
-pointer_position_invalidated (MetaCursorTracker *cursor_tracker,
- 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->position_invalidated_handler_id =
- g_signal_connect_after (cursor_tracker, "position-invalidated",
- G_CALLBACK (pointer_position_invalidated),
- window_src);
- window_src->cursor_changed_handler_id =
- g_signal_connect_after (cursor_tracker, "cursor-changed",
- G_CALLBACK (cursor_changed),
- window_src);
- meta_cursor_tracker_track_position (cursor_tracker);
- 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,
- int width,
- int height,
- int stride,
- uint8_t *data,
- GError **error)
-{
- MetaScreenCastWindowStreamSrc *window_src =
- META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
-
- capture_into (window_src, width, height, stride, 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 = cogl_framebuffer_get_width (framebuffer);
- stream_rect.height = cogl_framebuffer_get_height (framebuffer);
-
- 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_flush (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);
- MetaCursorTracker *cursor_tracker =
- meta_backend_get_cursor_tracker (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);
- meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
-
- if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) ||
- !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
deleted file mode 100644
index 37f786979..000000000
--- a/src/backends/meta-screen-cast-window-stream-src.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 6f42a446e..000000000
--- a/src/backends/meta-screen-cast-window-stream.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * 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,
- MetaScreenCastFlag flags,
- GError **error)
-{
- return g_initable_new (META_TYPE_SCREEN_CAST_WINDOW_STREAM,
- NULL,
- error,
- "session", session,
- "connection", connection,
- "cursor-mode", cursor_mode,
- "flags", flags,
- "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 gboolean
-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);
- return TRUE;
-}
-
-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
deleted file mode 100644
index 0acceaac6..000000000
--- a/src/backends/meta-screen-cast-window-stream.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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,
- MetaScreenCastFlag flags,
- 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
deleted file mode 100644
index ab3e4ebe3..000000000
--- a/src/backends/meta-screen-cast-window.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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
deleted file mode 100644
index e149646ed..000000000
--- a/src/backends/meta-screen-cast-window.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 6162b8d27..000000000
--- a/src/backends/meta-screen-cast.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/* -*- 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 4
-
-struct _MetaScreenCast
-{
- MetaDBusScreenCastSkeleton parent;
-
- int dbus_name_id;
-
- int inhibit_count;
-
- GList *sessions;
-
- MetaDbusSessionWatcher *session_watcher;
- MetaBackend *backend;
-
- gboolean disable_dma_bufs;
-};
-
-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))
-
-void
-meta_screen_cast_inhibit (MetaScreenCast *screen_cast)
-{
- screen_cast->inhibit_count++;
- if (screen_cast->inhibit_count == 1)
- {
- while (screen_cast->sessions)
- {
- MetaScreenCastSession *session = screen_cast->sessions->data;
-
- meta_screen_cast_session_close (session);
- }
- }
-}
-
-void
-meta_screen_cast_uninhibit (MetaScreenCast *screen_cast)
-{
- g_return_if_fail (screen_cast->inhibit_count > 0);
-
- screen_cast->inhibit_count--;
-}
-
-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;
-}
-
-void
-meta_screen_cast_disable_dma_bufs (MetaScreenCast *screen_cast)
-{
- screen_cast->disable_dma_bufs = TRUE;
-}
-
-CoglDmaBufHandle *
-meta_screen_cast_create_dma_buf_handle (MetaScreenCast *screen_cast,
- int width,
- int height)
-{
- ClutterBackend *clutter_backend =
- meta_backend_get_clutter_backend (screen_cast->backend);
- CoglContext *cogl_context =
- clutter_backend_get_cogl_context (clutter_backend);
- CoglRenderer *cogl_renderer = cogl_context_get_renderer (cogl_context);
- g_autoptr (GError) error = NULL;
- CoglDmaBufHandle *dmabuf_handle;
-
- if (screen_cast->disable_dma_bufs)
- return NULL;
-
- dmabuf_handle = cogl_renderer_create_dma_buf (cogl_renderer,
- width, height,
- &error);
- if (!dmabuf_handle)
- {
- g_warning ("Failed to allocate DMA buffer, "
- "disabling DMA buffer based screen casting: %s",
- error->message);
- screen_cast->disable_dma_bufs = TRUE;
- return NULL;
- }
-
- return dmabuf_handle;
-}
-
-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;
-
- if (screen_cast->inhibit_count > 0)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_ACCESS_DENIED,
- "Session creation inhibited");
-
- return TRUE;
- }
-
- 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", error->message);
-}
-
-static void
-on_name_acquired (GDBusConnection *connection,
- const char *name,
- gpointer user_data)
-{
- g_info ("Acquired name %s", name);
-}
-
-static void
-on_name_lost (GDBusConnection *connection,
- const char *name,
- gpointer user_data)
-{
- g_warning ("Lost or failed to acquire name %s", 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);
-
- g_assert (!screen_cast->sessions);
-
- G_OBJECT_CLASS (meta_screen_cast_parent_class)->finalize (object);
-}
-
-static void
-on_prepare_shutdown (MetaBackend *backend,
- MetaScreenCast *screen_cast)
-{
- while (screen_cast->sessions)
- {
- MetaScreenCastSession *session = screen_cast->sessions->data;
-
- if (meta_screen_cast_session_get_session_type (session) !=
- META_SCREEN_CAST_SESSION_TYPE_REMOTE_DESKTOP)
- meta_screen_cast_session_close (session);
- }
-}
-
-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;
-
- g_signal_connect (backend, "prepare-shutdown",
- G_CALLBACK (on_prepare_shutdown),
- screen_cast);
-
- 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
deleted file mode 100644
index be297e28d..000000000
--- a/src/backends/meta-screen-cast.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- 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;
-
-typedef enum _MetaScreenCastFlag
-{
- META_SCREEN_CAST_FLAG_NONE = 0,
- META_SCREEN_CAST_FLAG_IS_RECORDING = 1 << 0,
- META_SCREEN_CAST_FLAG_IS_PLATFORM = 1 << 1,
-} MetaScreenCastFlag;
-
-#define META_TYPE_SCREEN_CAST (meta_screen_cast_get_type ())
-G_DECLARE_FINAL_TYPE (MetaScreenCast, meta_screen_cast,
- META, SCREEN_CAST,
- MetaDBusScreenCastSkeleton)
-
-void meta_screen_cast_inhibit (MetaScreenCast *screen_cast);
-
-void meta_screen_cast_uninhibit (MetaScreenCast *screen_cast);
-
-GDBusConnection * meta_screen_cast_get_connection (MetaScreenCast *screen_cast);
-
-MetaBackend * meta_screen_cast_get_backend (MetaScreenCast *screen_cast);
-
-void meta_screen_cast_disable_dma_bufs (MetaScreenCast *screen_cast);
-
-CoglDmaBufHandle * meta_screen_cast_create_dma_buf_handle (MetaScreenCast *screen_cast,
- int width,
- int height);
-
-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
deleted file mode 100644
index cde7e0439..000000000
--- a/src/backends/meta-settings-private.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- 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_DMA_BUF_SCREEN_SHARING = (1 << 3),
- META_EXPERIMENTAL_FEATURE_AUTOCLOSE_XWAYLAND = (1 << 4),
-} MetaExperimentalFeature;
-
-typedef enum _MetaXwaylandExtension
-{
- META_XWAYLAND_EXTENSION_SECURITY = (1 << 0),
- META_XWAYLAND_EXTENSION_XTEST = (1 << 1),
-} MetaXwaylandExtension;
-
-#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 **allow_list_patterns,
- GPtrArray **deny_list_patterns);
-
-gboolean meta_settings_are_xwayland_grabs_allowed (MetaSettings *settings);
-
-int meta_settings_get_xwayland_disable_extensions (MetaSettings *settings);
-
-#endif /* META_SETTINGS_PRIVATE_H */
diff --git a/src/backends/meta-settings.c b/src/backends/meta-settings.c
deleted file mode 100644
index 6a754d4e0..000000000
--- a/src/backends/meta-settings.c
+++ /dev/null
@@ -1,559 +0,0 @@
-/* -*- 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,
- 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;
-
- 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_allow_list_patterns;
- GPtrArray *xwayland_grab_deny_list_patterns;
-
- /* A bitmask of MetaXwaylandExtension enum */
- int xwayland_disable_extensions;
-};
-
-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);
- 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);
-}
-
-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;
-}
-
-void
-meta_settings_enable_experimental_feature (MetaSettings *settings,
- MetaExperimentalFeature feature)
-{
- g_assert (settings->experimental_features_overridden);
-
- settings->experimental_features |= feature;
-}
-
-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, "dma-buf-screen-sharing"))
- feature = META_EXPERIMENTAL_FEATURE_DMA_BUF_SCREEN_SHARING;
- else if (g_str_equal (feature_str, "autoclose-xwayland"))
- feature = META_EXPERIMENTAL_FEATURE_AUTOCLOSE_XWAYLAND;
-
- 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;
- *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 denied value */
- if (item[0] != '!')
- g_ptr_array_add (settings->xwayland_grab_allow_list_patterns,
- g_pattern_spec_new (item));
- else if (item[1] != 0)
- g_ptr_array_add (settings->xwayland_grab_deny_list_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_allow_list_patterns,
- g_ptr_array_unref);
- settings->xwayland_grab_allow_list_patterns =
- g_ptr_array_new_with_free_func ((GDestroyNotify) g_pattern_spec_free);
-
- g_clear_pointer (&settings->xwayland_grab_deny_list_patterns,
- g_ptr_array_unref);
- settings->xwayland_grab_deny_list_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
-update_xwayland_disable_extensions (MetaSettings *settings)
-{
- settings->xwayland_disable_extensions =
- g_settings_get_flags (settings->wayland_settings,
- "xwayland-disable-extension");
-}
-
-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);
- }
- else if (g_str_equal (key, "xwayland-disable-extension"))
- {
- update_xwayland_disable_extensions (settings);
- }
-}
-
-void
-meta_settings_get_xwayland_grab_patterns (MetaSettings *settings,
- GPtrArray **allow_list_patterns,
- GPtrArray **deny_list_patterns)
-{
- *allow_list_patterns = settings->xwayland_grab_allow_list_patterns;
- *deny_list_patterns = settings->xwayland_grab_deny_list_patterns;
-}
-
-gboolean
-meta_settings_are_xwayland_grabs_allowed (MetaSettings *settings)
-{
- return (settings->xwayland_allow_grabs);
-}
-
-int
-meta_settings_get_xwayland_disable_extensions (MetaSettings *settings)
-{
- return (settings->xwayland_disable_extensions);
-}
-
-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_pointer (&settings->xwayland_grab_allow_list_patterns,
- g_ptr_array_unref);
- g_clear_pointer (&settings->xwayland_grab_deny_list_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.gnome.desktop.interface");
- g_signal_connect (settings->interface_settings, "changed",
- G_CALLBACK (interface_settings_changed),
- settings);
- settings->mutter_settings = g_settings_new ("org.gnome.mutter");
- g_signal_connect (settings->mutter_settings, "changed",
- G_CALLBACK (mutter_settings_changed),
- settings);
- settings->wayland_settings = g_settings_new ("org.gnome.mutter.wayland");
- g_signal_connect (settings->wayland_settings, "changed",
- G_CALLBACK (wayland_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);
- update_xwayland_disable_extensions (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[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-impl-private.h b/src/backends/meta-stage-impl-private.h
deleted file mode 100644
index ab3e0d391..000000000
--- a/src/backends/meta-stage-impl-private.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2007,2008,2009,2010,2011 Intel Corporation.
- * Copyright (C) 2021 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/>.
- *
- * Written by:
- * Matthew Allum
- * Robert Bragg
- * Neil Roberts
- * Emmanuele Bassi
- *
- */
-
-#ifndef META_STAGE_IMPL_PRIVATE_H
-#define META_STAGE_IMPL_PRIVATE_H
-
-#include <cairo.h>
-
-#include "clutter/clutter.h"
-
-G_BEGIN_DECLS
-
-#define META_TYPE_STAGE_IMPL (meta_stage_impl_get_type ())
-#define META_STAGE_IMPL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_STAGE_IMPL, MetaStageImpl))
-#define META_IS_STAGE_IMPL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_STAGE_IMPL))
-#define META_STAGE_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_STAGE_IMPL, MetaStageImplClass))
-#define META_IS_STAGE_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_STAGE_IMPL))
-#define META_STAGE_IMPL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_STAGE_IMPL, MetaStageImplClass))
-
-typedef struct _MetaStageImpl MetaStageImpl;
-typedef struct _MetaStageImplClass MetaStageImplClass;
-
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaStageImpl, g_object_unref)
-
-#define META_TYPE_STAGE_VIEW (meta_stage_view_get_type ())
-
-struct _MetaStageImpl
-{
- GObject parent_instance;
-
- /* the stage wrapper */
- ClutterStage *wrapper;
-
- /* back pointer to the backend */
- ClutterBackend *backend;
-};
-
-struct _MetaStageImplClass
-{
- GObjectClass parent_class;
-};
-
-GType meta_stage_impl_get_type (void) G_GNUC_CONST;
-
-void meta_stage_impl_presented (MetaStageImpl *stage_impl,
- CoglFrameEvent frame_event,
- ClutterFrameInfo *frame_info);
-
-void meta_stage_impl_add_onscreen_frame_info (MetaStageImpl *stage_impl,
- ClutterStageView *view);
-
-G_END_DECLS
-
-#endif /* META_STAGE_IMPL_PRIVATE_H */
diff --git a/src/backends/meta-stage-impl.c b/src/backends/meta-stage-impl.c
deleted file mode 100644
index 28534ec81..000000000
--- a/src/backends/meta-stage-impl.c
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * Clutter.
- *
- * An OpenGL based 'interactive canvas' library.
- *
- * Copyright (C) 2007,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 <http://www.gnu.org/licenses/>.
-
- * Authors:
- * Matthew Allum
- * Robert Bragg
- * Neil Roberts
- * Emmanuele Bassi
- */
-
-#include "config.h"
-
-#include "backends/meta-stage-impl-private.h"
-
-#include <stdlib.h>
-#include <math.h>
-
-#include "backends/meta-stage-view-private.h"
-#include "clutter/clutter-mutter.h"
-#include "cogl/cogl.h"
-#include "core/util-private.h"
-
-#define MAX_STACK_RECTS 256
-
-typedef struct _MetaStageImplPrivate
-{
- int64_t global_frame_counter;
-} MetaStageImplPrivate;
-
-static void
-clutter_stage_window_iface_init (ClutterStageWindowInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaStageImpl,
- meta_stage_impl,
- G_TYPE_OBJECT,
- G_ADD_PRIVATE (MetaStageImpl)
- G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
- clutter_stage_window_iface_init));
-
-enum
-{
- PROP_0,
- PROP_WRAPPER,
- PROP_BACKEND,
- PROP_LAST
-};
-
-static void
-meta_stage_impl_unrealize (ClutterStageWindow *stage_window)
-{
- meta_topic (META_DEBUG_BACKEND, "Unrealizing Cogl stage [%p]", stage_window);
-}
-
-static gboolean
-meta_stage_impl_realize (ClutterStageWindow *stage_window)
-{
- ClutterBackend *backend;
-
- meta_topic (META_DEBUG_BACKEND,
- "Realizing stage '%s' [%p]",
- G_OBJECT_TYPE_NAME (stage_window),
- stage_window);
-
- backend = clutter_get_default_backend ();
-
- if (backend->cogl_context == NULL)
- {
- g_warning ("Failed to realize stage: missing Cogl context");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static int64_t
-meta_stage_impl_get_frame_counter (ClutterStageWindow *stage_window)
-{
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_window);
- MetaStageImplPrivate *priv =
- meta_stage_impl_get_instance_private (stage_impl);
-
- return priv->global_frame_counter;
-}
-
-static ClutterActor *
-meta_stage_impl_get_wrapper (ClutterStageWindow *stage_window)
-{
- return CLUTTER_ACTOR (META_STAGE_IMPL (stage_window)->wrapper);
-}
-
-static void
-meta_stage_impl_show (ClutterStageWindow *stage_window,
- gboolean do_raise)
-{
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_window);
-
- clutter_actor_map (CLUTTER_ACTOR (stage_impl->wrapper));
-}
-
-static void
-meta_stage_impl_hide (ClutterStageWindow *stage_window)
-{
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_window);
-
- clutter_actor_unmap (CLUTTER_ACTOR (stage_impl->wrapper));
-}
-
-static void
-meta_stage_impl_resize (ClutterStageWindow *stage_window,
- gint width,
- gint height)
-{
-}
-
-static void
-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_framebuffer (view);
- CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
- static CoglPipeline *overlay_blue = NULL;
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_window);
- ClutterActor *actor = CLUTTER_ACTOR (stage_impl->wrapper);
- graphene_matrix_t transform;
- int n_rects, i;
-
- cogl_framebuffer_push_matrix (framebuffer);
- clutter_actor_get_transform (actor, &transform);
- cogl_framebuffer_transform (framebuffer, &transform);
-
- /* Blue for the swap region */
- if (G_UNLIKELY (overlay_blue == NULL))
- {
- overlay_blue = cogl_pipeline_new (ctx);
- cogl_pipeline_set_color4ub (overlay_blue, 0x00, 0x00, 0x33, 0x33);
- }
-
- n_rects = cairo_region_num_rectangles (swap_region);
- for (i = 0; i < n_rects; i++)
- {
- cairo_rectangle_int_t rect;
- float x_1, x_2, y_1, y_2;
-
- 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;
-
- cogl_framebuffer_draw_rectangle (framebuffer, overlay_blue, x_1, y_1, x_2, y_2);
- }
-
- /* Red for the clip */
- if (queued_redraw_clip)
- {
- static CoglPipeline *overlay_red = NULL;
-
- if (G_UNLIKELY (overlay_red == NULL))
- {
- overlay_red = cogl_pipeline_new (ctx);
- cogl_pipeline_set_color4ub (overlay_red, 0x33, 0x00, 0x00, 0x33);
- }
-
- 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;
-
- 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;
-
- cogl_framebuffer_draw_rectangle (framebuffer, overlay_red, x_1, y_1, x_2, y_2);
- }
- }
-
- cogl_framebuffer_pop_matrix (framebuffer);
-}
-
-static void
-swap_framebuffer (ClutterStageWindow *stage_window,
- ClutterStageView *stage_view,
- cairo_region_t *swap_region,
- gboolean swap_with_damage,
- ClutterFrame *frame)
-{
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_window);
- MetaStageImplPrivate *priv =
- meta_stage_impl_get_instance_private (stage_impl);
- CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (stage_view);
- CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
-
- clutter_stage_view_before_swap_buffer (stage_view, swap_region);
-
- if (COGL_IS_ONSCREEN (framebuffer))
- {
- CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
- int *damage, n_rects, i;
- CoglFrameInfo *frame_info;
-
- 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;
-
- 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;
- }
-
- frame_info =
- cogl_frame_info_new (cogl_context, priv->global_frame_counter);
- priv->global_frame_counter++;
-
- /* push on the screen */
- if (n_rects > 0 && !swap_with_damage)
- {
- meta_topic (META_DEBUG_BACKEND,
- "cogl_onscreen_swap_region (onscreen: %p)",
- onscreen);
-
- cogl_onscreen_swap_region (onscreen,
- damage, n_rects,
- frame_info,
- frame);
- }
- else
- {
- meta_topic (META_DEBUG_BACKEND,
- "cogl_onscreen_swap_buffers (onscreen: %p)",
- onscreen);
-
- cogl_onscreen_swap_buffers_with_damage (onscreen,
- damage, n_rects,
- frame_info,
- frame);
- }
- }
- else
- {
- MetaStageView *view = META_STAGE_VIEW (stage_view);
-
- meta_topic (META_DEBUG_BACKEND,
- "fake offscreen swap (framebuffer: %p)",
- framebuffer);
- meta_stage_view_perform_fake_swap (view, priv->global_frame_counter);
- priv->global_frame_counter++;
- }
-}
-
-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_rectangle_int_t *rect = &rects[i];
- graphene_rect_t tmp;
-
- cairo_region_get_rectangle (region, i, rect);
-
- _clutter_util_rect_from_rectangle (rect, &tmp);
- graphene_rect_offset (&tmp, offset_x, offset_y);
- graphene_rect_scale (&tmp, scale, scale, &tmp);
- _clutter_util_rectangle_int_extents (&tmp, rect);
- }
-
- return cairo_region_create_rectangles (rects, n_rects);
-}
-
-static cairo_region_t *
-scale_offset_and_clamp_region (const cairo_region_t *region,
- float scale,
- int offset_x,
- int offset_y)
-{
- 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_rectangle_int_t *rect = &rects[i];
- graphene_rect_t tmp;
-
- cairo_region_get_rectangle (region, i, rect);
-
- _clutter_util_rect_from_rectangle (rect, &tmp);
- graphene_rect_scale (&tmp, scale, scale, &tmp);
- graphene_rect_offset (&tmp, offset_x, offset_y);
- _clutter_util_rectangle_int_extents (&tmp, rect);
- }
-
- return cairo_region_create_rectangles (rects, n_rects);
-}
-
-static void
-paint_stage (MetaStageImpl *stage_impl,
- ClutterStageView *stage_view,
- cairo_region_t *redraw_clip)
-{
- ClutterStage *stage = stage_impl->wrapper;
-
- _clutter_stage_maybe_setup_viewport (stage, stage_view);
- clutter_stage_paint_view (stage, stage_view, redraw_clip);
-
- clutter_stage_view_after_paint (stage_view, redraw_clip);
-}
-
-static cairo_region_t *
-transform_swap_region_to_onscreen (ClutterStageView *stage_view,
- cairo_region_t *swap_region)
-{
- CoglFramebuffer *onscreen = clutter_stage_view_get_onscreen (stage_view);
- int n_rects, i;
- cairo_rectangle_int_t *rects;
- cairo_region_t *transformed_region;
- int width, height;
-
- width = cogl_framebuffer_get_width (onscreen);
- height = cogl_framebuffer_get_height (onscreen);
-
- n_rects = cairo_region_num_rectangles (swap_region);
- rects = g_newa (cairo_rectangle_int_t, n_rects);
- for (i = 0; i < n_rects; i++)
- {
- cairo_region_get_rectangle (swap_region, i, &rects[i]);
- clutter_stage_view_transform_rect_to_onscreen (stage_view,
- &rects[i],
- width,
- height,
- &rects[i]);
- }
- transformed_region = cairo_region_create_rectangles (rects, n_rects);
-
- return transformed_region;
-}
-
-static void
-meta_stage_impl_redraw_view_primary (MetaStageImpl *stage_impl,
- ClutterStageView *stage_view,
- ClutterFrame *frame)
-{
- ClutterStageWindow *stage_window = CLUTTER_STAGE_WINDOW (stage_impl);
- MetaStageView *view = META_STAGE_VIEW (stage_view);
- CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (stage_view);
- CoglFramebuffer *onscreen = clutter_stage_view_get_onscreen (stage_view);
- cairo_rectangle_int_t view_rect;
- gboolean is_full_redraw;
- gboolean use_clipped_redraw = TRUE;
- gboolean can_blit_sub_buffer;
- gboolean has_buffer_age;
- gboolean swap_with_damage;
- cairo_region_t *redraw_clip;
- cairo_region_t *queued_redraw_clip = NULL;
- cairo_region_t *fb_clip_region;
- cairo_region_t *swap_region;
- ClutterDrawDebugFlag paint_debug_flags;
- ClutterDamageHistory *damage_history;
- float fb_scale;
- int fb_width, fb_height;
- int buffer_age = 0;
-
- clutter_stage_view_get_layout (stage_view, &view_rect);
- fb_scale = clutter_stage_view_get_scale (stage_view);
- fb_width = cogl_framebuffer_get_width (fb);
- fb_height = cogl_framebuffer_get_height (fb);
-
- can_blit_sub_buffer =
- COGL_IS_ONSCREEN (onscreen) &&
- cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION);
-
- has_buffer_age =
- COGL_IS_ONSCREEN (onscreen) &&
- cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
-
- redraw_clip = clutter_stage_view_take_redraw_clip (stage_view);
-
- /* NB: a NULL redraw clip == full stage redraw */
- if (!redraw_clip)
- is_full_redraw = TRUE;
- else
- is_full_redraw = FALSE;
-
- damage_history = meta_stage_view_get_damage_history (view);
-
- if (has_buffer_age)
- {
- buffer_age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (onscreen));
- if (!clutter_damage_history_is_age_valid (damage_history, buffer_age))
- {
- meta_topic (META_DEBUG_BACKEND,
- "Invalid back buffer(age=%d): forcing full redraw",
- buffer_age);
- use_clipped_redraw = FALSE;
- }
- }
-
- meta_get_clutter_debug_flags (NULL, &paint_debug_flags, NULL);
-
- use_clipped_redraw =
- use_clipped_redraw &&
- !(paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS) &&
- _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 (onscreen)) > 3;
-
- if (use_clipped_redraw)
- {
- fb_clip_region = offset_scale_and_clamp_region (redraw_clip,
- -view_rect.x,
- -view_rect.y,
- fb_scale);
-
- if (G_UNLIKELY (paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION))
- {
- queued_redraw_clip =
- scale_offset_and_clamp_region (fb_clip_region,
- 1.0 / fb_scale,
- view_rect.x,
- view_rect.y);
- }
- }
- else
- {
- 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 (G_UNLIKELY (paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION))
- queued_redraw_clip = cairo_region_reference (redraw_clip);
- }
-
- g_return_if_fail (!cairo_region_is_empty (fb_clip_region));
-
- swap_with_damage = FALSE;
- if (has_buffer_age)
- {
- clutter_damage_history_record (damage_history, fb_clip_region);
-
- if (use_clipped_redraw)
- {
- int age;
-
- for (age = 1; age <= buffer_age; age++)
- {
- const cairo_region_t *old_damage;
-
- old_damage =
- clutter_damage_history_lookup (damage_history, age);
- cairo_region_union (fb_clip_region, old_damage);
- }
-
- meta_topic (META_DEBUG_BACKEND,
- "Reusing back buffer(age=%d) - repairing region: num rects: %d",
- buffer_age,
- cairo_region_num_rectangles (fb_clip_region));
-
- swap_with_damage = TRUE;
- }
-
- clutter_damage_history_step (damage_history);
- }
-
- if (use_clipped_redraw)
- {
- /* Regenerate redraw_clip because:
- * 1. It's missing the regions added from damage_history above; and
- * 2. If using fractional scaling then it might be a fraction of a
- * logical pixel (or one physical pixel) smaller than
- * fb_clip_region, due to the clamping from
- * offset_scale_and_clamp_region. So we need to ensure redraw_clip
- * is a superset of fb_clip_region to avoid such gaps.
- */
- cairo_region_destroy (redraw_clip);
- redraw_clip = scale_offset_and_clamp_region (fb_clip_region,
- 1.0 / fb_scale,
- view_rect.x,
- view_rect.y);
- }
-
- if (paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION)
- {
- cairo_region_t *debug_redraw_clip;
-
- debug_redraw_clip = cairo_region_create_rectangle (&view_rect);
- paint_stage (stage_impl, stage_view, debug_redraw_clip);
- cairo_region_destroy (debug_redraw_clip);
- }
- else if (use_clipped_redraw)
- {
- cogl_framebuffer_push_region_clip (fb, fb_clip_region);
-
- paint_stage (stage_impl, stage_view, redraw_clip);
-
- cogl_framebuffer_pop_clip (fb);
- }
- else
- {
- meta_topic (META_DEBUG_BACKEND, "Unclipped stage paint");
-
- paint_stage (stage_impl, stage_view, redraw_clip);
- }
-
- /* XXX: It seems there will be a race here in that the stage
- * window may be resized before the cogl_onscreen_swap_region
- * is handled and so we may copy the wrong region. I can't
- * really see how we can handle this with the current state of X
- * but at least in this case a full redraw should be queued by
- * the resize anyway so it should only exhibit temporary
- * artefacts.
- */
- if (use_clipped_redraw)
- swap_region = cairo_region_reference (fb_clip_region);
- else
- swap_region = cairo_region_create ();
-
- g_clear_pointer (&redraw_clip, cairo_region_destroy);
- g_clear_pointer (&fb_clip_region, cairo_region_destroy);
-
- COGL_TRACE_BEGIN_SCOPED (MetaStageImplRedrawViewSwapFramebuffer,
- "Paint (swap framebuffer)");
-
- if (clutter_stage_view_get_onscreen (stage_view) !=
- clutter_stage_view_get_framebuffer (stage_view))
- {
- cairo_region_t *transformed_swap_region;
-
- transformed_swap_region =
- transform_swap_region_to_onscreen (stage_view, swap_region);
- cairo_region_destroy (swap_region);
- swap_region = transformed_swap_region;
- }
-
- if (queued_redraw_clip)
- {
- cairo_region_t *swap_region_in_stage_space;
-
- swap_region_in_stage_space =
- scale_offset_and_clamp_region (swap_region,
- 1.0f / fb_scale,
- view_rect.x,
- view_rect.y);
-
- cairo_region_subtract (swap_region_in_stage_space, queued_redraw_clip);
-
- paint_damage_region (stage_window, stage_view,
- swap_region_in_stage_space, queued_redraw_clip);
-
- cairo_region_destroy (queued_redraw_clip);
- cairo_region_destroy (swap_region_in_stage_space);
- }
-
- swap_framebuffer (stage_window,
- stage_view,
- swap_region,
- swap_with_damage,
- frame);
-
- cairo_region_destroy (swap_region);
-}
-
-static gboolean
-meta_stage_impl_scanout_view (MetaStageImpl *stage_impl,
- ClutterStageView *stage_view,
- CoglScanout *scanout,
- ClutterFrame *frame,
- GError **error)
-{
- MetaStageImplPrivate *priv =
- meta_stage_impl_get_instance_private (stage_impl);
- CoglFramebuffer *framebuffer =
- clutter_stage_view_get_framebuffer (stage_view);
- CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
- CoglOnscreen *onscreen;
- CoglFrameInfo *frame_info;
-
- g_assert (COGL_IS_ONSCREEN (framebuffer));
-
- onscreen = COGL_ONSCREEN (framebuffer);
-
- frame_info = cogl_frame_info_new (cogl_context, priv->global_frame_counter);
-
- if (!cogl_onscreen_direct_scanout (onscreen,
- scanout,
- frame_info,
- frame,
- error))
- {
- cogl_object_unref (frame_info);
- return FALSE;
- }
-
- priv->global_frame_counter++;
-
- return TRUE;
-}
-
-static void
-meta_stage_impl_redraw_view (ClutterStageWindow *stage_window,
- ClutterStageView *stage_view,
- ClutterFrame *frame)
-{
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_window);
- g_autoptr (CoglScanout) scanout = NULL;
-
- scanout = clutter_stage_view_take_scanout (stage_view);
- if (scanout)
- {
- g_autoptr (GError) error = NULL;
-
- if (meta_stage_impl_scanout_view (stage_impl,
- stage_view,
- scanout,
- frame,
- &error))
- return;
-
- if (!g_error_matches (error,
- COGL_SCANOUT_ERROR,
- COGL_SCANOUT_ERROR_INHIBITED))
- g_warning ("Failed to scan out client buffer: %s", error->message);
- }
-
- meta_stage_impl_redraw_view_primary (stage_impl, stage_view, frame);
-}
-
-void
-meta_stage_impl_add_onscreen_frame_info (MetaStageImpl *stage_impl,
- ClutterStageView *stage_view)
-{
- MetaStageImplPrivate *priv =
- meta_stage_impl_get_instance_private (stage_impl);
- CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (stage_view);
- CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
- CoglFrameInfo *frame_info;
-
- frame_info = cogl_frame_info_new (cogl_context, priv->global_frame_counter);
- priv->global_frame_counter++;
-
- cogl_onscreen_add_frame_info (COGL_ONSCREEN (framebuffer), frame_info);
-}
-
-static void
-clutter_stage_window_iface_init (ClutterStageWindowInterface *iface)
-{
- iface->realize = meta_stage_impl_realize;
- iface->unrealize = meta_stage_impl_unrealize;
- iface->get_wrapper = meta_stage_impl_get_wrapper;
- iface->resize = meta_stage_impl_resize;
- iface->show = meta_stage_impl_show;
- iface->hide = meta_stage_impl_hide;
- iface->get_frame_counter = meta_stage_impl_get_frame_counter;
- iface->redraw_view = meta_stage_impl_redraw_view;
-}
-
-static void
-meta_stage_impl_set_property (GObject *gobject,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaStageImpl *self = META_STAGE_IMPL (gobject);
-
- switch (prop_id)
- {
- case PROP_WRAPPER:
- self->wrapper = g_value_get_object (value);
- break;
-
- case PROP_BACKEND:
- self->backend = g_value_get_object (value);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_stage_impl_class_init (MetaStageImplClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->set_property = meta_stage_impl_set_property;
-
- g_object_class_override_property (gobject_class, PROP_WRAPPER, "wrapper");
- g_object_class_override_property (gobject_class, PROP_BACKEND, "backend");
-}
-
-static void
-meta_stage_impl_init (MetaStageImpl *stage)
-{
-}
diff --git a/src/backends/meta-stage-private.h b/src/backends/meta-stage-private.h
deleted file mode 100644
index 07534f6e3..000000000
--- a/src/backends/meta-stage-private.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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 "core/util-private.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_overlay_set_visible (MetaOverlay *overlay,
- gboolean is_visible);
-
-gboolean meta_overlay_is_visible (MetaOverlay *overlay);
-
-void meta_stage_set_active (MetaStage *stage,
- gboolean is_active);
-
-META_EXPORT_TEST
-MetaStageWatch * meta_stage_watch_view (MetaStage *stage,
- ClutterStageView *view,
- MetaStageWatchPhase watch_mode,
- MetaStageWatchFunc callback,
- gpointer user_data);
-
-META_EXPORT_TEST
-void meta_stage_remove_watch (MetaStage *stage,
- MetaStageWatch *watch);
-
-G_END_DECLS
-
-#endif /* META_STAGE_PRIVATE_H */
diff --git a/src/backends/meta-stage-view-private.h b/src/backends/meta-stage-view-private.h
deleted file mode 100644
index aaf3f31eb..000000000
--- a/src/backends/meta-stage-view-private.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2007,2008,2009,2010,2011 Intel Corporation.
- * Copyright (C) 2021 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/>.
- *
- * Written by:
- * Matthew Allum
- * Robert Bragg
- * Neil Roberts
- * Emmanuele Bassi
- *
- */
-
-#ifndef META_STAGE_VIEW_H
-#define META_STAGE_VIEW_H
-
-#include <cairo.h>
-
-#include "clutter/clutter-mutter.h"
-
-G_BEGIN_DECLS
-
-#define META_TYPE_STAGE_VIEW (meta_stage_view_get_type ())
-
-G_DECLARE_DERIVABLE_TYPE (MetaStageView,
- meta_stage_view,
- META, STAGE_VIEW,
- ClutterStageView)
-
-struct _MetaStageViewClass
-{
- ClutterStageViewClass parent_class;
-};
-
-ClutterDamageHistory * meta_stage_view_get_damage_history (MetaStageView *view);
-void meta_stage_view_perform_fake_swap (MetaStageView *view,
- int64_t counter);
-
-#endif /* META_STAGE_VIEW_H */
diff --git a/src/backends/meta-stage-view.c b/src/backends/meta-stage-view.c
deleted file mode 100644
index 473943196..000000000
--- a/src/backends/meta-stage-view.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2007,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 <http://www.gnu.org/licenses/>.
-
- * Authors:
- * Matthew Allum
- * Robert Bragg
- * Neil Roberts
- * Emmanuele Bassi
- */
-
-#include "config.h"
-
-#include "meta-stage-view-private.h"
-
-typedef struct _MetaStageViewPrivate
-{
- /* Damage history, in stage view render target framebuffer coordinate space.
- */
- ClutterDamageHistory *damage_history;
-
- guint notify_presented_handle_id;
-
- CoglFrameClosure *frame_cb_closure;
-} MetaStageViewPrivate;
-
-G_DEFINE_TYPE_WITH_PRIVATE (MetaStageView, meta_stage_view,
- CLUTTER_TYPE_STAGE_VIEW)
-
-static void
-frame_cb (CoglOnscreen *onscreen,
- CoglFrameEvent frame_event,
- CoglFrameInfo *frame_info,
- void *user_data)
-{
- ClutterStageView *view = user_data;
-
- if (frame_event == COGL_FRAME_EVENT_SYNC)
- return;
-
- if (cogl_frame_info_get_is_symbolic (frame_info))
- {
- clutter_stage_view_notify_ready (view);
- }
- else
- {
- ClutterFrameInfo clutter_frame_info;
- ClutterFrameInfoFlag flags = CLUTTER_FRAME_INFO_FLAG_NONE;
-
- if (cogl_frame_info_is_hw_clock (frame_info))
- flags |= CLUTTER_FRAME_INFO_FLAG_HW_CLOCK;
-
- if (cogl_frame_info_is_zero_copy (frame_info))
- flags |= CLUTTER_FRAME_INFO_FLAG_ZERO_COPY;
-
- if (cogl_frame_info_is_vsync (frame_info))
- flags |= CLUTTER_FRAME_INFO_FLAG_VSYNC;
-
- clutter_frame_info = (ClutterFrameInfo) {
- .frame_counter = cogl_frame_info_get_global_frame_counter (frame_info),
- .refresh_rate = cogl_frame_info_get_refresh_rate (frame_info),
- .presentation_time =
- cogl_frame_info_get_presentation_time_us (frame_info),
- .flags = flags,
- .sequence = cogl_frame_info_get_sequence (frame_info),
- .gpu_rendering_duration_ns =
- cogl_frame_info_get_rendering_duration_ns (frame_info),
- .cpu_time_before_buffer_swap_us =
- cogl_frame_info_get_time_before_buffer_swap_us (frame_info),
- };
- clutter_stage_view_notify_presented (view, &clutter_frame_info);
- }
-}
-
-static void
-meta_stage_view_dispose (GObject *object)
-{
- MetaStageView *view = META_STAGE_VIEW (object);
- MetaStageViewPrivate *priv =
- meta_stage_view_get_instance_private (view);
- ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (view);
-
- g_clear_handle_id (&priv->notify_presented_handle_id, g_source_remove);
- g_clear_pointer (&priv->damage_history, clutter_damage_history_free);
-
- if (priv->frame_cb_closure)
- {
- CoglFramebuffer *framebuffer;
-
- framebuffer = clutter_stage_view_get_onscreen (stage_view);
- cogl_onscreen_remove_frame_callback (COGL_ONSCREEN (framebuffer),
- priv->frame_cb_closure);
- priv->frame_cb_closure = NULL;
- }
-
- G_OBJECT_CLASS (meta_stage_view_parent_class)->dispose (object);
-}
-
-static void
-meta_stage_view_constructed (GObject *object)
-{
- MetaStageView *view = META_STAGE_VIEW (object);
- MetaStageViewPrivate *priv =
- meta_stage_view_get_instance_private (view);
- ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (view);
- CoglFramebuffer *framebuffer;
-
- framebuffer = clutter_stage_view_get_onscreen (stage_view);
- if (framebuffer && COGL_IS_ONSCREEN (framebuffer))
- {
- priv->frame_cb_closure =
- cogl_onscreen_add_frame_callback (COGL_ONSCREEN (framebuffer),
- frame_cb,
- view,
- NULL);
- }
-
- G_OBJECT_CLASS (meta_stage_view_parent_class)->constructed (object);
-}
-
-static void
-meta_stage_view_init (MetaStageView *view)
-{
- MetaStageViewPrivate *priv =
- meta_stage_view_get_instance_private (view);
-
- priv->damage_history = clutter_damage_history_new ();
-}
-
-static void
-meta_stage_view_class_init (MetaStageViewClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->constructed = meta_stage_view_constructed;
- object_class->dispose = meta_stage_view_dispose;
-}
-
-ClutterDamageHistory *
-meta_stage_view_get_damage_history (MetaStageView *view)
-{
- MetaStageViewPrivate *priv =
- meta_stage_view_get_instance_private (view);
-
- return priv->damage_history;
-}
-
-typedef struct _NotifyPresentedClosure
-{
- ClutterStageView *view;
- ClutterFrameInfo frame_info;
-} NotifyPresentedClosure;
-
-static gboolean
-notify_presented_idle (gpointer user_data)
-{
- NotifyPresentedClosure *closure = user_data;
- MetaStageView *view = META_STAGE_VIEW (closure->view);
- MetaStageViewPrivate *priv =
- meta_stage_view_get_instance_private (view);
-
- priv->notify_presented_handle_id = 0;
- clutter_stage_view_notify_presented (closure->view, &closure->frame_info);
-
- return G_SOURCE_REMOVE;
-}
-
-void
-meta_stage_view_perform_fake_swap (MetaStageView *view,
- int64_t counter)
-{
- ClutterStageView *clutter_view = CLUTTER_STAGE_VIEW (view);
- MetaStageViewPrivate *priv =
- meta_stage_view_get_instance_private (view);
- NotifyPresentedClosure *closure;
-
- closure = g_new0 (NotifyPresentedClosure, 1);
- closure->view = clutter_view;
- closure->frame_info = (ClutterFrameInfo) {
- .frame_counter = counter,
- .refresh_rate = clutter_stage_view_get_refresh_rate (clutter_view),
- .presentation_time = g_get_monotonic_time (),
- .flags = CLUTTER_FRAME_INFO_FLAG_NONE,
- .sequence = 0,
- };
-
- g_warn_if_fail (priv->notify_presented_handle_id == 0);
- priv->notify_presented_handle_id =
- g_idle_add_full (G_PRIORITY_DEFAULT,
- notify_presented_idle,
- closure, g_free);
-}
diff --git a/src/backends/meta-stage.c b/src/backends/meta-stage.c
deleted file mode 100644
index 6f8e3feae..000000000
--- a/src/backends/meta-stage.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * 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 "backends/meta-cursor-tracker-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
-{
- MetaStage *stage;
-
- gboolean is_visible;
-
- CoglPipeline *pipeline;
- CoglTexture *texture;
-
- graphene_rect_t current_rect;
- graphene_rect_t previous_rect;
- gboolean previous_is_valid;
-};
-
-struct _MetaStage
-{
- ClutterStage parent;
-
- MetaBackend *backend;
-
- GPtrArray *watchers[N_WATCH_MODES];
-
- GList *overlays;
- gboolean is_active;
-};
-
-G_DEFINE_TYPE (MetaStage, meta_stage, CLUTTER_TYPE_STAGE);
-
-static MetaOverlay *
-meta_overlay_new (MetaStage *stage)
-{
- ClutterBackend *clutter_backend =
- meta_backend_get_clutter_backend (stage->backend);
- CoglContext *ctx = clutter_backend_get_cogl_context (clutter_backend);
- MetaOverlay *overlay;
-
- overlay = g_new0 (MetaOverlay, 1);
- overlay->stage = stage;
- overlay->pipeline = cogl_pipeline_new (ctx);
-
- return overlay;
-}
-
-static void
-meta_overlay_free (MetaOverlay *overlay)
-{
- if (overlay->pipeline)
- cogl_object_unref (overlay->pipeline);
-
- g_free (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);
- else
- cogl_pipeline_set_layer_texture (overlay->pipeline, 0, NULL);
- }
-
- overlay->current_rect = *rect;
-}
-
-static void
-meta_overlay_paint (MetaOverlay *overlay,
- ClutterPaintContext *paint_context)
-{
- CoglFramebuffer *framebuffer;
-
- if (!overlay->texture)
- return;
-
- if (!overlay->is_visible &&
- !(clutter_paint_context_get_paint_flags (paint_context) &
- CLUTTER_PAINT_FLAG_FORCE_CURSORS))
- return;
-
- 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_before_paint (ClutterStage *stage,
- ClutterStageView *view)
-{
- MetaStage *meta_stage = META_STAGE (stage);
-
- notify_watchers_for_mode (meta_stage, view, NULL,
- META_STAGE_WATCH_BEFORE_PAINT);
-}
-
-static void
-meta_stage_paint (ClutterActor *actor,
- ClutterPaintContext *paint_context)
-{
- MetaStage *stage = META_STAGE (actor);
- ClutterStageView *view;
-
- 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);
- }
-
- g_signal_emit (stage, signals[ACTORS_PAINTED], 0);
-
- if ((clutter_paint_context_get_paint_flags (paint_context) &
- CLUTTER_PAINT_FLAG_FORCE_CURSORS))
- {
- MetaCursorTracker *cursor_tracker =
- meta_backend_get_cursor_tracker (stage->backend);
-
- meta_cursor_tracker_track_position (cursor_tracker);
- }
-
- if (!(clutter_paint_context_get_paint_flags (paint_context) &
- CLUTTER_PAINT_FLAG_NO_CURSORS))
- g_list_foreach (stage->overlays, (GFunc) meta_overlay_paint, paint_context);
-
- if ((clutter_paint_context_get_paint_flags (paint_context) &
- CLUTTER_PAINT_FLAG_FORCE_CURSORS))
- {
- MetaCursorTracker *cursor_tracker =
- meta_backend_get_cursor_tracker (stage->backend);
-
- meta_cursor_tracker_untrack_position (cursor_tracker);
- }
-
- 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);
-
- 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->before_paint = meta_stage_before_paint;
- 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, NULL);
- stage->backend = backend;
-
- 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->is_visible && overlay->texture)
- queue_redraw_clutter_rect (stage, overlay, &overlay->current_rect);
-}
-
-MetaOverlay *
-meta_stage_create_cursor_overlay (MetaStage *stage)
-{
- MetaOverlay *overlay;
-
- overlay = meta_overlay_new (stage);
- 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)
-{
- meta_overlay_set (overlay, texture, rect);
- queue_redraw_for_overlay (stage, overlay);
-}
-
-void
-meta_overlay_set_visible (MetaOverlay *overlay,
- gboolean is_visible)
-{
- if (overlay->is_visible == is_visible)
- return;
-
- overlay->is_visible = is_visible;
- queue_redraw_for_overlay (overlay->stage, overlay);
-}
-
-gboolean
-meta_overlay_is_visible (MetaOverlay *overlay)
-{
- return overlay->is_visible;
-}
-
-void
-meta_stage_set_active (MetaStage *stage,
- gboolean is_active)
-{
- if (stage->is_active == is_active)
- return;
-
- if (is_active)
- g_signal_emit_by_name (CLUTTER_STAGE (stage), "activate");
- else
- g_signal_emit_by_name (CLUTTER_STAGE (stage), "deactivate");
-}
-
-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/meta-viewport-info.c b/src/backends/meta-viewport-info.c
deleted file mode 100644
index 1adef8759..000000000
--- a/src/backends/meta-viewport-info.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * 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>
- */
-
-#include "config.h"
-
-#include "backends/meta-viewport-info.h"
-#include "core/boxes-private.h"
-
-typedef struct _ViewInfo ViewInfo;
-
-struct _ViewInfo
-{
- MetaRectangle rect;
- float scale;
-};
-
-struct _MetaViewportInfo
-{
- GObject parent;
- GArray *views;
- gboolean is_views_scaled;
-};
-
-G_DEFINE_TYPE (MetaViewportInfo, meta_viewport_info, G_TYPE_OBJECT)
-
-static void
-meta_viewport_info_finalize (GObject *object)
-{
- MetaViewportInfo *info = META_VIEWPORT_INFO (object);
-
- g_array_unref (info->views);
-
- G_OBJECT_CLASS (meta_viewport_info_parent_class)->finalize (object);
-}
-
-static void
-meta_viewport_info_class_init (MetaViewportInfoClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = meta_viewport_info_finalize;
-}
-
-static void
-meta_viewport_info_init (MetaViewportInfo *info)
-{
- info->views = g_array_new (FALSE, FALSE, sizeof (ViewInfo));
-}
-
-MetaViewportInfo *
-meta_viewport_info_new (cairo_rectangle_int_t *views,
- float *scales,
- int n_views,
- gboolean is_views_scaled)
-{
- MetaViewportInfo *viewport_info;
- int i;
-
- viewport_info = g_object_new (META_TYPE_VIEWPORT_INFO, NULL);
-
- for (i = 0; i < n_views; i++)
- {
- ViewInfo info;
-
- info.rect = views[i];
- info.scale = scales[i];
- g_array_append_val (viewport_info->views, info);
- }
-
- viewport_info->is_views_scaled = is_views_scaled;
-
- return viewport_info;
-}
-
-int
-meta_viewport_info_get_view_at (MetaViewportInfo *viewport_info,
- float x,
- float y)
-{
- int i;
-
- for (i = 0; i < viewport_info->views->len; i++)
- {
- ViewInfo *info = &g_array_index (viewport_info->views, ViewInfo, i);
-
- if (META_POINT_IN_RECT (x, y, info->rect))
- return i;
- }
-
- return -1;
-}
-
-gboolean
-meta_viewport_info_get_view_info (MetaViewportInfo *viewport_info,
- int idx,
- cairo_rectangle_int_t *rect,
- float *scale)
-{
- ViewInfo *info;
-
- if (idx < 0 || idx >= viewport_info->views->len)
- return FALSE;
-
- info = &g_array_index (viewport_info->views, ViewInfo, idx);
- if (rect)
- *rect = info->rect;
- if (scale)
- *scale = info->scale;
-
- return TRUE;
-}
-
-static gboolean
-view_has_neighbor (cairo_rectangle_int_t *view,
- cairo_rectangle_int_t *neighbor,
- MetaDisplayDirection neighbor_direction)
-{
- switch (neighbor_direction)
- {
- case META_DISPLAY_RIGHT:
- if (neighbor->x == (view->x + view->width) &&
- meta_rectangle_vert_overlap (neighbor, view))
- return TRUE;
- break;
- case META_DISPLAY_LEFT:
- if (view->x == (neighbor->x + neighbor->width) &&
- meta_rectangle_vert_overlap (neighbor, view))
- return TRUE;
- break;
- case META_DISPLAY_UP:
- if (view->y == (neighbor->y + neighbor->height) &&
- meta_rectangle_horiz_overlap (neighbor, view))
- return TRUE;
- break;
- case META_DISPLAY_DOWN:
- if (neighbor->y == (view->y + view->height) &&
- meta_rectangle_horiz_overlap (neighbor, view))
- return TRUE;
- break;
- }
-
- return FALSE;
-}
-
-int
-meta_viewport_info_get_neighbor (MetaViewportInfo *viewport_info,
- int idx,
- MetaDisplayDirection direction)
-{
- cairo_rectangle_int_t rect;
- int i;
-
- if (!meta_viewport_info_get_view_info (viewport_info, idx, &rect, NULL))
- return -1;
-
- for (i = 0; i < viewport_info->views->len; i++)
- {
- ViewInfo *info = &g_array_index (viewport_info->views, ViewInfo, i);
-
- if (idx == i)
- continue;
- if (view_has_neighbor (&rect, &info->rect, direction))
- return i;
- }
-
- return -1;
-}
-
-int
-meta_viewport_info_get_num_views (MetaViewportInfo *info)
-{
- return info->views->len;
-}
-
-void
-meta_viewport_info_get_extents (MetaViewportInfo *viewport_info,
- float *width,
- float *height)
-{
- int min_x = G_MAXINT, min_y = G_MAXINT, max_x = G_MININT, max_y = G_MININT, i;
-
- g_return_if_fail (viewport_info != NULL);
-
- for (i = 0; i < viewport_info->views->len; i++)
- {
- ViewInfo *info = &g_array_index (viewport_info->views, ViewInfo, i);
-
- min_x = MIN (min_x, info->rect.x);
- max_x = MAX (max_x, info->rect.x + info->rect.width);
- min_y = MIN (min_y, info->rect.y);
- max_y = MAX (max_y, info->rect.y + info->rect.height);
- }
-
- if (width)
- *width = (float) max_x - min_x;
- if (height)
- *height = (float) max_y - min_y;
-}
-
-gboolean
-meta_viewport_info_is_views_scaled (MetaViewportInfo *viewport_info)
-{
- return viewport_info->is_views_scaled;
-}
diff --git a/src/backends/meta-viewport-info.h b/src/backends/meta-viewport-info.h
deleted file mode 100644
index e10f5b78f..000000000
--- a/src/backends/meta-viewport-info.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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_VIEWPORT_INFO_H
-#define META_VIEWPORT_INFO_H
-
-#include <cairo.h>
-#include <glib-object.h>
-
-#include "meta/display.h"
-
-#define META_TYPE_VIEWPORT_INFO (meta_viewport_info_get_type ())
-G_DECLARE_FINAL_TYPE (MetaViewportInfo, meta_viewport_info,
- META, VIEWPORT_INFO, GObject)
-
-MetaViewportInfo * meta_viewport_info_new (cairo_rectangle_int_t *views,
- float *scales,
- int n_views,
- gboolean is_views_scaled);
-
-int meta_viewport_info_get_view_at (MetaViewportInfo *info,
- float x,
- float y);
-
-gboolean meta_viewport_info_get_view_info (MetaViewportInfo *viewport_info,
- int idx,
- cairo_rectangle_int_t *rect,
- float *scale);
-
-int meta_viewport_info_get_neighbor (MetaViewportInfo *info,
- int idx,
- MetaDisplayDirection direction);
-
-int meta_viewport_info_get_num_views (MetaViewportInfo *info);
-
-void meta_viewport_info_get_extents (MetaViewportInfo *info,
- float *width,
- float *height);
-
-gboolean meta_viewport_info_is_views_scaled (MetaViewportInfo *info);
-
-#endif /* META_VIEWPORT_INFO_H */
diff --git a/src/backends/meta-virtual-monitor.c b/src/backends/meta-virtual-monitor.c
deleted file mode 100644
index 2bd95ffd7..000000000
--- a/src/backends/meta-virtual-monitor.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2021 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-virtual-monitor.h"
-
-#include "backends/meta-crtc.h"
-#include "backends/meta-crtc-mode.h"
-#include "backends/meta-output.h"
-
-enum
-{
- DESTROY,
-
- N_SIGNALS
-};
-
-static guint signals[N_SIGNALS] = { 0 };
-
-enum
-{
- PROP_0,
-
- PROP_CRTC,
- PROP_CRTC_MODE,
- PROP_OUTPUT,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS];
-
-typedef struct _MetaVirtualMonitorPrivate
-{
- MetaCrtc *crtc;
- MetaCrtcMode *crtc_mode;
- MetaOutput *output;
-
- gboolean is_destroyed;
-} MetaVirtualMonitorPrivate;
-
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaVirtualMonitor, meta_virtual_monitor,
- G_TYPE_OBJECT)
-
-MetaVirtualMonitorInfo *
-meta_virtual_monitor_info_new (int width,
- int height,
- float refresh_rate,
- const char *vendor,
- const char *product,
- const char *serial)
-{
- MetaVirtualMonitorInfo *info;
-
- info = g_new0 (MetaVirtualMonitorInfo, 1);
- info->width = width;
- info->height = height;
- info->refresh_rate = refresh_rate;
- info->vendor = g_strdup (vendor);
- info->product = g_strdup (product);
- info->serial = g_strdup (serial);
-
- return info;
-}
-
-void
-meta_virtual_monitor_info_free (MetaVirtualMonitorInfo *info)
-{
- g_free (info->vendor);
- g_free (info->product);
- g_free (info->serial);
- g_free (info);
-}
-
-MetaCrtc *
-meta_virtual_monitor_get_crtc (MetaVirtualMonitor *virtual_monitor)
-{
- MetaVirtualMonitorPrivate *priv =
- meta_virtual_monitor_get_instance_private (virtual_monitor);
-
- return priv->crtc;
-}
-
-MetaCrtcMode *
-meta_virtual_monitor_get_crtc_mode (MetaVirtualMonitor *virtual_monitor)
-{
- MetaVirtualMonitorPrivate *priv =
- meta_virtual_monitor_get_instance_private (virtual_monitor);
-
- return priv->crtc_mode;
-}
-
-MetaOutput *
-meta_virtual_monitor_get_output (MetaVirtualMonitor *virtual_monitor)
-{
- MetaVirtualMonitorPrivate *priv =
- meta_virtual_monitor_get_instance_private (virtual_monitor);
-
- return priv->output;
-}
-
-static void
-meta_virtual_monitor_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaVirtualMonitor *virtual_monitor = META_VIRTUAL_MONITOR (object);
- MetaVirtualMonitorPrivate *priv =
- meta_virtual_monitor_get_instance_private (virtual_monitor);
-
- switch (prop_id)
- {
- case PROP_CRTC:
- priv->crtc = g_value_get_object (value);
- break;
- case PROP_CRTC_MODE:
- priv->crtc_mode = g_value_get_object (value);
- break;
- case PROP_OUTPUT:
- priv->output = g_value_get_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-meta_virtual_monitor_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaVirtualMonitor *virtual_monitor = META_VIRTUAL_MONITOR (object);
- MetaVirtualMonitorPrivate *priv =
- meta_virtual_monitor_get_instance_private (virtual_monitor);
-
- switch (prop_id)
- {
- case PROP_CRTC:
- g_value_set_object (value, priv->crtc);
- break;
- case PROP_CRTC_MODE:
- g_value_set_object (value, priv->crtc_mode);
- break;
- case PROP_OUTPUT:
- g_value_set_object (value, priv->output);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-meta_virtual_monitor_dispose (GObject *object)
-{
- MetaVirtualMonitor *virtual_monitor = META_VIRTUAL_MONITOR (object);
- MetaVirtualMonitorPrivate *priv =
- meta_virtual_monitor_get_instance_private (virtual_monitor);
-
- if (!priv->is_destroyed)
- {
- g_signal_emit (virtual_monitor, signals[DESTROY], 0);
- priv->is_destroyed = TRUE;
- }
-
- g_clear_object (&priv->crtc);
- g_clear_object (&priv->crtc_mode);
- g_clear_object (&priv->output);
-
- G_OBJECT_CLASS (meta_virtual_monitor_parent_class)->dispose (object);
-}
-
-static void
-meta_virtual_monitor_init (MetaVirtualMonitor *virtual_monitor)
-{
-}
-
-static void
-meta_virtual_monitor_class_init (MetaVirtualMonitorClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->set_property = meta_virtual_monitor_set_property;
- object_class->get_property = meta_virtual_monitor_get_property;
- object_class->dispose = meta_virtual_monitor_dispose;
-
- obj_props[PROP_CRTC] =
- g_param_spec_object ("crtc",
- "crtc",
- "The virtual CRTC",
- META_TYPE_CRTC,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- obj_props[PROP_CRTC_MODE] =
- g_param_spec_object ("crtc-mode",
- "crtc-mode",
- "The virtual CRTC mode",
- META_TYPE_CRTC_MODE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- obj_props[PROP_OUTPUT] =
- g_param_spec_object ("output",
- "output",
- "The virtual output",
- META_TYPE_OUTPUT,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, N_PROPS, obj_props);
-
- signals[DESTROY] =
- g_signal_new ("destroy",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST, 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-}
diff --git a/src/backends/meta-virtual-monitor.h b/src/backends/meta-virtual-monitor.h
deleted file mode 100644
index 2b733df9c..000000000
--- a/src/backends/meta-virtual-monitor.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2021 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_VIRTUAL_MONITOR_H
-#define META_VIRTUAL_MONITOR_H
-
-#include <glib-object.h>
-
-#include "backends/meta-backend-types.h"
-#include "core/util-private.h"
-
-typedef struct _MetaVirtualMonitorInfo
-{
- int width;
- int height;
- float refresh_rate;
-
- char *vendor;
- char *product;
- char *serial;
-} MetaVirtualMonitorInfo;
-
-#define META_TYPE_VIRTUAL_MONITOR (meta_virtual_monitor_get_type ())
-G_DECLARE_DERIVABLE_TYPE (MetaVirtualMonitor, meta_virtual_monitor,
- META, VIRTUAL_MONITOR,
- GObject)
-
-struct _MetaVirtualMonitorClass
-{
- GObjectClass parent_class;
-};
-
-META_EXPORT_TEST
-MetaVirtualMonitorInfo * meta_virtual_monitor_info_new (int width,
- int height,
- float refresh_rate,
- const char *vendor,
- const char *product,
- const char *serial);
-
-META_EXPORT_TEST
-void meta_virtual_monitor_info_free (MetaVirtualMonitorInfo *info);
-
-MetaCrtc * meta_virtual_monitor_get_crtc (MetaVirtualMonitor *virtual_monitor);
-
-MetaCrtcMode * meta_virtual_monitor_get_crtc_mode (MetaVirtualMonitor *virtual_monitor);
-
-META_EXPORT_TEST
-MetaOutput * meta_virtual_monitor_get_output (MetaVirtualMonitor *virtual_monitor);
-
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaVirtualMonitorInfo,
- meta_virtual_monitor_info_free)
-
-#endif /* META_VIRTUAL_MONITOR_H */
diff --git a/src/backends/native/dbus-utils.c b/src/backends/native/dbus-utils.c
deleted file mode 100644
index 79fafe881..000000000
--- a/src/backends/native/dbus-utils.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -*- 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
deleted file mode 100644
index ee56c455a..000000000
--- a/src/backends/native/dbus-utils.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- 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
deleted file mode 100755
index fed514d45..000000000
--- a/src/backends/native/gen-default-modes.py
+++ /dev/null
@@ -1,127 +0,0 @@
-#!/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
deleted file mode 100644
index cd184685f..000000000
--- a/src/backends/native/meta-backend-native-private.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- 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-backend-native.h"
-#include "backends/native/meta-barrier-native.h"
-
-MetaBarrierManagerNative *meta_backend_native_get_barrier_manager (MetaBackendNative *native);
-
-MetaDevicePool * meta_backend_native_get_device_pool (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
deleted file mode 100644
index 152b57cf6..000000000
--- a/src/backends/native/meta-backend-native-types.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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;
-typedef struct _MetaSeatNative MetaSeatNative;
-typedef struct _MetaSeatImpl MetaSeatImpl;
-typedef struct _MetaKeymapNative MetaKeymapNative;
-typedef struct _MetaRendererNative MetaRendererNative;
-typedef struct _MetaGpuKms MetaGpuKms;
-typedef struct _MetaCrtcVirtual MetaCrtcVirtual;
-typedef struct _MetaCrtcModeVirtual MetaCrtcModeVirtual;
-typedef struct _MetaDevicePool MetaDevicePool;
-typedef struct _MetaDeviceFile MetaDeviceFile;
-
-typedef enum _MetaSeatNativeFlag
-{
- META_SEAT_NATIVE_FLAG_NONE = 0,
- META_SEAT_NATIVE_FLAG_NO_LIBINPUT = 1 << 0,
-} MetaSeatNativeFlag;
-
-#endif /* META_BACKEND_NATIVE_TYPES_H */
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
deleted file mode 100644
index 81d9629d0..000000000
--- a/src/backends/native/meta-backend-native.c
+++ /dev/null
@@ -1,768 +0,0 @@
-/* -*- 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 "backends/native/meta-input-thread.h"
-
-#include <sched.h>
-#include <stdlib.h>
-
-#include "backends/meta-cursor-tracker-private.h"
-#include "backends/meta-idle-manager.h"
-#include "backends/meta-keymap-utils.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-clutter-backend-native.h"
-#include "backends/native/meta-device-pool-private.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-native.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"
-
-#ifdef HAVE_REMOTE_DESKTOP
-#include "backends/meta-screen-cast.h"
-#endif
-
-enum
-{
- PROP_0,
-
- PROP_HEADLESS,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS];
-
-struct _MetaBackendNative
-{
- MetaBackend parent;
-
- MetaLauncher *launcher;
- MetaDevicePool *device_pool;
- MetaUdev *udev;
- MetaKms *kms;
-
- gboolean is_headless;
-
- 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_dispose (GObject *object)
-{
- MetaBackendNative *native = META_BACKEND_NATIVE (object);
-
- if (native->udev_device_added_handler_id)
- {
- disconnect_udev_device_added_handler (native);
- native->udev_device_added_handler_id = 0;
- }
-
- if (native->kms)
- meta_kms_prepare_shutdown (native->kms);
-
- G_OBJECT_CLASS (meta_backend_native_parent_class)->dispose (object);
-
- g_clear_object (&native->kms);
- g_clear_object (&native->udev);
- g_clear_object (&native->device_pool);
- g_clear_pointer (&native->launcher, meta_launcher_free);
-}
-
-static ClutterBackend *
-meta_backend_native_create_clutter_backend (MetaBackend *backend)
-{
- return g_object_new (META_TYPE_CLUTTER_BACKEND_NATIVE, NULL);
-}
-
-static ClutterSeat *
-meta_backend_native_create_default_seat (MetaBackend *backend,
- GError **error)
-{
- MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
- const char *seat_id;
- MetaSeatNativeFlag flags;
-
- seat_id = meta_backend_native_get_seat_id (backend_native);
-
- if (meta_backend_native_is_headless (backend_native))
- flags = META_SEAT_NATIVE_FLAG_NO_LIBINPUT;
- else
- flags = META_SEAT_NATIVE_FLAG_NONE;
-
- return CLUTTER_SEAT (g_object_new (META_TYPE_SEAT_NATIVE,
- "backend", backend,
- "seat-id", seat_id,
- "flags", flags,
- NULL));
-}
-
-#ifdef HAVE_REMOTE_DESKTOP
-static void
-maybe_disable_screen_cast_dma_bufs (MetaBackendNative *native)
-{
- MetaBackend *backend = META_BACKEND (native);
- MetaSettings *settings = meta_backend_get_settings (backend);
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
- MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
- MetaScreenCast *screen_cast = meta_backend_get_screen_cast (backend);
- MetaGpuKms *primary_gpu;
- MetaKmsDevice *kms_device;
- const char *driver_name;
- static const char *enable_dma_buf_drivers[] = {
- "i915",
- NULL,
- };
-
- primary_gpu = meta_renderer_native_get_primary_gpu (renderer_native);
- if (!primary_gpu)
- {
- g_message ("Disabling DMA buffer screen sharing (surfaceless)");
- goto disable_dma_bufs;
- }
-
- kms_device = meta_gpu_kms_get_kms_device (primary_gpu);
- driver_name = meta_kms_device_get_driver_name (kms_device);
-
- if (g_strv_contains (enable_dma_buf_drivers, driver_name))
- return;
-
- if (meta_settings_is_experimental_feature_enabled (settings,
- META_EXPERIMENTAL_FEATURE_DMA_BUF_SCREEN_SHARING))
- return;
-
- g_message ("Disabling DMA buffer screen sharing for driver '%s'.",
- driver_name);
-
-disable_dma_bufs:
- meta_screen_cast_disable_dma_bufs (screen_cast);
-}
-#endif /* HAVE_REMOTE_DESKTOP */
-
-static void
-update_viewports (MetaBackend *backend)
-{
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- MetaSeatNative *seat =
- META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
- MetaViewportInfo *viewports;
-
- viewports = meta_monitor_manager_get_viewports (monitor_manager);
- meta_seat_native_set_viewports (seat, viewports);
- g_object_unref (viewports);
-}
-
-static void
-meta_backend_native_post_init (MetaBackend *backend)
-{
- MetaSettings *settings = meta_backend_get_settings (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_REMOTE_DESKTOP
- maybe_disable_screen_cast_dma_bufs (META_BACKEND_NATIVE (backend));
-#endif
-
- update_viewports (backend);
-}
-
-static MetaMonitorManager *
-meta_backend_native_create_monitor_manager (MetaBackend *backend,
- GError **error)
-{
- MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
- MetaMonitorManager *manager;
-
- manager = g_initable_new (META_TYPE_MONITOR_MANAGER_NATIVE, NULL, error,
- "backend", backend,
- "needs-outputs", !backend_native->is_headless,
- NULL);
- if (!manager)
- return NULL;
-
- g_signal_connect_swapped (manager, "monitors-changed-internal",
- G_CALLBACK (update_viewports), backend);
-
- return manager;
-}
-
-static MetaCursorRenderer *
-meta_backend_native_get_cursor_renderer (MetaBackend *backend,
- ClutterInputDevice *device)
-{
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- MetaSeatNative *seat_native =
- META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
-
- return meta_seat_native_maybe_ensure_cursor_renderer (seat_native, device);
-}
-
-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_get_input_settings (MetaBackend *backend)
-{
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- MetaSeatNative *seat_native =
- META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
-
- return meta_seat_impl_get_input_settings (seat_native->impl);
-}
-
-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);
- graphene_point_t point;
-
- meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
- return meta_monitor_manager_get_logical_monitor_at (monitor_manager,
- point.x, point.y);
-}
-
-static void
-meta_backend_native_set_keymap (MetaBackend *backend,
- const char *layouts,
- const char *variants,
- const char *options)
-{
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- ClutterSeat *seat;
-
- seat = clutter_backend_get_default_seat (clutter_backend);
- meta_seat_native_set_keyboard_map (META_SEAT_NATIVE (seat),
- layouts, variants, options);
-
- meta_backend_notify_keymap_changed (backend);
-}
-
-static struct xkb_keymap *
-meta_backend_native_get_keymap (MetaBackend *backend)
-{
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- ClutterSeat *seat;
-
- seat = clutter_backend_get_default_seat (clutter_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)
-{
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- ClutterSeat *seat;
-
- seat = clutter_backend_get_default_seat (clutter_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)
-{
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- 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_backend);
- meta_seat_native_set_keyboard_layout_index (META_SEAT_NATIVE (seat), idx);
- meta_backend_notify_keymap_layout_group_changed (backend, idx);
-}
-
-const char *
-meta_backend_native_get_seat_id (MetaBackendNative *backend_native)
-{
- if (backend_native->is_headless)
- return "seat0";
- else
- return meta_launcher_get_seat_id (backend_native->launcher);
-}
-
-gboolean
-meta_backend_native_is_headless (MetaBackendNative *backend_native)
-{
- return backend_native->is_headless;
-}
-
-static void
-meta_backend_native_set_pointer_constraint (MetaBackend *backend,
- MetaPointerConstraint *constraint)
-{
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
- MetaPointerConstraintImpl *constraint_impl = NULL;
- cairo_region_t *region;
-
- if (constraint)
- {
- region = meta_pointer_constraint_get_region (constraint);
- constraint_impl = meta_pointer_constraint_impl_native_new (constraint,
- region);
- }
-
- meta_seat_native_set_pointer_constraint (META_SEAT_NATIVE (seat),
- constraint_impl);
-}
-
-static void
-meta_backend_native_update_screen_size (MetaBackend *backend,
- int width, int height)
-{
- ClutterActor *stage = meta_backend_get_stage (backend);
- ClutterStageWindow *stage_window =
- _clutter_stage_get_window (CLUTTER_STAGE (stage));
- MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
-
- 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;
-
- if (meta_is_udev_device_disable_modifiers (device))
- flags |= META_KMS_DEVICE_FLAG_DISABLE_MODIFIERS;
-
- if (meta_is_udev_device_preferred_primary (device))
- flags |= META_KMS_DEVICE_FLAG_PREFERRED_PRIMARY;
-
- 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;
- }
- }
-
- if (meta_is_udev_device_ignore (device))
- {
- g_message ("Ignoring DRM device '%s' (from udev rule)", device_path);
- 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 (*error)
- return FALSE;
-
- for (l = devices; l; l = l->next)
- {
- GUdevDevice *device = l->data;
- MetaGpuKms *gpu_kms;
- GError *local_error = NULL;
-
- if (meta_is_udev_device_ignore (device))
- {
- g_message ("Ignoring DRM device '%s' (from udev rule)",
- g_udev_device_get_device_file (device));
- continue;
- }
-
- 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 (!native->is_headless &&
- 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);
- MetaKmsFlags kms_flags;
-
- 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;
- }
-
- if (!native->is_headless)
- {
- native->launcher = meta_launcher_new (error);
- if (!native->launcher)
- return FALSE;
- }
-
- native->device_pool = meta_device_pool_new (native->launcher);
- native->udev = meta_udev_new (native);
-
- kms_flags = META_KMS_FLAG_NONE;
- if (native->is_headless)
- kms_flags |= META_KMS_FLAG_NO_MODE_SETTING;
-
- native->kms = meta_kms_new (META_BACKEND (native), kms_flags, error);
- if (!native->kms)
- return FALSE;
-
- if (!init_gpus (native, error))
- return FALSE;
-
- return initable_parent_iface->init (initable, cancellable, error);
-}
-
-static void
-meta_backend_native_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaBackendNative *backend_native = META_BACKEND_NATIVE (object);
-
- switch (prop_id)
- {
- case PROP_HEADLESS:
- backend_native->is_headless = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-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->set_property = meta_backend_native_set_property;
- object_class->dispose = meta_backend_native_dispose;
-
- backend_class->create_clutter_backend = meta_backend_native_create_clutter_backend;
- backend_class->create_default_seat = meta_backend_native_create_default_seat;
-
- backend_class->post_init = meta_backend_native_post_init;
-
- backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager;
- backend_class->get_cursor_renderer = meta_backend_native_get_cursor_renderer;
- backend_class->create_renderer = meta_backend_native_create_renderer;
- backend_class->get_input_settings = meta_backend_native_get_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_pointer_constraint = meta_backend_native_set_pointer_constraint;
-
- obj_props[PROP_HEADLESS] =
- g_param_spec_boolean ("headless",
- "headless",
- "Headless",
- FALSE,
- G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, N_PROPS, obj_props);
-}
-
-static void
-meta_backend_native_init (MetaBackendNative *native)
-{
-}
-
-MetaLauncher *
-meta_backend_native_get_launcher (MetaBackendNative *native)
-{
- return native->launcher;
-}
-
-MetaDevicePool *
-meta_backend_native_get_device_pool (MetaBackendNative *native)
-{
- return native->device_pool;
-}
-
-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);
-
- if (native->is_headless)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Can't switch VT while headless");
- return FALSE;
- }
-
- return meta_launcher_activate_vt (launcher, vt, error);
-}
-
-void
-meta_backend_native_pause (MetaBackendNative *native)
-{
- MetaBackend *backend = META_BACKEND (native);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- MetaMonitorManagerNative *monitor_manager_native =
- META_MONITOR_MANAGER_NATIVE (monitor_manager);
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- MetaSeatNative *seat =
- META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
-
- COGL_TRACE_BEGIN_SCOPED (MetaBackendNativePause,
- "Backend (pause)");
-
- meta_seat_native_release_devices (seat);
- meta_renderer_pause (renderer);
-
- disconnect_udev_device_added_handler (native);
-
- meta_monitor_manager_native_pause (monitor_manager_native);
-}
-
-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);
- MetaMonitorManagerNative *monitor_manager_native =
- META_MONITOR_MANAGER_NATIVE (monitor_manager);
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- MetaSeatNative *seat =
- META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
- MetaIdleManager *idle_manager;
- MetaInputSettings *input_settings;
-
- COGL_TRACE_BEGIN_SCOPED (MetaBackendNativeResume,
- "Backend (resume)");
-
- meta_monitor_manager_native_resume (monitor_manager_native);
- meta_kms_resume (native->kms);
-
- connect_udev_device_added_handler (native);
-
- meta_seat_native_reclaim_devices (seat);
- meta_renderer_resume (renderer);
-
- clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
-
- idle_manager = meta_backend_get_idle_manager (backend);
- meta_idle_manager_reset_idle_time (idle_manager);
-
- 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
deleted file mode 100644
index aad4c8413..000000000
--- a/src/backends/native/meta-backend-native.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- 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 ())
-META_EXPORT_TEST
-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);
-
-const char * meta_backend_native_get_seat_id (MetaBackendNative *backend_native);
-
-gboolean meta_backend_native_is_headless (MetaBackendNative *backend_native);
-
-#endif /* META_BACKEND_NATIVE_H */
diff --git a/src/backends/native/meta-barrier-native.c b/src/backends/native/meta-barrier-native.c
deleted file mode 100644
index 3c9c1eabe..000000000
--- a/src/backends/native/meta-barrier-native.c
+++ /dev/null
@@ -1,652 +0,0 @@
-/* -*- 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-seat-native.h"
-#include "meta/barrier.h"
-#include "meta/util.h"
-
-struct _MetaBarrierManagerNative
-{
- GHashTable *barriers;
- GMutex mutex;
-};
-
-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;
- GMainContext *main_context;
-};
-
-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;
-
-typedef struct
-{
- MetaBarrierEvent *event;
- MetaBarrier *barrier;
- MetaBarrierState state;
-} MetaBarrierIdleData;
-
-static gboolean
-emit_event_idle (MetaBarrierIdleData *idle_data)
-{
- if (idle_data->state == META_BARRIER_STATE_HELD)
- _meta_barrier_emit_hit_signal (idle_data->barrier, idle_data->event);
- else
- _meta_barrier_emit_left_signal (idle_data->barrier, idle_data->event);
-
- meta_barrier_event_unref (idle_data->event);
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-queue_event (MetaBarrierImplNative *self,
- MetaBarrierEvent *event)
-{
- MetaBarrierIdleData *idle_data;
- GSource *source;
-
- idle_data = g_new0 (MetaBarrierIdleData, 1);
- idle_data->state = self->state;
- idle_data->barrier = self->barrier;
- idle_data->event = event;
-
- source = g_idle_source_new ();
- g_source_set_priority (source, G_PRIORITY_HIGH);
- g_source_set_callback (source,
- (GSourceFunc) emit_event_idle,
- idle_data,
- g_free);
-
- g_source_attach (source, self->main_context);
- g_source_unref (source);
-}
-
-static void
-emit_barrier_event (MetaBarrierImplNative *self,
- guint32 time,
- float prev_x,
- float prev_y,
- float x,
- float y,
- float dx,
- float dy)
-{
- MetaBarrierEvent *event = g_new0 (MetaBarrierEvent, 1);
- 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;
-
- queue_event (self, 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_in_impl (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_seat_query_state (clutter_input_device_get_seat (device),
- device, NULL, &prev_pos, NULL))
- return;
-
- g_mutex_lock (&manager->mutex);
-
- 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);
-
- g_mutex_unlock (&manager->mutex);
-}
-
-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_mutex_lock (&self->manager->mutex);
- g_hash_table_remove (self->manager->barriers, self);
- g_mutex_unlock (&self->manager->mutex);
- g_main_context_unref (self->main_context);
- self->is_active = FALSE;
-}
-
-MetaBarrierImpl *
-meta_barrier_impl_native_new (MetaBarrier *barrier)
-{
- MetaBarrierImplNative *self;
- MetaBarrierManagerNative *manager;
- ClutterBackend *backend = clutter_get_default_backend ();
- ClutterSeat *seat = clutter_backend_get_default_seat (backend);
-
- self = g_object_new (META_TYPE_BARRIER_IMPL_NATIVE, NULL);
-
- self->barrier = barrier;
- self->is_active = TRUE;
- self->main_context = g_main_context_ref_thread_default ();
-
- manager = meta_seat_native_get_barrier_manager (META_SEAT_NATIVE (seat));
- self->manager = manager;
- g_mutex_lock (&manager->mutex);
- g_hash_table_add (manager->barriers, self);
- g_mutex_unlock (&manager->mutex);
-
- 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);
- g_mutex_init (&manager->mutex);
-
- return manager;
-}
diff --git a/src/backends/native/meta-barrier-native.h b/src/backends/native/meta-barrier-native.h
deleted file mode 100644
index 1bcf56c7c..000000000
--- a/src/backends/native/meta-barrier-native.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- 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_in_impl (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
deleted file mode 100644
index a28ecea99..000000000
--- a/src/backends/native/meta-clutter-backend-native.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* -*- 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-backend-native.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
-{
- ClutterBackend parent;
-};
-
-G_DEFINE_TYPE (MetaClutterBackendNative, meta_clutter_backend_native,
- CLUTTER_TYPE_BACKEND)
-
-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 *clutter_backend,
- ClutterStage *wrapper,
- GError **error)
-{
- return g_object_new (META_TYPE_STAGE_NATIVE,
- "backend", clutter_backend,
- "wrapper", wrapper,
- NULL);
-}
-
-static ClutterSeat *
-meta_clutter_backend_native_get_default_seat (ClutterBackend *clutter_backend)
-{
- MetaBackend *backend = meta_get_backend ();
-
- return meta_backend_get_default_seat (backend);
-}
-
-static gboolean
-meta_clutter_backend_native_is_display_server (ClutterBackend *clutter_backend)
-{
- return TRUE;
-}
-
-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->get_default_seat = meta_clutter_backend_native_get_default_seat;
- clutter_backend_class->is_display_server = meta_clutter_backend_native_is_display_server;
-}
diff --git a/src/backends/native/meta-clutter-backend-native.h b/src/backends/native/meta-clutter-backend-native.h
deleted file mode 100644
index dea35988c..000000000
--- a/src/backends/native/meta-clutter-backend-native.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- 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"
-
-#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,
- ClutterBackend)
-
-#endif /* META_CLUTTER_BACKEND_NATIVE_H */
diff --git a/src/backends/native/meta-cogl-utils.c b/src/backends/native/meta-cogl-utils.c
deleted file mode 100644
index 582f86661..000000000
--- a/src/backends/native/meta-cogl-utils.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* meta-cogl-utils.c
- *
- * Copyright 2020 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- *
- */
-
-#include "backends/native/meta-cogl-utils.h"
-
-#include <drm_fourcc.h>
-
-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
-};
-
-gboolean
-meta_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;
-}
diff --git a/src/backends/native/meta-cogl-utils.h b/src/backends/native/meta-cogl-utils.h
deleted file mode 100644
index b5fe6296f..000000000
--- a/src/backends/native/meta-cogl-utils.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* meta-cogl-utils.h
- *
- * Copyright 2020 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- *
- */
-
-#ifndef META_COGL_UTILS_H
-#define META_COGL_UTILS_H
-
-#include "cogl/cogl.h"
-
-G_BEGIN_DECLS
-
-gboolean
-meta_cogl_pixel_format_from_drm_format (uint32_t drm_format,
- CoglPixelFormat *out_format,
- CoglTextureComponents *out_components);
-
-G_END_DECLS
-
-#endif /* META_COGL_UTILS_H */
diff --git a/src/backends/native/meta-crtc-kms.c b/src/backends/native/meta-crtc-kms.c
deleted file mode 100644
index f1bc79146..000000000
--- a/src/backends/native/meta-crtc-kms.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/* -*- 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-crtc-mode-kms.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-mode.h"
-#include "backends/native/meta-kms-plane.h"
-#include "backends/native/meta-kms-update.h"
-#include "backends/native/meta-kms.h"
-#include "backends/native/meta-monitor-manager-native.h"
-
-#define ALL_TRANSFORMS_MASK ((1 << META_MONITOR_N_TRANSFORMS) - 1)
-
-struct _MetaCrtcKms
-{
- MetaCrtcNative parent;
-
- MetaKmsCrtc *kms_crtc;
-
- MetaKmsPlane *primary_plane;
-
- gpointer cursor_renderer_private;
- GDestroyNotify cursor_renderer_private_destroy_notify;
-
- gboolean is_gamma_valid;
-};
-
-static GQuark kms_crtc_crtc_kms_quark;
-
-G_DEFINE_TYPE (MetaCrtcKms, meta_crtc_kms, META_TYPE_CRTC_NATIVE)
-
-gpointer
-meta_crtc_kms_get_cursor_renderer_private (MetaCrtcKms *crtc_kms)
-{
- return crtc_kms->cursor_renderer_private;
-}
-
-void
-meta_crtc_kms_set_cursor_renderer_private (MetaCrtcKms *crtc_kms,
- gpointer cursor_renderer_private,
- GDestroyNotify destroy_notify)
-{
- g_clear_pointer (&crtc_kms->cursor_renderer_private,
- crtc_kms->cursor_renderer_private_destroy_notify);
-
- crtc_kms->cursor_renderer_private = cursor_renderer_private;
- crtc_kms->cursor_renderer_private_destroy_notify = destroy_notify;
-}
-
-static gboolean
-is_transform_handled (MetaCrtcKms *crtc_kms,
- MetaMonitorTransform transform)
-{
- if (!crtc_kms->primary_plane)
- return FALSE;
-
- return meta_kms_plane_is_transform_handled (crtc_kms->primary_plane,
- transform);
-}
-
-static gboolean
-meta_crtc_kms_is_transform_handled (MetaCrtcNative *crtc_native,
- MetaMonitorTransform transform)
-{
- MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc_native);
-
- return is_transform_handled (crtc_kms, transform);
-}
-
-void
-meta_crtc_kms_apply_transform (MetaCrtcKms *crtc_kms,
- MetaKmsPlaneAssignment *kms_plane_assignment)
-{
- MetaCrtc *crtc = META_CRTC (crtc_kms);
- const MetaCrtcConfig *crtc_config;
- MetaMonitorTransform hw_transform;
-
- crtc_config = meta_crtc_get_config (crtc);
-
- hw_transform = crtc_config->transform;
- if (!is_transform_handled (crtc_kms, hw_transform))
- hw_transform = META_MONITOR_TRANSFORM_NORMAL;
- if (!is_transform_handled (crtc_kms, 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 (MetaCrtcKms *crtc_kms,
- MetaDrmBuffer *buffer,
- MetaKmsUpdate *kms_update)
-{
- MetaCrtc *crtc = META_CRTC (crtc_kms);
- const MetaCrtcConfig *crtc_config;
- const MetaCrtcModeInfo *crtc_mode_info;
- MetaFixed16Rectangle src_rect;
- MetaRectangle dst_rect;
- MetaKmsAssignPlaneFlag flags;
- MetaKmsCrtc *kms_crtc;
- MetaKmsDevice *kms_device;
- MetaKmsPlane *primary_kms_plane;
- MetaKmsPlaneAssignment *plane_assignment;
-
- crtc_config = meta_crtc_get_config (crtc);
- crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode);
-
- src_rect = (MetaFixed16Rectangle) {
- .x = meta_fixed_16_from_int (0),
- .y = meta_fixed_16_from_int (0),
- .width = meta_fixed_16_from_int (crtc_mode_info->width),
- .height = meta_fixed_16_from_int (crtc_mode_info->height),
- };
- dst_rect = (MetaRectangle) {
- .x = 0,
- .y = 0,
- .width = crtc_mode_info->width,
- .height = crtc_mode_info->height,
- };
-
- flags = META_KMS_ASSIGN_PLANE_FLAG_NONE;
-
- kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
- 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,
- buffer,
- src_rect,
- dst_rect,
- flags);
- meta_crtc_kms_apply_transform (crtc_kms, 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 (META_OUTPUT_KMS (output));
-
- connectors = g_list_prepend (connectors, kms_connector);
- }
- }
-
- return connectors;
-}
-
-void
-meta_crtc_kms_maybe_set_gamma (MetaCrtcKms *crtc_kms,
- MetaKmsDevice *kms_device)
-{
- MetaGpu *gpu = meta_crtc_get_gpu (META_CRTC (crtc_kms));
- MetaBackend *backend = meta_gpu_get_backend (gpu);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- MetaMonitorManagerNative *monitor_manager_native =
- META_MONITOR_MANAGER_NATIVE (monitor_manager);
- MetaKms *kms = meta_kms_device_get_kms (kms_device);
- MetaKmsUpdate *kms_update;
- MetaKmsCrtcGamma *gamma;
-
- if (crtc_kms->is_gamma_valid)
- return;
-
- gamma = meta_monitor_manager_native_get_cached_crtc_gamma (monitor_manager_native,
- crtc_kms);
- if (!gamma)
- return;
-
- kms_update = meta_kms_ensure_pending_update (kms, kms_device);
- meta_kms_update_set_crtc_gamma (kms_update,
- meta_crtc_kms_get_kms_crtc (crtc_kms),
- gamma->size,
- gamma->red,
- gamma->green,
- gamma->blue);
-
- crtc_kms->is_gamma_valid = TRUE;
-}
-
-void
-meta_crtc_kms_set_mode (MetaCrtcKms *crtc_kms,
- MetaKmsUpdate *kms_update)
-{
- MetaCrtc *crtc = META_CRTC (crtc_kms);
- MetaGpu *gpu = meta_crtc_get_gpu (crtc);
- GList *connectors;
- MetaKmsMode *kms_mode;
-
- connectors = generate_crtc_connector_list (gpu, crtc);
-
- if (connectors)
- {
- const MetaCrtcConfig *crtc_config = meta_crtc_get_config (crtc);
- MetaCrtcModeKms *crtc_mode_kms = META_CRTC_MODE_KMS (crtc_config->mode);
-
- kms_mode = meta_crtc_mode_kms_get_kms_mode (crtc_mode_kms);
-
- meta_topic (META_DEBUG_KMS,
- "Setting CRTC (%" G_GUINT64_FORMAT ") mode to %s",
- meta_crtc_get_id (crtc), meta_kms_mode_get_name (kms_mode));
- }
- else
- {
- kms_mode = NULL;
-
- meta_topic (META_DEBUG_KMS,
- "Unsetting CRTC (%" G_GUINT64_FORMAT ") mode",
- meta_crtc_get_id (crtc));
- }
-
- meta_kms_update_mode_set (kms_update,
- meta_crtc_kms_get_kms_crtc (crtc_kms),
- g_steal_pointer (&connectors),
- kms_mode);
-}
-
-MetaKmsCrtc *
-meta_crtc_kms_get_kms_crtc (MetaCrtcKms *crtc_kms)
-{
- return crtc_kms->kms_crtc;
-}
-
-/**
- * meta_crtc_kms_get_modifiers:
- * @crtc_kms: 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 (MetaCrtcKms *crtc_kms,
- uint32_t format)
-{
- return meta_kms_plane_get_modifiers_for_format (crtc_kms->primary_plane,
- format);
-}
-
-/**
- * meta_crtc_kms_copy_drm_format_list:
- * @crtc_kms: 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 (MetaCrtcKms *crtc_kms)
-{
- return meta_kms_plane_copy_drm_format_list (crtc_kms->primary_plane);
-}
-
-/**
- * meta_crtc_kms_supports_format:
- * @crtc_kms: 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 (MetaCrtcKms *crtc_kms,
- uint32_t drm_format)
-{
- return meta_kms_plane_is_format_supported (crtc_kms->primary_plane,
- drm_format);
-}
-
-void
-meta_crtc_kms_invalidate_gamma (MetaCrtcKms *crtc_kms)
-{
- crtc_kms->is_gamma_valid = FALSE;
-}
-
-MetaCrtcKms *
-meta_crtc_kms_from_kms_crtc (MetaKmsCrtc *kms_crtc)
-{
- return g_object_get_qdata (G_OBJECT (kms_crtc), kms_crtc_crtc_kms_quark);
-}
-
-MetaCrtcKms *
-meta_crtc_kms_new (MetaGpuKms *gpu_kms,
- MetaKmsCrtc *kms_crtc)
-{
- MetaGpu *gpu = META_GPU (gpu_kms);
- MetaKmsDevice *kms_device;
- 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_kms = g_object_new (META_TYPE_CRTC_KMS,
- "id", (uint64_t) meta_kms_crtc_get_id (kms_crtc),
- "gpu", gpu,
- NULL);
-
- crtc_kms->kms_crtc = kms_crtc;
- crtc_kms->primary_plane = primary_plane;
-
- 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_kms);
-
- return crtc_kms;
-}
-
-static void
-meta_crtc_kms_dispose (GObject *object)
-{
- MetaCrtcKms *crtc_kms = META_CRTC_KMS (object);
-
- g_clear_pointer (&crtc_kms->cursor_renderer_private,
- crtc_kms->cursor_renderer_private_destroy_notify);
-
- G_OBJECT_CLASS (meta_crtc_kms_parent_class)->dispose (object);
-}
-
-static void
-meta_crtc_kms_init (MetaCrtcKms *crtc_kms)
-{
-}
-
-static void
-meta_crtc_kms_class_init (MetaCrtcKmsClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- MetaCrtcNativeClass *crtc_native_class = META_CRTC_NATIVE_CLASS (klass);
-
- object_class->dispose = meta_crtc_kms_dispose;
-
- crtc_native_class->is_transform_handled = meta_crtc_kms_is_transform_handled;
-}
diff --git a/src/backends/native/meta-crtc-kms.h b/src/backends/native/meta-crtc-kms.h
deleted file mode 100644
index f8d241bbb..000000000
--- a/src/backends/native/meta-crtc-kms.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- 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-crtc-native.h"
-#include "backends/native/meta-drm-buffer.h"
-#include "backends/native/meta-gpu-kms.h"
-#include "backends/native/meta-kms-crtc.h"
-#include "backends/native/meta-kms-update.h"
-
-#define META_TYPE_CRTC_KMS (meta_crtc_kms_get_type ())
-G_DECLARE_FINAL_TYPE (MetaCrtcKms, meta_crtc_kms,
- META, CRTC_KMS,
- MetaCrtcNative)
-
-gpointer meta_crtc_kms_get_cursor_renderer_private (MetaCrtcKms *crtc_kms);
-
-void meta_crtc_kms_set_cursor_renderer_private (MetaCrtcKms *crtc_kms,
- gpointer cursor_renderer_private,
- GDestroyNotify destroy_notify);
-
-void meta_crtc_kms_apply_transform (MetaCrtcKms *crtc_kms,
- MetaKmsPlaneAssignment *kms_plane_assignment);
-
-void meta_crtc_kms_assign_primary_plane (MetaCrtcKms *crtc_kms,
- MetaDrmBuffer *buffer,
- MetaKmsUpdate *kms_update);
-
-void meta_crtc_kms_set_mode (MetaCrtcKms *crtc_kms,
- MetaKmsUpdate *kms_update);
-
-void meta_crtc_kms_set_is_underscanning (MetaCrtcKms *crtc_kms,
- gboolean is_underscanning);
-
-MetaKmsCrtc * meta_crtc_kms_get_kms_crtc (MetaCrtcKms *crtc_kms);
-
-GArray * meta_crtc_kms_get_modifiers (MetaCrtcKms *crtc_kms,
- uint32_t format);
-
-GArray *
-meta_crtc_kms_copy_drm_format_list (MetaCrtcKms *crtc_kms);
-
-gboolean
-meta_crtc_kms_supports_format (MetaCrtcKms *crtc_kms,
- uint32_t drm_format);
-
-void meta_crtc_kms_invalidate_gamma (MetaCrtcKms *crtc_kms);
-
-void meta_crtc_kms_maybe_set_gamma (MetaCrtcKms *crtc_kms,
- MetaKmsDevice *kms_device);
-
-MetaCrtcKms * meta_crtc_kms_from_kms_crtc (MetaKmsCrtc *kms_crtc);
-
-MetaCrtcKms * meta_crtc_kms_new (MetaGpuKms *gpu_kms,
- MetaKmsCrtc *kms_crtc);
-
-#endif /* META_CRTC_KMS_H */
diff --git a/src/backends/native/meta-crtc-mode-kms.c b/src/backends/native/meta-crtc-mode-kms.c
deleted file mode 100644
index 053367cfd..000000000
--- a/src/backends/native/meta-crtc-mode-kms.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2017-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.
- */
-
-#include "config.h"
-
-#include "backends/native/meta-crtc-mode-kms.h"
-
-#include "backends/native/meta-kms-mode.h"
-#include "backends/native/meta-kms-utils.h"
-
-struct _MetaCrtcModeKms
-{
- MetaCrtcMode parent;
-
- MetaKmsMode *kms_mode;
-};
-
-G_DEFINE_TYPE (MetaCrtcModeKms, meta_crtc_mode_kms,
- META_TYPE_CRTC_MODE)
-
-MetaKmsMode *
-meta_crtc_mode_kms_get_kms_mode (MetaCrtcModeKms *mode_kms)
-{
- return mode_kms->kms_mode;
-}
-
-MetaCrtcModeKms *
-meta_crtc_mode_kms_new (MetaKmsMode *kms_mode,
- uint64_t id)
-{
- const drmModeModeInfo *drm_mode = meta_kms_mode_get_drm_mode (kms_mode);
- g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL;
- g_autofree char *crtc_mode_name = NULL;
- MetaCrtcModeKms *mode_kms;
-
- crtc_mode_info = meta_crtc_mode_info_new ();
- crtc_mode_info->width = drm_mode->hdisplay;
- crtc_mode_info->height = drm_mode->vdisplay;
- crtc_mode_info->flags = drm_mode->flags;
- crtc_mode_info->refresh_rate =
- meta_calculate_drm_mode_refresh_rate (drm_mode);
- crtc_mode_info->vblank_duration_us =
- meta_calculate_drm_mode_vblank_duration_us (drm_mode);
-
- crtc_mode_name = g_strndup (drm_mode->name, DRM_DISPLAY_MODE_LEN);
- mode_kms = g_object_new (META_TYPE_CRTC_MODE_KMS,
- "id", id,
- "name", crtc_mode_name,
- "info", crtc_mode_info,
- NULL);
-
- mode_kms->kms_mode = kms_mode;
-
- return mode_kms;
-}
-
-static void
-meta_crtc_mode_kms_init (MetaCrtcModeKms *mode_kms)
-{
-}
-
-static void
-meta_crtc_mode_kms_class_init (MetaCrtcModeKmsClass *klass)
-{
-}
diff --git a/src/backends/native/meta-crtc-mode-kms.h b/src/backends/native/meta-crtc-mode-kms.h
deleted file mode 100644
index f39268612..000000000
--- a/src/backends/native/meta-crtc-mode-kms.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017-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.
- */
-
-#ifndef META_CRTC_MODE_KMS_H
-#define META_CRTC_MODE_KMS_H
-
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-
-#include "backends/meta-crtc-mode.h"
-#include "backends/native/meta-kms-types.h"
-
-#define META_TYPE_CRTC_MODE_KMS (meta_crtc_mode_kms_get_type ())
-G_DECLARE_FINAL_TYPE (MetaCrtcModeKms, meta_crtc_mode_kms,
- META, CRTC_MODE_KMS,
- MetaCrtcMode)
-
-MetaKmsMode * meta_crtc_mode_kms_get_kms_mode (MetaCrtcModeKms *mode_kms);
-
-MetaCrtcModeKms * meta_crtc_mode_kms_new (MetaKmsMode *kms_mode,
- uint64_t id);
-
-#endif /* META_CRTC_MODE_KMS_H */
diff --git a/src/backends/native/meta-crtc-mode-virtual.c b/src/backends/native/meta-crtc-mode-virtual.c
deleted file mode 100644
index 3bb883049..000000000
--- a/src/backends/native/meta-crtc-mode-virtual.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2021 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-crtc-mode-virtual.h"
-
-#include "backends/meta-virtual-monitor.h"
-
-struct _MetaCrtcModeVirtual
-{
- MetaCrtcMode parent;
-};
-
-#define META_CRTC_MODE_VIRTUAL_ID_BIT (((uint64_t) 1) << 63)
-
-G_DEFINE_TYPE (MetaCrtcModeVirtual, meta_crtc_mode_virtual,
- META_TYPE_CRTC_MODE)
-
-MetaCrtcModeVirtual *
-meta_crtc_mode_virtual_new (uint64_t id,
- const MetaVirtualMonitorInfo *info)
-{
- g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL;
- g_autofree char *crtc_mode_name = NULL;
- MetaCrtcModeVirtual *mode_virtual;
-
- crtc_mode_info = meta_crtc_mode_info_new ();
- crtc_mode_info->width = info->width;
- crtc_mode_info->height = info->height;
- crtc_mode_info->refresh_rate = info->refresh_rate;
-
- crtc_mode_name = g_strdup_printf ("%dx%d@%f",
- info->width,
- info->height,
- info->refresh_rate);
- mode_virtual = g_object_new (META_TYPE_CRTC_MODE_VIRTUAL,
- "id", META_CRTC_MODE_VIRTUAL_ID_BIT | id,
- "name", crtc_mode_name,
- "info", crtc_mode_info,
- NULL);
-
- return mode_virtual;
-}
-
-static void
-meta_crtc_mode_virtual_init (MetaCrtcModeVirtual *mode_virtual)
-{
-}
-
-static void
-meta_crtc_mode_virtual_class_init (MetaCrtcModeVirtualClass *klass)
-{
-}
diff --git a/src/backends/native/meta-crtc-mode-virtual.h b/src/backends/native/meta-crtc-mode-virtual.h
deleted file mode 100644
index e3ddb289c..000000000
--- a/src/backends/native/meta-crtc-mode-virtual.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2021 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_MODE_VIRTUAL_H
-#define META_CRTC_MODE_VIRTUAL_H
-
-#include "backends/meta-backend-types.h"
-#include "backends/meta-crtc-mode.h"
-
-#define META_TYPE_CRTC_MODE_VIRTUAL (meta_crtc_mode_virtual_get_type ())
-G_DECLARE_FINAL_TYPE (MetaCrtcModeVirtual, meta_crtc_mode_virtual,
- META, CRTC_MODE_VIRTUAL,
- MetaCrtcMode)
-
-MetaCrtcModeVirtual * meta_crtc_mode_virtual_new (uint64_t id,
- const MetaVirtualMonitorInfo *info);
-
-#endif /* META_CRTC_MODE_VIRTUAL_H */
diff --git a/src/backends/native/meta-crtc-native.c b/src/backends/native/meta-crtc-native.c
deleted file mode 100644
index 5e5751780..000000000
--- a/src/backends/native/meta-crtc-native.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2021 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-crtc-native.h"
-
-G_DEFINE_ABSTRACT_TYPE (MetaCrtcNative, meta_crtc_native,
- META_TYPE_CRTC)
-
-gboolean
-meta_crtc_native_is_transform_handled (MetaCrtcNative *crtc_native,
- MetaMonitorTransform transform)
-{
- MetaCrtcNativeClass *klass = META_CRTC_NATIVE_GET_CLASS (crtc_native);
-
- return klass->is_transform_handled (crtc_native, transform);
-}
-
-static void
-meta_crtc_native_init (MetaCrtcNative *crtc_native)
-{
-}
-
-static void
-meta_crtc_native_class_init (MetaCrtcNativeClass *klass)
-{
-}
diff --git a/src/backends/native/meta-crtc-native.h b/src/backends/native/meta-crtc-native.h
deleted file mode 100644
index 0c16e5895..000000000
--- a/src/backends/native/meta-crtc-native.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 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_NATIVE_H
-#define META_CRTC_NATIVE_H
-
-#include "backends/meta-crtc.h"
-
-#define META_TYPE_CRTC_NATIVE (meta_crtc_native_get_type ())
-G_DECLARE_DERIVABLE_TYPE (MetaCrtcNative, meta_crtc_native,
- META, CRTC_NATIVE,
- MetaCrtc)
-
-struct _MetaCrtcNativeClass
-{
- MetaCrtcClass parent_class;
-
- gboolean (* is_transform_handled) (MetaCrtcNative *crtc_native,
- MetaMonitorTransform monitor_transform);
-};
-
-gboolean meta_crtc_native_is_transform_handled (MetaCrtcNative *crtc_native,
- MetaMonitorTransform transform);
-
-#endif /* META_CRTC_NATIVE_H */
diff --git a/src/backends/native/meta-crtc-virtual.c b/src/backends/native/meta-crtc-virtual.c
deleted file mode 100644
index eee346a23..000000000
--- a/src/backends/native/meta-crtc-virtual.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2021 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-crtc-virtual.h"
-
-struct _MetaCrtcVirtual
-{
- MetaCrtcNative parent;
-};
-
-#define META_CRTC_VIRTUAL_ID_BIT (((uint64_t) 1) << 63)
-
-G_DEFINE_TYPE (MetaCrtcVirtual, meta_crtc_virtual, META_TYPE_CRTC_NATIVE)
-
-MetaCrtcVirtual *
-meta_crtc_virtual_new (uint64_t id)
-{
- return g_object_new (META_TYPE_CRTC_VIRTUAL,
- "id", META_CRTC_VIRTUAL_ID_BIT | id,
- NULL);
-}
-
-static gboolean
-meta_crtc_virtual_is_transform_handled (MetaCrtcNative *crtc_native,
- MetaMonitorTransform transform)
-{
- return transform == META_MONITOR_TRANSFORM_NORMAL;
-}
-
-static void
-meta_crtc_virtual_init (MetaCrtcVirtual *crtc_virtual)
-{
-}
-
-static void
-meta_crtc_virtual_class_init (MetaCrtcVirtualClass *klass)
-{
- MetaCrtcNativeClass *crtc_native_class = META_CRTC_NATIVE_CLASS (klass);
-
- crtc_native_class->is_transform_handled =
- meta_crtc_virtual_is_transform_handled;
-}
diff --git a/src/backends/native/meta-crtc-virtual.h b/src/backends/native/meta-crtc-virtual.h
deleted file mode 100644
index 89b1bcc7a..000000000
--- a/src/backends/native/meta-crtc-virtual.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2021 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_VIRTUAL_H
-#define META_CRTC_VIRTUAL_H
-
-#include "backends/native/meta-crtc-native.h"
-
-#define META_TYPE_CRTC_VIRTUAL (meta_crtc_virtual_get_type ())
-G_DECLARE_FINAL_TYPE (MetaCrtcVirtual, meta_crtc_virtual,
- META, CRTC_VIRTUAL,
- MetaCrtcNative)
-
-MetaCrtcVirtual * meta_crtc_virtual_new (uint64_t id);
-
-#endif /* META_CRTC_VIRTUAL_H */
diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c
deleted file mode 100644
index effa0851d..000000000
--- a/src/backends/native/meta-cursor-renderer-native.c
+++ /dev/null
@@ -1,1878 +0,0 @@
-/* -*- 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-backend-native-private.h"
-#include "backends/native/meta-crtc-kms.h"
-#include "backends/native/meta-device-pool.h"
-#include "backends/native/meta-drm-buffer-gbm.h"
-#include "backends/native/meta-kms-device.h"
-#include "backends/native/meta-kms-plane.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;
-
-typedef struct _CrtcCursorData
-{
- MetaDrmBuffer *buffer;
- gboolean needs_sync_position;
- gboolean hw_state_invalidated;
-} CrtcCursorData;
-
-struct _MetaCursorRendererNative
-{
- MetaCursorRenderer parent;
-};
-
-struct _MetaCursorRendererNativePrivate
-{
- MetaBackend *backend;
-
- 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 _MetaCursorBufferState
-{
- META_CURSOR_BUFFER_STATE_NONE,
- META_CURSOR_BUFFER_STATE_SET,
- META_CURSOR_BUFFER_STATE_INVALIDATED,
-} MetaCursorBufferState;
-
-typedef struct _MetaCursorNativeGpuState
-{
- MetaGpu *gpu;
- unsigned int active_buffer_idx;
- MetaCursorBufferState pending_buffer_state;
- MetaDrmBuffer *buffers[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
-on_kms_update_result (const MetaKmsFeedback *kms_feedback,
- gpointer user_data);
-
-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 unsigned int
-get_pending_cursor_sprite_buffer_index (MetaCursorNativeGpuState *cursor_gpu_state)
-{
- return (cursor_gpu_state->active_buffer_idx + 1) % HW_CURSOR_BUFFER_COUNT;
-}
-
-static MetaDrmBuffer *
-get_pending_cursor_sprite_buffer (MetaCursorNativeGpuState *cursor_gpu_state)
-{
- unsigned int pending_buffer_idx;
-
- pending_buffer_idx =
- get_pending_cursor_sprite_buffer_index (cursor_gpu_state);
- return cursor_gpu_state->buffers[pending_buffer_idx];
-}
-
-static MetaDrmBuffer *
-get_active_cursor_sprite_buffer (MetaCursorNativeGpuState *cursor_gpu_state)
-{
- return cursor_gpu_state->buffers[cursor_gpu_state->active_buffer_idx];
-}
-
-static void
-set_pending_cursor_sprite_buffer (MetaCursorSprite *cursor_sprite,
- MetaGpuKms *gpu_kms,
- MetaDrmBuffer *buffer)
-{
- MetaCursorNativePrivate *cursor_priv;
- MetaCursorNativeGpuState *cursor_gpu_state;
- unsigned int pending_buffer_idx;
-
- cursor_priv = ensure_cursor_priv (cursor_sprite);
- cursor_gpu_state = ensure_cursor_gpu_state (cursor_priv, gpu_kms);
-
- pending_buffer_idx =
- get_pending_cursor_sprite_buffer_index (cursor_gpu_state);
- cursor_gpu_state->buffers[pending_buffer_idx] = buffer;
- cursor_gpu_state->pending_buffer_state = META_CURSOR_BUFFER_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 CrtcCursorData *
-ensure_crtc_cursor_data (MetaCrtcKms *crtc_kms)
-{
- CrtcCursorData *crtc_cursor_data;
-
- crtc_cursor_data = meta_crtc_kms_get_cursor_renderer_private (crtc_kms);
- if (!crtc_cursor_data)
- {
- crtc_cursor_data = g_new0 (CrtcCursorData, 1);
- crtc_cursor_data->hw_state_invalidated = TRUE;
- meta_crtc_kms_set_cursor_renderer_private (crtc_kms,
- crtc_cursor_data,
- g_free);
- }
-
- return crtc_cursor_data;
-}
-
-static void
-assign_cursor_plane (MetaCursorRendererNative *native,
- MetaCrtcKms *crtc_kms,
- int x,
- int y,
- MetaCursorSprite *cursor_sprite)
-{
- MetaCrtc *crtc = META_CRTC (crtc_kms);
- 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;
- MetaDrmBuffer *buffer;
- int cursor_width, cursor_height;
- MetaFixed16Rectangle src_rect;
- MetaRectangle dst_rect;
- MetaDrmBuffer *crtc_buffer;
- MetaKmsAssignPlaneFlag flags;
- CrtcCursorData *crtc_cursor_data;
- int cursor_hotspot_x;
- int cursor_hotspot_y;
- MetaKmsUpdate *kms_update;
- MetaKmsPlaneAssignment *plane_assignment;
-
- if (cursor_gpu_state->pending_buffer_state == META_CURSOR_BUFFER_STATE_SET)
- buffer = get_pending_cursor_sprite_buffer (cursor_gpu_state);
- else
- buffer = get_active_cursor_sprite_buffer (cursor_gpu_state);
-
- kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
- 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);
-
- 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 = (MetaRectangle) {
- .x = x,
- .y = y,
- .width = cursor_width,
- .height = cursor_height,
- };
-
- flags = META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL;
- crtc_cursor_data = ensure_crtc_cursor_data (crtc_kms);
- crtc_buffer = crtc_cursor_data->buffer;
- if (!crtc_cursor_data->hw_state_invalidated && buffer == crtc_buffer)
- flags |= META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED;
-
- kms_update =
- meta_kms_ensure_pending_update (meta_kms_device_get_kms (kms_device),
- meta_kms_crtc_get_device (kms_crtc));
- plane_assignment = meta_kms_update_assign_plane (kms_update,
- kms_crtc,
- cursor_plane,
- buffer,
- 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);
-
- meta_kms_update_add_result_listener (kms_update,
- on_kms_update_result,
- native);
-
- crtc_cursor_data->buffer = buffer;
-
- if (cursor_gpu_state->pending_buffer_state == META_CURSOR_BUFFER_STATE_SET)
- {
- cursor_gpu_state->active_buffer_idx =
- (cursor_gpu_state->active_buffer_idx + 1) % HW_CURSOR_BUFFER_COUNT;
- cursor_gpu_state->pending_buffer_state = META_CURSOR_BUFFER_STATE_NONE;
- }
-}
-
-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;
- }
-}
-
-static void
-set_crtc_cursor (MetaCursorRendererNative *cursor_renderer_native,
- MetaRendererView *view,
- MetaCrtc *crtc,
- MetaCursorSprite *cursor_sprite)
-{
- MetaCursorRenderer *cursor_renderer =
- META_CURSOR_RENDERER (cursor_renderer_native);
- MetaOutput *output = meta_crtc_get_outputs (crtc)->data;
- MetaMonitor *monitor = meta_output_get_monitor (output);
- MetaLogicalMonitor *logical_monitor =
- meta_monitor_get_logical_monitor (monitor);
- const MetaCrtcConfig *crtc_config = meta_crtc_get_config (crtc);
- graphene_rect_t rect;
- graphene_rect_t local_crtc_rect;
- graphene_rect_t local_cursor_rect;
- float view_scale;
- float crtc_cursor_x, crtc_cursor_y;
- CoglTexture *texture;
- int tex_width, tex_height;
- float cursor_crtc_scale;
- MetaRectangle cursor_rect;
- MetaMonitorTransform transform;
- MetaMonitorTransform inverted_transform;
- MetaMonitorMode *monitor_mode;
- MetaMonitorCrtcMode *monitor_crtc_mode;
- const MetaCrtcModeInfo *crtc_mode_info;
-
- view_scale = clutter_stage_view_get_scale (CLUTTER_STAGE_VIEW (view));
-
- rect = meta_cursor_renderer_calculate_rect (cursor_renderer, cursor_sprite);
- local_cursor_rect =
- GRAPHENE_RECT_INIT (rect.origin.x - logical_monitor->rect.x,
- rect.origin.y - logical_monitor->rect.y,
- rect.size.width,
- rect.size.height);
-
- local_crtc_rect = crtc_config->layout;
- graphene_rect_offset (&local_crtc_rect,
- -logical_monitor->rect.x,
- -logical_monitor->rect.y);
-
- crtc_cursor_x = (local_cursor_rect.origin.x -
- local_crtc_rect.origin.x) * view_scale;
- crtc_cursor_y = (local_cursor_rect.origin.y -
- local_crtc_rect.origin.y) * view_scale;
-
- texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
- tex_width = cogl_texture_get_width (texture);
- tex_height = cogl_texture_get_height (texture);
-
- cursor_crtc_scale =
- calculate_cursor_crtc_sprite_scale (cursor_sprite,
- 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)
- };
-
- transform = meta_logical_monitor_get_transform (logical_monitor);
- transform = meta_monitor_logical_to_crtc_transform (monitor, transform);
-
- inverted_transform = meta_monitor_transform_invert (transform);
-
- monitor_mode = meta_monitor_get_current_mode (monitor);
- monitor_crtc_mode = meta_monitor_get_crtc_mode_for_output (monitor,
- monitor_mode,
- output);
- crtc_mode_info = meta_crtc_mode_get_info (monitor_crtc_mode->crtc_mode);
- meta_rectangle_transform (&cursor_rect,
- inverted_transform,
- crtc_mode_info->width,
- crtc_mode_info->height,
- &cursor_rect);
-
- assign_cursor_plane (cursor_renderer_native,
- META_CRTC_KMS (crtc),
- cursor_rect.x,
- cursor_rect.y,
- cursor_sprite);
-}
-
-static void
-unset_crtc_cursor (MetaCursorRendererNative *native,
- MetaCrtc *crtc)
-{
- MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
- CrtcCursorData *crtc_cursor_data;
- MetaKmsCrtc *kms_crtc;
- MetaKmsDevice *kms_device;
- MetaKmsPlane *cursor_plane;
- MetaDrmBuffer *crtc_buffer;
-
- crtc_cursor_data = ensure_crtc_cursor_data (crtc_kms);
- crtc_buffer = crtc_cursor_data->buffer;
- if (!crtc_cursor_data->hw_state_invalidated && !crtc_buffer)
- return;
-
- kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
- 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)
- {
- MetaKms *kms = meta_kms_device_get_kms (kms_device);
- MetaKmsUpdate *kms_update;
-
- kms_update = meta_kms_ensure_pending_update (kms, kms_device);
- meta_kms_update_unassign_plane (kms_update, kms_crtc, cursor_plane);
- }
-
- crtc_cursor_data->buffer = NULL;
-}
-
-static void
-disable_hw_cursor_for_crtc (MetaKmsCrtc *kms_crtc,
- const GError *error)
-{
- MetaCrtcKms *crtc_kms = meta_crtc_kms_from_kms_crtc (kms_crtc);
- MetaCrtc *crtc = META_CRTC (crtc_kms);
- 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;
-}
-
-void
-meta_cursor_renderer_native_prepare_frame (MetaCursorRendererNative *cursor_renderer_native,
- MetaRendererView *view)
-{
- MetaCursorRenderer *cursor_renderer =
- META_CURSOR_RENDERER (cursor_renderer_native);
- 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);
- MetaCrtc *crtc = meta_renderer_view_get_crtc (view);
- MetaCursorSprite *cursor_sprite;
- graphene_rect_t cursor_rect;
- cairo_rectangle_int_t view_layout;
- graphene_rect_t view_rect;
- CrtcCursorData *crtc_cursor_data;
-
- if (meta_monitor_manager_get_power_save_mode (monitor_manager) !=
- META_POWER_SAVE_ON)
- return;
-
- if (!meta_crtc_get_gpu (crtc))
- return;
-
- crtc_cursor_data = ensure_crtc_cursor_data (META_CRTC_KMS (crtc));
- if (!crtc_cursor_data->hw_state_invalidated &&
- !crtc_cursor_data->needs_sync_position)
- return;
-
- cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
- if (!cursor_sprite)
- goto unset_cursor;
-
- if (!priv->has_hw_cursor)
- goto unset_cursor;
-
- cursor_rect = meta_cursor_renderer_calculate_rect (cursor_renderer,
- cursor_sprite);
- clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (view), &view_layout);
- view_rect = GRAPHENE_RECT_INIT (view_layout.x, view_layout.y,
- view_layout.width, view_layout.height);
- if (!graphene_rect_intersection (&cursor_rect, &view_rect, NULL))
- goto unset_cursor;
-
- set_crtc_cursor (cursor_renderer_native, view, crtc, cursor_sprite);
-
- meta_cursor_renderer_emit_painted (cursor_renderer,
- cursor_sprite,
- CLUTTER_STAGE_VIEW (view));
-
- crtc_cursor_data->needs_sync_position = FALSE;
- crtc_cursor_data->hw_state_invalidated = FALSE;
- return;
-
-unset_cursor:
- unset_crtc_cursor (cursor_renderer_native, crtc);
-
- crtc_cursor_data = ensure_crtc_cursor_data (META_CRTC_KMS (crtc));
- crtc_cursor_data->hw_state_invalidated = FALSE;
-}
-
-static gboolean
-has_valid_cursor_sprite_buffer (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_buffer_state)
- {
- case META_CURSOR_BUFFER_STATE_NONE:
- return get_active_cursor_sprite_buffer (cursor_gpu_state) != NULL;
- case META_CURSOR_BUFFER_STATE_SET:
- return TRUE;
- case META_CURSOR_BUFFER_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;
- MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
- MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
- 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)
-{
- MetaCursorRendererNative *cursor_renderer_native =
- META_CURSOR_RENDERER_NATIVE (renderer);
- MetaCursorRendererNativePrivate *priv =
- meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
- CoglTexture *texture;
- MetaMonitorTransform transform;
- float scale;
- GList *l;
-
- if (!gpus)
- return FALSE;
-
- if (!cursor_sprite)
- return FALSE;
-
- if (meta_backend_is_hw_cursors_inhibited (priv->backend))
- 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_buffer (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;
- MetaOutput *output = meta_monitor_get_main_output (monitor);
- MetaGpu *gpu;
-
- gpu = meta_output_get_gpu (output);
- if (gpu && !g_list_find (gpus, gpu))
- gpus = g_list_prepend (gpus, gpu);
- }
- }
-
- return gpus;
-}
-
-static void
-on_kms_update_result (const MetaKmsFeedback *kms_feedback,
- gpointer user_data)
-{
- MetaCursorRendererNative *cursor_renderer_native = user_data;
- MetaCursorRenderer *cursor_renderer =
- META_CURSOR_RENDERER (cursor_renderer_native);
- MetaCursorRendererNativePrivate *priv =
- meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
- gboolean has_hw_cursor_failure = FALSE;
- GList *l;
-
- for (l = meta_kms_feedback_get_failed_planes (kms_feedback); l; l = l->next)
- {
- MetaKmsPlaneFeedback *plane_feedback = l->data;
-
- switch (meta_kms_plane_get_plane_type (plane_feedback->plane))
- {
- case META_KMS_PLANE_TYPE_CURSOR:
- break;
- case META_KMS_PLANE_TYPE_PRIMARY:
- case META_KMS_PLANE_TYPE_OVERLAY:
- continue;
- }
-
- disable_hw_cursor_for_crtc (plane_feedback->crtc,
- plane_feedback->error);
- has_hw_cursor_failure = TRUE;
- }
-
- if (has_hw_cursor_failure)
- {
- priv->has_hw_cursor = FALSE;
- meta_cursor_renderer_force_update (cursor_renderer);
- }
-}
-
-static void
-schedule_sync_position (MetaCursorRendererNative *cursor_renderer_native)
-{
- MetaCursorRendererNativePrivate *priv =
- meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
- GList *l;
-
- for (l = meta_backend_get_gpus (priv->backend); l; l = l->next)
- {
- MetaGpu *gpu = l->data;
- GList *l_crtc;
-
- for (l_crtc = meta_gpu_get_crtcs (gpu); l_crtc; l_crtc = l_crtc->next)
- {
- MetaCrtcKms *crtc_kms = META_CRTC_KMS (l_crtc->data);
- CrtcCursorData *crtc_cursor_data;
-
- crtc_cursor_data = ensure_crtc_cursor_data (crtc_kms);
- crtc_cursor_data->needs_sync_position = TRUE;
- }
- }
-}
-
-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);
- ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (priv->backend));
- 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);
-
- schedule_sync_position (native);
- clutter_stage_schedule_update (stage);
-
- return (priv->has_hw_cursor ||
- !cursor_sprite ||
- !meta_cursor_sprite_get_cogl_texture (cursor_sprite));
-}
-
-static void
-unset_crtc_cursor_renderer_privates (MetaGpu *gpu,
- MetaDrmBuffer *buffer)
-{
- GList *l;
-
- for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
- {
- MetaCrtcKms *crtc_kms = META_CRTC_KMS (l->data);
- MetaDrmBuffer *crtc_buffer;
-
- crtc_buffer = meta_crtc_kms_get_cursor_renderer_private (crtc_kms);
- if (buffer == crtc_buffer)
- meta_crtc_kms_set_cursor_renderer_private (crtc_kms, NULL, NULL);
- }
-}
-
-static void
-cursor_gpu_state_free (MetaCursorNativeGpuState *cursor_gpu_state)
-{
- int i;
- MetaDrmBuffer *active_buffer;
-
- active_buffer = get_active_cursor_sprite_buffer (cursor_gpu_state);
- if (active_buffer)
- unset_crtc_cursor_renderer_privates (cursor_gpu_state->gpu,
- active_buffer);
-
- for (i = 0; i < HW_CURSOR_BUFFER_COUNT; i++)
- g_clear_object (&cursor_gpu_state->buffers[i]);
- 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))
- {
- unsigned int pending_buffer_idx;
-
- pending_buffer_idx = get_pending_cursor_sprite_buffer_index (cursor_gpu_state);
- g_clear_object (&cursor_gpu_state->buffers[pending_buffer_idx]);
- cursor_gpu_state->pending_buffer_state =
- META_CURSOR_BUFFER_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)
-{
- MetaCursorRendererNativePrivate *priv =
- meta_cursor_renderer_native_get_instance_private (native);
- 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)",
- (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))
- {
- MetaBackendNative *backend_native = META_BACKEND_NATIVE (priv->backend);
- MetaDevicePool *device_pool =
- meta_backend_native_get_device_pool (backend_native);
- g_autoptr (MetaDeviceFile) device_file = NULL;
- struct gbm_bo *bo;
- uint8_t buf[4 * cursor_width * cursor_height];
- uint i;
- g_autoptr (GError) error = NULL;
- MetaDrmBufferGbm *buffer_gbm;
-
- device_file = meta_device_pool_open (device_pool,
- meta_gpu_kms_get_file_path (gpu_kms),
- META_DEVICE_FILE_FLAG_TAKE_CONTROL,
- &error);
- if (!device_file)
- {
- g_warning ("Failed to open '%s' for updating the cursor: %s",
- meta_gpu_kms_get_file_path (gpu_kms),
- error->message);
- return;
- }
-
- 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");
- 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;
- }
-
- buffer_gbm = meta_drm_buffer_gbm_new_take (device_file, bo, FALSE, &error);
- if (!buffer_gbm)
- {
- meta_warning ("Failed to create DRM buffer wrapper: %s",
- error->message);
- gbm_bo_destroy (bo);
- return;
- }
-
- set_pending_cursor_sprite_buffer (cursor_sprite, gpu_kms,
- META_DRM_BUFFER (buffer_gbm));
- }
- else
- {
- meta_warning ("HW cursor for format %d not supported", 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_buffer_state)
- {
- case META_CURSOR_BUFFER_STATE_SET:
- case META_CURSOR_BUFFER_STATE_NONE:
- return TRUE;
- case META_CURSOR_BUFFER_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);
- MetaCursorRendererNativePrivate *priv =
- meta_cursor_renderer_native_get_instance_private (native);
- 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
- {
- MetaBackendNative *backend_native = META_BACKEND_NATIVE (priv->backend);
- MetaDevicePool *device_pool =
- meta_backend_native_get_device_pool (backend_native);
- g_autoptr (MetaDeviceFile) device_file = NULL;
- struct gbm_device *gbm_device;
- struct gbm_bo *bo;
- g_autoptr (GError) error = NULL;
- MetaDrmBufferGbm *buffer_gbm;
-
- device_file = meta_device_pool_open (device_pool,
- meta_gpu_kms_get_file_path (gpu_kms),
- META_DEVICE_FILE_FLAG_TAKE_CONTROL,
- &error);
- if (!device_file)
- {
- g_warning ("Failed to open '%s' for updating the cursor: %s",
- meta_gpu_kms_get_file_path (gpu_kms),
- error->message);
- return;
- }
-
- /* 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");
- 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");
- return;
- }
-
- unset_can_preprocess (cursor_sprite);
-
- buffer_gbm = meta_drm_buffer_gbm_new_take (device_file, bo, FALSE, &error);
- if (!buffer_gbm)
- {
- meta_warning ("Failed to create DRM buffer wrapper: %s",
- error->message);
- gbm_bo_destroy (bo);
- return;
- }
-
- set_pending_cursor_sprite_buffer (cursor_sprite, gpu_kms,
- META_DRM_BUFFER (buffer_gbm));
- }
-}
-#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);
- GList *l;
-
- for (l = meta_backend_get_gpus (priv->backend); l; l = l->next)
- {
- MetaGpu *gpu = l->data;
- GList *l_crtc;
-
- for (l_crtc = meta_gpu_get_crtcs (gpu); l_crtc; l_crtc = l_crtc->next)
- {
- MetaCrtcKms *crtc_kms = META_CRTC_KMS (l_crtc->data);
- CrtcCursorData *crtc_cursor_data;
-
- crtc_cursor_data = ensure_crtc_cursor_data (crtc_kms);
- crtc_cursor_data->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,
- ClutterInputDevice *device)
-{
- 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,
- "backend", backend,
- "device", device,
- 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;
-
- 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
deleted file mode 100644
index 5113b96ce..000000000
--- a/src/backends/native/meta-cursor-renderer-native.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- 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)
-
-void meta_cursor_renderer_native_prepare_frame (MetaCursorRendererNative *cursor_renderer_native,
- MetaRendererView *view);
-
-MetaCursorRendererNative * meta_cursor_renderer_native_new (MetaBackend *backend,
- ClutterInputDevice *device);
-
-#endif /* META_CURSOR_RENDERER_NATIVE_H */
diff --git a/src/backends/native/meta-device-pool-private.h b/src/backends/native/meta-device-pool-private.h
deleted file mode 100644
index 06a43f6f4..000000000
--- a/src/backends/native/meta-device-pool-private.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2021 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_DEVICE_POOL_PRIVATE_H
-#define META_DEVICE_POOL_PRIVATE_H
-
-#include <glib-object.h>
-
-#include "backends/native/meta-device-pool.h"
-#include "backends/native/meta-launcher.h"
-
-#define META_TYPE_DEVICE_POOL (meta_device_pool_get_type ())
-G_DECLARE_FINAL_TYPE (MetaDevicePool, meta_device_pool,
- META, DEVICE_POOL,
- GObject)
-
-MetaDevicePool * meta_device_pool_new (MetaLauncher *launcher);
-
-#endif /* META_DEVICE_POOL_PRIVATE_H */
diff --git a/src/backends/native/meta-device-pool.c b/src/backends/native/meta-device-pool.c
deleted file mode 100644
index 8bbbe3e34..000000000
--- a/src/backends/native/meta-device-pool.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (C) 2013-2021 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-device-pool-private.h"
-
-#include <fcntl.h>
-#include <gio/gunixfdlist.h>
-#include <sys/stat.h>
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-#include <sys/types.h>
-
-#include "backends/native/meta-launcher.h"
-#include "meta/util.h"
-
-#include "meta-dbus-login1.h"
-
-struct _MetaDeviceFile
-{
- MetaDevicePool *pool;
-
- grefcount ref_count;
-
- char *path;
- int major;
- int minor;
- int fd;
- MetaDeviceFileFlags flags;
- uint32_t tags[META_DEVICE_FILE_N_TAGS];
-};
-
-struct _MetaDevicePool
-{
- GObject parent;
-
- MetaDbusLogin1Session *session_proxy;
-
- GMutex mutex;
-
- GList *files;
-};
-
-G_DEFINE_TYPE (MetaDevicePool, meta_device_pool, G_TYPE_OBJECT)
-
-static void
-release_device_file (MetaDevicePool *pool,
- MetaDeviceFile *file);
-
-static MetaDeviceFile *
-meta_device_file_new (MetaDevicePool *pool,
- const char *path,
- int major,
- int minor,
- int fd,
- MetaDeviceFileFlags flags)
-{
- MetaDeviceFile *file;
-
- file = g_new0 (MetaDeviceFile, 1);
-
- file->pool = pool;
- g_ref_count_init (&file->ref_count);
-
- file->path = g_strdup (path);
- file->major = major;
- file->minor = minor;
- file->fd = fd;
- file->flags = flags;
-
- return file;
-}
-
-static void
-meta_device_file_free (MetaDeviceFile *file)
-{
- g_free (file->path);
- g_free (file);
-}
-
-int
-meta_device_file_get_fd (MetaDeviceFile *device_file)
-{
- g_assert (!g_ref_count_compare (&device_file->ref_count, 0));
-
- return device_file->fd;
-}
-
-const char *
-meta_device_file_get_path (MetaDeviceFile *device_file)
-{
- return device_file->path;
-}
-
-void
-meta_device_file_tag (MetaDeviceFile *device_file,
- MetaDeviceFileTags tag,
- uint32_t value)
-{
- device_file->tags[tag] |= value;
-}
-
-uint32_t
-meta_device_file_has_tag (MetaDeviceFile *device_file,
- MetaDeviceFileTags tag,
- uint32_t value)
-{
- return (device_file->tags[tag] & value) == value;
-}
-
-static MetaDeviceFile *
-meta_device_file_acquire_locked (MetaDeviceFile *file)
-{
- g_ref_count_inc (&file->ref_count);
- return file;
-}
-
-MetaDeviceFile *
-meta_device_file_acquire (MetaDeviceFile *file)
-{
- g_mutex_lock (&file->pool->mutex);
- meta_topic (META_DEBUG_BACKEND, "Acquiring device file '%s'", file->path);
- meta_device_file_acquire_locked (file);
- g_mutex_unlock (&file->pool->mutex);
-
- return file;
-}
-
-void
-meta_device_file_release (MetaDeviceFile *file)
-{
- g_warn_if_fail (file->fd != -1);
-
- release_device_file (file->pool, file);
-}
-
-MetaDevicePool *
-meta_device_file_get_pool (MetaDeviceFile *device_file)
-{
- return device_file->pool;
-}
-
-static MetaDeviceFile *
-find_device_file_from_path (MetaDevicePool *pool,
- const char *path)
-{
- GList *l;
-
- for (l = pool->files; l; l = l->next)
- {
- MetaDeviceFile *file = l->data;
-
- if (g_strcmp0 (file->path, path) == 0)
- return file;
- }
-
- return NULL;
-}
-
-static gboolean
-take_device (MetaDbusLogin1Session *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 (!meta_dbus_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 ret;
- struct stat st;
-
- ret = stat (path, &st);
- if (ret < 0 || !S_ISCHR (st.st_mode))
- return FALSE;
-
- *out_major = major (st.st_rdev);
- *out_minor = minor (st.st_rdev);
- return TRUE;
-}
-
-MetaDeviceFile *
-meta_device_pool_open (MetaDevicePool *pool,
- const char *path,
- MetaDeviceFileFlags flags,
- GError **error)
-{
- g_autoptr (GMutexLocker) locker = NULL;
- MetaDeviceFile *file;
- int major = -1, minor = -1;
- int fd;
-
- locker = g_mutex_locker_new (&pool->mutex);
-
- file = find_device_file_from_path (pool, path);
- if (file)
- {
- g_warn_if_fail (file->flags == flags);
- meta_device_file_acquire_locked (file);
- return file;
- }
-
- if (flags & META_DEVICE_FILE_FLAG_TAKE_CONTROL)
- {
- meta_topic (META_DEBUG_BACKEND,
- "Opening and taking control of device file '%s'",
- path);
-
- if (!pool->session_proxy)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- "Can't take control without logind session");
- return NULL;
- }
-
- 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 NULL;
- }
-
- if (!take_device (pool->session_proxy, major, minor, &fd, NULL, error))
- return NULL;
- }
- else
- {
- int open_flags;
-
- meta_topic (META_DEBUG_BACKEND,
- "Opening device file '%s'",
- path);
-
- if (flags & META_DEVICE_FILE_FLAG_READ_ONLY)
- open_flags = O_RDONLY;
- else
- open_flags = O_RDWR;
- open_flags |= O_CLOEXEC;
-
- do
- {
- fd = open (path, open_flags);
- }
- while (fd == -1 && errno == EINTR);
-
- if (fd == -1)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to open device '%s': %s",
- path, g_strerror (errno));
- return NULL;
- }
- }
-
- file = meta_device_file_new (pool, path, major, minor, fd, flags);
- pool->files = g_list_prepend (pool->files, file);
-
- return file;
-}
-
-static void
-release_device_file (MetaDevicePool *pool,
- MetaDeviceFile *file)
-{
- g_autoptr (GMutexLocker) locker = NULL;
- g_autoptr (GError) error = NULL;
-
- locker = g_mutex_locker_new (&pool->mutex);
-
- meta_topic (META_DEBUG_BACKEND, "Releasing device file '%s'", file->path);
-
- if (!g_ref_count_dec (&file->ref_count))
- return;
-
- pool->files = g_list_remove (pool->files, file);
-
- if (file->flags & META_DEVICE_FILE_FLAG_TAKE_CONTROL)
- {
- MetaDbusLogin1Session *session_proxy;
-
- meta_topic (META_DEBUG_BACKEND,
- "Releasing control of and closing device file '%s'",
- file->path);
-
- session_proxy = pool->session_proxy;
- if (!meta_dbus_login1_session_call_release_device_sync (session_proxy,
- file->major,
- file->minor,
- NULL, &error))
- {
- g_warning ("Could not release device '%s' (%d,%d): %s",
- file->path,
- file->major, file->minor,
- error->message);
- }
- }
- else
- {
- meta_topic (META_DEBUG_BACKEND,
- "Closing device file '%s'",
- file->path);
- }
-
- close (file->fd);
-
- meta_device_file_free (file);
-}
-
-MetaDevicePool *
-meta_device_pool_new (MetaLauncher *launcher)
-{
- MetaDevicePool *pool;
-
- pool = g_object_new (META_TYPE_DEVICE_POOL, NULL);
-
- if (launcher)
- pool->session_proxy = meta_launcher_get_session_proxy (launcher);
-
- return pool;
-}
-
-static void
-meta_device_pool_finalize (GObject *object)
-{
- MetaDevicePool *pool = META_DEVICE_POOL (object);
-
- g_mutex_clear (&pool->mutex);
- g_warn_if_fail (!pool->files);
-
- G_OBJECT_CLASS (meta_device_pool_parent_class)->finalize (object);
-}
-
-static void
-meta_device_pool_init (MetaDevicePool *pool)
-{
- g_mutex_init (&pool->mutex);
-}
-
-static void
-meta_device_pool_class_init (MetaDevicePoolClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = meta_device_pool_finalize;
-}
diff --git a/src/backends/native/meta-device-pool.h b/src/backends/native/meta-device-pool.h
deleted file mode 100644
index 0e9653bd6..000000000
--- a/src/backends/native/meta-device-pool.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2021 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_DEVICE_POOL_H
-#define META_DEVICE_POOL_H
-
-#include <glib-object.h>
-#include <stdint.h>
-
-typedef enum _MetaDeviceFileFlags
-{
- META_DEVICE_FILE_FLAG_NONE = 0,
- META_DEVICE_FILE_FLAG_TAKE_CONTROL = 1 << 0,
- META_DEVICE_FILE_FLAG_READ_ONLY = 1 << 1,
-} MetaDeviceFileFlags;
-
-typedef enum _MetaDeviceFileTags
-{
- META_DEVICE_FILE_TAG_KMS,
-
- META_DEVICE_FILE_N_TAGS,
-} MetaDeviceFileTags;
-
-typedef struct _MetaDeviceFile MetaDeviceFile;
-typedef struct _MetaDevicePool MetaDevicePool;
-
-int meta_device_file_get_fd (MetaDeviceFile *device_file);
-
-const char * meta_device_file_get_path (MetaDeviceFile *device_file);
-
-void meta_device_file_tag (MetaDeviceFile *device_file,
- MetaDeviceFileTags tag,
- uint32_t value);
-
-uint32_t meta_device_file_has_tag (MetaDeviceFile *device_file,
- MetaDeviceFileTags tag,
- uint32_t value);
-
-MetaDeviceFile * meta_device_file_acquire (MetaDeviceFile *file);
-
-void meta_device_file_release (MetaDeviceFile *device_file);
-
-MetaDevicePool * meta_device_file_get_pool (MetaDeviceFile *device_file);
-
-MetaDeviceFile * meta_device_pool_open (MetaDevicePool *pool,
- const char *path,
- MetaDeviceFileFlags flags,
- GError **error);
-
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaDeviceFile, meta_device_file_release)
-
-#endif /* META_DEVICE_FILE_POOL_H */
diff --git a/src/backends/native/meta-drm-buffer-dumb.c b/src/backends/native/meta-drm-buffer-dumb.c
deleted file mode 100644
index d2fcad2f0..000000000
--- a/src/backends/native/meta-drm-buffer-dumb.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * 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"
-
-#include <gio/gio.h>
-#include <xf86drm.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-
-#include "backends/native/meta-device-pool.h"
-
-struct _MetaDrmBufferDumb
-{
- MetaDrmBuffer parent;
-
- uint32_t handle;
- void *map;
- uint64_t map_size;
- int width;
- int height;
- int stride_bytes;
- uint32_t drm_format;
- int dmabuf_fd;
-};
-
-G_DEFINE_TYPE (MetaDrmBufferDumb, meta_drm_buffer_dumb, META_TYPE_DRM_BUFFER)
-
-static int
-meta_drm_buffer_dumb_get_width (MetaDrmBuffer *buffer)
-{
- MetaDrmBufferDumb *buffer_dumb = META_DRM_BUFFER_DUMB (buffer);
-
- return buffer_dumb->width;
-}
-
-static int
-meta_drm_buffer_dumb_get_height (MetaDrmBuffer *buffer)
-{
- MetaDrmBufferDumb *buffer_dumb = META_DRM_BUFFER_DUMB (buffer);
-
- return buffer_dumb->height;
-}
-
-static int
-meta_drm_buffer_dumb_get_stride (MetaDrmBuffer *buffer)
-{
- MetaDrmBufferDumb *buffer_dumb = META_DRM_BUFFER_DUMB (buffer);
-
- return buffer_dumb->stride_bytes;
-}
-
-static uint32_t
-meta_drm_buffer_dumb_get_format (MetaDrmBuffer *buffer)
-{
- MetaDrmBufferDumb *buffer_dumb = META_DRM_BUFFER_DUMB (buffer);
-
- return buffer_dumb->drm_format;
-}
-
-static int
-handle_to_dmabuf_fd (MetaDrmBufferDumb *buffer_dumb,
- GError **error)
-{
- MetaDrmBuffer *buffer = META_DRM_BUFFER (buffer_dumb);
- MetaDeviceFile *device_file;
- int fd;
- int ret;
- int dmabuf_fd;
-
- device_file = meta_drm_buffer_get_device_file (buffer);
- fd = meta_device_file_get_fd (device_file);
-
- ret = drmPrimeHandleToFD (fd, buffer_dumb->handle, DRM_CLOEXEC,
- &dmabuf_fd);
- if (ret)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
- "drmPrimeHandleToFd: %s", g_strerror (-ret));
- return -1;
- }
-
- return dmabuf_fd;
-}
-
-int
-meta_drm_buffer_dumb_ensure_dmabuf_fd (MetaDrmBufferDumb *buffer_dumb,
- GError **error)
-{
- if (buffer_dumb->dmabuf_fd != -1)
- return buffer_dumb->dmabuf_fd;
-
- buffer_dumb->dmabuf_fd = handle_to_dmabuf_fd (buffer_dumb, error);
- return buffer_dumb->dmabuf_fd;
-}
-
-void *
-meta_drm_buffer_dumb_get_data (MetaDrmBufferDumb *buffer_dumb)
-{
- return buffer_dumb->map;
-}
-
-static gboolean
-init_dumb_buffer (MetaDrmBufferDumb *buffer_dumb,
- int width,
- int height,
- uint32_t format,
- GError **error)
-{
- MetaDrmBuffer *buffer = META_DRM_BUFFER (buffer_dumb);
- MetaDeviceFile *device_file;
- int fd;
- struct drm_mode_create_dumb create_arg;
- struct drm_mode_destroy_dumb destroy_arg;
- struct drm_mode_map_dumb map_arg;
- void *map;
- MetaDrmFbArgs fb_args;
-
- device_file = meta_drm_buffer_get_device_file (buffer);
- fd = meta_device_file_get_fd (device_file);
-
- create_arg = (struct drm_mode_create_dumb) {
- .bpp = 32, /* RGBX8888 */
- .width = width,
- .height = height
- };
- if (drmIoctl (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 = (MetaDrmFbArgs) {
- .width = width,
- .height = height,
- .format = format,
- .handles = { create_arg.handle },
- .strides = { create_arg.pitch },
- };
- if (!meta_drm_buffer_ensure_fb_id (buffer, FALSE, &fb_args, error))
- goto err_add_fb;
-
- map_arg = (struct drm_mode_map_dumb) {
- .handle = create_arg.handle
- };
- if (drmIoctl (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,
- 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;
- }
-
- buffer_dumb->handle = create_arg.handle;
- buffer_dumb->map = map;
- buffer_dumb->map_size = create_arg.size;
- buffer_dumb->width = width;
- buffer_dumb->height = height;
- buffer_dumb->stride_bytes = create_arg.pitch;
- buffer_dumb->drm_format = format;
-
- return TRUE;
-
-err_mmap:
-err_map_dumb:
-err_add_fb:
- destroy_arg = (struct drm_mode_destroy_dumb) {
- .handle = create_arg.handle
- };
- drmIoctl (fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
-
-err_ioctl:
- return FALSE;
-}
-
-MetaDrmBufferDumb *
-meta_drm_buffer_dumb_new (MetaDeviceFile *device_file,
- int width,
- int height,
- uint32_t format,
- GError **error)
-{
- MetaDrmBufferDumb *buffer_dumb;
-
- buffer_dumb = g_object_new (META_TYPE_DRM_BUFFER_DUMB,
- "device-file", device_file,
- NULL);
-
- if (!init_dumb_buffer (buffer_dumb, width, height, format, error))
- {
- g_object_unref (buffer_dumb);
- return NULL;
- }
-
- return buffer_dumb;
-}
-
-static void
-destroy_dumb_buffer (MetaDrmBufferDumb *buffer_dumb)
-{
- MetaDrmBuffer *buffer = META_DRM_BUFFER (buffer_dumb);
- MetaDeviceFile *device_file;
- int fd;
- struct drm_mode_destroy_dumb destroy_arg;
-
- device_file = meta_drm_buffer_get_device_file (buffer);
- fd = meta_device_file_get_fd (device_file);
-
- munmap (buffer_dumb->map, buffer_dumb->map_size);
-
- destroy_arg = (struct drm_mode_destroy_dumb) {
- .handle = buffer_dumb->handle
- };
- drmIoctl (fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
-
- if (buffer_dumb->dmabuf_fd != -1)
- close (buffer_dumb->dmabuf_fd);
-}
-
-static void
-meta_drm_buffer_dumb_finalize (GObject *object)
-{
- MetaDrmBufferDumb *buffer_dumb = META_DRM_BUFFER_DUMB (object);
-
- if (buffer_dumb->handle)
- destroy_dumb_buffer (buffer_dumb);
-
- G_OBJECT_CLASS (meta_drm_buffer_dumb_parent_class)->finalize (object);
-}
-
-static void
-meta_drm_buffer_dumb_init (MetaDrmBufferDumb *buffer_dumb)
-{
- buffer_dumb->dmabuf_fd = -1;
-}
-
-static void
-meta_drm_buffer_dumb_class_init (MetaDrmBufferDumbClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- MetaDrmBufferClass *buffer_class = META_DRM_BUFFER_CLASS (klass);
-
- object_class->finalize = meta_drm_buffer_dumb_finalize;
-
- buffer_class->get_width = meta_drm_buffer_dumb_get_width;
- buffer_class->get_height = meta_drm_buffer_dumb_get_height;
- buffer_class->get_stride = meta_drm_buffer_dumb_get_stride;
- buffer_class->get_format = meta_drm_buffer_dumb_get_format;
-}
diff --git a/src/backends/native/meta-drm-buffer-dumb.h b/src/backends/native/meta-drm-buffer-dumb.h
deleted file mode 100644
index afc14660b..000000000
--- a/src/backends/native/meta-drm-buffer-dumb.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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-backend-native-types.h"
-#include "backends/native/meta-drm-buffer-private.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 (MetaDeviceFile *device,
- int width,
- int height,
- uint32_t format,
- GError **error);
-
-int meta_drm_buffer_dumb_ensure_dmabuf_fd (MetaDrmBufferDumb *buffer_dumb,
- GError **error);
-
-void * meta_drm_buffer_dumb_get_data (MetaDrmBufferDumb *buffer_dumb);
-
-#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
deleted file mode 100644
index f011afaca..000000000
--- a/src/backends/native/meta-drm-buffer-gbm.c
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * 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 <gio/gio.h>
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-
-#include "backends/meta-backend-private.h"
-#include "backends/native/meta-cogl-utils.h"
-#include "backends/native/meta-drm-buffer-private.h"
-
-struct _MetaDrmBufferGbm
-{
- MetaDrmBuffer parent;
-
- struct gbm_surface *surface;
-
- struct gbm_bo *bo;
-};
-
-static void
-cogl_scanout_iface_init (CoglScanoutInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaDrmBufferGbm, meta_drm_buffer_gbm, META_TYPE_DRM_BUFFER,
- G_IMPLEMENT_INTERFACE (COGL_TYPE_SCANOUT,
- cogl_scanout_iface_init))
-
-struct gbm_bo *
-meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm)
-{
- return buffer_gbm->bo;
-}
-
-static int
-meta_drm_buffer_gbm_get_width (MetaDrmBuffer *buffer)
-{
- MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (buffer);
-
- return gbm_bo_get_width (buffer_gbm->bo);
-}
-
-static int
-meta_drm_buffer_gbm_get_height (MetaDrmBuffer *buffer)
-{
- MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (buffer);
-
- return gbm_bo_get_height (buffer_gbm->bo);
-}
-
-static int
-meta_drm_buffer_gbm_get_stride (MetaDrmBuffer *buffer)
-{
- MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (buffer);
-
- return gbm_bo_get_stride (buffer_gbm->bo);
-}
-
-static uint32_t
-meta_drm_buffer_gbm_get_format (MetaDrmBuffer *buffer)
-{
- MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (buffer);
-
- return gbm_bo_get_format (buffer_gbm->bo);
-}
-
-static gboolean
-init_fb_id (MetaDrmBufferGbm *buffer_gbm,
- struct gbm_bo *bo,
- gboolean use_modifiers,
- GError **error)
-{
- MetaDrmFbArgs fb_args = { 0, };
-
- 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_drm_buffer_ensure_fb_id (META_DRM_BUFFER (buffer_gbm),
- use_modifiers, &fb_args, error))
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-lock_front_buffer (MetaDrmBufferGbm *buffer_gbm,
- gboolean use_modifiers,
- GError **error)
-{
- buffer_gbm->bo = gbm_surface_lock_front_buffer (buffer_gbm->surface);
- if (!buffer_gbm->bo)
- {
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "gbm_surface_lock_front_buffer failed");
- return FALSE;
- }
-
- return init_fb_id (buffer_gbm, buffer_gbm->bo, use_modifiers, error);
-}
-
-MetaDrmBufferGbm *
-meta_drm_buffer_gbm_new_lock_front (MetaDeviceFile *device_file,
- struct gbm_surface *gbm_surface,
- gboolean use_modifiers,
- GError **error)
-{
- MetaDrmBufferGbm *buffer_gbm;
-
- buffer_gbm = g_object_new (META_TYPE_DRM_BUFFER_GBM,
- "device-file", device_file,
- NULL);
- buffer_gbm->surface = gbm_surface;
-
- if (!lock_front_buffer (buffer_gbm, use_modifiers, error))
- {
- g_object_unref (buffer_gbm);
- return NULL;
- }
-
- return buffer_gbm;
-}
-
-MetaDrmBufferGbm *
-meta_drm_buffer_gbm_new_take (MetaDeviceFile *device_file,
- struct gbm_bo *bo,
- gboolean use_modifiers,
- GError **error)
-{
- MetaDrmBufferGbm *buffer_gbm;
-
- buffer_gbm = g_object_new (META_TYPE_DRM_BUFFER_GBM,
- "device-file", device_file,
- NULL);
-
- if (!init_fb_id (buffer_gbm, bo, use_modifiers, error))
- {
- g_object_unref (buffer_gbm);
- return NULL;
- }
-
- buffer_gbm->bo = bo;
-
- return buffer_gbm;
-}
-
-static gboolean
-meta_drm_buffer_gbm_fill_timings (MetaDrmBuffer *buffer,
- CoglFrameInfo *info,
- GError **error)
-{
- MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (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);
- 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;
- EGLImageKHR egl_image;
- CoglPixelFormat cogl_format;
- CoglEglImageFlags flags;
- g_autoptr (CoglOffscreen) cogl_fbo = NULL;
- CoglTexture2D *cogl_tex;
- uint32_t n_planes;
- uint64_t *modifiers;
- uint32_t *strides;
- uint32_t *offsets;
- uint32_t width;
- uint32_t height;
- uint32_t drm_format;
- int *fds;
- gboolean result;
- int dmabuf_fd = -1;
- uint32_t i;
-
- dmabuf_fd = gbm_bo_get_fd (buffer_gbm->bo);
- if (dmabuf_fd == -1)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Failed to export buffer's DMA fd: %s",
- g_strerror (errno));
- return FALSE;
- }
-
- drm_format = gbm_bo_get_format (buffer_gbm->bo);
- result = meta_cogl_pixel_format_from_drm_format (drm_format,
- &cogl_format,
- NULL);
- g_assert (result);
-
- width = gbm_bo_get_width (buffer_gbm->bo);
- height = gbm_bo_get_height (buffer_gbm->bo);
- n_planes = gbm_bo_get_plane_count (buffer_gbm->bo);
- fds = g_alloca (sizeof (int) * n_planes);
- strides = g_alloca (sizeof (uint32_t) * n_planes);
- offsets = g_alloca (sizeof (uint32_t) * n_planes);
- modifiers = g_alloca (sizeof (uint64_t) * n_planes);
-
- for (i = 0; i < n_planes; i++)
- {
- fds[i] = dmabuf_fd;
- strides[i] = gbm_bo_get_stride_for_plane (buffer_gbm->bo, i);
- offsets[i] = gbm_bo_get_offset (buffer_gbm->bo, i);
- modifiers[i] = gbm_bo_get_modifier (buffer_gbm->bo);
- }
-
- egl_image = meta_egl_create_dmabuf_image (egl,
- egl_display,
- width,
- height,
- drm_format,
- n_planes,
- fds,
- strides,
- offsets,
- modifiers,
- error);
- if (egl_image == EGL_NO_IMAGE_KHR)
- goto out;
-
- 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)
- goto out;
-
- cogl_fbo = cogl_offscreen_new_with_texture (COGL_TEXTURE (cogl_tex));
- cogl_object_unref (cogl_tex);
-
- if (cogl_has_feature (cogl_context, COGL_FEATURE_ID_GET_GPU_TIME))
- {
- info->gpu_time_before_buffer_swap_ns =
- cogl_context_get_gpu_time_ns (cogl_context);
- }
-
- info->cpu_time_before_buffer_swap_us = g_get_monotonic_time ();
-
- /* Set up a timestamp query for when all rendering will be finished. */
- if (cogl_has_feature (cogl_context, COGL_FEATURE_ID_TIMESTAMP_QUERY))
- {
- info->timestamp_query =
- cogl_framebuffer_create_timestamp_query (COGL_FRAMEBUFFER (cogl_fbo));
- }
-
-out:
- close (dmabuf_fd);
-
- return TRUE;
-}
-
-static gboolean
-meta_drm_buffer_gbm_blit_to_framebuffer (CoglScanout *scanout,
- CoglFramebuffer *framebuffer,
- int x,
- int y,
- GError **error)
-{
- MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (scanout);
- 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);
- 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;
- EGLImageKHR egl_image;
- CoglPixelFormat cogl_format;
- CoglEglImageFlags flags;
- CoglOffscreen *cogl_fbo = NULL;
- CoglTexture2D *cogl_tex;
- uint32_t n_planes;
- uint64_t *modifiers;
- uint32_t *strides;
- uint32_t *offsets;
- uint32_t width;
- uint32_t height;
- uint32_t drm_format;
- int *fds;
- gboolean result;
- int dmabuf_fd = -1;
- uint32_t i;
-
- dmabuf_fd = gbm_bo_get_fd (buffer_gbm->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 FALSE;
- }
-
- drm_format = gbm_bo_get_format (buffer_gbm->bo);
- result = meta_cogl_pixel_format_from_drm_format (drm_format,
- &cogl_format,
- NULL);
- g_assert (result);
-
- width = gbm_bo_get_width (buffer_gbm->bo);
- height = gbm_bo_get_height (buffer_gbm->bo);
- n_planes = gbm_bo_get_plane_count (buffer_gbm->bo);
- fds = g_alloca (sizeof (int) * n_planes);
- strides = g_alloca (sizeof (uint32_t) * n_planes);
- offsets = g_alloca (sizeof (uint32_t) * n_planes);
- modifiers = g_alloca (sizeof (uint64_t) * n_planes);
-
- for (i = 0; i < n_planes; i++)
- {
- fds[i] = dmabuf_fd;
- strides[i] = gbm_bo_get_stride_for_plane (buffer_gbm->bo, i);
- offsets[i] = gbm_bo_get_offset (buffer_gbm->bo, i);
- modifiers[i] = gbm_bo_get_modifier (buffer_gbm->bo);
- }
-
- egl_image = meta_egl_create_dmabuf_image (egl,
- egl_display,
- width,
- height,
- drm_format,
- n_planes,
- fds,
- strides,
- offsets,
- modifiers,
- error);
- if (egl_image == EGL_NO_IMAGE_KHR)
- {
- result = FALSE;
- goto out;
- }
-
- 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)
- {
- result = FALSE;
- goto out;
- }
-
- 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))
- {
- result = FALSE;
- goto out;
- }
-
- result = cogl_blit_framebuffer (COGL_FRAMEBUFFER (cogl_fbo),
- framebuffer,
- 0, 0,
- x, y,
- width, height,
- error);
-
-out:
- g_clear_object (&cogl_fbo);
- close (dmabuf_fd);
-
- return result;
-}
-
-static void
-cogl_scanout_iface_init (CoglScanoutInterface *iface)
-{
- iface->blit_to_framebuffer = meta_drm_buffer_gbm_blit_to_framebuffer;
-}
-
-static void
-meta_drm_buffer_gbm_finalize (GObject *object)
-{
- MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (object);
-
- if (buffer_gbm->bo)
- {
- if (buffer_gbm->surface)
- gbm_surface_release_buffer (buffer_gbm->surface, buffer_gbm->bo);
- else
- gbm_bo_destroy (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_width = meta_drm_buffer_gbm_get_width;
- buffer_class->get_height = meta_drm_buffer_gbm_get_height;
- buffer_class->get_stride = meta_drm_buffer_gbm_get_stride;
- buffer_class->get_format = meta_drm_buffer_gbm_get_format;
- buffer_class->fill_timings = meta_drm_buffer_gbm_fill_timings;
-}
diff --git a/src/backends/native/meta-drm-buffer-gbm.h b/src/backends/native/meta-drm-buffer-gbm.h
deleted file mode 100644
index 0413c9fa2..000000000
--- a/src/backends/native/meta-drm-buffer-gbm.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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-backend-native-types.h"
-#include "backends/native/meta-drm-buffer-private.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_lock_front (MetaDeviceFile *device_file,
- struct gbm_surface *gbm_surface,
- gboolean use_modifiers,
- GError **error);
-
-
-MetaDrmBufferGbm * meta_drm_buffer_gbm_new_take (MetaDeviceFile *device_file,
- struct gbm_bo *gbm_bo,
- 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
deleted file mode 100644
index 77cd138d2..000000000
--- a/src/backends/native/meta-drm-buffer-import.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * 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"
-
-struct _MetaDrmBufferImport
-{
- MetaDrmBuffer parent;
-
- MetaDrmBufferGbm *importee;
-};
-
-G_DEFINE_TYPE (MetaDrmBufferImport, meta_drm_buffer_import,
- META_TYPE_DRM_BUFFER)
-
-static int
-meta_drm_buffer_import_get_width (MetaDrmBuffer *buffer)
-{
- MetaDrmBufferImport *buffer_import = META_DRM_BUFFER_IMPORT (buffer);
-
- return meta_drm_buffer_get_width (META_DRM_BUFFER (buffer_import->importee));
-}
-
-static int
-meta_drm_buffer_import_get_height (MetaDrmBuffer *buffer)
-{
- MetaDrmBufferImport *buffer_import = META_DRM_BUFFER_IMPORT (buffer);
-
- return meta_drm_buffer_get_height (META_DRM_BUFFER (buffer_import->importee));
-}
-
-static int
-meta_drm_buffer_import_get_stride (MetaDrmBuffer *buffer)
-{
- MetaDrmBufferImport *buffer_import = META_DRM_BUFFER_IMPORT (buffer);
-
- return meta_drm_buffer_get_stride (META_DRM_BUFFER (buffer_import->importee));
-}
-
-static uint32_t
-meta_drm_buffer_import_get_format (MetaDrmBuffer *buffer)
-{
- MetaDrmBufferImport *buffer_import = META_DRM_BUFFER_IMPORT (buffer);
-
- return meta_drm_buffer_get_format (META_DRM_BUFFER (buffer_import->importee));
-}
-
-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,
- struct gbm_device *importer,
- GError **error)
-{
- MetaDrmFbArgs fb_args = { 0, };
- struct gbm_bo *primary_bo;
- struct gbm_bo *imported_bo;
- int dmabuf_fd;
- gboolean ret;
-
- 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_drm_buffer_ensure_fb_id (META_DRM_BUFFER (buffer_import),
- FALSE /* use_modifiers */,
- &fb_args,
- error);
-
- gbm_bo_destroy (imported_bo);
-
-out_close:
- close (dmabuf_fd);
-
- return ret;
-}
-
-MetaDrmBufferImport *
-meta_drm_buffer_import_new (MetaDeviceFile *device_file,
- struct gbm_device *gbm_device,
- MetaDrmBufferGbm *buffer_gbm,
- GError **error)
-{
- MetaDrmBufferImport *buffer_import;
-
- buffer_import = g_object_new (META_TYPE_DRM_BUFFER_IMPORT,
- "device-file", device_file,
- NULL);
- g_set_object (&buffer_import->importee, buffer_gbm);
-
- if (!import_gbm_buffer (buffer_import, gbm_device, error))
- {
- g_object_unref (buffer_import);
- return NULL;
- }
-
- return buffer_import;
-}
-
-static void
-meta_drm_buffer_import_finalize (GObject *object)
-{
- MetaDrmBufferImport *buffer_import = META_DRM_BUFFER_IMPORT (object);
-
- 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_width = meta_drm_buffer_import_get_width;
- buffer_class->get_height = meta_drm_buffer_import_get_height;
- buffer_class->get_stride = meta_drm_buffer_import_get_stride;
- buffer_class->get_format = meta_drm_buffer_import_get_format;
-}
diff --git a/src/backends/native/meta-drm-buffer-import.h b/src/backends/native/meta-drm-buffer-import.h
deleted file mode 100644
index faff560fa..000000000
--- a/src/backends/native/meta-drm-buffer-import.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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 (MetaDeviceFile *device_file,
- struct gbm_device *gbm_device,
- MetaDrmBufferGbm *buffer_gbm,
- GError **error);
-
-#endif /* META_DRM_BUFFER_IMPORT_H */
diff --git a/src/backends/native/meta-drm-buffer-private.h b/src/backends/native/meta-drm-buffer-private.h
deleted file mode 100644
index a54ce7c31..000000000
--- a/src/backends/native/meta-drm-buffer-private.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2018 Canonical Ltd.
- * Copyright (C) 2019-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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef META_DRM_BUFFER_PRIVATE_H
-#define META_DRM_BUFFER_PRIVATE_H
-
-#include "backends/native/meta-backend-native-types.h"
-#include "backends/native/meta-drm-buffer.h"
-
-typedef struct _MetaDrmFbArgs
-{
- 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];
-} MetaDrmFbArgs;
-
-struct _MetaDrmBufferClass
-{
- GObjectClass parent_class;
-
- int (* get_width) (MetaDrmBuffer *buffer);
- int (* get_height) (MetaDrmBuffer *buffer);
- int (* get_stride) (MetaDrmBuffer *buffer);
- uint32_t (* get_format) (MetaDrmBuffer *buffer);
-
- gboolean (* fill_timings) (MetaDrmBuffer *buffer,
- CoglFrameInfo *info,
- GError **error);
-};
-
-MetaDeviceFile * meta_drm_buffer_get_device_file (MetaDrmBuffer *buffer);
-
-gboolean meta_drm_buffer_ensure_fb_id (MetaDrmBuffer *buffer,
- gboolean use_modifiers,
- const MetaDrmFbArgs *fb_args,
- GError **error);
-
-gboolean meta_drm_buffer_ensure_fb_in_impl (MetaDrmBuffer *buffer,
- gboolean use_modifiers,
- const MetaDrmFbArgs *fb_args,
- GError **error);
-
-#endif /* META_DRM_BUFFER_PRIVATE_H */
diff --git a/src/backends/native/meta-drm-buffer.c b/src/backends/native/meta-drm-buffer.c
deleted file mode 100644
index 1da622037..000000000
--- a/src/backends/native/meta-drm-buffer.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (C) 2011 Intel Corporation.
- * Copyright (C) 2016-2020 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-private.h"
-
-#include <drm_fourcc.h>
-
-#include "backends/native/meta-device-pool.h"
-#include "backends/native/meta-kms-utils.h"
-
-#define INVALID_FB_ID 0U
-
-enum
-{
- PROP_0,
-
- PROP_DEVICE_FILE,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS];
-
-typedef struct _MetaDrmBufferPrivate
-{
- MetaDeviceFile *device_file;
- uint32_t fb_id;
-} MetaDrmBufferPrivate;
-
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaDrmBuffer, meta_drm_buffer,
- G_TYPE_OBJECT)
-
-MetaDeviceFile *
-meta_drm_buffer_get_device_file (MetaDrmBuffer *buffer)
-{
- MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
-
- return priv->device_file;
-}
-
-gboolean
-meta_drm_buffer_ensure_fb_id (MetaDrmBuffer *buffer,
- gboolean use_modifiers,
- const MetaDrmFbArgs *fb_args,
- GError **error)
-{
- MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
- int fd;
- MetaDrmFormatBuf tmp;
- uint32_t fb_id;
-
- fd = meta_device_file_get_fd (priv->device_file);
-
- if (use_modifiers && fb_args->modifiers[0] != DRM_FORMAT_MOD_INVALID)
- {
- if (drmModeAddFB2WithModifiers (fd,
- fb_args->width,
- fb_args->height,
- fb_args->format,
- fb_args->handles,
- fb_args->strides,
- fb_args->offsets,
- fb_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 (fd,
- fb_args->width,
- fb_args->height,
- fb_args->format,
- fb_args->handles,
- fb_args->strides,
- fb_args->offsets,
- &fb_id,
- 0))
- {
- if (fb_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, fb_args->format),
- fb_args->format);
- return FALSE;
- }
-
- if (drmModeAddFB (fd,
- fb_args->width,
- fb_args->height,
- 24,
- 32,
- fb_args->strides[0],
- fb_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;
- }
- }
-
- priv->fb_id = fb_id;
- return TRUE;
-}
-
-static void
-meta_drm_buffer_release_fb_id (MetaDrmBuffer *buffer)
-{
- MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
- int fd;
- int ret;
-
- fd = meta_device_file_get_fd (priv->device_file);
- ret = drmModeRmFB (fd, priv->fb_id);
- if (ret != 0)
- g_warning ("drmModeRmFB: %s", g_strerror (-ret));
-
- priv->fb_id = 0;
-}
-
-uint32_t
-meta_drm_buffer_get_fb_id (MetaDrmBuffer *buffer)
-{
- MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
-
- return priv->fb_id;
-}
-
-int
-meta_drm_buffer_get_width (MetaDrmBuffer *buffer)
-{
- return META_DRM_BUFFER_GET_CLASS (buffer)->get_width (buffer);
-}
-
-int
-meta_drm_buffer_get_height (MetaDrmBuffer *buffer)
-{
- return META_DRM_BUFFER_GET_CLASS (buffer)->get_height (buffer);
-}
-
-int
-meta_drm_buffer_get_stride (MetaDrmBuffer *buffer)
-{
- return META_DRM_BUFFER_GET_CLASS (buffer)->get_stride (buffer);
-}
-
-uint32_t
-meta_drm_buffer_get_format (MetaDrmBuffer *buffer)
-{
- return META_DRM_BUFFER_GET_CLASS (buffer)->get_format (buffer);
-}
-
-gboolean
-meta_drm_buffer_supports_fill_timings (MetaDrmBuffer *buffer)
-{
- return META_DRM_BUFFER_GET_CLASS (buffer)->fill_timings != NULL;
-}
-
-gboolean
-meta_drm_buffer_fill_timings (MetaDrmBuffer *buffer,
- CoglFrameInfo *info,
- GError **error)
-{
- if (!meta_drm_buffer_supports_fill_timings (buffer))
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- "Buffer doesn't support filling timing info");
- return FALSE;
- }
-
- return META_DRM_BUFFER_GET_CLASS (buffer)->fill_timings (buffer, info, error);
-}
-
-static void
-meta_drm_buffer_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaDrmBuffer *buffer = META_DRM_BUFFER (object);
- MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
-
- switch (prop_id)
- {
- case PROP_DEVICE_FILE:
- g_value_set_pointer (value, priv->device_file);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_drm_buffer_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaDrmBuffer *buffer = META_DRM_BUFFER (object);
- MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
-
- switch (prop_id)
- {
- case PROP_DEVICE_FILE:
- priv->device_file = g_value_get_pointer (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_drm_buffer_finalize (GObject *object)
-{
- MetaDrmBuffer *buffer = META_DRM_BUFFER (object);
- MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
-
- if (priv->fb_id != INVALID_FB_ID)
- meta_drm_buffer_release_fb_id (buffer);
- meta_device_file_release (priv->device_file);
-
- G_OBJECT_CLASS (meta_drm_buffer_parent_class)->finalize (object);
-}
-
-static void
-meta_drm_buffer_constructed (GObject *object)
-{
- MetaDrmBuffer *buffer = META_DRM_BUFFER (object);
- MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
-
- meta_device_file_acquire (priv->device_file);
-
- G_OBJECT_CLASS (meta_drm_buffer_parent_class)->constructed (object);
-}
-
-static void
-meta_drm_buffer_init (MetaDrmBuffer *buffer)
-{
-}
-
-static void
-meta_drm_buffer_class_init (MetaDrmBufferClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->get_property = meta_drm_buffer_get_property;
- object_class->set_property = meta_drm_buffer_set_property;
- object_class->constructed = meta_drm_buffer_constructed;
- object_class->finalize = meta_drm_buffer_finalize;
-
- obj_props[PROP_DEVICE_FILE] =
- g_param_spec_pointer ("device-file",
- "device file",
- "MetaDeviceFile",
- 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/native/meta-drm-buffer.h b/src/backends/native/meta-drm-buffer.h
deleted file mode 100644
index d32135591..000000000
--- a/src/backends/native/meta-drm-buffer.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2018 Canonical Ltd.
- * Copyright (C) 2019-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, 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>
-
-#include "cogl/cogl.h"
-
-#define META_TYPE_DRM_BUFFER (meta_drm_buffer_get_type ())
-G_DECLARE_DERIVABLE_TYPE (MetaDrmBuffer,
- meta_drm_buffer,
- META, DRM_BUFFER,
- GObject)
-
-uint32_t meta_drm_buffer_get_fb_id (MetaDrmBuffer *buffer);
-
-int meta_drm_buffer_get_width (MetaDrmBuffer *buffer);
-
-int meta_drm_buffer_get_height (MetaDrmBuffer *buffer);
-
-int meta_drm_buffer_get_stride (MetaDrmBuffer *buffer);
-
-uint32_t meta_drm_buffer_get_format (MetaDrmBuffer *buffer);
-
-gboolean meta_drm_buffer_supports_fill_timings (MetaDrmBuffer *buffer);
-
-gboolean meta_drm_buffer_fill_timings (MetaDrmBuffer *buffer,
- CoglFrameInfo *info,
- GError **error);
-
-#endif /* META_DRM_BUFFER_H */
diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c
deleted file mode 100644
index 97b47f9f9..000000000
--- a/src/backends/native/meta-gpu-kms.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/* -*- 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-crtc-mode-kms.h"
-#include "backends/native/meta-kms-connector.h"
-#include "backends/native/meta-kms-device.h"
-#include "backends/native/meta-kms-mode.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"
-
-struct _MetaGpuKms
-{
- MetaGpu parent;
-
- MetaKmsDevice *kms_device;
-
- uint32_t id;
- int fd;
-
- gboolean resources_init_failed_before;
-};
-
-G_DEFINE_TYPE (MetaGpuKms, meta_gpu_kms, META_TYPE_GPU)
-
-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;
-}
-
-MetaKmsDevice *
-meta_gpu_kms_get_kms_device (MetaGpuKms *gpu_kms)
-{
- return gpu_kms->kms_device;
-}
-
-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);
-}
-
-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);
-}
-
-gboolean
-meta_gpu_kms_disable_modifiers (MetaGpuKms *gpu_kms)
-{
- MetaKmsDeviceFlag flags;
-
- flags = meta_kms_device_get_flags (gpu_kms->kms_device);
- return !!(flags & META_KMS_DEVICE_FLAG_DISABLE_MODIFIERS);
-}
-
-static int
-compare_outputs (gconstpointer one,
- gconstpointer two)
-{
- MetaOutput *o_one = (MetaOutput *) one;
- MetaOutput *o_two = (MetaOutput *) two;
- const MetaOutputInfo *output_info_one = meta_output_get_info (o_one);
- const MetaOutputInfo *output_info_two = meta_output_get_info (o_two);
-
- return strcmp (output_info_one->name, output_info_two->name);
-}
-
-MetaCrtcMode *
-meta_gpu_kms_get_mode_from_kms_mode (MetaGpuKms *gpu_kms,
- MetaKmsMode *kms_mode)
-{
- MetaGpu *gpu = META_GPU (gpu_kms);
- GList *l;
-
- for (l = meta_gpu_get_modes (gpu); l; l = l->next)
- {
- MetaCrtcModeKms *crtc_mode_kms = l->data;
-
- if (meta_kms_mode_equal (kms_mode,
- meta_crtc_mode_kms_get_kms_mode (crtc_mode_kms)))
- return META_CRTC_MODE (crtc_mode_kms);
- }
-
- g_assert_not_reached ();
- return NULL;
-}
-
-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 (META_OUTPUT_KMS (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 (META_OUTPUT_KMS (output),
- META_OUTPUT_KMS (other_output)))
- meta_output_add_possible_clone (output, other_output);
- }
- }
-}
-
-static void
-init_modes (MetaGpuKms *gpu_kms)
-{
- MetaGpu *gpu = META_GPU (gpu_kms);
- MetaKmsDevice *kms_device = gpu_kms->kms_device;
- GHashTable *modes_table;
- GList *l;
- GList *modes;
- GHashTableIter iter;
- gpointer value;
- uint64_t mode_id;
-
- /*
- * Gather all modes on all connected connectors.
- */
- modes_table = g_hash_table_new ((GHashFunc) meta_kms_mode_hash,
- (GEqualFunc) meta_kms_mode_equal);
- for (l = meta_kms_device_get_connectors (kms_device); l; l = l->next)
- {
- MetaKmsConnector *kms_connector = l->data;
- const MetaKmsConnectorState *state;
- GList *l_mode;
-
- state = meta_kms_connector_get_current_state (kms_connector);
- if (!state)
- continue;
-
- for (l_mode = state->modes; l_mode; l_mode = l_mode->next)
- {
- MetaKmsMode *kms_mode = l_mode->data;
-
- g_hash_table_add (modes_table, kms_mode);
- }
- }
-
- for (l = meta_kms_device_get_fallback_modes (kms_device); l; l = l->next)
- {
- MetaKmsMode *fallback_mode = l->data;
-
- g_hash_table_add (modes_table, fallback_mode);
- }
-
- modes = NULL;
-
- g_hash_table_iter_init (&iter, modes_table);
- mode_id = 0;
- while (g_hash_table_iter_next (&iter, NULL, &value))
- {
- MetaKmsMode *kms_mode = value;
- MetaCrtcModeKms *mode;
-
- mode = meta_crtc_mode_kms_new (kms_mode, mode_id);
- modes = g_list_append (modes, mode);
-
- mode_id++;
- }
-
- g_hash_table_destroy (modes_table);
-
- 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;
- MetaCrtcKms *crtc_kms;
-
- crtc_kms = meta_crtc_kms_new (gpu_kms, kms_crtc);
-
- crtcs = g_list_append (crtcs, crtc_kms);
- }
-
- meta_gpu_take_crtcs (gpu, crtcs);
-}
-
-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;
- MetaOutputKms *output_kms;
- MetaOutput *old_output;
- GError *error = NULL;
-
- connector_state = meta_kms_connector_get_current_state (kms_connector);
- if (!connector_state || connector_state->non_desktop)
- continue;
-
- old_output =
- find_output_by_connector_id (old_outputs,
- meta_kms_connector_get_id (kms_connector));
- output_kms = meta_output_kms_new (gpu_kms,
- kms_connector,
- old_output,
- &error);
- if (!output_kms)
- {
- g_warning ("Failed to create KMS output: %s", error->message);
- g_error_free (error);
- }
- else
- {
- outputs = g_list_prepend (outputs, output_kms);
- }
- }
-
-
- /* 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);
-
- 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;
-
- gpu_kms = g_object_new (META_TYPE_GPU_KMS,
- "backend", backend_native,
- NULL);
-
- gpu_kms->kms_device = kms_device;
-
- 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->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
deleted file mode 100644
index 06f6e100a..000000000
--- a/src/backends/native/meta-gpu-kms.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- 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_disable_modifiers (MetaGpuKms *gpu_kms);
-
-MetaKmsDevice * meta_gpu_kms_get_kms_device (MetaGpuKms *gpu_kms);
-
-uint32_t meta_gpu_kms_get_id (MetaGpuKms *gpu_kms);
-
-const char * meta_gpu_kms_get_file_path (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_kms_mode (MetaGpuKms *gpu_kms,
- MetaKmsMode *kms_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);
-
-#endif /* META_GPU_KMS_H */
diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c
deleted file mode 100644
index 468aef557..000000000
--- a/src/backends/native/meta-input-device-native.c
+++ /dev/null
@@ -1,1599 +0,0 @@
-/*
- * 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>
- */
-
-#include "config.h"
-
-#include <math.h>
-#include <cairo-gobject.h>
-
-#include "backends/meta-backend-private.h"
-#include "backends/native/meta-input-thread.h"
-#include "clutter/clutter-mutter.h"
-
-G_DEFINE_TYPE (MetaInputDeviceNative,
- meta_input_device_native,
- META_TYPE_INPUT_DEVICE)
-
-enum
-{
- PROP_0,
- PROP_DEVICE_MATRIX,
- PROP_OUTPUT_ASPECT_RATIO,
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS] = { 0 };
-
-typedef struct _SlowKeysEventPending
-{
- MetaInputDeviceNative *device;
- ClutterEvent *event;
- GSource *timer;
-} SlowKeysEventPending;
-
-typedef struct _PadFeature PadFeature;
-
-struct _PadFeature
-{
- ClutterInputDevicePadFeature feature;
- int n_feature;
- int group;
- gboolean mode_switch;
-};
-
-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
-meta_input_device_native_finalize (GObject *object)
-{
- MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (object);
-
- g_warn_if_fail (!device_evdev->libinput_device);
-
- clear_slow_keys (device_evdev);
- stop_bounce_keys (device_evdev);
- stop_toggle_slowkeys (device_evdev);
- stop_mousekeys_move (device_evdev);
-
- g_clear_pointer (&device_evdev->pad_features, g_array_unref);
- g_clear_pointer (&device_evdev->modes, g_array_unref);
-
- G_OBJECT_CLASS (meta_input_device_native_parent_class)->finalize (object);
-}
-
-static void
-meta_input_device_native_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaInputDeviceNative *device = META_INPUT_DEVICE_NATIVE (object);
-
- switch (prop_id)
- {
- case PROP_DEVICE_MATRIX:
- {
- const cairo_matrix_t *matrix = g_value_get_boxed (value);
- cairo_matrix_init_identity (&device->device_matrix);
- cairo_matrix_multiply (&device->device_matrix,
- &device->device_matrix, matrix);
- break;
- }
- case PROP_OUTPUT_ASPECT_RATIO:
- device->output_ratio = g_value_get_double (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-meta_input_device_native_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaInputDeviceNative *device = META_INPUT_DEVICE_NATIVE (object);
-
- switch (prop_id)
- {
- case PROP_DEVICE_MATRIX:
- g_value_set_boxed (value, &device->device_matrix);
- break;
- case PROP_OUTPUT_ASPECT_RATIO:
- g_value_set_double (value, device->output_ratio);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static gboolean
-meta_input_device_native_is_mode_switch_button (ClutterInputDevice *device,
- uint32_t group,
- uint32_t button)
-{
- MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
- int i;
-
- if (!device_native->pad_features)
- return FALSE;
-
- for (i = 0; i < device_native->pad_features->len; i++)
- {
- PadFeature *pad_feature;
-
- pad_feature = &g_array_index (device_native->pad_features, PadFeature, i);
-
- if (pad_feature->feature == CLUTTER_PAD_FEATURE_BUTTON &&
- pad_feature->group == group &&
- pad_feature->n_feature == button)
- return pad_feature->mode_switch;
- }
-
- return FALSE;
-}
-
-static int
-meta_input_device_native_get_group_n_modes (ClutterInputDevice *device,
- int group)
-{
- MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
-
- if (!device_native->modes || group >= device_native->modes->len)
- return -1;
-
- return g_array_index (device_native->modes, int, group);
-}
-
-static gboolean
-meta_input_device_native_is_grouped (ClutterInputDevice *device,
- ClutterInputDevice *other_device)
-{
- MetaInputDeviceNative *device_native, *other_device_native;
-
- device_native = META_INPUT_DEVICE_NATIVE (device);
- other_device_native = META_INPUT_DEVICE_NATIVE (other_device);
-
- return device_native->group == other_device_native->group;
-}
-
-static int
-meta_input_device_native_get_pad_feature_group (ClutterInputDevice *device,
- ClutterInputDevicePadFeature feature,
- int n_feature)
-{
- MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
- int i;
-
- if (!device_native->pad_features)
- return -1;
-
- for (i = 0; i < device_native->pad_features->len; i++)
- {
- PadFeature *pad_feature;
-
- pad_feature = &g_array_index (device_native->pad_features, PadFeature, i);
-
- if (pad_feature->feature == feature &&
- pad_feature->n_feature == n_feature)
- return pad_feature->group;
- }
-
- return -1;
-}
-
-static void
-meta_input_device_native_bell_notify (MetaInputDeviceNative *device)
-{
- meta_seat_impl_notify_bell_in_impl (device->seat_impl);
-}
-
-static void
-meta_input_device_native_free_pending_slow_key (gpointer data)
-{
- SlowKeysEventPending *slow_keys_event = data;
-
- clutter_event_free (slow_keys_event->event);
- g_clear_pointer (&slow_keys_event->timer, g_source_destroy);
- g_free (slow_keys_event);
-}
-
-static void
-clear_slow_keys (MetaInputDeviceNative *device)
-{
- 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;
-}
-
-static guint
-get_slow_keys_delay (ClutterInputDevice *device)
-{
- MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
- MetaKbdA11ySettings a11y_settings;
- MetaInputSettings *input_settings;
-
- input_settings = meta_seat_impl_get_input_settings (device_native->seat_impl);
- meta_input_settings_get_kbd_a11y_settings (input_settings, &a11y_settings);
- /* Settings use int, we use uint, make sure we dont go negative */
- return MAX (0, a11y_settings.slowkeys_delay);
-}
-
-static gboolean
-trigger_slow_keys (gpointer data)
-{
- SlowKeysEventPending *slow_keys_event = data;
- MetaInputDeviceNative *device = slow_keys_event->device;
- ClutterKeyEvent *key_event = (ClutterKeyEvent *) slow_keys_event->event;
-
- /* Alter timestamp and emit the event */
- key_event->time = us2ms (g_get_monotonic_time ());
- _clutter_event_push (slow_keys_event->event, TRUE);
-
- /* Then remote the pending event */
- device->slow_keys_list = g_list_remove (device->slow_keys_list, slow_keys_event);
- meta_input_device_native_free_pending_slow_key (slow_keys_event);
-
- if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_ACCEPT)
- meta_input_device_native_bell_notify (device);
-
- return G_SOURCE_REMOVE;
-}
-
-static int
-find_pending_event_by_keycode (gconstpointer a,
- gconstpointer b)
-{
- const SlowKeysEventPending *pa = a;
- const ClutterKeyEvent *ka = (ClutterKeyEvent *) pa->event;
- const ClutterKeyEvent *kb = b;
-
- return kb->hardware_keycode - ka->hardware_keycode;
-}
-
-static GSource *
-timeout_source_new (MetaSeatImpl *seat_impl,
- guint interval,
- GSourceFunc func,
- gpointer user_data)
-{
- GSource *source;
-
- source = g_timeout_source_new (interval);
- g_source_set_callback (source,
- func,
- user_data, NULL);
- g_source_attach (source, seat_impl->input_context);
- g_source_unref (source);
-
- return source;
-}
-
-static gboolean
-start_slow_keys (ClutterEvent *event,
- MetaInputDeviceNative *device)
-{
- SlowKeysEventPending *slow_keys_event;
- ClutterKeyEvent *key_event = (ClutterKeyEvent *) event;
-
- if (key_event->flags & CLUTTER_EVENT_FLAG_REPEATED)
- return TRUE;
-
- slow_keys_event = g_new0 (SlowKeysEventPending, 1);
- slow_keys_event->device = device;
- slow_keys_event->event = clutter_event_copy (event);
- slow_keys_event->timer =
- timeout_source_new (device->seat_impl,
- get_slow_keys_delay (CLUTTER_INPUT_DEVICE (device)),
- trigger_slow_keys,
- slow_keys_event);
- device->slow_keys_list = g_list_append (device->slow_keys_list, slow_keys_event);
-
- if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_PRESS)
- meta_input_device_native_bell_notify (device);
-
- return TRUE;
-}
-
-static gboolean
-stop_slow_keys (ClutterEvent *event,
- MetaInputDeviceNative *device)
-{
- GList *item;
-
- /* Check if we have a slow key event queued for this key event */
- item = g_list_find_custom (device->slow_keys_list, event, find_pending_event_by_keycode);
- if (item)
- {
- SlowKeysEventPending *slow_keys_event = item->data;
-
- device->slow_keys_list = g_list_delete_link (device->slow_keys_list, item);
- meta_input_device_native_free_pending_slow_key (slow_keys_event);
-
- if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_REJECT)
- meta_input_device_native_bell_notify (device);
-
- return TRUE;
- }
-
- /* If no key press event was pending, just emit the key release as-is */
- return FALSE;
-}
-
-static guint
-get_debounce_delay (ClutterInputDevice *device)
-{
- MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
- MetaKbdA11ySettings a11y_settings;
- MetaInputSettings *input_settings;
-
- input_settings = meta_seat_impl_get_input_settings (device_native->seat_impl);
- meta_input_settings_get_kbd_a11y_settings (input_settings, &a11y_settings);
- /* Settings use int, we use uint, make sure we dont go negative */
- return MAX (0, a11y_settings.debounce_delay);
-}
-
-static gboolean
-clear_bounce_keys (gpointer data)
-{
- MetaInputDeviceNative *device = data;
-
- device->debounce_key = 0;
- device->debounce_timer = 0;
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-start_bounce_keys (ClutterEvent *event,
- MetaInputDeviceNative *device)
-{
- stop_bounce_keys (device);
-
- device->debounce_key = ((ClutterKeyEvent *) event)->hardware_keycode;
- device->debounce_timer =
- timeout_source_new (device->seat_impl,
- get_debounce_delay (CLUTTER_INPUT_DEVICE (device)),
- clear_bounce_keys,
- device);
-}
-
-static void
-stop_bounce_keys (MetaInputDeviceNative *device)
-{
- g_clear_pointer (&device->debounce_timer, g_source_destroy);
-}
-
-static void
-notify_bounce_keys_reject (MetaInputDeviceNative *device)
-{
- if (device->a11y_flags & META_A11Y_BOUNCE_KEYS_BEEP_REJECT)
- meta_input_device_native_bell_notify (device);
-}
-
-static gboolean
-debounce_key (ClutterEvent *event,
- MetaInputDeviceNative *device)
-{
- return (device->debounce_key == ((ClutterKeyEvent *) event)->hardware_keycode);
-}
-
-static gboolean
-key_event_is_modifier (ClutterEvent *event)
-{
- switch (event->key.keyval)
- {
- case XKB_KEY_Shift_L:
- case XKB_KEY_Shift_R:
- case XKB_KEY_Control_L:
- case XKB_KEY_Control_R:
- case XKB_KEY_Alt_L:
- case XKB_KEY_Alt_R:
- case XKB_KEY_Meta_L:
- case XKB_KEY_Meta_R:
- case XKB_KEY_Super_L:
- case XKB_KEY_Super_R:
- case XKB_KEY_Hyper_L:
- case XKB_KEY_Hyper_R:
- case XKB_KEY_Caps_Lock:
- case XKB_KEY_Shift_Lock:
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-static void
-notify_stickykeys_mask (MetaInputDeviceNative *device)
-{
- meta_seat_impl_notify_kbd_a11y_mods_state_changed_in_impl (device->seat_impl,
- device->stickykeys_latched_mask,
- device->stickykeys_locked_mask);
-}
-
-static void
-update_internal_xkb_state (MetaInputDeviceNative *device,
- xkb_mod_mask_t new_latched_mask,
- xkb_mod_mask_t new_locked_mask)
-{
- MetaSeatImpl *seat_impl = device->seat_impl;
- xkb_mod_mask_t depressed_mods;
- xkb_mod_mask_t latched_mods;
- xkb_mod_mask_t locked_mods;
- xkb_mod_mask_t group_mods;
- struct xkb_state *xkb_state;
-
- g_rw_lock_writer_lock (&seat_impl->state_lock);
-
- xkb_state = meta_seat_impl_get_xkb_state_in_impl (seat_impl);
- depressed_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_DEPRESSED);
- latched_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LATCHED);
- locked_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LOCKED);
-
- latched_mods &= ~device->stickykeys_latched_mask;
- locked_mods &= ~device->stickykeys_locked_mask;
-
- device->stickykeys_latched_mask = new_latched_mask;
- device->stickykeys_locked_mask = new_locked_mask;
-
- latched_mods |= device->stickykeys_latched_mask;
- locked_mods |= device->stickykeys_locked_mask;
-
- group_mods = xkb_state_serialize_layout (xkb_state, XKB_STATE_LAYOUT_EFFECTIVE);
-
- xkb_state_update_mask (xkb_state,
- depressed_mods,
- latched_mods,
- locked_mods,
- 0, 0, group_mods);
- notify_stickykeys_mask (device);
-
- g_rw_lock_writer_unlock (&seat_impl->state_lock);
-}
-
-static void
-update_stickykeys_event (ClutterEvent *event,
- MetaInputDeviceNative *device,
- xkb_mod_mask_t new_latched_mask,
- xkb_mod_mask_t new_locked_mask)
-{
- MetaSeatImpl *seat_impl = device->seat_impl;
- xkb_mod_mask_t effective_mods;
- xkb_mod_mask_t latched_mods;
- xkb_mod_mask_t locked_mods;
- struct xkb_state *xkb_state;
-
- update_internal_xkb_state (device, new_latched_mask, new_locked_mask);
-
- xkb_state = meta_seat_impl_get_xkb_state_in_impl (seat_impl);
- effective_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_EFFECTIVE);
- latched_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LATCHED);
- locked_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LOCKED);
-
- _clutter_event_set_state_full (event,
- seat_impl->button_state,
- device->stickykeys_depressed_mask,
- latched_mods,
- locked_mods,
- effective_mods | seat_impl->button_state);
-}
-
-static void
-notify_stickykeys_change (MetaInputDeviceNative *device)
-{
- /* Every time sticky keys setting is changed, clear the masks */
- device->stickykeys_depressed_mask = 0;
- update_internal_xkb_state (device, 0, 0);
-
- meta_seat_impl_notify_kbd_a11y_flags_changed_in_impl (device->seat_impl,
- device->a11y_flags,
- META_A11Y_STICKY_KEYS_ENABLED);
-}
-
-static void
-set_stickykeys_off (MetaInputDeviceNative *device)
-{
- device->a11y_flags &= ~META_A11Y_STICKY_KEYS_ENABLED;
- notify_stickykeys_change (device);
-}
-
-static void
-set_stickykeys_on (MetaInputDeviceNative *device)
-{
- device->a11y_flags |= META_A11Y_STICKY_KEYS_ENABLED;
- notify_stickykeys_change (device);
-}
-
-static void
-clear_stickykeys_event (ClutterEvent *event,
- MetaInputDeviceNative *device)
-{
- set_stickykeys_off (device);
- update_stickykeys_event (event, device, 0, 0);
-}
-
-static void
-set_slowkeys_off (MetaInputDeviceNative *device)
-{
- device->a11y_flags &= ~META_A11Y_SLOW_KEYS_ENABLED;
-
- meta_seat_impl_notify_kbd_a11y_flags_changed_in_impl (device->seat_impl,
- device->a11y_flags,
- META_A11Y_SLOW_KEYS_ENABLED);
-}
-
-static void
-set_slowkeys_on (MetaInputDeviceNative *device)
-{
- device->a11y_flags |= META_A11Y_SLOW_KEYS_ENABLED;
-
- meta_seat_impl_notify_kbd_a11y_flags_changed_in_impl (device->seat_impl,
- device->a11y_flags,
- META_A11Y_SLOW_KEYS_ENABLED);
-}
-
-static void
-handle_stickykeys_press (ClutterEvent *event,
- MetaInputDeviceNative *device)
-{
- MetaSeatImpl *seat_impl = device->seat_impl;
- xkb_mod_mask_t depressed_mods;
- xkb_mod_mask_t new_latched_mask;
- xkb_mod_mask_t new_locked_mask;
- struct xkb_state *xkb_state;
-
- if (!key_event_is_modifier (event))
- return;
-
- if (device->stickykeys_depressed_mask &&
- (device->a11y_flags & META_A11Y_STICKY_KEYS_TWO_KEY_OFF))
- {
- clear_stickykeys_event (event, device);
- return;
- }
-
- xkb_state = meta_seat_impl_get_xkb_state_in_impl (seat_impl);
- depressed_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_DEPRESSED);
- /* Ignore the lock modifier mask, that one cannot be sticky, yet the
- * CAPS_LOCK key itself counts as a modifier as it might be remapped
- * to some other modifier which can be sticky.
- */
- depressed_mods &= ~CLUTTER_LOCK_MASK;
-
- new_latched_mask = device->stickykeys_latched_mask;
- new_locked_mask = device->stickykeys_locked_mask;
-
- device->stickykeys_depressed_mask = depressed_mods;
-
- if (new_locked_mask & depressed_mods)
- {
- new_locked_mask &= ~depressed_mods;
- }
- else if (new_latched_mask & depressed_mods)
- {
- new_locked_mask |= depressed_mods;
- new_latched_mask &= ~depressed_mods;
- }
- else
- {
- new_latched_mask |= depressed_mods;
- }
-
- update_stickykeys_event (event, device, new_latched_mask, new_locked_mask);
-}
-
-static void
-handle_stickykeys_release (ClutterEvent *event,
- MetaInputDeviceNative *device)
-{
- MetaSeatImpl *seat_impl = device->seat_impl;
- struct xkb_state *xkb_state;
-
- xkb_state = meta_seat_impl_get_xkb_state_in_impl (seat_impl);
- device->stickykeys_depressed_mask =
- xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_DEPRESSED);
-
- if (key_event_is_modifier (event))
- {
- if (device->a11y_flags & META_A11Y_STICKY_KEYS_BEEP)
- meta_input_device_native_bell_notify (device);
-
- return;
- }
-
- if (device->stickykeys_latched_mask == 0)
- return;
-
- update_stickykeys_event (event, device, 0, device->stickykeys_locked_mask);
-}
-
-static gboolean
-trigger_toggle_slowkeys (gpointer data)
-{
- MetaInputDeviceNative *device = data;
-
- device->toggle_slowkeys_timer = 0;
-
- if (device->a11y_flags & META_A11Y_FEATURE_STATE_CHANGE_BEEP)
- meta_input_device_native_bell_notify (device);
-
- if (device->a11y_flags & META_A11Y_SLOW_KEYS_ENABLED)
- set_slowkeys_off (device);
- else
- set_slowkeys_on (device);
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-start_toggle_slowkeys (MetaInputDeviceNative *device)
-{
- if (device->toggle_slowkeys_timer != 0)
- return;
-
- device->toggle_slowkeys_timer =
- timeout_source_new (device->seat_impl,
- 8 * 1000 /* 8 secs */,
- trigger_toggle_slowkeys,
- device);
-}
-
-static void
-stop_toggle_slowkeys (MetaInputDeviceNative *device)
-{
- g_clear_pointer (&device->toggle_slowkeys_timer, g_source_destroy);
-}
-
-static void
-handle_enablekeys_press (ClutterEvent *event,
- MetaInputDeviceNative *device)
-{
- if (event->key.keyval == XKB_KEY_Shift_L || event->key.keyval == XKB_KEY_Shift_R)
- {
- start_toggle_slowkeys (device);
-
- if (event->key.time > device->last_shift_time + 15 * 1000 /* 15 secs */)
- device->shift_count = 1;
- else
- device->shift_count++;
-
- device->last_shift_time = event->key.time;
- }
- else
- {
- device->shift_count = 0;
- stop_toggle_slowkeys (device);
- }
-}
-
-static void
-handle_enablekeys_release (ClutterEvent *event,
- MetaInputDeviceNative *device)
-{
- if (event->key.keyval == XKB_KEY_Shift_L || event->key.keyval == XKB_KEY_Shift_R)
- {
- stop_toggle_slowkeys (device);
- if (device->shift_count >= 5)
- {
- device->shift_count = 0;
-
- if (device->a11y_flags & META_A11Y_FEATURE_STATE_CHANGE_BEEP)
- meta_input_device_native_bell_notify (device);
-
- if (device->a11y_flags & META_A11Y_STICKY_KEYS_ENABLED)
- set_stickykeys_off (device);
- else
- set_stickykeys_on (device);
- }
- }
-}
-
-static int
-get_button_index (int button)
-{
- switch (button)
- {
- case CLUTTER_BUTTON_PRIMARY:
- return 0;
- case CLUTTER_BUTTON_MIDDLE:
- return 1;
- case CLUTTER_BUTTON_SECONDARY:
- return 2;
- default:
- break;
- }
-
- g_warn_if_reached ();
- return 0;
-}
-
-static void
-emulate_button_press (MetaInputDeviceNative *device_evdev)
-{
- ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
- int btn = device_evdev->mousekeys_btn;
-
- if (device_evdev->mousekeys_btn_states[get_button_index (btn)])
- return;
-
- clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
- g_get_monotonic_time (), btn,
- CLUTTER_BUTTON_STATE_PRESSED);
- device_evdev->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_PRESSED;
-}
-
-static void
-emulate_button_release (MetaInputDeviceNative *device_evdev)
-{
- ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
- int btn = device_evdev->mousekeys_btn;
-
- if (device_evdev->mousekeys_btn_states[get_button_index (btn)] == CLUTTER_BUTTON_STATE_RELEASED)
- return;
-
- clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
- g_get_monotonic_time (), btn,
- CLUTTER_BUTTON_STATE_RELEASED);
- device_evdev->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_RELEASED;
-}
-
-static void
-emulate_button_click (MetaInputDeviceNative *device)
-{
- emulate_button_press (device);
- emulate_button_release (device);
-}
-
-#define MOUSEKEYS_CURVE (1.0 + (((double) 50.0) * 0.001))
-
-static void
-update_mousekeys_params (MetaInputDeviceNative *device,
- MetaKbdA11ySettings *settings)
-{
- /* Prevent us from broken settings values */
- device->mousekeys_max_speed = MAX (1, settings->mousekeys_max_speed);
- device->mousekeys_accel_time = MAX (1, settings->mousekeys_accel_time);
- device->mousekeys_init_delay = MAX (0, settings->mousekeys_init_delay);
-
- device->mousekeys_curve_factor =
- (((double) device->mousekeys_max_speed) /
- pow ((double) device->mousekeys_accel_time, MOUSEKEYS_CURVE));
-}
-
-static double
-mousekeys_get_speed_factor (MetaInputDeviceNative *device,
- uint64_t time_us)
-{
- uint32_t time;
- int64_t delta_t;
- int64_t init_time;
- double speed;
-
- time = us2ms (time_us);
-
- if (device->mousekeys_first_motion_time == 0)
- {
- /* Start acceleration _after_ the first move, so take
- * mousekeys_init_delay into account for t0
- */
- device->mousekeys_first_motion_time = time + device->mousekeys_init_delay;
- device->mousekeys_last_motion_time = device->mousekeys_first_motion_time;
- return 1.0;
- }
-
- init_time = time - device->mousekeys_first_motion_time;
- delta_t = time - device->mousekeys_last_motion_time;
-
- if (delta_t < 0)
- return 0.0;
-
- if (init_time < device->mousekeys_accel_time)
- speed = (double) (device->mousekeys_curve_factor *
- pow ((double) init_time, MOUSEKEYS_CURVE) * delta_t / 1000.0);
- else
- speed = (double) (device->mousekeys_max_speed * delta_t / 1000.0);
-
- device->mousekeys_last_motion_time = time;
-
- return speed;
-}
-
-#undef MOUSEKEYS_CURVE
-
-static void
-emulate_pointer_motion (MetaInputDeviceNative *device_evdev,
- int dx,
- int dy)
-{
- 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_evdev, time_us);
-
- if (dx < 0)
- dx_motion = floor (((double) dx) * speed);
- else
- dx_motion = ceil (((double) dx) * speed);
-
- if (dy < 0)
- dy_motion = floor (((double) dy) * speed);
- else
- dy_motion = ceil (((double) dy) * speed);
-
- clutter_virtual_input_device_notify_relative_motion (device->accessibility_virtual_device,
- time_us, dx_motion, dy_motion);
-}
-static gboolean
-is_numlock_active (MetaInputDeviceNative *device)
-{
- MetaSeatImpl *seat_impl = device->seat_impl;
- struct xkb_state *xkb_state;
-
- xkb_state = meta_seat_impl_get_xkb_state_in_impl (seat_impl);
-
- return xkb_state_mod_name_is_active (xkb_state,
- "Mod2",
- XKB_STATE_MODS_LOCKED);
-}
-
-static void
-enable_mousekeys (MetaInputDeviceNative *device_evdev)
-{
- ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
-
- 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->accessibility_virtual_device)
- return;
-
- device->accessibility_virtual_device =
- clutter_seat_create_virtual_device (clutter_input_device_get_seat (device),
- CLUTTER_POINTER_DEVICE);
-}
-
-static void
-disable_mousekeys (MetaInputDeviceNative *device_evdev)
-{
- ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
-
- stop_mousekeys_move (device_evdev);
-
- /* Make sure we don't leave button pressed behind... */
- if (device_evdev->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_PRIMARY)])
- {
- device_evdev->mousekeys_btn = CLUTTER_BUTTON_PRIMARY;
- emulate_button_release (device_evdev);
- }
-
- if (device_evdev->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_MIDDLE)])
- {
- device_evdev->mousekeys_btn = CLUTTER_BUTTON_MIDDLE;
- emulate_button_release (device_evdev);
- }
-
- if (device_evdev->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_SECONDARY)])
- {
- device_evdev->mousekeys_btn = CLUTTER_BUTTON_SECONDARY;
- emulate_button_release (device_evdev);
- }
-
- if (device->accessibility_virtual_device)
- g_clear_object (&device->accessibility_virtual_device);
-}
-
-static gboolean
-trigger_mousekeys_move (gpointer data)
-{
- MetaInputDeviceNative *device = data;
- int dx = 0;
- int dy = 0;
-
- if (device->mousekeys_first_motion_time == 0)
- {
- /* This is the first move, Secdule at mk_init_delay */
- device->move_mousekeys_timer =
- timeout_source_new (device->seat_impl,
- device->mousekeys_init_delay,
- trigger_mousekeys_move,
- device);
-
- }
- else
- {
- /* More moves, reschedule at mk_interval */
- device->move_mousekeys_timer =
- timeout_source_new (device->seat_impl,
- 100, /* msec between mousekey events */
- trigger_mousekeys_move,
- device);
- }
-
- /* Pointer motion */
- switch (device->last_mousekeys_key)
- {
- case XKB_KEY_KP_Home:
- case XKB_KEY_KP_7:
- case XKB_KEY_KP_Up:
- case XKB_KEY_KP_8:
- case XKB_KEY_KP_Page_Up:
- case XKB_KEY_KP_9:
- dy = -1;
- break;
- case XKB_KEY_KP_End:
- case XKB_KEY_KP_1:
- case XKB_KEY_KP_Down:
- case XKB_KEY_KP_2:
- case XKB_KEY_KP_Page_Down:
- case XKB_KEY_KP_3:
- dy = 1;
- break;
- default:
- break;
- }
-
- switch (device->last_mousekeys_key)
- {
- case XKB_KEY_KP_Home:
- case XKB_KEY_KP_7:
- case XKB_KEY_KP_Left:
- case XKB_KEY_KP_4:
- case XKB_KEY_KP_End:
- case XKB_KEY_KP_1:
- dx = -1;
- break;
- case XKB_KEY_KP_Page_Up:
- case XKB_KEY_KP_9:
- case XKB_KEY_KP_Right:
- case XKB_KEY_KP_6:
- case XKB_KEY_KP_Page_Down:
- case XKB_KEY_KP_3:
- dx = 1;
- break;
- default:
- break;
- }
-
- if (dx != 0 || dy != 0)
- emulate_pointer_motion (device, dx, dy);
-
- /* We reschedule each time */
- return G_SOURCE_REMOVE;
-}
-
-static void
-stop_mousekeys_move (MetaInputDeviceNative *device)
-{
- device->mousekeys_first_motion_time = 0;
- device->mousekeys_last_motion_time = 0;
-
- g_clear_pointer (&device->move_mousekeys_timer, g_source_destroy);
-}
-
-static void
-start_mousekeys_move (ClutterEvent *event,
- MetaInputDeviceNative *device)
-{
- device->last_mousekeys_key = event->key.keyval;
-
- if (device->move_mousekeys_timer != 0)
- return;
-
- trigger_mousekeys_move (device);
-}
-
-static gboolean
-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 = CLUTTER_BUTTON_PRIMARY;
- return TRUE;
- case XKB_KEY_KP_Multiply:
- device->mousekeys_btn = CLUTTER_BUTTON_MIDDLE;
- return TRUE;
- case XKB_KEY_KP_Subtract:
- device->mousekeys_btn = CLUTTER_BUTTON_SECONDARY;
- return TRUE;
- default:
- break;
- }
-
- /* Button events */
- switch (event->key.keyval)
- {
- case XKB_KEY_KP_Begin:
- case XKB_KEY_KP_5:
- emulate_button_click (device);
- return TRUE;
- case XKB_KEY_KP_Insert:
- case XKB_KEY_KP_0:
- emulate_button_press (device);
- return TRUE;
- case XKB_KEY_KP_Decimal:
- case XKB_KEY_KP_Delete:
- emulate_button_release (device);
- return TRUE;
- case XKB_KEY_KP_Add:
- emulate_button_click (device);
- emulate_button_click (device);
- return TRUE;
- default:
- break;
- }
-
- /* Pointer motion */
- switch (event->key.keyval)
- {
- case XKB_KEY_KP_1:
- case XKB_KEY_KP_2:
- case XKB_KEY_KP_3:
- case XKB_KEY_KP_4:
- case XKB_KEY_KP_6:
- case XKB_KEY_KP_7:
- case XKB_KEY_KP_8:
- case XKB_KEY_KP_9:
- case XKB_KEY_KP_Down:
- case XKB_KEY_KP_End:
- case XKB_KEY_KP_Home:
- case XKB_KEY_KP_Left:
- case XKB_KEY_KP_Page_Down:
- case XKB_KEY_KP_Page_Up:
- case XKB_KEY_KP_Right:
- case XKB_KEY_KP_Up:
- start_mousekeys_move (event, device);
- return TRUE;
- default:
- break;
- }
-
- return FALSE;
-}
-
-static gboolean
-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:
- case XKB_KEY_KP_1:
- case XKB_KEY_KP_2:
- case XKB_KEY_KP_3:
- case XKB_KEY_KP_4:
- case XKB_KEY_KP_5:
- case XKB_KEY_KP_6:
- case XKB_KEY_KP_7:
- case XKB_KEY_KP_8:
- case XKB_KEY_KP_9:
- case XKB_KEY_KP_Add:
- case XKB_KEY_KP_Begin:
- case XKB_KEY_KP_Decimal:
- case XKB_KEY_KP_Delete:
- case XKB_KEY_KP_Divide:
- case XKB_KEY_KP_Down:
- case XKB_KEY_KP_End:
- case XKB_KEY_KP_Home:
- case XKB_KEY_KP_Insert:
- case XKB_KEY_KP_Left:
- case XKB_KEY_KP_Multiply:
- case XKB_KEY_KP_Page_Down:
- case XKB_KEY_KP_Page_Up:
- case XKB_KEY_KP_Right:
- case XKB_KEY_KP_Subtract:
- case XKB_KEY_KP_Up:
- stop_mousekeys_move (device);
- return TRUE;
- default:
- break;
- }
-
- return FALSE;
-}
-
-gboolean
-meta_input_device_native_process_kbd_a11y_event_in_impl (ClutterInputDevice *device,
- ClutterEvent *event)
-{
- MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (device);
-
- if (device_evdev->a11y_flags & META_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 & META_A11Y_MOUSE_KEYS_ENABLED)
- {
- if (event->type == CLUTTER_KEY_PRESS &&
- handle_mousekeys_press (event, device_evdev))
- return TRUE; /* swallow event */
- if (event->type == CLUTTER_KEY_RELEASE &&
- handle_mousekeys_release (event, device_evdev))
- return TRUE; /* swallow event */
- }
-
- if ((device_evdev->a11y_flags & META_A11Y_BOUNCE_KEYS_ENABLED) &&
- (get_debounce_delay (device) != 0))
- {
- if ((event->type == CLUTTER_KEY_PRESS) && debounce_key (event, device_evdev))
- {
- notify_bounce_keys_reject (device_evdev);
-
- return TRUE;
- }
- else if (event->type == CLUTTER_KEY_RELEASE)
- start_bounce_keys (event, device_evdev);
- }
-
- if ((device_evdev->a11y_flags & META_A11Y_SLOW_KEYS_ENABLED) &&
- (get_slow_keys_delay (device) != 0))
- {
- if (event->type == CLUTTER_KEY_PRESS)
- return start_slow_keys (event, device_evdev);
- else if (event->type == CLUTTER_KEY_RELEASE)
- return stop_slow_keys (event, device_evdev);
- }
-
- if (device_evdev->a11y_flags & META_A11Y_STICKY_KEYS_ENABLED)
- {
- if (event->type == CLUTTER_KEY_PRESS)
- handle_stickykeys_press (event, device_evdev);
- else if (event->type == CLUTTER_KEY_RELEASE)
- handle_stickykeys_release (event, device_evdev);
- }
-
- return FALSE;
-}
-
-void
-meta_input_device_native_apply_kbd_a11y_settings_in_impl (MetaInputDeviceNative *device,
- MetaKbdA11ySettings *settings)
-{
- MetaKeyboardA11yFlags changed_flags = (device->a11y_flags ^ settings->controls);
-
- if (changed_flags & (META_A11Y_KEYBOARD_ENABLED | META_A11Y_SLOW_KEYS_ENABLED))
- clear_slow_keys (device);
-
- if (changed_flags & (META_A11Y_KEYBOARD_ENABLED | META_A11Y_BOUNCE_KEYS_ENABLED))
- device->debounce_key = 0;
-
- if (changed_flags & (META_A11Y_KEYBOARD_ENABLED | META_A11Y_STICKY_KEYS_ENABLED))
- {
- device->stickykeys_depressed_mask = 0;
- update_internal_xkb_state (device, 0, 0);
- }
-
- if (changed_flags & META_A11Y_KEYBOARD_ENABLED)
- {
- device->toggle_slowkeys_timer = 0;
- device->shift_count = 0;
- device->last_shift_time = 0;
- }
-
- if (changed_flags & (META_A11Y_KEYBOARD_ENABLED | META_A11Y_MOUSE_KEYS_ENABLED))
- {
- if (settings->controls &
- (META_A11Y_KEYBOARD_ENABLED | META_A11Y_MOUSE_KEYS_ENABLED))
- enable_mousekeys (device);
- else
- disable_mousekeys (device);
- }
- update_mousekeys_params (device, settings);
-
- /* Keep our own copy of keyboard a11y features flags to see what changes */
- device->a11y_flags = settings->controls;
-}
-
-void
-meta_input_device_native_a11y_maybe_notify_toggle_keys_in_impl (MetaInputDeviceNative *device)
-{
- if (device->a11y_flags & META_A11Y_TOGGLE_KEYS_ENABLED)
- meta_input_device_native_bell_notify (device);
-}
-
-static void
-meta_input_device_native_class_init (MetaInputDeviceNativeClass *klass)
-{
- ClutterInputDeviceClass *device_class = CLUTTER_INPUT_DEVICE_CLASS (klass);
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- 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;
-
- device_class->is_mode_switch_button = meta_input_device_native_is_mode_switch_button;
- device_class->get_group_n_modes = meta_input_device_native_get_group_n_modes;
- device_class->is_grouped = meta_input_device_native_is_grouped;
- device_class->get_pad_feature_group = meta_input_device_native_get_pad_feature_group;
-
- obj_props[PROP_DEVICE_MATRIX] =
- g_param_spec_boxed ("device-matrix",
- "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",
- "Output aspect ratio",
- "Output aspect ratio",
- 0, G_MAXDOUBLE, 0,
- CLUTTER_PARAM_READWRITE);
-
- g_object_class_install_properties (object_class, N_PROPS, obj_props);
-}
-
-static void
-meta_input_device_native_init (MetaInputDeviceNative *self)
-{
- cairo_matrix_init_identity (&self->device_matrix);
- self->device_aspect_ratio = 0;
- self->output_ratio = 0;
-}
-
-static void
-update_pad_features (MetaInputDeviceNative *device_native)
-{
- ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_native);
- struct libinput_device *libinput_device;
- struct libinput_tablet_pad_mode_group *mode_group;
- int n_groups, n_buttons, n_rings, n_strips, n_modes, i, j;
-
- libinput_device = meta_input_device_native_get_libinput_device (device);
- n_rings = libinput_device_tablet_pad_get_num_rings (libinput_device);
- n_strips = libinput_device_tablet_pad_get_num_strips (libinput_device);
- n_groups = libinput_device_tablet_pad_get_num_mode_groups (libinput_device);
- n_buttons = libinput_device_tablet_pad_get_num_buttons (libinput_device);
-
- device_native->pad_features = g_array_new (FALSE, FALSE, sizeof (PadFeature));
- device_native->modes = g_array_sized_new (FALSE, FALSE, sizeof (int), n_groups);
-
- for (i = 0; i < n_groups; i++)
- {
- mode_group =
- libinput_device_tablet_pad_get_mode_group (libinput_device, i);
-
- n_modes = libinput_tablet_pad_mode_group_get_num_modes (mode_group);
- g_array_append_val (device_native->modes, n_modes);
-
- for (j = 0; j < n_buttons; j++)
- {
- gboolean is_mode_switch =
- libinput_tablet_pad_mode_group_button_is_toggle (mode_group, j) != 0;
- PadFeature feature = { CLUTTER_PAD_FEATURE_BUTTON, j, i, is_mode_switch };
-
- if (libinput_tablet_pad_mode_group_has_button (mode_group, j))
- g_array_append_val (device_native->pad_features, feature);
- }
-
- for (j = 0; j < n_rings; j++)
- {
- PadFeature feature = { CLUTTER_PAD_FEATURE_RING, j, i };
-
- if (libinput_tablet_pad_mode_group_has_ring (mode_group, j))
- g_array_append_val (device_native->pad_features, feature);
- }
-
- for (j = 0; j < n_strips; j++)
- {
- PadFeature feature = { CLUTTER_PAD_FEATURE_STRIP, j, i };
-
- if (libinput_tablet_pad_mode_group_has_strip (mode_group, j))
- g_array_append_val (device_native->pad_features, feature);
- }
- }
-}
-
-/*
- * meta_input_device_native_new:
- * @manager: the device manager
- * @seat: the seat the device will belong to
- * @libinput_device: the libinput device
- *
- * Create a new ClutterInputDevice given a libinput device and associate
- * it with the provided seat.
- */
-ClutterInputDevice *
-meta_input_device_native_new_in_impl (MetaSeatImpl *seat_impl,
- struct libinput_device *libinput_device)
-{
- MetaInputDeviceNative *device;
- ClutterInputDeviceType type;
- char *vendor, *product;
- int n_rings = 0, n_strips = 0, n_groups = 1, n_buttons = 0;
- char *node_path;
- double width, height;
-
- type = meta_input_device_native_determine_type_in_impl (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));
- node_path = g_strdup_printf ("/dev/input/%s", libinput_device_get_sysname (libinput_device));
-
- if (libinput_device_has_capability (libinput_device,
- LIBINPUT_DEVICE_CAP_TABLET_PAD))
- {
- n_rings = libinput_device_tablet_pad_get_num_rings (libinput_device);
- n_strips = libinput_device_tablet_pad_get_num_strips (libinput_device);
- n_groups = libinput_device_tablet_pad_get_num_mode_groups (libinput_device);
- n_buttons = libinput_device_tablet_pad_get_num_buttons (libinput_device);
- }
-
- device = g_object_new (META_TYPE_INPUT_DEVICE_NATIVE,
- "name", libinput_device_get_name (libinput_device),
- "device-type", type,
- "device-mode", CLUTTER_INPUT_MODE_PHYSICAL,
- "vendor-id", vendor,
- "product-id", product,
- "n-rings", n_rings,
- "n-strips", n_strips,
- "n-mode-groups", n_groups,
- "n-buttons", n_buttons,
- "device-node", node_path,
- "seat", seat_impl->seat_native,
- NULL);
-
- device->seat_impl = seat_impl;
- device->libinput_device = libinput_device;
-
- libinput_device_set_user_data (libinput_device, device);
- libinput_device_ref (libinput_device);
- g_free (vendor);
- g_free (product);
- g_free (node_path);
-
- if (libinput_device_has_capability (libinput_device,
- LIBINPUT_DEVICE_CAP_TABLET_PAD))
- update_pad_features (device);
-
- if (libinput_device_get_size (libinput_device, &width, &height) == 0)
- device->device_aspect_ratio = width / height;
-
- device->group = (intptr_t) libinput_device_get_device_group (libinput_device);
-
- return CLUTTER_INPUT_DEVICE (device);
-}
-
-/*
- * 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 *
-meta_input_device_native_new_virtual (MetaSeatImpl *seat_impl,
- ClutterInputDeviceType type,
- ClutterInputMode mode)
-{
- MetaInputDeviceNative *device;
- const char *name;
-
- switch (type)
- {
- case CLUTTER_KEYBOARD_DEVICE:
- name = "Virtual keyboard device for seat";
- break;
- case CLUTTER_POINTER_DEVICE:
- name = "Virtual pointer device for seat";
- break;
- case CLUTTER_TOUCHSCREEN_DEVICE:
- name = "Virtual touchscreen device for seat";
- break;
- default:
- name = "Virtual device for seat";
- break;
- };
-
- device = g_object_new (META_TYPE_INPUT_DEVICE_NATIVE,
- "name", name,
- "device-type", type,
- "device-mode", mode,
- "seat", seat_impl->seat_native,
- NULL);
-
- device->seat_impl = seat_impl;
-
- return CLUTTER_INPUT_DEVICE (device);
-}
-
-MetaSeatImpl *
-meta_input_device_native_get_seat_impl (MetaInputDeviceNative *device)
-{
- return device->seat_impl;
-}
-
-void
-meta_input_device_native_update_leds_in_impl (MetaInputDeviceNative *device,
- enum libinput_led leds)
-{
- if (!device->libinput_device)
- return;
-
- libinput_device_led_update (device->libinput_device, leds);
-}
-
-ClutterInputDeviceType
-meta_input_device_native_determine_type_in_impl (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.
- */
- if (libinput_device_config_tap_get_finger_count (ldev) > 0)
- return CLUTTER_TOUCHPAD_DEVICE;
- else if (libinput_device_has_capability (ldev, LIBINPUT_DEVICE_CAP_TABLET_TOOL))
- return CLUTTER_TABLET_DEVICE;
- else if (libinput_device_has_capability (ldev, LIBINPUT_DEVICE_CAP_TABLET_PAD))
- return CLUTTER_PAD_DEVICE;
- else if (libinput_device_has_capability (ldev, LIBINPUT_DEVICE_CAP_POINTER))
- return CLUTTER_POINTER_DEVICE;
- else if (libinput_device_has_capability (ldev, LIBINPUT_DEVICE_CAP_TOUCH))
- return CLUTTER_TOUCHSCREEN_DEVICE;
- else if (libinput_device_has_capability (ldev, LIBINPUT_DEVICE_CAP_KEYBOARD))
- return CLUTTER_KEYBOARD_DEVICE;
- else
- return CLUTTER_EXTENSION_DEVICE;
-}
-
-/**
- * meta_input_device_native_get_libinput_device:
- * @device: a #ClutterInputDevice
- *
- * Retrieves the libinput_device struct held in @device.
- *
- * Returns: The libinput_device struct
- *
- * Since: 1.20
- * Stability: unstable
- **/
-struct libinput_device *
-meta_input_device_native_get_libinput_device (ClutterInputDevice *device)
-{
- MetaInputDeviceNative *device_evdev;
-
- g_return_val_if_fail (META_IS_INPUT_DEVICE_NATIVE (device), NULL);
-
- device_evdev = META_INPUT_DEVICE_NATIVE (device);
-
- return device_evdev->libinput_device;
-}
-
-void
-meta_input_device_native_translate_coordinates_in_impl (ClutterInputDevice *device,
- MetaViewportInfo *viewports,
- float *x,
- float *y)
-{
- MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (device);
- double min_x = 0, min_y = 0, max_x = 1, max_y = 1;
- float stage_width, stage_height;
- double x_d, y_d;
-
- meta_viewport_info_get_extents (viewports, &stage_width, &stage_height);
- x_d = *x / stage_width;
- y_d = *y / stage_height;
-
- /* Apply aspect ratio */
- if (device_evdev->output_ratio > 0 &&
- device_evdev->device_aspect_ratio > 0)
- {
- double ratio = device_evdev->device_aspect_ratio / device_evdev->output_ratio;
-
- if (ratio > 1)
- x_d *= ratio;
- else if (ratio < 1)
- y_d *= 1 / ratio;
- }
-
- cairo_matrix_transform_point (&device_evdev->device_matrix, &min_x, &min_y);
- cairo_matrix_transform_point (&device_evdev->device_matrix, &max_x, &max_y);
- cairo_matrix_transform_point (&device_evdev->device_matrix, &x_d, &y_d);
-
- *x = CLAMP (x_d, MIN (min_x, max_x), MAX (min_x, max_x)) * stage_width;
- *y = CLAMP (y_d, MIN (min_y, max_y), MAX (min_y, max_y)) * stage_height;
-}
-
-MetaInputDeviceMapping
-meta_input_device_native_get_mapping_mode_in_impl (ClutterInputDevice *device)
-{
- MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
- ClutterInputDeviceType device_type;
-
- g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device),
- META_INPUT_DEVICE_MAPPING_ABSOLUTE);
-
- device_type = clutter_input_device_get_device_type (device);
- g_return_val_if_fail (device_type == CLUTTER_TABLET_DEVICE ||
- device_type == CLUTTER_PEN_DEVICE ||
- device_type == CLUTTER_ERASER_DEVICE,
- META_INPUT_DEVICE_MAPPING_ABSOLUTE);
-
- return device_native->mapping_mode;
-}
-
-void
-meta_input_device_native_set_mapping_mode_in_impl (ClutterInputDevice *device,
- MetaInputDeviceMapping mapping)
-{
- MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
- ClutterInputDeviceType device_type;
-
- g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
-
- device_type = clutter_input_device_get_device_type (device);
- g_return_if_fail (device_type == CLUTTER_TABLET_DEVICE ||
- device_type == CLUTTER_PEN_DEVICE ||
- device_type == CLUTTER_ERASER_DEVICE);
-
- device_native->mapping_mode = mapping;
-}
-
-void
-meta_input_device_native_set_coords_in_impl (MetaInputDeviceNative *device_native,
- float x,
- float y)
-{
- device_native->pointer_x = x;
- device_native->pointer_y = y;
-}
-
-void
-meta_input_device_native_get_coords_in_impl (MetaInputDeviceNative *device_native,
- float *x,
- float *y)
-{
- if (x)
- *x = device_native->pointer_x;
- if (y)
- *y = device_native->pointer_y;
-}
-
-void
-meta_input_device_native_detach_libinput_in_impl (MetaInputDeviceNative *device_native)
-{
- g_clear_pointer (&device_native->libinput_device, libinput_device_unref);
-}
diff --git a/src/backends/native/meta-input-device-native.h b/src/backends/native/meta-input-device-native.h
deleted file mode 100644
index 88af07c43..000000000
--- a/src/backends/native/meta-input-device-native.h
+++ /dev/null
@@ -1,162 +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 <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
-
-#ifndef META_INPUT_THREAD_H_INSIDE
-#error "This header cannot be included directly. Use "backends/native/meta-input-thread.h""
-#endif /* META_INPUT_THREAD_H_INSIDE */
-
-#include <glib-object.h>
-
-#include "backends/meta-input-device-private.h"
-#include "backends/meta-input-settings-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 enum
-{
- META_INPUT_DEVICE_MAPPING_ABSOLUTE,
- META_INPUT_DEVICE_MAPPING_RELATIVE,
-} MetaInputDeviceMapping;
-
-typedef struct _MetaInputDeviceNative MetaInputDeviceNative;
-typedef struct _MetaInputDeviceNativeClass MetaInputDeviceNativeClass;
-
-struct _MetaInputDeviceNative
-{
- ClutterInputDevice parent;
-
- struct libinput_device *libinput_device;
- MetaSeatImpl *seat_impl;
- ClutterInputDeviceTool *last_tool;
- GArray *pad_features;
- GArray *modes;
- intptr_t group;
-
- cairo_matrix_t device_matrix;
- double device_aspect_ratio; /* w:h */
- double output_ratio; /* w:h */
- MetaInputDeviceMapping mapping_mode;
-
- /* Pointer position */
- float pointer_x;
- float pointer_y;
-
- /* Keyboard a11y */
- MetaKeyboardA11yFlags a11y_flags;
- GList *slow_keys_list;
- GSource *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;
- GSource *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;
- GSource *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_in_impl (MetaSeatImpl *seat_impl,
- struct libinput_device *libinput_device);
-
-ClutterInputDevice * meta_input_device_native_new_virtual (MetaSeatImpl *seat_impl,
- ClutterInputDeviceType type,
- ClutterInputMode mode);
-
-MetaSeatImpl * meta_input_device_native_get_seat_impl (MetaInputDeviceNative *device);
-
-void meta_input_device_native_update_leds_in_impl (MetaInputDeviceNative *device,
- enum libinput_led leds);
-
-ClutterInputDeviceType meta_input_device_native_determine_type_in_impl (struct libinput_device *libinput_device);
-
-
-void meta_input_device_native_translate_coordinates_in_impl (ClutterInputDevice *device,
- MetaViewportInfo *viewports,
- float *x,
- float *y);
-
-MetaInputDeviceMapping meta_input_device_native_get_mapping_mode_in_impl (ClutterInputDevice *device);
-void meta_input_device_native_set_mapping_mode_in_impl (ClutterInputDevice *device,
- MetaInputDeviceMapping mapping);
-
-void meta_input_device_native_apply_kbd_a11y_settings_in_impl (MetaInputDeviceNative *device,
- MetaKbdA11ySettings *settings);
-
-void meta_input_device_native_a11y_maybe_notify_toggle_keys_in_impl (MetaInputDeviceNative *device_evdev);
-
-struct libinput_device * meta_input_device_native_get_libinput_device (ClutterInputDevice *device);
-
-void meta_input_device_native_set_coords_in_impl (MetaInputDeviceNative *device_native,
- float x,
- float y);
-void meta_input_device_native_get_coords_in_impl (MetaInputDeviceNative *device_native,
- float *x,
- float *y);
-gboolean meta_input_device_native_process_kbd_a11y_event_in_impl (ClutterInputDevice *device,
- ClutterEvent *event);
-void meta_input_device_native_detach_libinput_in_impl (MetaInputDeviceNative *device_native);
-
-#endif /* META_INPUT_DEVICE_NATIVE_H */
diff --git a/src/backends/native/meta-input-device-tool-native.c b/src/backends/native/meta-input-device-tool-native.c
deleted file mode 100644
index e6ec0c758..000000000
--- a/src/backends/native/meta-input-device-tool-native.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * 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>
- */
-
-#include "config.h"
-
-#include "backends/native/meta-input-thread.h"
-
-G_DEFINE_TYPE (MetaInputDeviceToolNative, meta_input_device_tool_native,
- CLUTTER_TYPE_INPUT_DEVICE_TOOL)
-
-static void
-meta_input_device_tool_native_finalize (GObject *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 (meta_input_device_tool_native_parent_class)->finalize (object);
-}
-
-static void
-meta_input_device_tool_native_class_init (MetaInputDeviceToolNativeClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = meta_input_device_tool_native_finalize;
-}
-
-static void
-meta_input_device_tool_native_init (MetaInputDeviceToolNative *tool)
-{
- tool->button_map = g_hash_table_new (NULL, NULL);
-}
-
-static ClutterInputAxisFlags
-translate_axes (struct libinput_tablet_tool *tool)
-{
- ClutterInputAxisFlags axes = 0;
-
- if (libinput_tablet_tool_has_pressure (tool))
- axes |= CLUTTER_INPUT_AXIS_FLAG_PRESSURE;
- if (libinput_tablet_tool_has_distance (tool))
- axes |= CLUTTER_INPUT_AXIS_FLAG_DISTANCE;
- if (libinput_tablet_tool_has_rotation (tool))
- axes |= CLUTTER_INPUT_AXIS_FLAG_ROTATION;
- if (libinput_tablet_tool_has_slider (tool))
- axes |= CLUTTER_INPUT_AXIS_FLAG_SLIDER;
- if (libinput_tablet_tool_has_wheel (tool))
- axes |= CLUTTER_INPUT_AXIS_FLAG_WHEEL;
- if (libinput_tablet_tool_has_tilt (tool))
- axes |= CLUTTER_INPUT_AXIS_FLAG_XTILT | CLUTTER_INPUT_AXIS_FLAG_YTILT;
-
- return axes;
-}
-
-ClutterInputDeviceTool *
-meta_input_device_tool_native_new (struct libinput_tablet_tool *tool,
- uint64_t serial,
- ClutterInputDeviceToolType type)
-{
- MetaInputDeviceToolNative *evdev_tool;
-
- evdev_tool = g_object_new (META_TYPE_INPUT_DEVICE_TOOL_NATIVE,
- "type", type,
- "serial", serial,
- "id", libinput_tablet_tool_get_tool_id (tool),
- "axes", translate_axes (tool),
- NULL);
-
- evdev_tool->tool = libinput_tablet_tool_ref (tool);
-
- return CLUTTER_INPUT_DEVICE_TOOL (evdev_tool);
-}
-
-void
-meta_input_device_tool_native_set_pressure_curve_in_impl (ClutterInputDeviceTool *tool,
- double curve[4])
-{
- MetaInputDeviceToolNative *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 = 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];
- evdev_tool->pressure_curve[3] = curve[3];
-}
-
-void
-meta_input_device_tool_native_set_button_code_in_impl (ClutterInputDeviceTool *tool,
- uint32_t button,
- uint32_t evcode)
-{
- MetaInputDeviceToolNative *evdev_tool;
-
- g_return_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool));
-
- evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool);
-
- if (evcode == 0)
- {
- g_hash_table_remove (evdev_tool->button_map, GUINT_TO_POINTER (button));
- }
- else
- {
- g_hash_table_insert (evdev_tool->button_map, GUINT_TO_POINTER (button),
- GUINT_TO_POINTER (evcode));
- }
-}
-
-static double
-calculate_bezier_position (double pos,
- double x1,
- double y1,
- double x2,
- double y2)
-{
- double int1_y, int2_y;
-
- pos = CLAMP (pos, 0, 1);
-
- /* Intersection between 0,0 and x1,y1 */
- int1_y = pos * y1;
-
- /* Intersection between x2,y2 and 1,1 */
- int2_y = (pos * (1 - y2)) + y2;
-
- /* Find the new position in the line traced by the previous points */
- return (pos * (int2_y - int1_y)) + int1_y;
-}
-
-double
-meta_input_device_tool_native_translate_pressure_in_impl (ClutterInputDeviceTool *tool,
- double pressure)
-{
- MetaInputDeviceToolNative *evdev_tool;
-
- g_return_val_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool), pressure);
-
- evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool);
-
- return calculate_bezier_position (CLAMP (pressure, 0, 1),
- evdev_tool->pressure_curve[0],
- evdev_tool->pressure_curve[1],
- evdev_tool->pressure_curve[2],
- evdev_tool->pressure_curve[3]);
-}
-
-uint32_t
-meta_input_device_tool_native_get_button_code_in_impl (ClutterInputDeviceTool *tool,
- uint32_t button)
-{
- MetaInputDeviceToolNative *evdev_tool;
-
- g_return_val_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool), 0);
-
- 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
deleted file mode 100644
index fa12358ad..000000000
--- a/src/backends/native/meta-input-device-tool-native.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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
-
-#ifndef META_INPUT_THREAD_H_INSIDE
-#error "This header cannot be included directly. Use "backends/native/meta-input-thread.h""
-#endif /* META_INPUT_THREAD_H_INSIDE */
-
-#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_in_impl (ClutterInputDeviceTool *tool,
- double pressure);
-uint32_t meta_input_device_tool_native_get_button_code_in_impl (ClutterInputDeviceTool *tool,
- uint32_t button);
-
-void meta_input_device_tool_native_set_pressure_curve_in_impl (ClutterInputDeviceTool *tool,
- double curve[4]);
-void meta_input_device_tool_native_set_button_code_in_impl (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
deleted file mode 100644
index 8f61b8bcc..000000000
--- a/src/backends/native/meta-input-settings-native.c
+++ /dev/null
@@ -1,876 +0,0 @@
-/* -*- 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/native/meta-backend-native.h"
-#include "backends/native/meta-input-thread.h"
-#include "backends/native/meta-input-settings-native.h"
-
-G_DEFINE_TYPE (MetaInputSettingsNative, meta_input_settings_native, META_TYPE_INPUT_SETTINGS)
-
-enum
-{
- PROP_0,
- PROP_SEAT_IMPL,
- N_PROPS,
-};
-
-static GParamSpec *props[N_PROPS] = { 0 };
-
-static void
-meta_input_settings_native_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaInputSettingsNative *input_settings_native =
- META_INPUT_SETTINGS_NATIVE (object);
-
- switch (prop_id)
- {
- case PROP_SEAT_IMPL:
- input_settings_native->seat_impl = g_value_get_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_input_settings_native_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaInputSettingsNative *input_settings_native =
- META_INPUT_SETTINGS_NATIVE (object);
-
- switch (prop_id)
- {
- case PROP_SEAT_IMPL:
- g_value_set_object (value, input_settings_native->seat_impl);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static gboolean
-set_send_events (GTask *task)
-{
- GDesktopDeviceSendEvents mode;
- ClutterInputDevice *device;
- enum libinput_config_send_events_mode libinput_mode;
- struct libinput_device *libinput_device;
-
- device = g_task_get_source_object (task);
- mode = GPOINTER_TO_UINT (g_task_get_task_data (task));
-
- switch (mode)
- {
- case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED:
- libinput_mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
- break;
- case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
- libinput_mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
- break;
- case G_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)
- libinput_device_config_send_events_set_mode (libinput_device, libinput_mode);
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_input_settings_native_set_send_events (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopDeviceSendEvents mode)
-{
- MetaInputSettingsNative *input_settings_native;
- GTask *task;
-
- task = g_task_new (device, NULL, NULL, NULL);
- g_task_set_task_data (task, GUINT_TO_POINTER (mode), NULL);
-
- input_settings_native = META_INPUT_SETTINGS_NATIVE (settings);
- meta_seat_impl_run_input_task (input_settings_native->seat_impl,
- task, (GSourceFunc) set_send_events);
- g_object_unref (task);
-}
-
-static gboolean
-set_matrix (GTask *task)
-{
- ClutterInputDevice *device = g_task_get_source_object (task);
- float *matrix = g_task_get_task_data (task);
- cairo_matrix_t dev_matrix;
-
- if (clutter_input_device_get_device_type (device) ==
- CLUTTER_TOUCHSCREEN_DEVICE ||
- meta_input_device_native_get_mapping_mode_in_impl (device) ==
- META_INPUT_DEVICE_MAPPING_ABSOLUTE)
- {
- cairo_matrix_init (&dev_matrix,
- matrix[0], matrix[3], matrix[1],
- matrix[4], matrix[2], matrix[5]);
- }
- else
- {
- cairo_matrix_init_identity (&dev_matrix);
- }
-
- g_object_set (device, "device-matrix", &dev_matrix, NULL);
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_input_settings_native_set_matrix (MetaInputSettings *settings,
- ClutterInputDevice *device,
- const float matrix[6])
-{
- MetaInputSettingsNative *input_settings_native;
- GTask *task;
-
- task = g_task_new (device, NULL, NULL, NULL);
-
- g_task_set_task_data (task, g_memdup2 (matrix, sizeof (float) * 6), g_free);
-
- input_settings_native = META_INPUT_SETTINGS_NATIVE (settings);
- meta_seat_impl_run_input_task (input_settings_native->seat_impl,
- task, (GSourceFunc) set_matrix);
- g_object_unref (task);
-}
-
-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_tap_and_drag_lock_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_lock_enabled (libinput_device,
- enabled ?
- LIBINPUT_CONFIG_DRAG_LOCK_ENABLED :
- LIBINPUT_CONFIG_DRAG_LOCK_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 gboolean
-device_set_tap_button_map (struct libinput_device *libinput_device,
- enum libinput_config_tap_button_map map)
-{
- enum libinput_config_status status =
- libinput_device_config_tap_set_button_map (libinput_device, map);
- 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,
- gboolean button_lock)
-{
- struct libinput_device *libinput_device;
- enum libinput_config_scroll_method method;
- enum libinput_config_scroll_button_lock_state lock_state;
- 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
- {
- switch (button)
- {
- case 1:
- evcode = BTN_LEFT;
- break;
- case 2:
- evcode = BTN_MIDDLE;
- break;
- case 3:
- evcode = BTN_RIGHT;
- break;
- default:
- /* 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);
-
- if (button_lock)
- lock_state = LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED;
- else
- lock_state = LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED;
-
- libinput_device_config_scroll_set_button_lock (libinput_device, lock_state);
-}
-
-static void
-meta_input_settings_native_set_click_method (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopTouchpadClickMethod 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 G_DESKTOP_TOUCHPAD_CLICK_METHOD_DEFAULT:
- click_method = libinput_device_config_click_get_default_method (libinput_device);
- break;
- case G_DESKTOP_TOUCHPAD_CLICK_METHOD_NONE:
- click_method = LIBINPUT_CONFIG_CLICK_METHOD_NONE;
- break;
- case G_DESKTOP_TOUCHPAD_CLICK_METHOD_AREAS:
- click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
- break;
- case G_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_tap_button_map (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopTouchpadTapButtonMap mode)
-{
- enum libinput_config_tap_button_map button_map = 0;
- 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)
- return;
-
- switch (mode)
- {
- case G_DESKTOP_TOUCHPAD_BUTTON_TAP_MAP_DEFAULT:
- button_map = libinput_device_config_tap_get_default_button_map (libinput_device);
- break;
- case G_DESKTOP_TOUCHPAD_BUTTON_TAP_MAP_LRM:
- button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
- break;
- case G_DESKTOP_TOUCHPAD_BUTTON_TAP_MAP_LMR:
- button_map = LIBINPUT_CONFIG_TAP_MAP_LMR;
- break;
- default:
- g_assert_not_reached ();
- return;
- }
-
- device_set_tap_button_map (libinput_device, button_map);
-}
-
-static void
-meta_input_settings_native_set_keyboard_repeat (MetaInputSettings *settings,
- gboolean enabled,
- guint delay,
- guint interval)
-{
- MetaInputSettingsNative *input_settings_native;
-
- input_settings_native = META_INPUT_SETTINGS_NATIVE (settings);
- meta_seat_impl_set_keyboard_repeat_in_impl (input_settings_native->seat_impl,
- enabled, delay, interval);
-}
-
-static void
-set_device_accel_profile (ClutterInputDevice *device,
- GDesktopPointerAccelProfile 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 G_DESKTOP_POINTER_ACCEL_PROFILE_FLAT:
- libinput_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT;
- break;
- case G_DESKTOP_POINTER_ACCEL_PROFILE_ADAPTIVE:
- libinput_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
- break;
- default:
- g_warn_if_reached ();
- case G_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,
- GDesktopPointerAccelProfile 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,
- GDesktopPointerAccelProfile 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,
- GDesktopTabletMapping mapping)
-{
- MetaInputDeviceMapping dev_mapping;
-
- if (mapping == G_DESKTOP_TABLET_MAPPING_ABSOLUTE)
- dev_mapping = META_INPUT_DEVICE_MAPPING_ABSOLUTE;
- else if (mapping == G_DESKTOP_TABLET_MAPPING_RELATIVE)
- dev_mapping = META_INPUT_DEVICE_MAPPING_RELATIVE;
- else
- return;
-
- meta_input_device_native_set_mapping_mode_in_impl (device, dev_mapping);
-}
-
-static gboolean
-set_tablet_aspect_ratio (GTask *task)
-{
- ClutterInputDevice *device;
- double *aspect_ratio;
-
- device = g_task_get_source_object (task);
- aspect_ratio = g_task_get_task_data (task);
- g_object_set (device, "output-aspect-ratio", *aspect_ratio, NULL);
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_input_settings_native_set_tablet_aspect_ratio (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gdouble aspect_ratio)
-{
- MetaInputSettingsNative *input_settings_native;
- GTask *task;
-
- if (meta_input_device_native_get_mapping_mode_in_impl (device) ==
- META_INPUT_DEVICE_MAPPING_RELATIVE)
- aspect_ratio = 0;
-
- task = g_task_new (device, NULL, NULL, NULL);
- g_task_set_task_data (task,
- g_memdup2 (&aspect_ratio, sizeof (double)),
- g_free);
-
- input_settings_native = META_INPUT_SETTINGS_NATIVE (settings);
- meta_seat_impl_run_input_task (input_settings_native->seat_impl,
- task, (GSourceFunc) set_tablet_aspect_ratio);
- g_object_unref (task);
-}
-
-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_in_impl (tool, pressure_curve);
-}
-
-static guint
-action_to_evcode (GDesktopStylusButtonAction action)
-{
- switch (action)
- {
- case G_DESKTOP_STYLUS_BUTTON_ACTION_MIDDLE:
- return BTN_STYLUS;
- case G_DESKTOP_STYLUS_BUTTON_ACTION_RIGHT:
- return BTN_STYLUS2;
- case G_DESKTOP_STYLUS_BUTTON_ACTION_BACK:
- return BTN_BACK;
- case G_DESKTOP_STYLUS_BUTTON_ACTION_FORWARD:
- return BTN_FORWARD;
- case G_DESKTOP_STYLUS_BUTTON_ACTION_DEFAULT:
- default:
- return 0;
- }
-}
-
-static void
-meta_input_settings_native_set_stylus_button_map (MetaInputSettings *settings,
- ClutterInputDevice *device,
- ClutterInputDeviceTool *tool,
- GDesktopStylusButtonAction primary,
- GDesktopStylusButtonAction secondary,
- GDesktopStylusButtonAction tertiary)
-{
- meta_input_device_tool_native_set_button_code_in_impl (tool, CLUTTER_BUTTON_MIDDLE,
- action_to_evcode (primary));
- meta_input_device_tool_native_set_button_code_in_impl (tool, CLUTTER_BUTTON_SECONDARY,
- action_to_evcode (secondary));
- meta_input_device_tool_native_set_button_code_in_impl (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);
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->set_property = meta_input_settings_native_set_property;
- object_class->get_property = meta_input_settings_native_get_property;
-
- 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_button_map = meta_input_settings_native_set_tap_button_map;
- input_settings_class->set_tap_and_drag_enabled = meta_input_settings_native_set_tap_and_drag_enabled;
- input_settings_class->set_tap_and_drag_lock_enabled =
- meta_input_settings_native_set_tap_and_drag_lock_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_aspect_ratio = meta_input_settings_native_set_tablet_aspect_ratio;
- 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;
-
- props[PROP_SEAT_IMPL] =
- g_param_spec_object ("seat-impl",
- "Seat Impl",
- "Seat Impl",
- META_TYPE_SEAT_IMPL,
- CLUTTER_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY);
-
- g_object_class_install_properties (object_class, N_PROPS, props);
-}
-
-static void
-meta_input_settings_native_init (MetaInputSettingsNative *settings)
-{
-}
-
-MetaInputSettings *
-meta_input_settings_native_new_in_impl (MetaSeatImpl *seat_impl)
-{
- return g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE,
- "seat-impl", seat_impl,
- NULL);
-}
diff --git a/src/backends/native/meta-input-settings-native.h b/src/backends/native/meta-input-settings-native.h
deleted file mode 100644
index cddd5b15f..000000000
--- a/src/backends/native/meta-input-settings-native.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- 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
-
-#ifndef META_INPUT_THREAD_H_INSIDE
-#error "This header cannot be included directly. Use "backends/native/meta-input-thread.h""
-#endif /* META_INPUT_THREAD_H_INSIDE */
-
-#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;
- MetaSeatImpl *seat_impl;
-};
-
-struct _MetaInputSettingsNativeClass
-{
- MetaInputSettingsClass parent_class;
-};
-
-GType meta_input_settings_native_get_type (void) G_GNUC_CONST;
-
-MetaInputSettings * meta_input_settings_native_new_in_impl (MetaSeatImpl *seat_impl);
-
-#endif /* META_INPUT_SETTINGS_NATIVE_H */
diff --git a/src/backends/native/meta-input-thread.h b/src/backends/native/meta-input-thread.h
deleted file mode 100644
index 196adc27b..000000000
--- a/src/backends/native/meta-input-thread.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2020 Red Hat Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 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_THREAD_H
-#define META_INPUT_THREAD_H
-
-#define META_INPUT_THREAD_H_INSIDE
-
-#include "src/backends/native/meta-input-device-native.h"
-#include "src/backends/native/meta-input-device-tool-native.h"
-#include "src/backends/native/meta-input-settings-native.h"
-#include "src/backends/native/meta-keymap-native.h"
-#include "src/backends/native/meta-seat-impl.h"
-
-#undef META_INPUT_THREAD_H_INSIDE
-
-#endif /* META_INPUT_THREAD_H */
diff --git a/src/backends/native/meta-keymap-native.c b/src/backends/native/meta-keymap-native.c
deleted file mode 100644
index 500bb1012..000000000
--- a/src/backends/native/meta-keymap-native.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * 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/meta-keymap-utils.h"
-#include "backends/native/meta-input-thread.h"
-#include "backends/native/meta-seat-impl.h"
-#include "backends/native/meta-seat-native.h"
-#include "clutter/clutter-keymap-private.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;
- gboolean num_lock;
- gboolean caps_lock;
-};
-
-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 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_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 = meta_create_xkb_context ();
- g_assert (ctx);
- keymap->keymap = xkb_keymap_new_from_names (ctx, &names, 0);
- xkb_context_unref (ctx);
-}
-
-void
-meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap,
- struct xkb_keymap *xkb_keymap)
-{
- g_return_if_fail (xkb_keymap != NULL);
-
- if (keymap->keymap)
- xkb_keymap_unref (keymap->keymap);
- keymap->keymap = xkb_keymap_ref (xkb_keymap);
-}
-
-struct xkb_keymap *
-meta_keymap_native_get_keyboard_map_in_impl (MetaKeymapNative *keymap)
-{
- return keymap->keymap;
-}
-
-typedef struct
-{
- MetaKeymapNative *keymap_native;
- gboolean num_lock_state;
- gboolean caps_lock_state;
-} UpdateLockedModifierStateData;
-
-static gboolean
-update_locked_modifier_state_in_main (gpointer user_data)
-{
- UpdateLockedModifierStateData *data = user_data;
-
- clutter_keymap_set_lock_modifier_state (CLUTTER_KEYMAP (data->keymap_native),
- data->caps_lock_state,
- data->num_lock_state);
-
- return G_SOURCE_REMOVE;
-}
-
-void
-meta_keymap_native_update_in_impl (MetaKeymapNative *keymap_native,
- MetaSeatImpl *seat_impl,
- struct xkb_state *xkb_state)
-{
- UpdateLockedModifierStateData *data;
-
- data = g_new0 (UpdateLockedModifierStateData, 1);
- data->keymap_native = keymap_native;
- data->num_lock_state =
- xkb_state_mod_name_is_active (xkb_state,
- XKB_MOD_NAME_NUM,
- XKB_STATE_MODS_LATCHED |
- XKB_STATE_MODS_LOCKED);
- data->caps_lock_state =
- xkb_state_mod_name_is_active (xkb_state,
- XKB_MOD_NAME_CAPS,
- XKB_STATE_MODS_LATCHED |
- XKB_STATE_MODS_LOCKED);
-
- meta_seat_impl_queue_main_thread_idle (seat_impl,
- update_locked_modifier_state_in_main,
- data, g_free);
-}
diff --git a/src/backends/native/meta-keymap-native.h b/src/backends/native/meta-keymap-native.h
deleted file mode 100644
index 0aa62d085..000000000
--- a/src/backends/native/meta-keymap-native.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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
-
-#ifndef META_INPUT_THREAD_H_INSIDE
-#error "This header cannot be included directly. Use "backends/native/meta-input-thread.h""
-#endif /* META_INPUT_THREAD_H_INSIDE */
-
-#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_in_impl (MetaKeymapNative *keymap,
- struct xkb_keymap *xkb_keymap);
-struct xkb_keymap * meta_keymap_native_get_keyboard_map_in_impl (MetaKeymapNative *keymap);
-void meta_keymap_native_update_in_impl (MetaKeymapNative *keymap,
- MetaSeatImpl *seat_impl,
- struct xkb_state *xkb_state);
-
-#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
deleted file mode 100644
index 9accf8ccd..000000000
--- a/src/backends/native/meta-kms-connector-private.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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-connector.h"
-
-typedef enum _MetaKmsConnectorProp
-{
- META_KMS_CONNECTOR_PROP_CRTC_ID = 0,
- META_KMS_CONNECTOR_PROP_DPMS,
- META_KMS_CONNECTOR_PROP_UNDERSCAN,
- META_KMS_CONNECTOR_PROP_UNDERSCAN_HBORDER,
- META_KMS_CONNECTOR_PROP_UNDERSCAN_VBORDER,
- META_KMS_CONNECTOR_N_PROPS
-} MetaKmsConnectorProp;
-
-uint32_t meta_kms_connector_get_prop_id (MetaKmsConnector *connector,
- MetaKmsConnectorProp prop);
-
-const char * meta_kms_connector_get_prop_name (MetaKmsConnector *connector,
- MetaKmsConnectorProp prop);
-
-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
deleted file mode 100644
index a666bb45c..000000000
--- a/src/backends/native/meta-kms-connector.c
+++ /dev/null
@@ -1,700 +0,0 @@
-/*
- * 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-mode-private.h"
-#include "backends/native/meta-kms-update-private.h"
-
-typedef struct _MetaKmsConnectorPropTable
-{
- MetaKmsProp props[META_KMS_CONNECTOR_N_PROPS];
-} MetaKmsConnectorPropTable;
-
-struct _MetaKmsConnector
-{
- GObject parent;
-
- MetaKmsDevice *device;
-
- uint32_t id;
- uint32_t type;
- uint32_t type_id;
- char *name;
-
- MetaKmsConnectorState *current_state;
-
- MetaKmsConnectorPropTable prop_table;
-
- uint32_t edid_blob_id;
- uint32_t tile_blob_id;
-
- gboolean fd_held;
-};
-
-G_DEFINE_TYPE (MetaKmsConnector, meta_kms_connector, G_TYPE_OBJECT)
-
-MetaKmsDevice *
-meta_kms_connector_get_device (MetaKmsConnector *connector)
-{
- return connector->device;
-}
-
-uint32_t
-meta_kms_connector_get_prop_id (MetaKmsConnector *connector,
- MetaKmsConnectorProp prop)
-{
- return connector->prop_table.props[prop].prop_id;
-}
-
-const char *
-meta_kms_connector_get_prop_name (MetaKmsConnector *connector,
- MetaKmsConnectorProp prop)
-{
- return connector->prop_table.props[prop].name;
-}
-
-uint32_t
-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)
-{
- uint32_t underscan_prop_id;
-
- underscan_prop_id =
- connector->prop_table.props[META_KMS_CONNECTOR_PROP_UNDERSCAN].prop_id;
-
- return underscan_prop_id != 0;
-}
-
-static void
-sync_fd_held (MetaKmsConnector *connector,
- MetaKmsImplDevice *impl_device)
-{
- gboolean should_hold_fd;
-
- should_hold_fd = connector->current_state->current_crtc_id != 0;
-
- if (connector->fd_held == should_hold_fd)
- return;
-
- if (should_hold_fd)
- meta_kms_impl_device_hold_fd (impl_device);
- else
- meta_kms_impl_device_unhold_fd (impl_device);
-
- connector->fd_held = should_hold_fd;
-}
-
-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]);
- else if ((prop->flags & DRM_MODE_PROP_RANGE) &&
- strcmp (prop->name, "non-desktop") == 0)
- state->non_desktop = 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,
- MetaKmsImplDevice *impl_device,
- drmModeConnector *drm_connector)
-{
- int i;
-
- for (i = 0; i < drm_connector->count_modes; i++)
- {
- MetaKmsMode *mode;
-
- mode = meta_kms_mode_new (impl_device, &drm_connector->modes[i],
- META_KMS_MODE_FLAG_NONE);
- state->modes = g_list_prepend (state->modes, mode);
- }
- state->modes = g_list_reverse (state->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_list_free_full (state->modes, (GDestroyNotify) meta_kms_mode_free);
- 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, impl_device, drm_connector);
-
- state_set_crtc_state (state, drm_connector, impl_device, drm_resources);
-
- connector->current_state = state;
-
- sync_fd_held (connector, impl_device);
-}
-
-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)
-{
- MetaKmsImplDevice *impl_device;
- MetaKmsConnectorState *current_state;
- GList *mode_sets;
- GList *l;
- current_state = connector->current_state;
- if (!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 = mode_set->crtc;
-
- if (current_state->current_crtc_id == meta_kms_crtc_get_id (crtc))
- {
- if (g_list_find (mode_set->connectors, connector))
- break;
- else
- current_state->current_crtc_id = 0;
- }
- else
- {
- if (g_list_find (mode_set->connectors, connector))
- {
- current_state->current_crtc_id = meta_kms_crtc_get_id (crtc);
- break;
- }
- }
- }
-
- impl_device = meta_kms_device_get_impl_device (connector->device);
- sync_fd_held (connector, impl_device);
-}
-
-static void
-init_properties (MetaKmsConnector *connector,
- MetaKmsImplDevice *impl_device,
- drmModeConnector *drm_connector)
-{
- MetaKmsConnectorPropTable *prop_table = &connector->prop_table;
-
- *prop_table = (MetaKmsConnectorPropTable) {
- .props = {
- [META_KMS_CONNECTOR_PROP_CRTC_ID] =
- {
- .name = "CRTC_ID",
- .type = DRM_MODE_PROP_OBJECT,
- },
- [META_KMS_CONNECTOR_PROP_DPMS] =
- {
- .name = "DPMS",
- .type = DRM_MODE_PROP_ENUM,
- },
- [META_KMS_CONNECTOR_PROP_UNDERSCAN] =
- {
- .name = "underscan",
- .type = DRM_MODE_PROP_ENUM,
- },
- [META_KMS_CONNECTOR_PROP_UNDERSCAN_HBORDER] =
- {
- .name = "underscan hborder",
- .type = DRM_MODE_PROP_RANGE,
- },
- [META_KMS_CONNECTOR_PROP_UNDERSCAN_VBORDER] =
- {
- .name = "underscan vborder",
- .type = DRM_MODE_PROP_RANGE,
- },
- }
- };
-
- meta_kms_impl_device_init_prop_table (impl_device,
- drm_connector->props,
- drm_connector->prop_values,
- drm_connector->count_props,
- connector->prop_table.props,
- META_KMS_CONNECTOR_N_PROPS,
- NULL);
-}
-
-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 = drm_connector->connector_type;
- connector->type_id = drm_connector->connector_type_id;
- connector->name = make_connector_name (drm_connector);
-
- init_properties (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);
-
- if (connector->fd_held)
- {
- MetaKmsImplDevice *impl_device;
-
- impl_device = meta_kms_device_get_impl_device (connector->device);
- meta_kms_impl_device_unhold_fd (impl_device);
- }
-
- 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
deleted file mode 100644
index a3a7136c5..000000000
--- a/src/backends/native/meta-kms-connector.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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;
-
- GList *modes;
-
- uint32_t width_mm;
- uint32_t height_mm;
-
- MetaTileInfo tile_info;
- GBytes *edid_data;
-
- gboolean has_scaling;
- gboolean non_desktop;
-
- 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);
-
-uint32_t 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
deleted file mode 100644
index 60c5fd309..000000000
--- a/src/backends/native/meta-kms-crtc-private.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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-crtc.h"
-
-typedef enum _MetaKmsCrtcProp
-{
- META_KMS_CRTC_PROP_MODE_ID = 0,
- META_KMS_CRTC_PROP_ACTIVE,
- META_KMS_CRTC_PROP_GAMMA_LUT,
- META_KMS_CRTC_N_PROPS
-} MetaKmsCrtcProp;
-
-MetaKmsCrtc * meta_kms_crtc_new (MetaKmsImplDevice *impl_device,
- drmModeCrtc *drm_crtc,
- int idx,
- GError **error);
-
-void meta_kms_crtc_update_state (MetaKmsCrtc *crtc);
-
-void meta_kms_crtc_predict_state (MetaKmsCrtc *crtc,
- MetaKmsUpdate *update);
-
-uint32_t meta_kms_crtc_get_prop_id (MetaKmsCrtc *crtc,
- MetaKmsCrtcProp prop);
-
-const char * meta_kms_crtc_get_prop_name (MetaKmsCrtc *crtc,
- MetaKmsCrtcProp prop);
-
-#endif /* META_KMS_CRTC_PRIVATE_H */
diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c
deleted file mode 100644
index 51d040b44..000000000
--- a/src/backends/native/meta-kms-crtc.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * 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-mode.h"
-#include "backends/native/meta-kms-update-private.h"
-
-typedef struct _MetaKmsCrtcPropTable
-{
- MetaKmsProp props[META_KMS_CRTC_N_PROPS];
-} MetaKmsCrtcPropTable;
-
-struct _MetaKmsCrtc
-{
- GObject parent;
-
- MetaKmsDevice *device;
-
- uint32_t id;
- int idx;
-
- MetaKmsCrtcState current_state;
-
- MetaKmsCrtcPropTable prop_table;
-};
-
-G_DEFINE_TYPE (MetaKmsCrtc, meta_kms_crtc, G_TYPE_OBJECT)
-
-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;
-}
-
-uint32_t
-meta_kms_crtc_get_prop_id (MetaKmsCrtc *crtc,
- MetaKmsCrtcProp prop)
-{
- return crtc->prop_table.props[prop].prop_id;
-}
-
-const char *
-meta_kms_crtc_get_prop_name (MetaKmsCrtc *crtc,
- MetaKmsCrtcProp prop)
-{
- return crtc->prop_table.props[prop].name;
-}
-
-gboolean
-meta_kms_crtc_is_active (MetaKmsCrtc *crtc)
-{
- return crtc->current_state.is_active;
-}
-
-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 int
-find_prop_idx (MetaKmsProp *prop,
- uint32_t *drm_props,
- int n_drm_props)
-{
- int i;
-
- g_return_val_if_fail (prop->prop_id > 0, -1);
-
- for (i = 0; i < n_drm_props; i++)
- {
- if (drm_props[i] == prop->prop_id)
- return i;
- }
-
- return -1;
-}
-
-static void
-meta_kms_crtc_read_state (MetaKmsCrtc *crtc,
- MetaKmsImplDevice *impl_device,
- drmModeCrtc *drm_crtc,
- drmModeObjectProperties *drm_props)
-{
- MetaKmsProp *active_prop;
- int active_idx;
-
- 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;
-
- active_prop = &crtc->prop_table.props[META_KMS_CRTC_PROP_ACTIVE];
- if (active_prop->prop_id)
- {
- active_idx = find_prop_idx (active_prop,
- drm_props->props,
- drm_props->count_props);
- crtc->current_state.is_active = !!drm_props->prop_values[active_idx];
- }
- else
- {
- crtc->current_state.is_active = drm_crtc->mode_valid;
- }
-
- meta_topic (META_DEBUG_KMS,
- "Read CRTC %u state: active: %d, mode: %s",
- crtc->id, crtc->current_state.is_active,
- crtc->current_state.is_drm_mode_valid
- ? crtc->current_state.drm_mode.name
- : "(nil)");
-
- read_gamma_state (crtc, impl_device, drm_crtc);
-}
-
-void
-meta_kms_crtc_update_state (MetaKmsCrtc *crtc)
-{
- MetaKmsImplDevice *impl_device;
- int fd;
- drmModeCrtc *drm_crtc;
- drmModeObjectProperties *drm_props;
-
- impl_device = meta_kms_device_get_impl_device (crtc->device);
- fd = meta_kms_impl_device_get_fd (impl_device);
-
- drm_crtc = drmModeGetCrtc (fd, crtc->id);
- drm_props = drmModeObjectGetProperties (fd, crtc->id, DRM_MODE_OBJECT_CRTC);
-
- if (!drm_crtc || !drm_props)
- {
- crtc->current_state.is_active = FALSE;
- crtc->current_state.rect = (MetaRectangle) { };
- crtc->current_state.is_drm_mode_valid = FALSE;
- goto out;
- }
-
- meta_kms_crtc_read_state (crtc, impl_device, drm_crtc, drm_props);
-
-out:
- g_clear_pointer (&drm_props, drmModeFreeObjectProperties);
- g_clear_pointer (&drm_crtc, drmModeFreeCrtc);
-}
-
-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->mode)
- {
- MetaKmsPlaneAssignment *plane_assignment;
- const drmModeModeInfo *drm_mode;
-
- plane_assignment =
- meta_kms_update_get_primary_plane_assignment (update, crtc);
- drm_mode = meta_kms_mode_get_drm_mode (mode_set->mode);
-
- crtc->current_state.is_active = TRUE;
- 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 = *drm_mode;
- }
- else
- {
- crtc->current_state.is_active = FALSE;
- 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_memdup2 (gamma->red, gamma->size * sizeof (uint16_t));
- crtc->current_state.gamma.green =
- g_memdup2 (gamma->green, gamma->size * sizeof (uint16_t));
- crtc->current_state.gamma.blue =
- g_memdup2 (gamma->blue, gamma->size * sizeof (uint16_t));
-
- break;
- }
-}
-
-static void
-parse_active (MetaKmsImplDevice *impl_device,
- MetaKmsProp *prop,
- drmModePropertyPtr drm_prop,
- uint64_t drm_prop_value,
- gpointer user_data)
-{
- MetaKmsCrtc *crtc = user_data;
-
- crtc->current_state.is_active = !!drm_prop_value;
-}
-
-static void
-init_proporties (MetaKmsCrtc *crtc,
- MetaKmsImplDevice *impl_device,
- drmModeCrtc *drm_crtc)
-{
- MetaKmsCrtcPropTable *prop_table = &crtc->prop_table;
- int fd;
- drmModeObjectProperties *drm_props;
-
- *prop_table = (MetaKmsCrtcPropTable) {
- .props = {
- [META_KMS_CRTC_PROP_MODE_ID] =
- {
- .name = "MODE_ID",
- .type = DRM_MODE_PROP_BLOB,
- },
- [META_KMS_CRTC_PROP_ACTIVE] =
- {
- .name = "ACTIVE",
- .type = DRM_MODE_PROP_RANGE,
- .parse = parse_active,
- },
- [META_KMS_CRTC_PROP_GAMMA_LUT] =
- {
- .name = "GAMMA_LUT",
- .type = DRM_MODE_PROP_BLOB,
- },
- }
- };
-
- fd = meta_kms_impl_device_get_fd (impl_device);
- drm_props = drmModeObjectGetProperties (fd,
- drm_crtc->crtc_id,
- DRM_MODE_OBJECT_CRTC);
-
- meta_kms_impl_device_init_prop_table (impl_device,
- drm_props->props,
- drm_props->prop_values,
- drm_props->count_props,
- crtc->prop_table.props,
- META_KMS_CRTC_N_PROPS,
- crtc);
-
- drmModeFreeObjectProperties (drm_props);
-}
-
-MetaKmsCrtc *
-meta_kms_crtc_new (MetaKmsImplDevice *impl_device,
- drmModeCrtc *drm_crtc,
- int idx,
- GError **error)
-{
- int fd;
- drmModeObjectProperties *drm_props;
- MetaKmsCrtc *crtc;
-
- fd = meta_kms_impl_device_get_fd (impl_device);
- drm_props = drmModeObjectGetProperties (fd, drm_crtc->crtc_id,
- DRM_MODE_OBJECT_CRTC);
- if (!drm_props)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "drmModeObjectGetProperties: %s", g_strerror (errno));
- return NULL;
- }
-
- 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;
-
- init_proporties (crtc, impl_device, drm_crtc);
-
- meta_kms_crtc_read_state (crtc, impl_device, drm_crtc, drm_props);
-
- drmModeFreeObjectProperties (drm_props);
-
- 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
deleted file mode 100644
index 406ca3ac1..000000000
--- a/src/backends/native/meta-kms-crtc.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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
-{
- gboolean is_active;
-
- MetaRectangle rect;
- gboolean is_drm_mode_valid;
- drmModeModeInfo drm_mode;
-
- struct {
- uint16_t *red;
- uint16_t *green;
- uint16_t *blue;
-
- int size;
- } gamma;
-} MetaKmsCrtcState;
-
-typedef struct _MetaKmsCrtcGamma
-{
- MetaKmsCrtc *crtc;
- int size;
- uint16_t *red;
- uint16_t *green;
- uint16_t *blue;
-} MetaKmsCrtcGamma;
-
-#define META_TYPE_KMS_CRTC (meta_kms_crtc_get_type ())
-G_DECLARE_FINAL_TYPE (MetaKmsCrtc, meta_kms_crtc,
- META, KMS_CRTC,
- GObject)
-
-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);
-
-gboolean meta_kms_crtc_is_active (MetaKmsCrtc *crtc);
-
-void meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *gamma);
-
-MetaKmsCrtcGamma * meta_kms_crtc_gamma_new (MetaKmsCrtc *crtc,
- int size,
- const uint16_t *red,
- const uint16_t *green,
- const uint16_t *blue);
-
-#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
deleted file mode 100644
index 41e05a2f7..000000000
--- a/src/backends/native/meta-kms-device-private.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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
deleted file mode 100644
index b4d3e5802..000000000
--- a/src/backends/native/meta-kms-device.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * 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 <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <xf86drm.h>
-
-#include "backends/native/meta-backend-native-private.h"
-#include "backends/native/meta-device-pool.h"
-#include "backends/native/meta-kms-impl-device-atomic.h"
-#include "backends/native/meta-kms-impl-device-dummy.h"
-#include "backends/native/meta-kms-impl-device-simple.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;
- char *driver_name;
- char *driver_description;
-
- GList *crtcs;
- GList *connectors;
- GList *planes;
-
- MetaKmsDeviceCaps caps;
-
- GList *fallback_modes;
-};
-
-G_DEFINE_TYPE (MetaKmsDevice, meta_kms_device, G_TYPE_OBJECT);
-
-MetaKms *
-meta_kms_device_get_kms (MetaKmsDevice *device)
-{
- return device->kms;
-}
-
-MetaKmsImplDevice *
-meta_kms_device_get_impl_device (MetaKmsDevice *device)
-{
- return device->impl_device;
-}
-
-const char *
-meta_kms_device_get_path (MetaKmsDevice *device)
-{
- return device->path;
-}
-
-const char *
-meta_kms_device_get_driver_name (MetaKmsDevice *device)
-{
- return device->driver_name;
-}
-
-const char *
-meta_kms_device_get_driver_description (MetaKmsDevice *device)
-{
- return device->driver_description;
-}
-
-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;
- }
-}
-
-gboolean
-meta_kms_device_prefers_shadow_buffer (MetaKmsDevice *device)
-{
- return device->caps.prefers_shadow_buffer;
-}
-
-gboolean
-meta_kms_device_uses_monotonic_clock (MetaKmsDevice *device)
-{
- return device->caps.uses_monotonic_clock;
-}
-
-GList *
-meta_kms_device_get_connectors (MetaKmsDevice *device)
-{
- return device->connectors;
-}
-
-GList *
-meta_kms_device_get_crtcs (MetaKmsDevice *device)
-{
- return device->crtcs;
-}
-
-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);
-}
-
-GList *
-meta_kms_device_get_fallback_modes (MetaKmsDevice *device)
-{
- return device->fallback_modes;
-}
-
-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);
-}
-
-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;
- const char *path;
- MetaKmsDeviceFlag flags;
-
- MetaKmsImplDevice *out_impl_device;
- GList *out_crtcs;
- GList *out_connectors;
- GList *out_planes;
- MetaKmsDeviceCaps out_caps;
- GList *out_fallback_modes;
- char *out_driver_name;
- char *out_driver_description;
- char *out_path;
-} CreateImplDeviceData;
-
-static const char *
-impl_device_type_to_string (GType type)
-{
- if (type == META_TYPE_KMS_IMPL_DEVICE_ATOMIC)
- return "atomic modesetting";
- else if (type == META_TYPE_KMS_IMPL_DEVICE_SIMPLE)
- return "legacy modesetting";
- else if (type == META_TYPE_KMS_IMPL_DEVICE_DUMMY)
- return "no modesetting";
- g_assert_not_reached();
-}
-
-static MetaKmsImplDevice *
-meta_create_kms_impl_device (MetaKmsDevice *device,
- MetaKmsImpl *impl,
- const char *path,
- MetaKmsDeviceFlag flags,
- GError **error)
-{
- meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl));
-
- if (flags & META_KMS_DEVICE_FLAG_NO_MODE_SETTING)
- {
- return g_initable_new (META_TYPE_KMS_IMPL_DEVICE_DUMMY,
- NULL, error,
- "device", device,
- "impl", impl,
- "path", path,
- "flags", flags,
- NULL);
- }
- else
- {
- GType impl_device_types[] = {
- META_TYPE_KMS_IMPL_DEVICE_ATOMIC,
- META_TYPE_KMS_IMPL_DEVICE_SIMPLE,
- };
- int i;
-
- for (i = 0; i < G_N_ELEMENTS (impl_device_types); i++)
- {
- MetaKmsImplDevice *impl_device;
- g_autoptr (GError) local_error = NULL;
-
- impl_device = g_initable_new (impl_device_types[i],
- NULL, &local_error,
- "device", device,
- "impl", impl,
- "path", path,
- "flags", flags,
- NULL);
- if (impl_device)
- return impl_device;
-
- if (local_error->domain != META_KMS_ERROR)
- {
- g_warning ("Failed to open %s backend: %s",
- impl_device_type_to_string (impl_device_types[i]),
- local_error->message);
- }
- }
-
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "No suitable mode setting backend found");
-
- return NULL;
- }
-}
-
-static gpointer
-create_impl_device_in_impl (MetaKmsImpl *impl,
- gpointer user_data,
- GError **error)
-{
- CreateImplDeviceData *data = user_data;
- MetaKmsImplDevice *impl_device;
-
- impl_device = meta_create_kms_impl_device (data->device,
- impl,
- data->path,
- data->flags,
- error);
- if (!impl_device)
- return FALSE;
-
- meta_kms_impl_add_impl_device (impl, impl_device);
-
- 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);
- data->out_fallback_modes =
- meta_kms_impl_device_copy_fallback_modes (impl_device);
- data->out_driver_name =
- g_strdup (meta_kms_impl_device_get_driver_name (impl_device));
- data->out_driver_description =
- g_strdup (meta_kms_impl_device_get_driver_description (impl_device));
- data->out_path = g_strdup (meta_kms_impl_device_get_path (impl_device));
-
- return GINT_TO_POINTER (TRUE);
-}
-
-MetaKmsDevice *
-meta_kms_device_new (MetaKms *kms,
- const char *path,
- MetaKmsDeviceFlag flags,
- GError **error)
-{
- MetaKmsDevice *device;
- CreateImplDeviceData data;
-
- device = g_object_new (META_TYPE_KMS_DEVICE, NULL);
- device->kms = kms;
-
- data = (CreateImplDeviceData) {
- .device = device,
- .path = path,
- .flags = flags,
- };
- if (!meta_kms_run_impl_task_sync (kms, create_impl_device_in_impl, &data,
- error))
- {
- 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;
- device->fallback_modes = data.out_fallback_modes;
- device->driver_name = data.out_driver_name;
- device->driver_description = data.out_driver_description;
- free (device->path);
- device->path = data.out_path;
-
- return device;
-}
-
-static gpointer
-free_impl_device_in_impl (MetaKmsImpl *impl,
- gpointer user_data,
- GError **error)
-{
- MetaKmsImplDevice *impl_device = user_data;
-
- g_object_unref (impl_device);
-
- return GINT_TO_POINTER (TRUE);
-}
-
-static void
-meta_kms_device_finalize (GObject *object)
-{
- MetaKmsDevice *device = META_KMS_DEVICE (object);
-
- g_free (device->path);
- g_list_free (device->crtcs);
- g_list_free (device->connectors);
- g_list_free (device->planes);
-
- if (device->impl_device)
- {
- meta_kms_run_impl_task_sync (device->kms, free_impl_device_in_impl,
- device->impl_device,
- NULL);
- }
-
- 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
deleted file mode 100644
index 58dda6136..000000000
--- a/src/backends/native/meta-kms-device.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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)
-
-MetaKms * meta_kms_device_get_kms (MetaKmsDevice *device);
-
-const char * meta_kms_device_get_path (MetaKmsDevice *device);
-
-const char * meta_kms_device_get_driver_name (MetaKmsDevice *device);
-
-const char * meta_kms_device_get_driver_description (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);
-
-gboolean meta_kms_device_prefers_shadow_buffer (MetaKmsDevice *device);
-
-gboolean meta_kms_device_uses_monotonic_clock (MetaKmsDevice *device);
-
-GList * meta_kms_device_get_connectors (MetaKmsDevice *device);
-
-GList * meta_kms_device_get_crtcs (MetaKmsDevice *device);
-
-GList * meta_kms_device_get_planes (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);
-
-GList * meta_kms_device_get_fallback_modes (MetaKmsDevice *device);
-
-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-atomic.c b/src/backends/native/meta-kms-impl-device-atomic.c
deleted file mode 100644
index 8e41207ee..000000000
--- a/src/backends/native/meta-kms-impl-device-atomic.c
+++ /dev/null
@@ -1,1202 +0,0 @@
-/*
- * Copyright (C) 2019-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.
- */
-
-#include "config.h"
-
-#include "backends/native/meta-kms-impl-device-atomic.h"
-
-#include "backends/native/meta-backend-native-private.h"
-#include "backends/native/meta-kms-connector-private.h"
-#include "backends/native/meta-kms-crtc-private.h"
-#include "backends/native/meta-kms-device-private.h"
-#include "backends/native/meta-kms-mode-private.h"
-#include "backends/native/meta-kms-plane-private.h"
-#include "backends/native/meta-kms-private.h"
-#include "backends/native/meta-kms-update-private.h"
-
-typedef gboolean (* MetaKmsAtomicProcessFunc) (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- drmModeAtomicReq *req,
- GArray *blob_ids,
- gpointer entry_data,
- gpointer user_data,
- GError **error);
-
-struct _MetaKmsImplDeviceAtomic
-{
- MetaKmsImplDevice parent;
-
- GHashTable *page_flip_datas;
-};
-
-static GInitableIface *initable_parent_iface;
-
-static void
-initable_iface_init (GInitableIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaKmsImplDeviceAtomic, meta_kms_impl_device_atomic,
- META_TYPE_KMS_IMPL_DEVICE,
- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
- initable_iface_init))
-
-static uint32_t
-store_new_blob (MetaKmsImplDevice *impl_device,
- GArray *blob_ids,
- const void *data,
- size_t size,
- GError **error)
-{
- int fd = meta_kms_impl_device_get_fd (impl_device);
- uint32_t blob_id;
- int ret;
-
- ret = drmModeCreatePropertyBlob (fd, data, size, &blob_id);
- if (ret < 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
- "drmModeCreatePropertyBlob: %s", g_strerror (-ret));
- return 0;
- }
-
- g_array_append_val (blob_ids, blob_id);
-
- return blob_id;
-}
-
-static void
-release_blob_ids (MetaKmsImplDevice *impl_device,
- GArray *blob_ids)
-{
- int fd = meta_kms_impl_device_get_fd (impl_device);
- unsigned int i;
-
- for (i = 0; i < blob_ids->len; i++)
- {
- uint32_t blob_id = g_array_index (blob_ids, uint32_t, i);
-
- drmModeDestroyPropertyBlob (fd, blob_id);
- }
-}
-
-static gboolean
-add_connector_property (MetaKmsImplDevice *impl_device,
- MetaKmsConnector *connector,
- drmModeAtomicReq *req,
- MetaKmsConnectorProp prop,
- uint64_t value,
- GError **error)
-{
- int ret;
- uint32_t prop_id;
-
- prop_id = meta_kms_connector_get_prop_id (connector, prop);
- if (!prop_id)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- "Connector property '%s' not found",
- meta_kms_connector_get_prop_name (connector, prop));
- return FALSE;
- }
-
- meta_topic (META_DEBUG_KMS,
- "[atomic] Setting connector %u (%s) property '%s' (%u) to %"
- G_GUINT64_FORMAT,
- meta_kms_connector_get_id (connector),
- meta_kms_impl_device_get_path (impl_device),
- meta_kms_connector_get_prop_name (connector, prop),
- meta_kms_connector_get_prop_id (connector, prop),
- value);
- ret = drmModeAtomicAddProperty (req,
- meta_kms_connector_get_id (connector),
- prop_id,
- value);
- if (ret < 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
- "drmModeAtomicAddProperty, connector: %u, prop id: %u: %s",
- meta_kms_connector_get_id (connector),
- prop_id,
- g_strerror (-ret));
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-process_connector_update (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- drmModeAtomicReq *req,
- GArray *blob_ids,
- gpointer update_entry,
- gpointer user_data,
- GError **error)
-{
- MetaKmsConnectorUpdate *connector_update = update_entry;
- MetaKmsConnector *connector = connector_update->connector;
-
- if (connector_update->underscanning.has_update &&
- connector_update->underscanning.is_active)
- {
- meta_topic (META_DEBUG_KMS,
- "[atomic] Setting underscanning on connector %u (%s) to "
- "%" G_GUINT64_FORMAT "x%" G_GUINT64_FORMAT,
- meta_kms_connector_get_id (connector),
- meta_kms_impl_device_get_path (impl_device),
- connector_update->underscanning.hborder,
- connector_update->underscanning.vborder);
-
- if (!add_connector_property (impl_device,
- connector, req,
- META_KMS_CONNECTOR_PROP_UNDERSCAN,
- 1,
- error))
- return FALSE;
- if (!add_connector_property (impl_device,
- connector, req,
- META_KMS_CONNECTOR_PROP_UNDERSCAN_HBORDER,
- connector_update->underscanning.hborder,
- error))
- return FALSE;
- if (!add_connector_property (impl_device,
- connector, req,
- META_KMS_CONNECTOR_PROP_UNDERSCAN_VBORDER,
- connector_update->underscanning.vborder,
- error))
- return FALSE;
- }
- else if (connector_update->underscanning.has_update)
- {
- meta_topic (META_DEBUG_KMS,
- "[atomic] Unsetting underscanning on connector %u (%s)",
- meta_kms_connector_get_id (connector),
- meta_kms_impl_device_get_path (impl_device));
-
- if (!add_connector_property (impl_device,
- connector, req,
- META_KMS_CONNECTOR_PROP_UNDERSCAN,
- 0,
- error))
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-add_crtc_property (MetaKmsImplDevice *impl_device,
- MetaKmsCrtc *crtc,
- drmModeAtomicReq *req,
- MetaKmsCrtcProp prop,
- uint64_t value,
- GError **error)
-{
- int ret;
- uint32_t prop_id;
-
- prop_id = meta_kms_crtc_get_prop_id (crtc, prop);
- if (!prop_id)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- "CRTC property (%s) not found",
- meta_kms_crtc_get_prop_name (crtc, prop));
- return FALSE;
- }
-
- meta_topic (META_DEBUG_KMS,
- "[atomic] Setting CRTC %u (%s) property '%s' (%u) to %"
- G_GUINT64_FORMAT,
- meta_kms_crtc_get_id (crtc),
- meta_kms_impl_device_get_path (impl_device),
- meta_kms_crtc_get_prop_name (crtc, prop),
- meta_kms_crtc_get_prop_id (crtc, prop),
- value);
- ret = drmModeAtomicAddProperty (req,
- meta_kms_crtc_get_id (crtc),
- prop_id,
- value);
- if (ret < 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
- "drmModeAtomicAddProperty, crtc: %u, prop: %s (%u): %s",
- meta_kms_crtc_get_id (crtc),
- meta_kms_crtc_get_prop_name (crtc, prop),
- prop_id,
- g_strerror (-ret));
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-process_mode_set (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- drmModeAtomicReq *req,
- GArray *blob_ids,
- gpointer update_entry,
- gpointer user_data,
- GError **error)
-{
- MetaKmsModeSet *mode_set = update_entry;
- MetaKmsCrtc *crtc = mode_set->crtc;
- MetaKmsMode *mode;
-
- mode = (MetaKmsMode *) mode_set->mode;
- if (mode)
- {
- uint32_t mode_id;
- GList *l;
-
- mode_id = meta_kms_mode_create_blob_id (mode, error);
- if (mode_id == 0)
- return FALSE;
-
- g_array_append_val (blob_ids, mode_id);
-
- meta_topic (META_DEBUG_KMS,
- "[atomic] Setting mode of CRTC %u (%s) to %s",
- meta_kms_crtc_get_id (crtc),
- meta_kms_impl_device_get_path (impl_device),
- meta_kms_mode_get_name (mode));
-
- if (!add_crtc_property (impl_device,
- crtc, req,
- META_KMS_CRTC_PROP_MODE_ID,
- mode_id,
- error))
- return FALSE;
-
- if (!add_crtc_property (impl_device,
- crtc, req,
- META_KMS_CRTC_PROP_ACTIVE,
- 1,
- error))
- return FALSE;
-
- for (l = mode_set->connectors; l; l = l->next)
- {
- MetaKmsConnector *connector = l->data;
-
- if (!add_connector_property (impl_device,
- connector, req,
- META_KMS_CONNECTOR_PROP_CRTC_ID,
- meta_kms_crtc_get_id (crtc),
- error))
- return FALSE;
- }
- }
- else
- {
- if (!add_crtc_property (impl_device,
- crtc, req,
- META_KMS_CRTC_PROP_MODE_ID,
- 0,
- error))
- return FALSE;
-
- if (!add_crtc_property (impl_device,
- crtc, req,
- META_KMS_CRTC_PROP_ACTIVE,
- 0,
- error))
- return FALSE;
-
- meta_topic (META_DEBUG_KMS,
- "[atomic] Unsetting mode of (%u, %s)",
- meta_kms_crtc_get_id (crtc),
- meta_kms_impl_device_get_path (impl_device));
- }
-
- return TRUE;
-}
-
-static gboolean
-add_plane_property (MetaKmsImplDevice *impl_device,
- MetaKmsPlane *plane,
- drmModeAtomicReq *req,
- MetaKmsCrtcProp prop,
- uint64_t value,
- GError **error)
-{
- int ret;
- uint32_t prop_id;
-
- prop_id = meta_kms_plane_get_prop_id (plane, prop);
- if (!prop_id)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- "Plane property (%s) not found on %u",
- meta_kms_plane_get_prop_name (plane, prop),
- meta_kms_plane_get_id (plane));
- return FALSE;
- }
-
- switch (meta_kms_plane_get_prop_internal_type (plane, prop))
- {
- case META_KMS_PROP_TYPE_RAW:
- meta_topic (META_DEBUG_KMS,
- "[atomic] Setting plane %u (%s) property '%s' (%u) to %"
- G_GUINT64_FORMAT,
- meta_kms_plane_get_id (plane),
- meta_kms_impl_device_get_path (impl_device),
- meta_kms_plane_get_prop_name (plane, prop),
- meta_kms_plane_get_prop_id (plane, prop),
- value);
- break;
- case META_KMS_PROP_TYPE_FIXED_16:
- meta_topic (META_DEBUG_KMS,
- "[atomic] Setting plane %u (%s) property '%s' (%u) to %.2f",
- meta_kms_plane_get_id (plane),
- meta_kms_impl_device_get_path (impl_device),
- meta_kms_plane_get_prop_name (plane, prop),
- meta_kms_plane_get_prop_id (plane, prop),
- meta_fixed_16_to_double (value));
- break;
- }
- ret = drmModeAtomicAddProperty (req,
- meta_kms_plane_get_id (plane),
- prop_id,
- value);
- if (ret < 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
- "drmModeAtomicAddProperty, plane: %u, prop: %s (%u): %s",
- meta_kms_plane_get_id (plane),
- meta_kms_plane_get_prop_name (plane, prop),
- prop_id,
- g_strerror (-ret));
- return FALSE;
- }
-
- return TRUE;
-}
-
-static const char *
-get_plane_type_string (MetaKmsPlane *plane)
-{
- switch (meta_kms_plane_get_plane_type (plane))
- {
- case META_KMS_PLANE_TYPE_PRIMARY:
- return "primary";
- case META_KMS_PLANE_TYPE_CURSOR:
- return "cursor";
- case META_KMS_PLANE_TYPE_OVERLAY:
- return "overlay";
- }
-
- g_assert_not_reached ();
-}
-
-static gboolean
-process_plane_assignment (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- drmModeAtomicReq *req,
- GArray *blob_ids,
- gpointer update_entry,
- gpointer user_data,
- GError **error)
-{
- MetaKmsPlaneAssignment *plane_assignment = update_entry;
- MetaKmsPlane *plane = plane_assignment->plane;
- MetaDrmBuffer *buffer;
-
- buffer = plane_assignment->buffer;
-
- meta_topic (META_DEBUG_KMS,
- "[atomic] Assigning %s plane (%u, %s) to %u, "
- "%hdx%hd+%hd+%hd -> %dx%d+%d+%d",
- get_plane_type_string (plane),
- meta_kms_plane_get_id (plane),
- meta_kms_impl_device_get_path (impl_device),
- buffer ? meta_drm_buffer_get_fb_id (buffer) : 0,
- meta_fixed_16_to_int (plane_assignment->src_rect.width),
- meta_fixed_16_to_int (plane_assignment->src_rect.height),
- meta_fixed_16_to_int (plane_assignment->src_rect.x),
- meta_fixed_16_to_int (plane_assignment->src_rect.y),
- plane_assignment->dst_rect.width,
- plane_assignment->dst_rect.height,
- plane_assignment->dst_rect.x,
- plane_assignment->dst_rect.y);
-
- if (buffer)
- {
- int i;
- struct {
- MetaKmsPlaneProp prop;
- uint64_t value;
- } props[] = {
- {
- .prop = META_KMS_PLANE_PROP_FB_ID,
- .value = meta_drm_buffer_get_fb_id (buffer),
- },
- {
- .prop = META_KMS_PLANE_PROP_CRTC_ID,
- .value = meta_kms_crtc_get_id (plane_assignment->crtc),
- },
- {
- .prop = META_KMS_PLANE_PROP_SRC_X,
- .value = plane_assignment->src_rect.x,
- },
- {
- .prop = META_KMS_PLANE_PROP_SRC_Y,
- .value = plane_assignment->src_rect.y,
- },
- {
- .prop = META_KMS_PLANE_PROP_SRC_W,
- .value = plane_assignment->src_rect.width,
- },
- {
- .prop = META_KMS_PLANE_PROP_SRC_H,
- .value = plane_assignment->src_rect.height,
- },
- {
- .prop = META_KMS_PLANE_PROP_CRTC_X,
- .value = plane_assignment->dst_rect.x,
- },
- {
- .prop = META_KMS_PLANE_PROP_CRTC_Y,
- .value = plane_assignment->dst_rect.y,
- },
- {
- .prop = META_KMS_PLANE_PROP_CRTC_W,
- .value = plane_assignment->dst_rect.width,
- },
- {
- .prop = META_KMS_PLANE_PROP_CRTC_H,
- .value = plane_assignment->dst_rect.height,
- },
- };
-
- for (i = 0; i < G_N_ELEMENTS (props); i++)
- {
- if (!add_plane_property (impl_device,
- plane, req,
- props[i].prop,
- props[i].value,
- error))
- return FALSE;
- }
- }
- else
- {
- int i;
- struct {
- MetaKmsPlaneProp prop;
- uint64_t value;
- } props[] = {
- {
- .prop = META_KMS_PLANE_PROP_FB_ID,
- .value = 0,
- },
- {
- .prop = META_KMS_PLANE_PROP_CRTC_ID,
- .value = 0,
- },
- };
-
- for (i = 0; i < G_N_ELEMENTS (props); i++)
- {
- if (!add_plane_property (impl_device,
- plane, req,
- props[i].prop,
- props[i].value,
- error))
- return FALSE;
- }
- }
-
- if (plane_assignment->rotation)
- {
- meta_topic (META_DEBUG_KMS,
- "[atomic] Setting plane (%u, %s) rotation to %"
- G_GUINT64_FORMAT,
- meta_kms_plane_get_id (plane),
- meta_kms_impl_device_get_path (impl_device),
- plane_assignment->rotation);
-
- if (!add_plane_property (impl_device,
- plane, req,
- META_KMS_PLANE_PROP_ROTATION,
- plane_assignment->rotation,
- error))
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-process_crtc_gamma (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- drmModeAtomicReq *req,
- GArray *blob_ids,
- gpointer update_entry,
- gpointer user_data,
- GError **error)
-{
- MetaKmsCrtcGamma *gamma = update_entry;
- MetaKmsCrtc *crtc = gamma->crtc;
- struct drm_color_lut drm_color_lut[gamma->size];
- int i;
- uint32_t color_lut_blob_id;
-
- for (i = 0; i < gamma->size; i++)
- {
- drm_color_lut[i].red = gamma->red[i];
- drm_color_lut[i].green = gamma->green[i];
- drm_color_lut[i].blue = gamma->blue[i];
- }
-
- color_lut_blob_id = store_new_blob (impl_device,
- blob_ids,
- drm_color_lut,
- sizeof drm_color_lut,
- error);
- if (!color_lut_blob_id)
- return FALSE;
-
- meta_topic (META_DEBUG_KMS,
- "[atomic] Setting CRTC (%u, %s) gamma, size: %d",
- meta_kms_crtc_get_id (crtc),
- meta_kms_impl_device_get_path (impl_device),
- gamma->size);
-
- if (!add_crtc_property (impl_device,
- crtc, req,
- META_KMS_CRTC_PROP_GAMMA_LUT,
- color_lut_blob_id,
- error))
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-process_page_flip_listener (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- drmModeAtomicReq *req,
- GArray *blob_ids,
- gpointer update_entry,
- gpointer user_data,
- GError **error)
-{
- MetaKmsImplDeviceAtomic *impl_device_atomic =
- META_KMS_IMPL_DEVICE_ATOMIC (impl_device);
- MetaKmsPageFlipListener *listener = update_entry;
- MetaKmsPageFlipData *page_flip_data;
- uint32_t crtc_id;
- gpointer listener_user_data;
- GDestroyNotify listener_destroy_notify;
-
- crtc_id = meta_kms_crtc_get_id (listener->crtc);
- page_flip_data = g_hash_table_lookup (impl_device_atomic->page_flip_datas,
- GUINT_TO_POINTER (crtc_id));
- if (!page_flip_data)
- {
- page_flip_data = meta_kms_page_flip_data_new (impl_device,
- listener->crtc);
- g_hash_table_insert (impl_device_atomic->page_flip_datas,
- GUINT_TO_POINTER (crtc_id),
- page_flip_data);
-
- meta_kms_impl_device_hold_fd (impl_device);
-
- meta_topic (META_DEBUG_KMS,
- "[atomic] Adding page flip data for (%u, %s): %p",
- crtc_id,
- meta_kms_impl_device_get_path (impl_device),
- page_flip_data);
- }
-
- listener_user_data = g_steal_pointer (&listener->user_data);
- listener_destroy_notify = g_steal_pointer (&listener->destroy_notify);
- meta_kms_page_flip_data_add_listener (page_flip_data,
- listener->vtable,
- listener->flags,
- listener_user_data,
- listener_destroy_notify);
-
- return TRUE;
-}
-
-static gboolean
-discard_page_flip_listener (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- drmModeAtomicReq *req,
- GArray *blob_ids,
- gpointer update_entry,
- gpointer user_data,
- GError **error)
-{
- MetaKmsPageFlipListener *listener = update_entry;
- GError *commit_error = user_data;
- MetaKmsPageFlipData *page_flip_data;
- gpointer listener_user_data;
- GDestroyNotify listener_destroy_notify;
-
- page_flip_data = meta_kms_page_flip_data_new (impl_device,
- listener->crtc);
-
- meta_topic (META_DEBUG_KMS,
- "[atomic] Creating transient page flip data for (%u, %s): %p",
- meta_kms_crtc_get_id (listener->crtc),
- meta_kms_impl_device_get_path (impl_device),
- page_flip_data);
-
- listener_user_data = g_steal_pointer (&listener->user_data);
- listener_destroy_notify = g_steal_pointer (&listener->destroy_notify);
- meta_kms_page_flip_data_add_listener (page_flip_data,
- listener->vtable,
- listener->flags,
- listener_user_data,
- listener_destroy_notify);
-
- meta_kms_page_flip_data_discard_in_impl (page_flip_data, commit_error);
-
- return TRUE;
-}
-
-static gboolean
-process_entries (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- drmModeAtomicReq *req,
- GArray *blob_ids,
- GList *entries,
- gpointer user_data,
- MetaKmsAtomicProcessFunc func,
- GError **error)
-{
- GList *l;
-
- for (l = entries; l; l = l->next)
- {
- if (!func (impl_device,
- update,
- req,
- blob_ids,
- l->data,
- user_data,
- error))
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-atomic_page_flip_handler (int fd,
- unsigned int sequence,
- unsigned int tv_sec,
- unsigned int tv_usec,
- unsigned int crtc_id,
- void *user_data)
-{
- MetaKmsImplDeviceAtomic *impl_device_atomic = user_data;
- MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (impl_device_atomic);
- MetaKmsPageFlipData *page_flip_data = NULL;
-
- g_hash_table_steal_extended (impl_device_atomic->page_flip_datas,
- GUINT_TO_POINTER (crtc_id),
- NULL,
- (gpointer *) &page_flip_data);
-
- meta_topic (META_DEBUG_KMS,
- "[atomic] Page flip callback for CRTC (%u, %s), data: %p",
- crtc_id, meta_kms_impl_device_get_path (impl_device),
- page_flip_data);
-
- if (!page_flip_data)
- return;
-
- meta_kms_impl_device_unhold_fd (impl_device);
-
- meta_kms_page_flip_data_set_timings_in_impl (page_flip_data,
- sequence, tv_sec, tv_usec);
- meta_kms_impl_device_handle_page_flip_callback (impl_device, page_flip_data);
-}
-
-static void
-meta_kms_impl_device_atomic_setup_drm_event_context (MetaKmsImplDevice *impl_device,
- drmEventContext *drm_event_context)
-{
- drm_event_context->version = 3;
- drm_event_context->page_flip_handler2 = atomic_page_flip_handler;
-}
-
-static const char *
-commit_flags_string (uint32_t commit_flags)
-{
- static char static_commit_flags_string[255];
- const char *commit_flag_strings[4] = { NULL };
- int i = 0;
- g_autofree char *commit_flags_string = NULL;
-
- if (commit_flags & DRM_MODE_ATOMIC_NONBLOCK)
- commit_flag_strings[i++] = "ATOMIC_NONBLOCK";
- if (commit_flags & DRM_MODE_ATOMIC_ALLOW_MODESET)
- commit_flag_strings[i++] = "ATOMIC_ALLOW_MODESET";
- if (commit_flags & DRM_MODE_PAGE_FLIP_EVENT)
- commit_flag_strings[i++] = "PAGE_FLIP_EVENT";
-
- commit_flags_string = g_strjoinv ("|", (char **) commit_flag_strings);
- strncpy (static_commit_flags_string, commit_flags_string,
- (sizeof static_commit_flags_string) - 1);
-
- return static_commit_flags_string;
-}
-
-static gboolean
-disable_connectors (MetaKmsImplDevice *impl_device,
- drmModeAtomicReq *req,
- GError **error)
-{
- GList *l;
-
- for (l = meta_kms_impl_device_peek_connectors (impl_device); l; l = l->next)
- {
- MetaKmsConnector *connector = l->data;
-
- if (!add_connector_property (impl_device,
- connector, req,
- META_KMS_CONNECTOR_PROP_CRTC_ID,
- 0,
- error))
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-disable_planes (MetaKmsImplDevice *impl_device,
- drmModeAtomicReq *req,
- GError **error)
-{
- GList *l;
-
- for (l = meta_kms_impl_device_peek_planes (impl_device); l; l = l->next)
- {
- MetaKmsPlane *plane = l->data;
-
- if (!add_plane_property (impl_device,
- plane, req,
- META_KMS_PLANE_PROP_CRTC_ID,
- 0,
- error))
- return FALSE;
-
- if (!add_plane_property (impl_device,
- plane, req,
- META_KMS_PLANE_PROP_FB_ID,
- 0,
- error))
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-disable_crtcs (MetaKmsImplDevice *impl_device,
- drmModeAtomicReq *req,
- GError **error)
-{
- GList *l;
-
- for (l = meta_kms_impl_device_peek_crtcs (impl_device); l; l = l->next)
- {
- MetaKmsCrtc *crtc = l->data;
-
- if (!add_crtc_property (impl_device,
- crtc, req,
- META_KMS_CRTC_PROP_ACTIVE,
- 0,
- error))
- return FALSE;
-
- if (!add_crtc_property (impl_device,
- crtc, req,
- META_KMS_CRTC_PROP_MODE_ID,
- 0,
- error))
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-disable_planes_and_connectors (MetaKmsImplDevice *impl_device,
- drmModeAtomicReq *req,
- GError **error)
-{
- if (!disable_connectors (impl_device, req, error))
- return FALSE;
- if (!disable_planes (impl_device, req, error))
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-process_power_save (MetaKmsImplDevice *impl_device,
- drmModeAtomicReq *req,
- GError **error)
-{
- if (!disable_connectors (impl_device, req, error))
- return FALSE;
- if (!disable_planes (impl_device, req, error))
- return FALSE;
- if (!disable_crtcs (impl_device, req, error))
- return FALSE;
-
- return TRUE;
-}
-
-static MetaKmsFeedback *
-meta_kms_impl_device_atomic_process_update (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- MetaKmsUpdateFlag flags)
-{
- GError *error = NULL;
- GList *failed_planes = NULL;
- drmModeAtomicReq *req;
- g_autoptr (GArray) blob_ids = NULL;
- int fd;
- uint32_t commit_flags = 0;
- int ret;
-
- blob_ids = g_array_new (FALSE, TRUE, sizeof (uint32_t));
-
- meta_topic (META_DEBUG_KMS,
- "[atomic] Processing update %" G_GUINT64_FORMAT,
- meta_kms_update_get_sequence_number (update));
-
- req = drmModeAtomicAlloc ();
- if (!req)
- {
- g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Failed to create atomic transaction request: %s",
- g_strerror (errno));
- goto err;
- }
-
- if (meta_kms_update_get_mode_sets (update))
- {
- if (!disable_planes_and_connectors (impl_device, req, &error))
- goto err;
- }
-
- if (meta_kms_update_is_power_save (update))
- {
- meta_topic (META_DEBUG_KMS,
- "[atomic] Entering power save mode for %s",
- meta_kms_impl_device_get_path (impl_device));
-
- if (!process_power_save (impl_device, req, &error))
- goto err;
-
- commit_flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
- goto commit;
- }
-
- if (!process_entries (impl_device,
- update,
- req,
- blob_ids,
- meta_kms_update_get_connector_updates (update),
- NULL,
- process_connector_update,
- &error))
- goto err;
-
- if (!process_entries (impl_device,
- update,
- req,
- blob_ids,
- meta_kms_update_get_mode_sets (update),
- NULL,
- process_mode_set,
- &error))
- goto err;
-
- if (!process_entries (impl_device,
- update,
- req,
- blob_ids,
- meta_kms_update_get_plane_assignments (update),
- NULL,
- process_plane_assignment,
- &error))
- goto err;
-
- if (!process_entries (impl_device,
- update,
- req,
- blob_ids,
- meta_kms_update_get_crtc_gammas (update),
- NULL,
- process_crtc_gamma,
- &error))
- goto err;
-
- if (meta_kms_update_get_mode_sets (update))
- commit_flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
- else
- commit_flags |= DRM_MODE_ATOMIC_NONBLOCK;
-
- if (meta_kms_update_get_page_flip_listeners (update))
- commit_flags |= DRM_MODE_PAGE_FLIP_EVENT;
-
-commit:
- meta_topic (META_DEBUG_KMS,
- "[atomic] Committing update %" G_GUINT64_FORMAT ", flags: %s",
- meta_kms_update_get_sequence_number (update),
- commit_flags_string (commit_flags));
-
- fd = meta_kms_impl_device_get_fd (impl_device);
- ret = drmModeAtomicCommit (fd, req, commit_flags, impl_device);
- drmModeAtomicFree (req);
- if (ret < 0)
- {
- g_set_error (&error, G_IO_ERROR, g_io_error_from_errno (-ret),
- "drmModeAtomicCommit: %s", g_strerror (-ret));
- goto err;
- }
-
- process_entries (impl_device,
- update,
- req,
- blob_ids,
- meta_kms_update_get_page_flip_listeners (update),
- NULL,
- process_page_flip_listener,
- NULL);
-
- release_blob_ids (impl_device, blob_ids);
-
- return meta_kms_feedback_new_passed (NULL);
-
-err:
- meta_topic (META_DEBUG_KMS, "[atomic] KMS update failed: %s", error->message);
-
- if (!(flags & META_KMS_UPDATE_FLAG_PRESERVE_ON_ERROR))
- {
- process_entries (impl_device,
- update,
- req,
- blob_ids,
- meta_kms_update_get_page_flip_listeners (update),
- error,
- discard_page_flip_listener,
- NULL);
- }
-
- release_blob_ids (impl_device, blob_ids);
-
- return meta_kms_feedback_new_failed (failed_planes, error);
-}
-
-static void
-meta_kms_impl_device_atomic_handle_page_flip_callback (MetaKmsImplDevice *impl_device,
- MetaKmsPageFlipData *page_flip_data)
-{
- meta_kms_page_flip_data_flipped_in_impl (page_flip_data);
-}
-
-static void
-meta_kms_impl_device_atomic_discard_pending_page_flips (MetaKmsImplDevice *impl_device)
-{
-}
-
-static gboolean
-dispose_page_flip_data (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- MetaKmsPageFlipData *page_flip_data = value;
- MetaKmsImplDevice *impl_device = user_data;
-
- meta_kms_page_flip_data_discard_in_impl (page_flip_data, NULL);
- meta_kms_impl_device_unhold_fd (impl_device);
-
- return TRUE;
-}
-
-static void
-meta_kms_impl_device_atomic_prepare_shutdown (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDeviceAtomic *impl_device_atomic =
- META_KMS_IMPL_DEVICE_ATOMIC (impl_device);
-
- g_hash_table_foreach_remove (impl_device_atomic->page_flip_datas,
- dispose_page_flip_data,
- impl_device);
-}
-
-static void
-meta_kms_impl_device_atomic_finalize (GObject *object)
-{
- MetaKmsImplDeviceAtomic *impl_device_atomic =
- META_KMS_IMPL_DEVICE_ATOMIC (object);
-
- g_assert (g_hash_table_size (impl_device_atomic->page_flip_datas) == 0);
-
- g_hash_table_unref (impl_device_atomic->page_flip_datas);
-
- G_OBJECT_CLASS (meta_kms_impl_device_atomic_parent_class)->finalize (object);
-}
-
-static MetaDeviceFile *
-meta_kms_impl_device_atomic_open_device_file (MetaKmsImplDevice *impl_device,
- const char *path,
- GError **error)
-{
- MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
- MetaKms *kms = meta_kms_device_get_kms (device);
- MetaBackend *backend = meta_kms_get_backend (kms);
- MetaDevicePool *device_pool =
- meta_backend_native_get_device_pool (META_BACKEND_NATIVE (backend));
- g_autoptr (MetaDeviceFile) device_file = NULL;
-
- device_file = meta_device_pool_open (device_pool, path,
- META_DEVICE_FILE_FLAG_TAKE_CONTROL,
- error);
- if (!device_file)
- return NULL;
-
- if (!meta_device_file_has_tag (device_file,
- META_DEVICE_FILE_TAG_KMS,
- META_KMS_DEVICE_FILE_TAG_ATOMIC))
- {
- int fd = meta_device_file_get_fd (device_file);
-
- g_warn_if_fail (!meta_device_file_has_tag (device_file,
- META_DEVICE_FILE_TAG_KMS,
- META_KMS_DEVICE_FILE_TAG_SIMPLE));
-
- if (drmSetClientCap (fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) != 0)
- {
- g_set_error (error, META_KMS_ERROR, META_KMS_ERROR_NOT_SUPPORTED,
- "DRM_CLIENT_CAP_UNIVERSAL_PLANES not supported");
- return NULL;
- }
-
- if (drmSetClientCap (fd, DRM_CLIENT_CAP_ATOMIC, 1) != 0)
- {
- g_set_error (error, META_KMS_ERROR, META_KMS_ERROR_NOT_SUPPORTED,
- "DRM_CLIENT_CAP_ATOMIC not supported");
- return NULL;
- }
-
- meta_device_file_tag (device_file,
- META_DEVICE_FILE_TAG_KMS,
- META_KMS_DEVICE_FILE_TAG_ATOMIC);
- }
-
- return g_steal_pointer (&device_file);
-}
-
-static gboolean
-is_atomic_allowed (const char *driver_name)
-{
- const char *atomic_driver_deny_list[] = {
- "qxl",
- "vmwgfx",
- "vboxvideo",
- "nvidia-drm",
- NULL,
- };
-
- return !g_strv_contains (atomic_driver_deny_list, driver_name);
-}
-
-static gboolean
-meta_kms_impl_device_atomic_initable_init (GInitable *initable,
- GCancellable *cancellable,
- GError **error)
-{
- MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (initable);
- const char *atomic_kms_enable_env;
-
- atomic_kms_enable_env = getenv ("MUTTER_DEBUG_ENABLE_ATOMIC_KMS");
- if (atomic_kms_enable_env && g_strcmp0 (atomic_kms_enable_env, "1") != 0)
- {
- g_set_error (error, META_KMS_ERROR, META_KMS_ERROR_USER_INHIBITED,
- "Atomic mode setting disable via env var");
- return FALSE;
- }
-
- if (!initable_parent_iface->init (initable, cancellable, error))
- return FALSE;
-
- if (!is_atomic_allowed (meta_kms_impl_device_get_driver_name (impl_device)))
- {
- g_set_error (error, META_KMS_ERROR, META_KMS_ERROR_DENY_LISTED,
- "Atomic mode setting disable via driver deny list");
- return FALSE;
- }
-
- if (!meta_kms_impl_device_init_mode_setting (impl_device, error))
- return FALSE;
-
- g_message ("Added device '%s' (%s) using atomic mode setting.",
- meta_kms_impl_device_get_path (impl_device),
- meta_kms_impl_device_get_driver_name (impl_device));
-
- return TRUE;
-}
-
-static void
-meta_kms_impl_device_atomic_init (MetaKmsImplDeviceAtomic *impl_device_atomic)
-{
- impl_device_atomic->page_flip_datas = g_hash_table_new (NULL, NULL);
-}
-
-static void
-initable_iface_init (GInitableIface *iface)
-{
- initable_parent_iface = g_type_interface_peek_parent (iface);
-
- iface->init = meta_kms_impl_device_atomic_initable_init;
-}
-
-static void
-meta_kms_impl_device_atomic_class_init (MetaKmsImplDeviceAtomicClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- MetaKmsImplDeviceClass *impl_device_class =
- META_KMS_IMPL_DEVICE_CLASS (klass);
-
- object_class->finalize = meta_kms_impl_device_atomic_finalize;
-
- impl_device_class->open_device_file =
- meta_kms_impl_device_atomic_open_device_file;
- impl_device_class->setup_drm_event_context =
- meta_kms_impl_device_atomic_setup_drm_event_context;
- impl_device_class->process_update =
- meta_kms_impl_device_atomic_process_update;
- impl_device_class->handle_page_flip_callback =
- meta_kms_impl_device_atomic_handle_page_flip_callback;
- impl_device_class->discard_pending_page_flips =
- meta_kms_impl_device_atomic_discard_pending_page_flips;
- impl_device_class->prepare_shutdown =
- meta_kms_impl_device_atomic_prepare_shutdown;
-}
diff --git a/src/backends/native/meta-kms-impl-device-atomic.h b/src/backends/native/meta-kms-impl-device-atomic.h
deleted file mode 100644
index 74658797c..000000000
--- a/src/backends/native/meta-kms-impl-device-atomic.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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_ATOMIC_H
-#define META_KMS_IMPL_DEVICE_ATOMIC_H
-
-#include "backends/native/meta-kms-impl-device.h"
-
-#define META_TYPE_KMS_IMPL_DEVICE_ATOMIC (meta_kms_impl_device_atomic_get_type ())
-G_DECLARE_FINAL_TYPE (MetaKmsImplDeviceAtomic, meta_kms_impl_device_atomic,
- META, KMS_IMPL_DEVICE_ATOMIC, MetaKmsImplDevice)
-
-#endif /* META_KMS_IMPL_DEVICE_ATOMIC_H */
diff --git a/src/backends/native/meta-kms-impl-device-dummy.c b/src/backends/native/meta-kms-impl-device-dummy.c
deleted file mode 100644
index 02583bbeb..000000000
--- a/src/backends/native/meta-kms-impl-device-dummy.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2021 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-dummy.h"
-
-#include "backends/native/meta-backend-native-private.h"
-#include "backends/native/meta-kms.h"
-
-struct _MetaKmsImplDeviceDummy
-{
- MetaKmsImplDevice parent;
-};
-
-static GInitableIface *initable_parent_iface;
-
-static void
-initable_iface_init (GInitableIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaKmsImplDeviceDummy,
- meta_kms_impl_device_dummy,
- META_TYPE_KMS_IMPL_DEVICE,
- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
- initable_iface_init))
-
-static void
-meta_kms_impl_device_dummy_discard_pending_page_flips (MetaKmsImplDevice *impl_device)
-{
-}
-
-static MetaDeviceFile *
-meta_kms_impl_device_dummy_open_device_file (MetaKmsImplDevice *impl_device,
- const char *path,
- GError **error)
-{
- MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
- MetaKms *kms = meta_kms_device_get_kms (device);
- MetaBackend *backend = meta_kms_get_backend (kms);
- MetaDevicePool *device_pool =
- meta_backend_native_get_device_pool (META_BACKEND_NATIVE (backend));
- g_autoptr (MetaDeviceFile) device_file = NULL;
- int fd;
- g_autofree char *render_node_path = NULL;
-
- device_file = meta_device_pool_open (device_pool, path,
- META_DEVICE_FILE_FLAG_NONE,
- error);
- if (!device_file)
- return NULL;
-
- fd = meta_device_file_get_fd (device_file);
- render_node_path = drmGetRenderDeviceNameFromFd (fd);
- if (!render_node_path)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Couldn't find render node device for '%s' (%s)",
- meta_kms_impl_device_get_path (impl_device),
- meta_kms_impl_device_get_driver_name (impl_device));
- return NULL;
- }
-
- meta_topic (META_DEBUG_KMS, "Found render node '%s' from '%s'",
- render_node_path, path);
-
- return meta_device_pool_open (device_pool, render_node_path,
- META_DEVICE_FILE_FLAG_NONE,
- error);
-}
-
-static gboolean
-meta_kms_impl_device_dummy_initable_init (GInitable *initable,
- GCancellable *cancellable,
- GError **error)
-{
- MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (initable);
-
- if (!initable_parent_iface->init (initable, cancellable, error))
- return FALSE;
-
- g_message ("Added device '%s' (%s) using no mode setting.",
- meta_kms_impl_device_get_path (impl_device),
- meta_kms_impl_device_get_driver_name (impl_device));
-
- return TRUE;
-}
-
-static void
-initable_iface_init (GInitableIface *iface)
-{
- initable_parent_iface = g_type_interface_peek_parent (iface);
-
- iface->init = meta_kms_impl_device_dummy_initable_init;
-}
-
-static void
-meta_kms_impl_device_dummy_init (MetaKmsImplDeviceDummy *impl_device_dummy)
-{
-}
-
-static void
-meta_kms_impl_device_dummy_class_init (MetaKmsImplDeviceDummyClass *klass)
-{
- MetaKmsImplDeviceClass *impl_device_class =
- META_KMS_IMPL_DEVICE_CLASS (klass);
-
- impl_device_class->open_device_file =
- meta_kms_impl_device_dummy_open_device_file;
- impl_device_class->discard_pending_page_flips =
- meta_kms_impl_device_dummy_discard_pending_page_flips;
-}
diff --git a/src/backends/native/meta-kms-impl-device-dummy.h b/src/backends/native/meta-kms-impl-device-dummy.h
deleted file mode 100644
index 9576939ad..000000000
--- a/src/backends/native/meta-kms-impl-device-dummy.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2021 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_DUMMY_H
-#define META_KMS_IMPL_DEVICE_DUMMY_H
-
-#include "backends/native/meta-kms-impl-device.h"
-
-#define META_TYPE_KMS_IMPL_DEVICE_DUMMY (meta_kms_impl_device_dummy_get_type ())
-G_DECLARE_FINAL_TYPE (MetaKmsImplDeviceDummy, meta_kms_impl_device_dummy,
- META, KMS_IMPL_DEVICE_DUMMY,
- MetaKmsImplDevice)
-
-#endif /* META_KMS_IMPL_DEVICE_DUMMY_H */
diff --git a/src/backends/native/meta-kms-impl-device-simple.c b/src/backends/native/meta-kms-impl-device-simple.c
deleted file mode 100644
index 28d512720..000000000
--- a/src/backends/native/meta-kms-impl-device-simple.c
+++ /dev/null
@@ -1,1678 +0,0 @@
-/*
- * Copyright (C) 2019-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.
- */
-
-#include "config.h"
-
-#include "backends/native/meta-kms-impl-device-simple.h"
-
-#include "backends/native/meta-backend-native-private.h"
-#include "backends/native/meta-drm-buffer-gbm.h"
-#include "backends/native/meta-kms-connector-private.h"
-#include "backends/native/meta-kms-crtc-private.h"
-#include "backends/native/meta-kms-device-private.h"
-#include "backends/native/meta-kms-mode-private.h"
-#include "backends/native/meta-kms-plane-private.h"
-#include "backends/native/meta-kms-private.h"
-#include "backends/native/meta-kms-update-private.h"
-#include "backends/native/meta-kms-utils.h"
-
-typedef gboolean (* MetaKmsSimpleProcessFunc) (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- gpointer entry_data,
- GError **error);
-
-typedef struct _CachedModeSet
-{
- GList *connectors;
- drmModeModeInfo *drm_mode;
-} CachedModeSet;
-
-struct _MetaKmsImplDeviceSimple
-{
- MetaKmsImplDevice 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;
-
- GList *posted_page_flip_datas;
-
- GHashTable *cached_mode_sets;
-};
-
-static GInitableIface *initable_parent_iface;
-
-static void
-initable_iface_init (GInitableIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaKmsImplDeviceSimple, meta_kms_impl_device_simple,
- META_TYPE_KMS_IMPL_DEVICE,
- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
- initable_iface_init))
-
-static void
-flush_postponed_page_flip_datas (MetaKmsImplDeviceSimple *impl_device_simple);
-
-static gboolean
-get_connector_property (MetaKmsImplDevice *impl_device,
- MetaKmsConnector *connector,
- MetaKmsConnectorProp prop,
- uint64_t *value,
- GError **error)
-{
- uint32_t prop_id;
- int fd;
- drmModeConnector *drm_connector;
- int i;
- gboolean found;
-
- prop_id = meta_kms_connector_get_prop_id (connector, prop);
- if (!prop_id)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- "Property (%s) not found on connector %u",
- meta_kms_connector_get_prop_name (connector, prop),
- meta_kms_connector_get_id (connector));
- return FALSE;
- }
-
- fd = meta_kms_impl_device_get_fd (impl_device);
-
- drm_connector = drmModeGetConnector (fd,
- meta_kms_connector_get_id (connector));
- if (!drm_connector)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to get connector %u resources: %s",
- meta_kms_connector_get_id (connector),
- g_strerror (errno));
- return FALSE;
- }
-
- found = FALSE;
- for (i = 0; i < drm_connector->count_props; i++)
- {
- if (drm_connector->props[i] == prop_id)
- {
- *value = drm_connector->prop_values[i];
- found = TRUE;
- break;
- }
- }
-
- drmModeFreeConnector (drm_connector);
-
- if (!found)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
- "Connector property %u not found", prop_id);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-set_connector_property (MetaKmsImplDevice *impl_device,
- MetaKmsConnector *connector,
- MetaKmsConnectorProp prop,
- uint64_t value,
- GError **error)
-{
- uint32_t prop_id;
- int fd;
- int ret;
-
- prop_id = meta_kms_connector_get_prop_id (connector, prop);
- if (!prop_id)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- "Property (%s) not found on connector %u",
- meta_kms_connector_get_prop_name (connector, prop),
- meta_kms_connector_get_id (connector));
- return FALSE;
- }
-
- fd = meta_kms_impl_device_get_fd (impl_device);
-
- ret = drmModeObjectSetProperty (fd,
- meta_kms_connector_get_id (connector),
- DRM_MODE_OBJECT_CONNECTOR,
- prop_id,
- 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),
- prop_id,
- g_strerror (-ret));
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-process_power_save (MetaKmsImplDevice *impl_device,
- GError **error)
-{
- GList *l;
-
- for (l = meta_kms_impl_device_peek_connectors (impl_device); l; l = l->next)
- {
- MetaKmsConnector *connector = l->data;
-
- meta_topic (META_DEBUG_KMS,
- "[simple] Setting DPMS of connector %u (%s) to OFF",
- meta_kms_connector_get_id (connector),
- meta_kms_impl_device_get_path (impl_device));
-
- if (!set_connector_property (impl_device,
- connector,
- META_KMS_CONNECTOR_PROP_DPMS,
- DRM_MODE_DPMS_OFF,
- error))
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-process_connector_update (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- gpointer update_entry,
- GError **error)
-{
- MetaKmsConnectorUpdate *connector_update = update_entry;
- MetaKmsConnector *connector = connector_update->connector;
-
- if (connector_update->underscanning.has_update &&
- connector_update->underscanning.is_active)
- {
- meta_topic (META_DEBUG_KMS,
- "[simple] Setting underscanning on connector %u (%s) to "
- "%" G_GUINT64_FORMAT "x%" G_GUINT64_FORMAT,
- meta_kms_connector_get_id (connector),
- meta_kms_impl_device_get_path (impl_device),
- connector_update->underscanning.hborder,
- connector_update->underscanning.vborder);
-
- if (!set_connector_property (impl_device,
- connector,
- META_KMS_CONNECTOR_PROP_UNDERSCAN,
- 1,
- error))
- return FALSE;
- if (!set_connector_property (impl_device,
- connector,
- META_KMS_CONNECTOR_PROP_UNDERSCAN_HBORDER,
- connector_update->underscanning.hborder,
- error))
- return FALSE;
- if (!set_connector_property (impl_device,
- connector,
- META_KMS_CONNECTOR_PROP_UNDERSCAN_VBORDER,
- connector_update->underscanning.vborder,
- error))
- return FALSE;
- }
- else if (connector_update->underscanning.has_update)
- {
- meta_topic (META_DEBUG_KMS,
- "[simple] Unsetting underscanning on connector %u (%s)",
- meta_kms_connector_get_id (connector),
- meta_kms_impl_device_get_path (impl_device));
-
- if (!set_connector_property (impl_device,
- connector,
- META_KMS_CONNECTOR_PROP_UNDERSCAN,
- 0,
- error))
- 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_memdup2 (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
-set_plane_rotation (MetaKmsImplDevice *impl_device,
- MetaKmsPlane *plane,
- uint64_t rotation,
- GError **error)
-{
- int fd;
- uint32_t rotation_prop_id;
- int ret;
-
- fd = meta_kms_impl_device_get_fd (impl_device);
-
- rotation_prop_id = meta_kms_plane_get_prop_id (plane,
- META_KMS_PLANE_PROP_ROTATION);
-
- meta_topic (META_DEBUG_KMS,
- "[simple] Setting plane %u (%s) rotation to %" G_GUINT64_FORMAT,
- meta_kms_plane_get_id (plane),
- meta_kms_impl_device_get_path (impl_device),
- rotation);
-
- ret = drmModeObjectSetProperty (fd,
- meta_kms_plane_get_id (plane),
- DRM_MODE_OBJECT_PLANE,
- rotation_prop_id,
- rotation);
- if (ret != 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
- "Failed to rotation property (%u) to %" G_GUINT64_FORMAT
- " on plane %u: %s",
- rotation_prop_id,
- rotation,
- meta_kms_plane_get_id (plane),
- g_strerror (-ret));
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-process_mode_set (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- gpointer update_entry,
- GError **error)
-{
- MetaKmsImplDeviceSimple *impl_device_simple =
- META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
- MetaKmsModeSet *mode_set = update_entry;
- MetaKmsCrtc *crtc = mode_set->crtc;
- g_autofree uint32_t *connectors = NULL;
- int n_connectors;
- MetaKmsPlaneAssignment *plane_assignment;
- drmModeModeInfo *drm_mode;
- uint32_t x, y;
- uint32_t fb_id;
- int fd;
- int ret;
-
- crtc = mode_set->crtc;
-
- if (mode_set->mode)
- {
- MetaDrmBuffer *buffer;
- GList *l;
-
- drm_mode = g_alloca (sizeof *drm_mode);
- *drm_mode = *meta_kms_mode_get_drm_mode (mode_set->mode);
-
- 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);
-
- if (plane_assignment->rotation)
- {
- if (!set_plane_rotation (impl_device,
- plane_assignment->plane,
- plane_assignment->rotation,
- error))
- return FALSE;
- }
-
- buffer = plane_assignment->buffer;
- fb_id = meta_drm_buffer_get_fb_id (buffer);
-
- for (l = mode_set->connectors; l; l = l->next)
- {
- MetaKmsConnector *connector = l->data;
- uint64_t dpms_value;
-
- if (!get_connector_property (impl_device,
- connector,
- META_KMS_CONNECTOR_PROP_DPMS,
- &dpms_value,
- error))
- return FALSE;
-
- if (dpms_value != DRM_MODE_DPMS_ON)
- {
- meta_topic (META_DEBUG_KMS,
- "[simple] Setting DPMS of connector %u (%s) to ON",
- meta_kms_connector_get_id (connector),
- meta_kms_impl_device_get_path (impl_device));
-
- if (!set_connector_property (impl_device,
- connector,
- META_KMS_CONNECTOR_PROP_DPMS,
- DRM_MODE_DPMS_ON,
- error))
- return FALSE;
- }
- }
-
- meta_topic (META_DEBUG_KMS,
- "[simple] Setting mode of CRTC %u (%s) to %s",
- meta_kms_crtc_get_id (crtc),
- meta_kms_impl_device_get_path (impl_device),
- drm_mode->name);
- }
- else
- {
- drm_mode = NULL;
- x = y = 0;
- n_connectors = 0;
- connectors = NULL;
- fb_id = 0;
-
- meta_topic (META_DEBUG_KMS,
- "[simple] Unsetting mode of CRTC %u (%s)",
- meta_kms_crtc_get_id (crtc),
- meta_kms_impl_device_get_path (impl_device));
- }
-
- 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,
- 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",
- drm_mode ? drm_mode->name : "off",
- meta_kms_crtc_get_id (crtc),
- g_strerror (-ret));
- return FALSE;
- }
-
- if (drm_mode)
- {
- g_hash_table_replace (impl_device_simple->cached_mode_sets,
- crtc,
- cached_mode_set_new (mode_set->connectors,
- drm_mode));
- }
- else
- {
- g_hash_table_remove (impl_device_simple->cached_mode_sets, crtc);
- }
-
- return TRUE;
-}
-
-static gboolean
-process_crtc_gamma (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- gpointer update_entry,
- GError **error)
-{
- MetaKmsCrtcGamma *gamma = update_entry;
- MetaKmsCrtc *crtc = gamma->crtc;
- int fd;
- int ret;
-
- meta_topic (META_DEBUG_KMS,
- "[simple] Setting CRTC %u (%s) gamma, size: %d",
- meta_kms_crtc_get_id (crtc),
- meta_kms_impl_device_get_path (impl_device),
- gamma->size);
-
- 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;
- MetaKmsCustomPageFlip *custom_page_flip;
-} RetryPageFlipData;
-
-static void
-retry_page_flip_data_free (RetryPageFlipData *retry_page_flip_data)
-{
- g_assert (!retry_page_flip_data->page_flip_data);
- g_clear_pointer (&retry_page_flip_data->custom_page_flip,
- meta_kms_custom_page_flip_free);
- g_free (retry_page_flip_data);
-}
-
-static CachedModeSet *
-get_cached_mode_set (MetaKmsImplDeviceSimple *impl_device_simple,
- MetaKmsCrtc *crtc)
-{
- return g_hash_table_lookup (impl_device_simple->cached_mode_sets, crtc);
-}
-
-static float
-get_cached_crtc_refresh_rate (MetaKmsImplDeviceSimple *impl_device_simple,
- MetaKmsCrtc *crtc)
-{
- CachedModeSet *cached_mode_set;
-
- cached_mode_set = g_hash_table_lookup (impl_device_simple->cached_mode_sets,
- crtc);
- g_assert (cached_mode_set);
-
- return meta_calculate_drm_mode_refresh_rate (cached_mode_set->drm_mode);
-}
-
-#define meta_assert_in_kms_impl(kms) \
- g_assert (meta_kms_in_impl_task (kms))
-
-static gboolean
-retry_page_flips (gpointer user_data)
-{
- MetaKmsImplDeviceSimple *impl_device_simple =
- META_KMS_IMPL_DEVICE_SIMPLE (user_data);
- MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (impl_device_simple);
- uint64_t now_us;
- GList *l;
-
- now_us = g_source_get_time (impl_device_simple->retry_page_flips_source);
-
- l = impl_device_simple->pending_page_flip_retries;
- while (l)
- {
- RetryPageFlipData *retry_page_flip_data = l->data;
- MetaKmsCrtc *crtc = retry_page_flip_data->crtc;
- GList *l_next = l->next;
- int fd;
- int ret;
- MetaKmsPageFlipData *page_flip_data;
- MetaKmsCustomPageFlip *custom_page_flip;
-
- if (is_timestamp_earlier_than (now_us,
- retry_page_flip_data->retry_time_us))
- {
- l = l_next;
- continue;
- }
-
- custom_page_flip = retry_page_flip_data->custom_page_flip;
- if (custom_page_flip)
- {
- meta_topic (META_DEBUG_KMS,
- "[simple] Retrying custom page flip on CRTC %u (%s)",
- meta_kms_crtc_get_id (crtc),
- meta_kms_impl_device_get_path (impl_device));
- ret = custom_page_flip->func (custom_page_flip->user_data,
- retry_page_flip_data->page_flip_data);
- }
- else
- {
- meta_topic (META_DEBUG_KMS,
- "[simple] Retrying page flip on CRTC %u (%s) with %u",
- meta_kms_crtc_get_id (crtc),
- meta_kms_impl_device_get_path (impl_device),
- retry_page_flip_data->fb_id);
-
- 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;
-
- meta_topic (META_DEBUG_KMS,
- "[simple] Rescheduling page flip retry on CRTC %u (%s)",
- meta_kms_crtc_get_id (crtc),
- meta_kms_impl_device_get_path (impl_device));
-
- refresh_rate =
- get_cached_crtc_refresh_rate (impl_device_simple, crtc);
- retry_page_flip_data->retry_time_us +=
- (uint64_t) (G_USEC_PER_SEC / refresh_rate);
- l = l_next;
- continue;
- }
-
- impl_device_simple->pending_page_flip_retries =
- g_list_remove_link (impl_device_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);
- meta_kms_impl_device_unhold_fd (impl_device);
- }
- else
- {
- impl_device_simple->posted_page_flip_datas =
- g_list_prepend (impl_device_simple->posted_page_flip_datas,
- page_flip_data);
- }
-
- retry_page_flip_data_free (retry_page_flip_data);
-
- l = l_next;
- }
-
- if (impl_device_simple->pending_page_flip_retries)
- {
- GList *l;
- uint64_t earliest_retry_time_us = 0;
-
- for (l = impl_device_simple->pending_page_flip_retries; l; l = l->next)
- {
- RetryPageFlipData *retry_page_flip_data = l->data;
-
- if (l == impl_device_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_device_simple->retry_page_flips_source,
- earliest_retry_time_us);
- return G_SOURCE_CONTINUE;
- }
- else
- {
- g_clear_pointer (&impl_device_simple->retry_page_flips_source,
- g_source_unref);
-
- flush_postponed_page_flip_datas (impl_device_simple);
-
- return G_SOURCE_REMOVE;
- }
-}
-
-static void
-schedule_retry_page_flip (MetaKmsImplDeviceSimple *impl_device_simple,
- MetaKmsCrtc *crtc,
- uint32_t fb_id,
- float refresh_rate,
- MetaKmsPageFlipData *page_flip_data,
- MetaKmsCustomPageFlip *custom_page_flip)
-{
- 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 = page_flip_data,
- .refresh_rate = refresh_rate,
- .retry_time_us = retry_time_us,
- .custom_page_flip = custom_page_flip,
- };
-
- if (!impl_device_simple->retry_page_flips_source)
- {
- MetaKmsImplDevice *impl_device =
- META_KMS_IMPL_DEVICE (impl_device_simple);
- MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
- MetaKms *kms = meta_kms_device_get_kms (device);
- GSource *source;
-
- source = meta_kms_add_source_in_impl (kms, retry_page_flips,
- impl_device_simple, NULL);
- g_source_set_ready_time (source, retry_time_us);
-
- impl_device_simple->retry_page_flips_source = source;
- }
- else
- {
- GList *l;
-
- for (l = impl_device_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_device_simple->retry_page_flips_source,
- retry_time_us);
- break;
- }
- }
- }
-
- impl_device_simple->pending_page_flip_retries =
- g_list_append (impl_device_simple->pending_page_flip_retries,
- retry_page_flip_data);
-}
-
-static void
-dispatch_page_flip_datas (GList **page_flip_datas,
- GFunc func,
- gpointer user_data)
-{
- g_list_foreach (*page_flip_datas, func, user_data);
- g_clear_pointer (page_flip_datas, g_list_free);
-}
-
-static gboolean
-mode_set_fallback_feedback_idle (gpointer user_data)
-{
- MetaKmsImplDeviceSimple *impl_device_simple = user_data;
-
- g_clear_pointer (&impl_device_simple->mode_set_fallback_feedback_source,
- g_source_unref);
-
- if (impl_device_simple->pending_page_flip_retries)
- {
- impl_device_simple->postponed_mode_set_fallback_datas =
- g_steal_pointer (&impl_device_simple->mode_set_fallback_page_flip_datas);
- }
- else
- {
- dispatch_page_flip_datas (&impl_device_simple->mode_set_fallback_page_flip_datas,
- (GFunc) meta_kms_page_flip_data_mode_set_fallback_in_impl,
- NULL);
- }
-
- return G_SOURCE_REMOVE;
-}
-
-static gboolean
-mode_set_fallback (MetaKmsImplDeviceSimple *impl_device_simple,
- MetaKmsUpdate *update,
- MetaKmsPlaneAssignment *plane_assignment,
- MetaKmsPageFlipData *page_flip_data,
- GError **error)
-{
- MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (impl_device_simple);
- MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
- MetaKms *kms = meta_kms_device_get_kms (device);
- MetaKmsCrtc *crtc = meta_kms_page_flip_data_get_crtc (page_flip_data);
- CachedModeSet *cached_mode_set;
- g_autofree uint32_t *connectors = NULL;
- int n_connectors;
- uint32_t fb_id;
- uint32_t x, y;
- int fd;
- int ret;
-
- cached_mode_set = g_hash_table_lookup (impl_device_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);
-
- fb_id = meta_drm_buffer_get_fb_id (plane_assignment->buffer);
-
- 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),
- 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_device_simple->mode_set_fallback_feedback_source)
- {
- GSource *source;
-
- source = meta_kms_add_source_in_impl (kms,
- mode_set_fallback_feedback_idle,
- impl_device_simple,
- NULL);
- impl_device_simple->mode_set_fallback_feedback_source = source;
- }
-
- impl_device_simple->mode_set_fallback_page_flip_datas =
- g_list_prepend (impl_device_simple->mode_set_fallback_page_flip_datas,
- page_flip_data);
-
- return TRUE;
-}
-
-static gboolean
-symbolic_page_flip_idle (gpointer user_data)
-{
- MetaKmsPageFlipData *page_flip_data = user_data;
- MetaKmsImplDevice *impl_device;
- MetaKmsCrtc *crtc;
-
- impl_device = meta_kms_page_flip_data_get_impl_device (page_flip_data);
- crtc = meta_kms_page_flip_data_get_crtc (page_flip_data);
-
- meta_topic (META_DEBUG_KMS,
- "[simple] Handling symbolic page flip callback from %s, data: %p, CRTC: %u",
- meta_kms_impl_device_get_path (impl_device),
- page_flip_data,
- meta_kms_crtc_get_id (crtc));
-
- meta_kms_impl_device_handle_page_flip_callback (impl_device, page_flip_data);
-
- return G_SOURCE_REMOVE;
-}
-
-static gboolean
-dispatch_page_flip (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- MetaKmsPageFlipData *page_flip_data,
- GError **error)
-{
- MetaKmsImplDeviceSimple *impl_device_simple =
- META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
- MetaKmsCrtc *crtc;
- MetaKmsPlaneAssignment *plane_assignment;
- g_autoptr (MetaKmsCustomPageFlip) custom_page_flip = NULL;
- int fd;
- int ret;
-
- crtc = meta_kms_page_flip_data_get_crtc (page_flip_data);
- plane_assignment = meta_kms_update_get_primary_plane_assignment (update,
- crtc);
-
- custom_page_flip = meta_kms_update_take_custom_page_flip_func (update);
-
- if (!plane_assignment && !custom_page_flip)
- {
- MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
- MetaKms *kms = meta_kms_device_get_kms (device);
- GSource *source;
-
- meta_kms_page_flip_data_make_symbolic (page_flip_data);
-
- source = meta_kms_add_source_in_impl (kms,
- symbolic_page_flip_idle,
- page_flip_data,
- NULL);
-
- g_source_set_ready_time (source, 0);
- g_source_unref (source);
-
- return TRUE;
- }
-
- fd = meta_kms_impl_device_get_fd (impl_device);
- if (custom_page_flip)
- {
- meta_topic (META_DEBUG_KMS,
- "[simple] Invoking custom page flip on CRTC %u (%s)",
- meta_kms_crtc_get_id (crtc),
- meta_kms_impl_device_get_path (impl_device));
- ret = custom_page_flip->func (custom_page_flip->user_data,
- page_flip_data);
- }
- else
- {
- uint32_t fb_id;
-
- fb_id = meta_drm_buffer_get_fb_id (plane_assignment->buffer);
-
- meta_topic (META_DEBUG_KMS,
- "[simple] Page flipping CRTC %u (%s) with %u, data: %p",
- meta_kms_crtc_get_id (crtc),
- meta_kms_impl_device_get_path (impl_device),
- fb_id,
- page_flip_data);
-
- ret = drmModePageFlip (fd,
- meta_kms_crtc_get_id (crtc),
- fb_id,
- DRM_MODE_PAGE_FLIP_EVENT,
- page_flip_data);
- }
-
- if (ret == -EBUSY)
- {
- CachedModeSet *cached_mode_set;
-
- meta_topic (META_DEBUG_KMS,
- "[simple] Scheduling page flip retry on CRTC %u (%s)",
- meta_kms_crtc_get_id (crtc),
- meta_kms_impl_device_get_path (impl_device));
-
- cached_mode_set = get_cached_mode_set (impl_device_simple, crtc);
- if (cached_mode_set)
- {
- uint32_t fb_id;
- drmModeModeInfo *drm_mode;
- float refresh_rate;
-
- if (plane_assignment)
- fb_id = meta_drm_buffer_get_fb_id (plane_assignment->buffer);
- else
- fb_id = 0;
- drm_mode = cached_mode_set->drm_mode;
- refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
- meta_kms_impl_device_hold_fd (impl_device);
- schedule_retry_page_flip (impl_device_simple,
- crtc,
- fb_id,
- refresh_rate,
- page_flip_data,
- g_steal_pointer (&custom_page_flip));
- return TRUE;
- }
- 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));
- return FALSE;
- }
- }
- else if (ret == -EINVAL)
- {
- meta_topic (META_DEBUG_KMS,
- "[simple] Falling back to mode set on CRTC %u (%s)",
- meta_kms_crtc_get_id (crtc),
- meta_kms_impl_device_get_path (impl_device));
-
- return mode_set_fallback (impl_device_simple,
- update,
- plane_assignment,
- page_flip_data,
- error);
- }
- 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));
- return FALSE;
- }
- else
- {
- meta_kms_impl_device_hold_fd (impl_device);
-
- impl_device_simple->posted_page_flip_datas =
- g_list_prepend (impl_device_simple->posted_page_flip_datas,
- page_flip_data);
-
- return TRUE;
- }
-}
-
-static GList *
-generate_page_flip_datas (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update)
-{
- GList *listeners;
- GList *page_flip_datas = NULL;
-
- listeners = g_list_copy (meta_kms_update_get_page_flip_listeners (update));
-
- while (listeners)
- {
- MetaKmsPageFlipListener *listener = listeners->data;
- MetaKmsCrtc *crtc = listener->crtc;
- MetaKmsPageFlipData *page_flip_data;
- gpointer user_data;
- GDestroyNotify destroy_notify;
- GList *l;
-
- page_flip_data = meta_kms_page_flip_data_new (impl_device, crtc);
- page_flip_datas = g_list_append (page_flip_datas, page_flip_data);
-
- user_data = g_steal_pointer (&listener->user_data);
- destroy_notify = g_steal_pointer (&listener->destroy_notify);
- meta_kms_page_flip_data_add_listener (page_flip_data,
- listener->vtable,
- listener->flags,
- user_data,
- destroy_notify);
-
- listeners = g_list_delete_link (listeners, listeners);
-
- l = listeners;
- while (l)
- {
- MetaKmsPageFlipListener *other_listener = l->data;
- GList *l_next = l->next;
-
- if (other_listener->crtc == crtc)
- {
- gpointer other_user_data;
- GDestroyNotify other_destroy_notify;
-
- other_user_data = g_steal_pointer (&other_listener->user_data);
- other_destroy_notify =
- g_steal_pointer (&other_listener->destroy_notify);
- meta_kms_page_flip_data_add_listener (page_flip_data,
- other_listener->vtable,
- other_listener->flags,
- other_user_data,
- other_destroy_notify);
- listeners = g_list_delete_link (listeners, l);
- }
-
- l = l_next;
- }
- }
-
- return page_flip_datas;
-}
-
-static gboolean
-maybe_dispatch_page_flips (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- GList **failed_planes,
- MetaKmsUpdateFlag flags,
- GError **error)
-{
- g_autoptr (GList) page_flip_datas = NULL;
- GList *l;
-
- page_flip_datas = generate_page_flip_datas (impl_device, update);
-
- while (page_flip_datas)
- {
- g_autoptr (GList) l = NULL;
- MetaKmsPageFlipData *page_flip_data;
-
- l = page_flip_datas;
- page_flip_datas = g_list_remove_link (page_flip_datas, l);
- page_flip_data = g_steal_pointer (&l->data);
-
- if (!dispatch_page_flip (impl_device, update, page_flip_data, error))
- {
- if (!g_error_matches (*error,
- G_IO_ERROR,
- G_IO_ERROR_PERMISSION_DENIED))
- {
- MetaKmsCrtc *crtc =
- meta_kms_page_flip_data_get_crtc (page_flip_data);
- MetaKmsPlaneAssignment *plane_assignment;
- MetaKmsPlaneFeedback *plane_feedback;
-
- plane_assignment =
- meta_kms_update_get_primary_plane_assignment (update, crtc);
-
- plane_feedback =
- meta_kms_plane_feedback_new_take_error (plane_assignment->plane,
- plane_assignment->crtc,
- g_error_copy (*error));
- *failed_planes = g_list_prepend (*failed_planes, plane_feedback);
- }
-
- if (!(flags & META_KMS_UPDATE_FLAG_PRESERVE_ON_ERROR))
- meta_kms_page_flip_data_discard_in_impl (page_flip_data, *error);
-
- goto err;
- }
- }
-
- return TRUE;
-
-err:
- if (!(flags & META_KMS_UPDATE_FLAG_PRESERVE_ON_ERROR))
- {
- for (l = page_flip_datas; l; l = l->next)
- {
- MetaKmsPageFlipData *page_flip_data = l->data;
-
- meta_kms_page_flip_data_discard_in_impl (page_flip_data, *error);
- }
- }
- g_list_free (page_flip_datas);
-
- return FALSE;
-}
-
-static gboolean
-process_entries (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- GList *entries,
- MetaKmsSimpleProcessFunc func,
- GError **error)
-{
- GList *l;
-
- for (l = entries; l; l = l->next)
- {
- if (!func (impl_device, update, l->data, error))
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-process_cursor_plane_assignment (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- MetaKmsPlaneAssignment *plane_assignment,
- GError **error)
-{
- uint32_t crtc_id;
- int fd;
-
- crtc_id = meta_kms_crtc_get_id (plane_assignment->crtc),
- 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;
- uint32_t handle_u32;
-
- width = plane_assignment->dst_rect.width;
- height = plane_assignment->dst_rect.height;
-
- if (plane_assignment->buffer)
- {
- MetaDrmBufferGbm *buffer_gbm =
- META_DRM_BUFFER_GBM (plane_assignment->buffer);
- struct gbm_bo *bo;
- union gbm_bo_handle handle;
-
- bo = meta_drm_buffer_gbm_get_bo (buffer_gbm);
- handle = gbm_bo_get_handle (bo);
- handle_u32 = handle.u32;
- }
- else
- {
- handle_u32 = 0;
- }
-
- meta_topic (META_DEBUG_KMS,
- "[simple] Setting HW cursor of CRTC %u (%s) to %u "
- "(size: %dx%d, hot: (%d, %d))",
- crtc_id,
- meta_kms_impl_device_get_path (impl_device),
- handle_u32,
- width, height,
- plane_assignment->cursor_hotspot.x,
- plane_assignment->cursor_hotspot.y);
-
- if (plane_assignment->cursor_hotspot.is_valid)
- {
- ret = drmModeSetCursor2 (fd,
- crtc_id,
- handle_u32,
- width, height,
- plane_assignment->cursor_hotspot.x,
- plane_assignment->cursor_hotspot.y);
- }
-
- if (ret != 0)
- {
- ret = drmModeSetCursor (fd, crtc_id,
- handle_u32,
- 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;
- }
- }
-
- meta_topic (META_DEBUG_KMS,
- "[simple] Moving HW cursor of CRTC %u (%s) to (%d, %d)",
- crtc_id,
- meta_kms_impl_device_get_path (impl_device),
- plane_assignment->dst_rect.x,
- plane_assignment->dst_rect.y);
-
- drmModeMoveCursor (fd,
- crtc_id,
- plane_assignment->dst_rect.x,
- plane_assignment->dst_rect.y);
-
- return TRUE;
-}
-
-static gboolean
-process_plane_assignment (MetaKmsImplDevice *impl_device,
- 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_device, 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 gboolean
-process_plane_assignments (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- GList **failed_planes,
- GError **error)
-{
- 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_device, update, plane_assignment,
- &plane_feedback))
- {
- if (g_error_matches (plane_feedback->error,
- G_IO_ERROR,
- G_IO_ERROR_PERMISSION_DENIED))
- {
- g_propagate_error (error,
- g_steal_pointer (&plane_feedback->error));
- meta_kms_plane_feedback_free (plane_feedback);
- return FALSE;
- }
-
- *failed_planes = g_list_prepend (*failed_planes, plane_feedback);
- if (plane_assignment->flags & META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL)
- {
- continue;
- }
- else
- {
- g_propagate_error (error, g_error_copy (plane_feedback->error));
- return FALSE;
- }
- }
- }
-
- return TRUE;
-}
-
-static void
-page_flip_handler (int fd,
- unsigned int sequence,
- unsigned int tv_sec,
- unsigned int tv_usec,
- void *user_data)
-{
- MetaKmsPageFlipData *page_flip_data = user_data;
- MetaKmsImplDevice *impl_device;
- MetaKmsImplDeviceSimple *impl_device_simple;
- MetaKmsCrtc *crtc;
-
- meta_kms_page_flip_data_set_timings_in_impl (page_flip_data,
- sequence, tv_sec, tv_usec);
-
- impl_device = meta_kms_page_flip_data_get_impl_device (page_flip_data);
- impl_device_simple = META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
- crtc = meta_kms_page_flip_data_get_crtc (page_flip_data);
-
- meta_topic (META_DEBUG_KMS,
- "[simple] Handling page flip callback from %s, data: %p, CRTC: %u",
- meta_kms_impl_device_get_path (impl_device),
- page_flip_data,
- meta_kms_crtc_get_id (crtc));
-
- meta_kms_impl_device_unhold_fd (impl_device);
-
- meta_kms_impl_device_handle_page_flip_callback (impl_device, page_flip_data);
- impl_device_simple->posted_page_flip_datas =
- g_list_remove (impl_device_simple->posted_page_flip_datas,
- page_flip_data);
-}
-
-static void
-meta_kms_impl_device_simple_setup_drm_event_context (MetaKmsImplDevice *impl_device,
- drmEventContext *drm_event_context)
-{
- drm_event_context->version = 2;
- drm_event_context->page_flip_handler = page_flip_handler;
-}
-
-static MetaKmsFeedback *
-meta_kms_impl_device_simple_process_update (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- MetaKmsUpdateFlag flags)
-{
- GError *error = NULL;
- GList *failed_planes = NULL;
-
- meta_topic (META_DEBUG_KMS,
- "[simple] Processing update %" G_GUINT64_FORMAT,
- meta_kms_update_get_sequence_number (update));
-
- if (meta_kms_update_is_power_save (update))
- {
- if (!process_power_save (impl_device, &error))
- goto err;
- goto out;
- }
-
- if (!process_entries (impl_device,
- update,
- meta_kms_update_get_mode_sets (update),
- process_mode_set,
- &error))
- goto err;
-
- if (!process_entries (impl_device,
- update,
- meta_kms_update_get_connector_updates (update),
- process_connector_update,
- &error))
- goto err;
-
- if (!process_entries (impl_device,
- update,
- meta_kms_update_get_crtc_gammas (update),
- process_crtc_gamma,
- &error))
- goto err;
-
- if (!process_plane_assignments (impl_device, update, &failed_planes, &error))
- goto err;
-
- if (!maybe_dispatch_page_flips (impl_device, update, &failed_planes, flags,
- &error))
- goto err;
-
-out:
- return meta_kms_feedback_new_passed (failed_planes);
-
-err:
- return meta_kms_feedback_new_failed (failed_planes, error);
-}
-
-static void
-flush_postponed_page_flip_datas (MetaKmsImplDeviceSimple *impl_device_simple)
-{
- dispatch_page_flip_datas (&impl_device_simple->postponed_page_flip_datas,
- (GFunc) meta_kms_page_flip_data_flipped_in_impl,
- NULL);
- dispatch_page_flip_datas (&impl_device_simple->postponed_mode_set_fallback_datas,
- (GFunc) meta_kms_page_flip_data_mode_set_fallback_in_impl,
- NULL);
-}
-
-static void
-meta_kms_impl_device_simple_handle_page_flip_callback (MetaKmsImplDevice *impl_device,
- MetaKmsPageFlipData *page_flip_data)
-{
- MetaKmsImplDeviceSimple *impl_device_simple =
- META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
-
- if (impl_device_simple->pending_page_flip_retries)
- {
- impl_device_simple->postponed_page_flip_datas =
- g_list_append (impl_device_simple->postponed_page_flip_datas,
- page_flip_data);
- }
- else
- {
- meta_kms_page_flip_data_flipped_in_impl (page_flip_data);
- }
-}
-
-static void
-dispose_page_flip_data (MetaKmsPageFlipData *page_flip_data,
- MetaKmsImplDevice *impl_device)
-{
- meta_kms_page_flip_data_discard_in_impl (page_flip_data, NULL);
- meta_kms_impl_device_unhold_fd (impl_device);
-}
-
-static void
-meta_kms_impl_device_simple_discard_pending_page_flips (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDeviceSimple *impl_device_simple =
- META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
- GList *l;
-
- if (!impl_device_simple->pending_page_flip_retries)
- return;
-
- for (l = impl_device_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_topic (META_DEBUG_KMS,
- "[simple] Discarding page flip retry for CRTC %u (%s)",
- meta_kms_crtc_get_id (
- meta_kms_page_flip_data_get_crtc (page_flip_data)),
- meta_kms_impl_device_get_path (
- meta_kms_page_flip_data_get_impl_device (page_flip_data)));
-
- dispose_page_flip_data (page_flip_data, impl_device);
- retry_page_flip_data_free (retry_page_flip_data);
- }
- g_clear_pointer (&impl_device_simple->pending_page_flip_retries, g_list_free);
-
- g_clear_pointer (&impl_device_simple->retry_page_flips_source,
- g_source_destroy);
-}
-
-static void
-meta_kms_impl_device_simple_prepare_shutdown (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDeviceSimple *impl_device_simple =
- META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
-
- g_list_foreach (impl_device_simple->posted_page_flip_datas,
- (GFunc) dispose_page_flip_data,
- impl_device);
- g_clear_list (&impl_device_simple->posted_page_flip_datas, NULL);
-}
-
-static void
-meta_kms_impl_device_simple_finalize (GObject *object)
-{
- MetaKmsImplDeviceSimple *impl_device_simple =
- META_KMS_IMPL_DEVICE_SIMPLE (object);
- MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (impl_device_simple);
-
- g_list_free_full (impl_device_simple->pending_page_flip_retries,
- (GDestroyNotify) retry_page_flip_data_free);
- dispatch_page_flip_datas (&impl_device_simple->postponed_page_flip_datas,
- (GFunc) dispose_page_flip_data,
- impl_device);
- dispatch_page_flip_datas (&impl_device_simple->postponed_mode_set_fallback_datas,
- (GFunc) dispose_page_flip_data,
- impl_device);
-
- g_assert (!impl_device_simple->posted_page_flip_datas);
-
- g_clear_pointer (&impl_device_simple->mode_set_fallback_feedback_source,
- g_source_destroy);
- g_hash_table_destroy (impl_device_simple->cached_mode_sets);
-
- G_OBJECT_CLASS (meta_kms_impl_device_simple_parent_class)->finalize (object);
-}
-
-static MetaDeviceFile *
-meta_kms_impl_device_simple_open_device_file (MetaKmsImplDevice *impl_device,
- const char *path,
- GError **error)
-{
- MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
- MetaKms *kms = meta_kms_device_get_kms (device);
- MetaBackend *backend = meta_kms_get_backend (kms);
- MetaDevicePool *device_pool =
- meta_backend_native_get_device_pool (META_BACKEND_NATIVE (backend));
- g_autoptr (MetaDeviceFile) device_file = NULL;
-
- device_file = meta_device_pool_open (device_pool, path,
- META_DEVICE_FILE_FLAG_TAKE_CONTROL,
- error);
- if (!device_file)
- return NULL;
-
- if (!meta_device_file_has_tag (device_file,
- META_DEVICE_FILE_TAG_KMS,
- META_KMS_DEVICE_FILE_TAG_SIMPLE))
- {
- int fd = meta_device_file_get_fd (device_file);
-
- g_warn_if_fail (!meta_device_file_has_tag (device_file,
- META_DEVICE_FILE_TAG_KMS,
- META_KMS_DEVICE_FILE_TAG_ATOMIC));
-
- if (drmSetClientCap (fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) != 0)
- {
- g_set_error (error, META_KMS_ERROR, META_KMS_ERROR_NOT_SUPPORTED,
- "DRM_CLIENT_CAP_UNIVERSAL_PLANES not supported");
- return NULL;
- }
-
- meta_device_file_tag (device_file,
- META_DEVICE_FILE_TAG_KMS,
- META_KMS_DEVICE_FILE_TAG_SIMPLE);
- }
-
- return g_steal_pointer (&device_file);
-}
-
-static gboolean
-meta_kms_impl_device_simple_initable_init (GInitable *initable,
- GCancellable *cancellable,
- GError **error)
-{
- MetaKmsImplDeviceSimple *impl_device_simple =
- META_KMS_IMPL_DEVICE_SIMPLE (initable);
- MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (impl_device_simple);
- MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
- GList *l;
-
- if (!initable_parent_iface->init (initable, cancellable, error))
- return FALSE;
-
- if (!meta_kms_impl_device_init_mode_setting (impl_device, error))
- return FALSE;
-
- impl_device_simple->cached_mode_sets =
- g_hash_table_new_full (NULL,
- NULL,
- NULL,
- (GDestroyNotify) cached_mode_set_free);
-
- 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_topic (META_DEBUG_KMS,
- "[simple] Adding fake cursor plane for CRTC %u (%s)",
- meta_kms_crtc_get_id (crtc),
- meta_kms_impl_device_get_path (impl_device));
-
- meta_kms_device_add_fake_plane_in_impl (device,
- META_KMS_PLANE_TYPE_CURSOR,
- crtc);
- }
-
- g_message ("Added device '%s' (%s) using non-atomic mode setting.",
- meta_kms_impl_device_get_path (impl_device),
- meta_kms_impl_device_get_driver_name (impl_device));
-
- return TRUE;
-}
-
-static void
-meta_kms_impl_device_simple_init (MetaKmsImplDeviceSimple *impl_device_simple)
-{
-}
-
-static void
-initable_iface_init (GInitableIface *iface)
-{
- initable_parent_iface = g_type_interface_peek_parent (iface);
-
- iface->init = meta_kms_impl_device_simple_initable_init;
-}
-
-static void
-meta_kms_impl_device_simple_class_init (MetaKmsImplDeviceSimpleClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- MetaKmsImplDeviceClass *impl_device_class =
- META_KMS_IMPL_DEVICE_CLASS (klass);
-
- object_class->finalize = meta_kms_impl_device_simple_finalize;
-
- impl_device_class->open_device_file =
- meta_kms_impl_device_simple_open_device_file;
- impl_device_class->setup_drm_event_context =
- meta_kms_impl_device_simple_setup_drm_event_context;
- impl_device_class->process_update =
- meta_kms_impl_device_simple_process_update;
- impl_device_class->handle_page_flip_callback =
- meta_kms_impl_device_simple_handle_page_flip_callback;
- impl_device_class->discard_pending_page_flips =
- meta_kms_impl_device_simple_discard_pending_page_flips;
- impl_device_class->prepare_shutdown =
- meta_kms_impl_device_simple_prepare_shutdown;
-}
diff --git a/src/backends/native/meta-kms-impl-device-simple.h b/src/backends/native/meta-kms-impl-device-simple.h
deleted file mode 100644
index 7be5f0a83..000000000
--- a/src/backends/native/meta-kms-impl-device-simple.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2018-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.
- */
-
-#ifndef META_KMS_IMPL_DEVICE_SIMPLE_H
-#define META_KMS_IMPL_DEVICE_SIMPLE_H
-
-#include "backends/native/meta-kms-impl-device.h"
-
-#define META_TYPE_KMS_IMPL_DEVICE_SIMPLE (meta_kms_impl_device_simple_get_type ())
-G_DECLARE_FINAL_TYPE (MetaKmsImplDeviceSimple, meta_kms_impl_device_simple,
- META, KMS_IMPL_DEVICE_SIMPLE, MetaKmsImplDevice)
-
-#endif /* META_KMS_IMPL_DEVICE_SIMPLE_H */
diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c
deleted file mode 100644
index e08e672e5..000000000
--- a/src/backends/native/meta-kms-impl-device.c
+++ /dev/null
@@ -1,1070 +0,0 @@
-/*
- * 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-backend-native.h"
-#include "backends/native/meta-device-pool.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-mode-private.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-private.h"
-
-#include "meta-default-modes.h"
-#include "meta-private-enum-types.h"
-
-enum
-{
- PROP_0,
-
- PROP_DEVICE,
- PROP_IMPL,
- PROP_PATH,
- PROP_FLAGS,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS];
-
-typedef struct _MetaKmsImplDevicePrivate
-{
- MetaKmsDevice *device;
- MetaKmsImpl *impl;
-
- int fd_hold_count;
- MetaDeviceFile *device_file;
- GSource *fd_source;
- char *path;
- MetaKmsDeviceFlag flags;
- gboolean has_latched_fd_hold;
-
- char *driver_name;
- char *driver_description;
-
- GList *crtcs;
- GList *connectors;
- GList *planes;
-
- MetaKmsDeviceCaps caps;
-
- GList *fallback_modes;
-} MetaKmsImplDevicePrivate;
-
-static void
-initable_iface_init (GInitableIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaKmsImplDevice, meta_kms_impl_device,
- G_TYPE_OBJECT,
- G_ADD_PRIVATE (MetaKmsImplDevice)
- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
- initable_iface_init))
-
-G_DEFINE_QUARK (-meta-kms-error-quark, meta_kms_error)
-
-MetaKmsDevice *
-meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- return priv->device;
-}
-
-GList *
-meta_kms_impl_device_copy_connectors (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- return g_list_copy (priv->connectors);
-}
-
-GList *
-meta_kms_impl_device_copy_crtcs (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- return g_list_copy (priv->crtcs);
-}
-
-GList *
-meta_kms_impl_device_copy_planes (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- return g_list_copy (priv->planes);
-}
-
-GList *
-meta_kms_impl_device_peek_connectors (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- return priv->connectors;
-}
-
-GList *
-meta_kms_impl_device_peek_crtcs (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- return priv->crtcs;
-}
-
-GList *
-meta_kms_impl_device_peek_planes (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- return priv->planes;
-}
-
-const MetaKmsDeviceCaps *
-meta_kms_impl_device_get_caps (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- return &priv->caps;
-}
-
-GList *
-meta_kms_impl_device_copy_fallback_modes (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- return g_list_copy (priv->fallback_modes);
-}
-
-const char *
-meta_kms_impl_device_get_driver_name (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- return priv->driver_name;
-}
-
-const char *
-meta_kms_impl_device_get_driver_description (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- return priv->driver_description;
-}
-
-const char *
-meta_kms_impl_device_get_path (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- return priv->path;
-}
-
-gboolean
-meta_kms_impl_device_dispatch (MetaKmsImplDevice *impl_device,
- GError **error)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
- int fd;
-
- drmEventContext drm_event_context;
-
- meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
-
- drm_event_context = (drmEventContext) { 0 };
- klass->setup_drm_event_context (impl_device, &drm_event_context);
-
- fd = meta_device_file_get_fd (priv->device_file);
-
- while (TRUE)
- {
- if (drmHandleEvent (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 = 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)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- int fd;
- unsigned int i;
-
- meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
-
- fd = meta_device_file_get_fd (priv->device_file);
-
- for (i = 0; i < props->count_props; i++)
- {
- drmModePropertyPtr prop;
-
- prop = drmModeGetProperty (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)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- int fd;
- uint64_t cursor_width, cursor_height;
- uint64_t prefer_shadow;
- uint64_t uses_monotonic_clock;
-
- fd = meta_device_file_get_fd (priv->device_file);
- if (drmGetCap (fd, DRM_CAP_CURSOR_WIDTH, &cursor_width) == 0 &&
- drmGetCap (fd, DRM_CAP_CURSOR_HEIGHT, &cursor_height) == 0)
- {
- priv->caps.has_cursor_size = TRUE;
- priv->caps.cursor_width = cursor_width;
- priv->caps.cursor_height = cursor_height;
- }
-
- if (drmGetCap (fd, DRM_CAP_DUMB_PREFER_SHADOW, &prefer_shadow) == 0)
- {
- if (prefer_shadow)
- g_message ("Device '%s' prefers shadow buffer", priv->path);
-
- priv->caps.prefers_shadow_buffer = prefer_shadow;
- }
-
- if (drmGetCap (fd, DRM_CAP_TIMESTAMP_MONOTONIC, &uses_monotonic_clock) == 0)
- {
- priv->caps.uses_monotonic_clock = uses_monotonic_clock;
- }
-}
-
-static void
-init_crtcs (MetaKmsImplDevice *impl_device,
- drmModeRes *drm_resources)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- int idx;
- int fd;
-
- fd = meta_device_file_get_fd (priv->device_file);
-
- for (idx = 0; idx < drm_resources->count_crtcs; idx++)
- {
- uint32_t crtc_id;
- drmModeCrtc *drm_crtc;
- MetaKmsCrtc *crtc;
- g_autoptr (GError) error = NULL;
-
- crtc_id = drm_resources->crtcs[idx];
- drm_crtc = drmModeGetCrtc (fd, crtc_id);
- if (!drm_crtc)
- {
- g_warning ("Failed to get CRTC %u info on '%s': %s",
- crtc_id, priv->path, error->message);
- continue;
- }
-
- crtc = meta_kms_crtc_new (impl_device, drm_crtc, idx, &error);
-
- drmModeFreeCrtc (drm_crtc);
-
- if (!crtc)
- {
- g_warning ("Failed to create CRTC for %u on '%s': %s",
- crtc_id, priv->path, error->message);
- continue;
- }
-
- priv->crtcs = g_list_prepend (priv->crtcs, crtc);
- }
- priv->crtcs = g_list_reverse (priv->crtcs);
-}
-
-static MetaKmsConnector *
-find_existing_connector (MetaKmsImplDevice *impl_device,
- drmModeConnector *drm_connector)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- GList *l;
-
- for (l = priv->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)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- GList *connectors = NULL;
- unsigned int i;
- int fd;
-
- fd = meta_device_file_get_fd (priv->device_file);
-
- for (i = 0; i < drm_resources->count_connectors; i++)
- {
- drmModeConnector *drm_connector;
- MetaKmsConnector *connector;
-
- drm_connector = drmModeGetConnector (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 (priv->connectors, g_object_unref);
- priv->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)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- MetaKmsPlane *plane;
-
- plane = meta_kms_plane_new_fake (plane_type, crtc);
- priv->planes = g_list_append (priv->planes, plane);
-
- return plane;
-}
-
-static MetaKmsProp *
-find_prop (MetaKmsProp *props,
- int n_props,
- const char *name)
-{
- int i;
-
- for (i = 0; i < n_props; i++)
- {
- MetaKmsProp *prop = &props[i];
-
- g_warn_if_fail (prop->name);
-
- if (g_strcmp0 (prop->name, name) == 0)
- return prop;
- }
-
- return NULL;
-}
-
-void
-meta_kms_impl_device_init_prop_table (MetaKmsImplDevice *impl_device,
- uint32_t *drm_props,
- uint64_t *drm_prop_values,
- int n_drm_props,
- MetaKmsProp *props,
- int n_props,
- gpointer user_data)
-{
- int fd;
- uint32_t i;
-
- fd = meta_kms_impl_device_get_fd (impl_device);
-
- for (i = 0; i < n_drm_props; i++)
- {
- drmModePropertyRes *drm_prop;
- MetaKmsProp *prop;
-
- drm_prop = drmModeGetProperty (fd, drm_props[i]);
- if (!drm_prop)
- continue;
-
- prop = find_prop (props, n_props, drm_prop->name);
- if (!prop)
- {
- drmModeFreeProperty (drm_prop);
- continue;
- }
-
- if (!(drm_prop->flags & prop->type))
- {
- g_warning ("DRM property '%s' (%u) had unexpected flags (0x%x), "
- "ignoring",
- drm_prop->name, drm_props[i], drm_prop->flags);
- drmModeFreeProperty (drm_prop);
- continue;
- }
-
- prop->prop_id = drm_props[i];
-
- if (prop->parse)
- {
- prop->parse (impl_device, prop,
- drm_prop, drm_prop_values[i],
- user_data);
- }
-
- drmModeFreeProperty (drm_prop);
- }
-}
-
-static void
-init_planes (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- int fd;
- drmModePlaneRes *drm_planes;
- unsigned int i;
-
- fd = meta_device_file_get_fd (priv->device_file);
-
- 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);
-
- priv->planes = g_list_prepend (priv->planes, plane);
- }
- }
-
- g_clear_pointer (&props, drmModeFreeObjectProperties);
- drmModeFreePlane (drm_plane);
- }
- priv->planes = g_list_reverse (priv->planes);
-}
-
-static void
-init_fallback_modes (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- GList *modes = NULL;
- int i;
-
- for (i = 0; i < G_N_ELEMENTS (meta_default_landscape_drm_mode_infos); i++)
- {
- MetaKmsMode *mode;
-
- mode = meta_kms_mode_new (impl_device,
- &meta_default_landscape_drm_mode_infos[i],
- META_KMS_MODE_FLAG_FALLBACK_LANDSCAPE);
- modes = g_list_prepend (modes, mode);
- }
-
- for (i = 0; i < G_N_ELEMENTS (meta_default_portrait_drm_mode_infos); i++)
- {
- MetaKmsMode *mode;
-
- mode = meta_kms_mode_new (impl_device,
- &meta_default_portrait_drm_mode_infos[i],
- META_KMS_MODE_FLAG_FALLBACK_PORTRAIT);
- modes = g_list_prepend (modes, mode);
- }
-
- priv->fallback_modes = g_list_reverse (modes);
-}
-
-static MetaDeviceFile *
-meta_kms_impl_device_open_device_file (MetaKmsImplDevice *impl_device,
- const char *path,
- GError **error)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
-
- return klass->open_device_file (impl_device, priv->path, error);
-}
-
-static gboolean
-ensure_device_file (MetaKmsImplDevice *impl_device,
- GError **error)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- MetaDeviceFile *device_file;
-
- if (priv->device_file)
- return TRUE;
-
- device_file = meta_kms_impl_device_open_device_file (impl_device,
- priv->path,
- error);
- if (!device_file)
- return FALSE;
-
- priv->device_file = device_file;
-
- if (!(priv->flags & META_KMS_DEVICE_FLAG_NO_MODE_SETTING))
- {
- priv->fd_source =
- meta_kms_register_fd_in_impl (meta_kms_impl_get_kms (priv->impl),
- meta_device_file_get_fd (device_file),
- kms_event_dispatch_in_impl,
- impl_device);
- }
-
- return TRUE;
-}
-
-static void
-ensure_latched_fd_hold (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- if (!priv->has_latched_fd_hold)
- {
- meta_kms_impl_device_hold_fd (impl_device);
- priv->has_latched_fd_hold = TRUE;
- }
-}
-
-static void
-clear_latched_fd_hold (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- if (priv->has_latched_fd_hold)
- {
- meta_kms_impl_device_unhold_fd (impl_device);
- priv->has_latched_fd_hold = FALSE;
- }
-}
-
-void
-meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- g_autoptr (GError) error = NULL;
- int fd;
- drmModeRes *drm_resources;
-
- meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
-
- meta_topic (META_DEBUG_KMS, "Updating device state for %s", priv->path);
-
- if (!ensure_device_file (impl_device, &error))
- {
- g_warning ("Failed to reopen '%s': %s", priv->path, error->message);
- goto err;
- }
-
- ensure_latched_fd_hold (impl_device);
-
- fd = meta_device_file_get_fd (priv->device_file);
- drm_resources = drmModeGetResources (fd);
- if (!drm_resources)
- {
- meta_topic (META_DEBUG_KMS, "Device '%s' didn't return any resources",
- priv->path);
- goto err;
- }
-
- update_connectors (impl_device, drm_resources);
-
- g_list_foreach (priv->crtcs, (GFunc) meta_kms_crtc_update_state,
- NULL);
- g_list_foreach (priv->connectors, (GFunc) meta_kms_connector_update_state,
- drm_resources);
- drmModeFreeResources (drm_resources);
-
- return;
-
-err:
- g_clear_list (&priv->planes, g_object_unref);
- g_clear_list (&priv->crtcs, g_object_unref);
- g_clear_list (&priv->connectors, g_object_unref);
-}
-
-void
-meta_kms_impl_device_predict_states (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- g_list_foreach (priv->crtcs, (GFunc) meta_kms_crtc_predict_state,
- update);
- g_list_foreach (priv->connectors, (GFunc) meta_kms_connector_predict_state,
- update);
-}
-
-void
-meta_kms_impl_device_notify_modes_set (MetaKmsImplDevice *impl_device)
-{
- clear_latched_fd_hold (impl_device);
-}
-
-int
-meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
-
- return meta_device_file_get_fd (priv->device_file);
-}
-
-MetaKmsFeedback *
-meta_kms_impl_device_process_update (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- MetaKmsUpdateFlag flags)
-{
- MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
- MetaKmsFeedback *feedback;
- g_autoptr (GError) error = NULL;
-
- if (!ensure_device_file (impl_device, &error))
- return meta_kms_feedback_new_failed (NULL, g_steal_pointer (&error));
-
- meta_kms_impl_device_hold_fd (impl_device);
- feedback = klass->process_update (impl_device, update, flags);
- meta_kms_impl_device_unhold_fd (impl_device);
-
- return feedback;
-}
-
-void
-meta_kms_impl_device_handle_page_flip_callback (MetaKmsImplDevice *impl_device,
- MetaKmsPageFlipData *page_flip_data)
-{
- MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
-
- klass->handle_page_flip_callback (impl_device, page_flip_data);
-}
-
-void
-meta_kms_impl_device_discard_pending_page_flips (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
-
- klass->discard_pending_page_flips (impl_device);
-}
-
-void
-meta_kms_impl_device_hold_fd (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- MetaKms *kms = meta_kms_device_get_kms (priv->device);
-
- meta_assert_in_kms_impl (kms);
-
- g_assert (priv->device_file);
-
- priv->fd_hold_count++;
-}
-
-void
-meta_kms_impl_device_unhold_fd (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- MetaKms *kms = meta_kms_device_get_kms (priv->device);
-
- meta_assert_in_kms_impl (kms);
-
- g_return_if_fail (priv->fd_hold_count > 0);
-
- priv->fd_hold_count--;
- if (priv->fd_hold_count == 0)
- {
- g_clear_pointer (&priv->device_file, meta_device_file_release);
-
- if (priv->fd_source)
- {
- g_source_destroy (priv->fd_source);
- g_clear_pointer (&priv->fd_source, g_source_unref);
- }
- }
-}
-
-static void
-meta_kms_impl_device_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (object);
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- switch (prop_id)
- {
- case PROP_DEVICE:
- g_value_set_object (value, priv->device);
- break;
- case PROP_IMPL:
- g_value_set_object (value, priv->impl);
- break;
- case PROP_FLAGS:
- g_value_set_flags (value, priv->flags);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_kms_impl_device_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (object);
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- switch (prop_id)
- {
- case PROP_DEVICE:
- priv->device = g_value_get_object (value);
- break;
- case PROP_IMPL:
- priv->impl = g_value_get_object (value);
- break;
- case PROP_PATH:
- priv->path = g_value_dup_string (value);
- break;
- case PROP_FLAGS:
- priv->flags = g_value_get_flags (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_kms_impl_device_finalize (GObject *object)
-{
- MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (object);
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
-
- meta_kms_impl_remove_impl_device (priv->impl, impl_device);
-
- g_list_free_full (priv->planes, g_object_unref);
- g_list_free_full (priv->crtcs, g_object_unref);
- g_list_free_full (priv->connectors, g_object_unref);
- g_list_free_full (priv->fallback_modes,
- (GDestroyNotify) meta_kms_mode_free);
-
- clear_latched_fd_hold (impl_device);
- g_warn_if_fail (!priv->device_file);
-
- g_free (priv->driver_name);
- g_free (priv->driver_description);
- g_free (priv->path);
-
- G_OBJECT_CLASS (meta_kms_impl_device_parent_class)->finalize (object);
-}
-
-gboolean
-meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice *impl_device,
- GError **error)
-{
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- int fd;
- drmModeRes *drm_resources;
-
- fd = meta_device_file_get_fd (priv->device_file);
-
- 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 FALSE;
- }
-
- init_caps (impl_device);
-
- init_crtcs (impl_device, drm_resources);
- init_planes (impl_device);
-
- init_fallback_modes (impl_device);
-
- update_connectors (impl_device, drm_resources);
-
- drmModeFreeResources (drm_resources);
-
- return TRUE;
-}
-
-void
-meta_kms_impl_device_prepare_shutdown (MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
-
- if (klass->prepare_shutdown)
- klass->prepare_shutdown (impl_device);
-}
-
-static gboolean
-get_driver_info (int fd,
- char **name,
- char **description)
-{
- drmVersion *drm_version;
-
- drm_version = drmGetVersion (fd);
- if (!drm_version)
- return FALSE;
-
- *name = g_strndup (drm_version->name,
- drm_version->name_len);
- *description = g_strndup (drm_version->desc,
- drm_version->desc_len);
- drmFreeVersion (drm_version);
-
- return TRUE;
-}
-
-static gboolean
-meta_kms_impl_device_initable_init (GInitable *initable,
- GCancellable *cancellable,
- GError **error)
-{
- MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (initable);
- MetaKmsImplDevicePrivate *priv =
- meta_kms_impl_device_get_instance_private (impl_device);
- int fd;
-
- if (!ensure_device_file (impl_device, error))
- return FALSE;
-
- ensure_latched_fd_hold (impl_device);
-
- g_clear_pointer (&priv->path, g_free);
- priv->path = g_strdup (meta_device_file_get_path (priv->device_file));
-
- fd = meta_device_file_get_fd (priv->device_file);
- if (!get_driver_info (fd, &priv->driver_name, &priv->driver_description))
- {
- priv->driver_name = g_strdup ("unknown");
- priv->driver_description = g_strdup ("Unknown");
- }
-
- return TRUE;
-}
-
-static void
-meta_kms_impl_device_init (MetaKmsImplDevice *impl_device)
-{
-}
-
-static void
-initable_iface_init (GInitableIface *iface)
-{
- iface->init = meta_kms_impl_device_initable_init;
-}
-
-static void
-meta_kms_impl_device_class_init (MetaKmsImplDeviceClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->get_property = meta_kms_impl_device_get_property;
- object_class->set_property = meta_kms_impl_device_set_property;
- object_class->finalize = meta_kms_impl_device_finalize;
-
- obj_props[PROP_DEVICE] =
- g_param_spec_object ("device",
- "device",
- "MetaKmsDevice",
- META_TYPE_KMS_DEVICE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- obj_props[PROP_IMPL] =
- g_param_spec_object ("impl",
- "impl",
- "MetaKmsImpl",
- META_TYPE_KMS_IMPL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- obj_props[PROP_PATH] =
- g_param_spec_string ("path",
- "path",
- "Device path",
- NULL,
- G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- obj_props[PROP_FLAGS] =
- g_param_spec_flags ("flags",
- "flags",
- "KMS impl device flags",
- META_TYPE_KMS_DEVICE_FLAG,
- META_KMS_DEVICE_FLAG_NONE,
- 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/native/meta-kms-impl-device.h b/src/backends/native/meta-kms-impl-device.h
deleted file mode 100644
index e77024ecd..000000000
--- a/src/backends/native/meta-kms-impl-device.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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 <xf86drm.h>
-#include <xf86drmMode.h>
-
-#include "backends/native/meta-device-pool.h"
-#include "backends/native/meta-kms-device.h"
-#include "backends/native/meta-kms-page-flip-private.h"
-#include "backends/native/meta-kms-types.h"
-#include "backends/native/meta-kms-update.h"
-#include "backends/native/meta-kms.h"
-
-typedef struct _MetaKmsDeviceCaps
-{
- gboolean has_cursor_size;
- uint64_t cursor_width;
- uint64_t cursor_height;
-
- gboolean prefers_shadow_buffer;
- gboolean uses_monotonic_clock;
-} MetaKmsDeviceCaps;
-
-typedef struct _MetaKmsProp MetaKmsProp;
-
-struct _MetaKmsProp
-{
- const char *name;
- uint32_t type;
- MetaKmsPropType internal_type;
- void (* parse) (MetaKmsImplDevice *impl_device,
- MetaKmsProp *prop,
- drmModePropertyPtr drm_prop,
- uint64_t value,
- gpointer user_data);
-
- uint32_t prop_id;
-};
-
-#define META_TYPE_KMS_IMPL_DEVICE (meta_kms_impl_device_get_type ())
-G_DECLARE_DERIVABLE_TYPE (MetaKmsImplDevice, meta_kms_impl_device,
- META, KMS_IMPL_DEVICE,
- GObject)
-
-struct _MetaKmsImplDeviceClass
-{
- GObjectClass parent_class;
-
- MetaDeviceFile * (* open_device_file) (MetaKmsImplDevice *impl_device,
- const char *path,
- GError **error);
- void (* setup_drm_event_context) (MetaKmsImplDevice *impl_device,
- drmEventContext *drm_event_context);
- MetaKmsFeedback * (* process_update) (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- MetaKmsUpdateFlag flags);
- void (* handle_page_flip_callback) (MetaKmsImplDevice *impl_device,
- MetaKmsPageFlipData *page_flip_data);
- void (* discard_pending_page_flips) (MetaKmsImplDevice *impl_device);
- void (* prepare_shutdown) (MetaKmsImplDevice *impl_device);
-};
-
-enum
-{
- META_KMS_ERROR_USER_INHIBITED,
- META_KMS_ERROR_DENY_LISTED,
- META_KMS_ERROR_NOT_SUPPORTED,
-};
-
-enum
-{
- META_KMS_DEVICE_FILE_TAG_ATOMIC = 1 << 0,
- META_KMS_DEVICE_FILE_TAG_SIMPLE = 1 << 1,
-};
-
-#define META_KMS_ERROR meta_kms_error_quark ()
-GQuark meta_kms_error_quark (void);
-
-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);
-
-GList * meta_kms_impl_device_peek_connectors (MetaKmsImplDevice *impl_device);
-
-GList * meta_kms_impl_device_peek_crtcs (MetaKmsImplDevice *impl_device);
-
-GList * meta_kms_impl_device_peek_planes (MetaKmsImplDevice *impl_device);
-
-const MetaKmsDeviceCaps * meta_kms_impl_device_get_caps (MetaKmsImplDevice *impl_device);
-
-GList * meta_kms_impl_device_copy_fallback_modes (MetaKmsImplDevice *impl_device);
-
-const char * meta_kms_impl_device_get_driver_name (MetaKmsImplDevice *impl_device);
-
-const char * meta_kms_impl_device_get_driver_description (MetaKmsImplDevice *impl_device);
-
-const char * meta_kms_impl_device_get_path (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);
-
-void meta_kms_impl_device_hold_fd (MetaKmsImplDevice *impl_device);
-
-void meta_kms_impl_device_unhold_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);
-
-void meta_kms_impl_device_notify_modes_set (MetaKmsImplDevice *impl_device);
-
-MetaKmsPlane * meta_kms_impl_device_add_fake_plane (MetaKmsImplDevice *impl_device,
- MetaKmsPlaneType plane_type,
- MetaKmsCrtc *crtc);
-
-void meta_kms_impl_device_init_prop_table (MetaKmsImplDevice *impl_device,
- uint32_t *drm_props,
- uint64_t *drm_props_values,
- int n_drm_props,
- MetaKmsProp *props,
- int n_props,
- gpointer user_data);
-
-void meta_kms_impl_device_reload_prop_values (MetaKmsImplDevice *impl_device,
- uint32_t *drm_props,
- uint64_t *drm_prop_values,
- int n_drm_props,
- gpointer user_data,
- ...);
-
-MetaKmsFeedback * meta_kms_impl_device_process_update (MetaKmsImplDevice *impl_device,
- MetaKmsUpdate *update,
- MetaKmsUpdateFlag flags);
-
-void meta_kms_impl_device_handle_page_flip_callback (MetaKmsImplDevice *impl_device,
- MetaKmsPageFlipData *page_flip_data);
-
-void meta_kms_impl_device_discard_pending_page_flips (MetaKmsImplDevice *impl_device);
-
-gboolean meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice *impl_device,
- GError **error);
-
-void meta_kms_impl_device_prepare_shutdown (MetaKmsImplDevice *impl_device);
-
-#endif /* META_KMS_IMPL_DEVICE_H */
diff --git a/src/backends/native/meta-kms-impl.c b/src/backends/native/meta-kms-impl.c
deleted file mode 100644
index 0ad76e085..000000000
--- a/src/backends/native/meta-kms-impl.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * 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"
-
-#include "backends/native/meta-kms-private.h"
-#include "backends/native/meta-kms-device-private.h"
-#include "backends/native/meta-kms-update-private.h"
-
-enum
-{
- PROP_0,
-
- PROP_KMS,
-};
-
-struct _MetaKmsImpl
-{
- GObject parent;
-};
-
-typedef struct _MetaKmsImplPrivate
-{
- MetaKms *kms;
-
- GList *impl_devices;
-} MetaKmsImplPrivate;
-
-G_DEFINE_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;
-}
-
-void
-meta_kms_impl_add_impl_device (MetaKmsImpl *impl,
- MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl);
-
- meta_assert_in_kms_impl (priv->kms);
-
- priv->impl_devices = g_list_append (priv->impl_devices, impl_device);
-}
-
-void
-meta_kms_impl_remove_impl_device (MetaKmsImpl *impl,
- MetaKmsImplDevice *impl_device)
-{
- MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl);
-
- meta_assert_in_kms_impl (priv->kms);
-
- priv->impl_devices = g_list_remove (priv->impl_devices, impl_device);
-}
-
-MetaKmsFeedback *
-meta_kms_impl_process_update (MetaKmsImpl *impl,
- MetaKmsUpdate *update,
- MetaKmsUpdateFlag flags)
-{
- MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl);
- MetaKmsDevice *device;
- MetaKmsImplDevice *impl_device;
-
- meta_assert_in_kms_impl (priv->kms);
-
- device = meta_kms_update_get_device (update);
- impl_device = meta_kms_device_get_impl_device (device);
-
- return meta_kms_impl_device_process_update (impl_device, update, flags);
-}
-
-void
-meta_kms_impl_discard_pending_page_flips (MetaKmsImpl *impl)
-{
- MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl);
-
- g_list_foreach (priv->impl_devices,
- (GFunc) meta_kms_impl_device_discard_pending_page_flips,
- NULL);
-}
-
-void
-meta_kms_impl_prepare_shutdown (MetaKmsImpl *impl)
-{
- MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl);
- GList *l;
-
- for (l = priv->impl_devices; l; l = l->next)
- {
- MetaKmsImplDevice *impl_device = l->data;
-
- meta_kms_impl_device_discard_pending_page_flips (impl_device);
- meta_kms_impl_device_prepare_shutdown (impl_device);
- }
-}
-
-void
-meta_kms_impl_notify_modes_set (MetaKmsImpl *impl)
-{
- MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl);
-
- g_list_foreach (priv->impl_devices,
- (GFunc) meta_kms_impl_device_notify_modes_set,
- NULL);
-}
-
-MetaKmsImpl *
-meta_kms_impl_new (MetaKms *kms)
-{
- return g_object_new (META_TYPE_KMS_IMPL,
- "kms", kms,
- NULL);
-}
-
-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
deleted file mode 100644
index 58f03f81a..000000000
--- a/src/backends/native/meta-kms-impl.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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_FINAL_TYPE (MetaKmsImpl, meta_kms_impl,
- META, KMS_IMPL, GObject)
-
-MetaKms * meta_kms_impl_get_kms (MetaKmsImpl *impl);
-
-MetaKmsFeedback * meta_kms_impl_process_update (MetaKmsImpl *impl,
- MetaKmsUpdate *update,
- MetaKmsUpdateFlag flags);
-
-void meta_kms_impl_add_impl_device (MetaKmsImpl *impl,
- MetaKmsImplDevice *impl_device);
-
-void meta_kms_impl_remove_impl_device (MetaKmsImpl *impl,
- MetaKmsImplDevice *impl_device);
-
-void meta_kms_impl_discard_pending_page_flips (MetaKmsImpl *impl);
-
-void meta_kms_impl_prepare_shutdown (MetaKmsImpl *impl);
-
-void meta_kms_impl_notify_modes_set (MetaKmsImpl *impl);
-
-MetaKmsImpl * meta_kms_impl_new (MetaKms *kms);
-
-#endif /* META_KMS_IMPL_H */
diff --git a/src/backends/native/meta-kms-mode-private.h b/src/backends/native/meta-kms-mode-private.h
deleted file mode 100644
index ded03c52e..000000000
--- a/src/backends/native/meta-kms-mode-private.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef META_KMS_MODE_PRIVATE_H
-#define META_KMS_MODE_PRIVATE_H
-
-#include "backends/native/meta-kms-mode.h"
-
-uint32_t meta_kms_mode_create_blob_id (MetaKmsMode *mode,
- GError **error);
-
-void meta_kms_mode_free (MetaKmsMode *mode);
-
-MetaKmsMode * meta_kms_mode_new (MetaKmsImplDevice *impl_device,
- const drmModeModeInfo *drm_mode,
- MetaKmsModeFlag flags);
-
-#endif /* META_KMS_MODE_PRIVATE_H */
diff --git a/src/backends/native/meta-kms-mode.c b/src/backends/native/meta-kms-mode.c
deleted file mode 100644
index 7094cd0da..000000000
--- a/src/backends/native/meta-kms-mode.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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.
- */
-
-#include "config.h"
-
-#include "backends/native/meta-kms-mode-private.h"
-
-#include "backends/native/meta-kms-impl-device.h"
-
-struct _MetaKmsMode
-{
- MetaKmsImplDevice *impl_device;
- MetaKmsModeFlag flags;
- drmModeModeInfo drm_mode;
-};
-
-uint32_t
-meta_kms_mode_create_blob_id (MetaKmsMode *mode,
- GError **error)
-{
- int fd;
- int ret;
- uint32_t blob_id;
-
- fd = meta_kms_impl_device_get_fd (mode->impl_device);
-
- ret = drmModeCreatePropertyBlob (fd,
- &mode->drm_mode,
- sizeof (mode->drm_mode),
- &blob_id);
- if (ret < 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
- "drmModeCreatePropertyBlob: %s",
- g_strerror (-ret));
- return 0;
- }
-
- return blob_id;
-}
-
-const char *
-meta_kms_mode_get_name (MetaKmsMode *mode)
-{
- return mode->drm_mode.name;
-}
-
-MetaKmsModeFlag
-meta_kms_mode_get_flags (MetaKmsMode *mode)
-{
- return mode->flags;
-}
-
-const drmModeModeInfo *
-meta_kms_mode_get_drm_mode (MetaKmsMode *mode)
-{
- return &mode->drm_mode;
-}
-
-static 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);
-}
-
-gboolean
-meta_kms_mode_equal (MetaKmsMode *mode,
- MetaKmsMode *other_mode)
-{
- return meta_drm_mode_equal (&mode->drm_mode, &other_mode->drm_mode);
-}
-
-unsigned int
-meta_kms_mode_hash (MetaKmsMode *mode)
-{
- const drmModeModeInfo *drm_mode = &mode->drm_mode;
- unsigned int 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 ^= drm_mode->clock;
- hash ^= drm_mode->hdisplay ^ drm_mode->hsync_start ^ drm_mode->hsync_end;
- hash ^= drm_mode->vdisplay ^ drm_mode->vsync_start ^ drm_mode->vsync_end;
- hash ^= drm_mode->vrefresh;
- hash ^= drm_mode->flags ^ drm_mode->type;
-
- return hash;
-}
-
-void
-meta_kms_mode_free (MetaKmsMode *mode)
-{
- g_free (mode);
-}
-
-MetaKmsMode *
-meta_kms_mode_new (MetaKmsImplDevice *impl_device,
- const drmModeModeInfo *drm_mode,
- MetaKmsModeFlag flags)
-{
- MetaKmsMode *mode;
-
- mode = g_new0 (MetaKmsMode, 1);
- mode->impl_device = impl_device;
- mode->flags = flags;
- mode->drm_mode = *drm_mode;
-
- return mode;
-}
diff --git a/src/backends/native/meta-kms-mode.h b/src/backends/native/meta-kms-mode.h
deleted file mode 100644
index 40e844796..000000000
--- a/src/backends/native/meta-kms-mode.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef META_KMS_MODE_H
-#define META_KMS_MODE_H
-
-#include <glib.h>
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-
-#include "backends/native/meta-kms-types.h"
-
-typedef enum _MetaKmsModeFlag
-{
- META_KMS_MODE_FLAG_NONE = 0,
- META_KMS_MODE_FLAG_FALLBACK_LANDSCAPE = 1 << 0,
- META_KMS_MODE_FLAG_FALLBACK_PORTRAIT = 1 << 1,
-} MetaKmsModeFlag;
-
-const char * meta_kms_mode_get_name (MetaKmsMode *mode);
-
-MetaKmsModeFlag meta_kms_mode_get_flags (MetaKmsMode *mode);
-
-const drmModeModeInfo * meta_kms_mode_get_drm_mode (MetaKmsMode *mode);
-
-gboolean meta_kms_mode_equal (MetaKmsMode *mode,
- MetaKmsMode *other_mode);
-
-unsigned int meta_kms_mode_hash (MetaKmsMode *mode);
-
-#endif /* META_KMS_MODE_H */
diff --git a/src/backends/native/meta-kms-page-flip-private.h b/src/backends/native/meta-kms-page-flip-private.h
deleted file mode 100644
index b23272ad9..000000000
--- a/src/backends/native/meta-kms-page-flip-private.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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 (MetaKmsImplDevice *impl_device,
- MetaKmsCrtc *crtc);
-
-MetaKmsPageFlipData * meta_kms_page_flip_data_ref (MetaKmsPageFlipData *page_flip_data);
-
-void meta_kms_page_flip_data_unref (MetaKmsPageFlipData *page_flip_data);
-
-void meta_kms_page_flip_data_add_listener (MetaKmsPageFlipData *page_flip_data,
- const MetaKmsPageFlipListenerVtable *vtable,
- MetaKmsPageFlipListenerFlag flags,
- gpointer user_data,
- GDestroyNotify destroy_notify);
-
-MetaKmsImplDevice * meta_kms_page_flip_data_get_impl_device (MetaKmsPageFlipData *page_flip_data);
-
-MetaKmsCrtc * meta_kms_page_flip_data_get_crtc (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);
-
-void meta_kms_page_flip_data_make_symbolic (MetaKmsPageFlipData *page_flip_data);
-
-#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
deleted file mode 100644
index 817f4e7c8..000000000
--- a/src/backends/native/meta-kms-page-flip.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * 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"
-
-typedef struct _MetaKmsPageFlipClosure
-{
- const MetaKmsPageFlipListenerVtable *vtable;
- MetaKmsPageFlipListenerFlag flags;
- gpointer user_data;
- GDestroyNotify destroy_notify;
-} MetaKmsPageFlipClosure;
-
-struct _MetaKmsPageFlipData
-{
- gatomicrefcount ref_count;
-
- MetaKmsImplDevice *impl_device;
- MetaKmsCrtc *crtc;
-
- GList *closures;
-
- unsigned int sequence;
- unsigned int sec;
- unsigned int usec;
-
- gboolean is_symbolic;
-
- GError *error;
-};
-
-static MetaKmsPageFlipClosure *
-meta_kms_page_flip_closure_new (const MetaKmsPageFlipListenerVtable *vtable,
- MetaKmsPageFlipListenerFlag flags,
- gpointer user_data,
- GDestroyNotify destroy_notify)
-{
- MetaKmsPageFlipClosure *closure;
-
- closure = g_new0 (MetaKmsPageFlipClosure, 1);
- *closure = (MetaKmsPageFlipClosure) {
- .vtable = vtable,
- .flags = flags,
- .user_data = user_data,
- .destroy_notify = destroy_notify,
- };
-
- return closure;
-}
-
-static void
-meta_kms_page_flip_closure_free (MetaKmsPageFlipClosure *closure)
-{
- g_clear_pointer (&closure->user_data, closure->destroy_notify);
- g_free (closure);
-}
-
-MetaKmsPageFlipData *
-meta_kms_page_flip_data_new (MetaKmsImplDevice *impl_device,
- MetaKmsCrtc *crtc)
-{
- MetaKmsPageFlipData *page_flip_data;
-
- page_flip_data = g_new0 (MetaKmsPageFlipData , 1);
- *page_flip_data = (MetaKmsPageFlipData) {
- .impl_device = impl_device,
- .crtc = crtc,
- };
- g_atomic_ref_count_init (&page_flip_data->ref_count);
-
- return page_flip_data;
-}
-
-MetaKmsPageFlipData *
-meta_kms_page_flip_data_ref (MetaKmsPageFlipData *page_flip_data)
-{
- g_atomic_ref_count_inc (&page_flip_data->ref_count);
-
- return page_flip_data;
-}
-
-void
-meta_kms_page_flip_data_unref (MetaKmsPageFlipData *page_flip_data)
-{
- if (g_atomic_ref_count_dec (&page_flip_data->ref_count))
- {
- g_list_free_full (page_flip_data->closures,
- (GDestroyNotify) meta_kms_page_flip_closure_free);
- g_clear_error (&page_flip_data->error);
- g_free (page_flip_data);
- }
-}
-
-void
-meta_kms_page_flip_data_add_listener (MetaKmsPageFlipData *page_flip_data,
- const MetaKmsPageFlipListenerVtable *vtable,
- MetaKmsPageFlipListenerFlag flags,
- gpointer user_data,
- GDestroyNotify destroy_notify)
-{
- MetaKmsPageFlipClosure *closure;
-
- closure = meta_kms_page_flip_closure_new (vtable, flags,
- user_data,
- destroy_notify);
- page_flip_data->closures = g_list_append (page_flip_data->closures, closure);
-}
-
-MetaKmsImplDevice *
-meta_kms_page_flip_data_get_impl_device (MetaKmsPageFlipData *page_flip_data)
-{
- return page_flip_data->impl_device;
-}
-
-MetaKmsCrtc *
-meta_kms_page_flip_data_get_crtc (MetaKmsPageFlipData *page_flip_data)
-{
- return page_flip_data->crtc;
-}
-
-static void
-meta_kms_page_flip_data_flipped (MetaKms *kms,
- gpointer user_data)
-{
- MetaKmsPageFlipData *page_flip_data = user_data;
- GList *l;
-
- meta_assert_not_in_kms_impl (kms);
-
- for (l = page_flip_data->closures; l; l = l->next)
- {
- MetaKmsPageFlipClosure *closure = l->data;
-
- if (page_flip_data->is_symbolic)
- {
- closure->vtable->ready (page_flip_data->crtc,
- closure->user_data);
- }
- else
- {
- closure->vtable->flipped (page_flip_data->crtc,
- page_flip_data->sequence,
- page_flip_data->sec,
- page_flip_data->usec,
- closure->user_data);
- }
- }
-}
-
-static MetaKms *
-meta_kms_from_impl_device (MetaKmsImplDevice *impl_device)
-{
- MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
-
- return meta_kms_device_get_kms (device);
-}
-
-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_from_impl_device (page_flip_data->impl_device);
-
- 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_make_symbolic (MetaKmsPageFlipData *page_flip_data)
-{
- page_flip_data->is_symbolic = TRUE;
-}
-
-void
-meta_kms_page_flip_data_flipped_in_impl (MetaKmsPageFlipData *page_flip_data)
-{
- MetaKms *kms = meta_kms_from_impl_device (page_flip_data->impl_device);
-
- meta_assert_in_kms_impl (kms);
-
- meta_kms_queue_callback (kms,
- meta_kms_page_flip_data_flipped,
- 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;
- GList *l;
-
- meta_assert_not_in_kms_impl (kms);
-
- for (l = page_flip_data->closures; l; l = l->next)
- {
- MetaKmsPageFlipClosure *closure = l->data;
-
- closure->vtable->mode_set_fallback (page_flip_data->crtc,
- closure->user_data);
- }
-}
-
-void
-meta_kms_page_flip_data_mode_set_fallback_in_impl (MetaKmsPageFlipData *page_flip_data)
-{
- MetaKms *kms = meta_kms_from_impl_device (page_flip_data->impl_device);
-
- meta_assert_in_kms_impl (kms);
-
- meta_kms_queue_callback (kms,
- meta_kms_page_flip_data_mode_set_fallback,
- 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;
- GList *l;
-
- meta_assert_not_in_kms_impl (kms);
-
- for (l = page_flip_data->closures; l; l = l->next)
- {
- MetaKmsPageFlipClosure *closure = l->data;
-
- closure->vtable->discarded (page_flip_data->crtc,
- closure->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_from_impl_device (page_flip_data->impl_device);
-
- 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,
- 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
deleted file mode 100644
index 92f9cfcc9..000000000
--- a/src/backends/native/meta-kms-plane-private.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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"
-
-typedef enum _MetaKmsPlaneProp
-{
- META_KMS_PLANE_PROP_TYPE = 0,
- META_KMS_PLANE_PROP_ROTATION,
- META_KMS_PLANE_PROP_IN_FORMATS,
- META_KMS_PLANE_PROP_SRC_X,
- META_KMS_PLANE_PROP_SRC_Y,
- META_KMS_PLANE_PROP_SRC_W,
- META_KMS_PLANE_PROP_SRC_H,
- META_KMS_PLANE_PROP_CRTC_X,
- META_KMS_PLANE_PROP_CRTC_Y,
- META_KMS_PLANE_PROP_CRTC_W,
- META_KMS_PLANE_PROP_CRTC_H,
- META_KMS_PLANE_PROP_FB_ID,
- META_KMS_PLANE_PROP_CRTC_ID,
- META_KMS_PLANE_N_PROPS
-} MetaKmsPlaneProp;
-
-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);
-
-uint32_t meta_kms_plane_get_prop_id (MetaKmsPlane *plane,
- MetaKmsPlaneProp prop);
-
-const char * meta_kms_plane_get_prop_name (MetaKmsPlane *plane,
- MetaKmsPlaneProp prop);
-
-MetaKmsPropType meta_kms_plane_get_prop_internal_type (MetaKmsPlane *plane,
- MetaKmsPlaneProp prop);
-
-#endif /* META_KMS_PLANE_PRIVATE_H */
diff --git a/src/backends/native/meta-kms-plane.c b/src/backends/native/meta-kms-plane.c
deleted file mode 100644
index 73fab7d8f..000000000
--- a/src/backends/native/meta-kms-plane.c
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * 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"
-
-typedef struct _MetaKmsPlanePropTable
-{
- MetaKmsProp props[META_KMS_PLANE_N_PROPS];
-} MetaKmsPlanePropTable;
-
-struct _MetaKmsPlane
-{
- GObject parent;
-
- MetaKmsPlaneType type;
- gboolean is_fake;
-
- uint32_t id;
-
- uint32_t possible_crtcs;
-
- 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;
-
- MetaKmsPlanePropTable prop_table;
-
- 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;
-}
-
-uint32_t
-meta_kms_plane_get_prop_id (MetaKmsPlane *plane,
- MetaKmsPlaneProp prop)
-{
- return plane->prop_table.props[prop].prop_id;
-}
-
-const char *
-meta_kms_plane_get_prop_name (MetaKmsPlane *plane,
- MetaKmsPlaneProp prop)
-{
- return plane->prop_table.props[prop].name;
-}
-
-MetaKmsPropType
-meta_kms_plane_get_prop_internal_type (MetaKmsPlane *plane,
- MetaKmsPlaneProp prop)
-{
- return plane->prop_table.props[prop].internal_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_rotation (plane_assignment,
- 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 (MetaKmsImplDevice *impl_device,
- MetaKmsProp *prop,
- drmModePropertyPtr drm_prop,
- uint64_t drm_prop_value,
- gpointer user_data)
-{
- MetaKmsPlane *plane = user_data;
- int i;
-
- for (i = 0; i < drm_prop->count_enums; i++)
- {
- MetaMonitorTransform transform = -1;
-
- if (strcmp (drm_prop->enums[i].name, "rotate-0") == 0)
- transform = META_MONITOR_TRANSFORM_NORMAL;
- else if (strcmp (drm_prop->enums[i].name, "rotate-90") == 0)
- transform = META_MONITOR_TRANSFORM_90;
- else if (strcmp (drm_prop->enums[i].name, "rotate-180") == 0)
- transform = META_MONITOR_TRANSFORM_180;
- else if (strcmp (drm_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 << drm_prop->enums[i].value;
- }
- }
-}
-
-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 (MetaKmsImplDevice *impl_device,
- MetaKmsProp *prop,
- drmModePropertyPtr drm_prop,
- uint64_t drm_prop_value,
- gpointer user_data)
-{
- MetaKmsPlane *plane = user_data;
- uint64_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);
-
- blob_id = drm_prop_value;
- 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_legacy_formats (MetaKmsPlane *plane,
- MetaKmsImplDevice *impl_device,
- drmModePlane *drm_plane,
- drmModeObjectProperties *drm_plane_props)
-{
- 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));
- }
-}
-
-static void
-init_properties (MetaKmsPlane *plane,
- MetaKmsImplDevice *impl_device,
- drmModePlane *drm_plane,
- drmModeObjectProperties *drm_plane_props)
-{
- MetaKmsPlanePropTable *prop_table = &plane->prop_table;
-
- *prop_table = (MetaKmsPlanePropTable) {
- .props = {
- [META_KMS_PLANE_PROP_TYPE] =
- {
- .name = "type",
- .type = DRM_MODE_PROP_ENUM,
- },
- [META_KMS_PLANE_PROP_ROTATION] =
- {
- .name = "rotation",
- .type = DRM_MODE_PROP_BITMASK,
- .parse = parse_rotations,
- },
- [META_KMS_PLANE_PROP_IN_FORMATS] =
- {
- .name = "IN_FORMATS",
- .type = DRM_MODE_PROP_BLOB,
- .parse = parse_formats,
- },
- [META_KMS_PLANE_PROP_SRC_X] =
- {
- .name = "SRC_X",
- .type = DRM_MODE_PROP_RANGE,
- .internal_type = META_KMS_PROP_TYPE_FIXED_16,
- },
- [META_KMS_PLANE_PROP_SRC_Y] =
- {
- .name = "SRC_Y",
- .type = DRM_MODE_PROP_RANGE,
- .internal_type = META_KMS_PROP_TYPE_FIXED_16,
- },
- [META_KMS_PLANE_PROP_SRC_W] =
- {
- .name = "SRC_W",
- .type = DRM_MODE_PROP_RANGE,
- .internal_type = META_KMS_PROP_TYPE_FIXED_16,
- },
- [META_KMS_PLANE_PROP_SRC_H] =
- {
- .name = "SRC_H",
- .type = DRM_MODE_PROP_RANGE,
- .internal_type = META_KMS_PROP_TYPE_FIXED_16,
- },
- [META_KMS_PLANE_PROP_CRTC_X] =
- {
- .name = "CRTC_X",
- .type = DRM_MODE_PROP_SIGNED_RANGE,
- },
- [META_KMS_PLANE_PROP_CRTC_Y] =
- {
- .name = "CRTC_Y",
- .type = DRM_MODE_PROP_SIGNED_RANGE,
- },
- [META_KMS_PLANE_PROP_CRTC_W] =
- {
- .name = "CRTC_W",
- .type = DRM_MODE_PROP_RANGE,
- },
- [META_KMS_PLANE_PROP_CRTC_H] =
- {
- .name = "CRTC_H",
- .type = DRM_MODE_PROP_RANGE,
- },
- [META_KMS_PLANE_PROP_FB_ID] =
- {
- .name = "FB_ID",
- .type = DRM_MODE_PROP_OBJECT,
- },
- [META_KMS_PLANE_PROP_CRTC_ID] =
- {
- .name = "CRTC_ID",
- .type = DRM_MODE_PROP_OBJECT,
- },
- }
- };
-
- meta_kms_impl_device_init_prop_table (impl_device,
- drm_plane_props->props,
- drm_plane_props->prop_values,
- drm_plane_props->count_props,
- plane->prop_table.props,
- META_KMS_PLANE_N_PROPS,
- plane);
-}
-
-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_properties (plane, impl_device, drm_plane, drm_plane_props);
- init_legacy_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
deleted file mode 100644
index 941c16680..000000000
--- a/src/backends/native/meta-kms-plane.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 8d0954c72..000000000
--- a/src/backends/native/meta-kms-private.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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);
-
-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
deleted file mode 100644
index 5786ff51f..000000000
--- a/src/backends/native/meta-kms-types.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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 _MetaKmsMode MetaKmsMode;
-
-typedef struct _MetaKmsFeedback MetaKmsFeedback;
-
-typedef struct _MetaKmsPageFlipListenerVtable MetaKmsPageFlipListenerVtable;
-typedef enum _MetaKmsPageFlipListenerFlag MetaKmsPageFlipListenerFlag;
-
-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,
- META_KMS_DEVICE_FLAG_DISABLE_MODIFIERS = 1 << 2,
- META_KMS_DEVICE_FLAG_PREFERRED_PRIMARY = 1 << 3,
- META_KMS_DEVICE_FLAG_NO_MODE_SETTING = 1 << 4,
-} MetaKmsDeviceFlag;
-
-typedef enum _MetaKmsPlaneType MetaKmsPlaneType;
-
-typedef enum _MetaKmsPropType
-{
- META_KMS_PROP_TYPE_RAW = 0,
- META_KMS_PROP_TYPE_FIXED_16,
-} MetaKmsPropType;
-
-#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
deleted file mode 100644
index 22491ece2..000000000
--- a/src/backends/native/meta-kms-update-private.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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 _MetaKmsPlaneAssignment
-{
- MetaKmsUpdate *update;
- MetaKmsCrtc *crtc;
- MetaKmsPlane *plane;
- MetaDrmBuffer *buffer;
- MetaFixed16Rectangle src_rect;
- MetaRectangle dst_rect;
- MetaKmsAssignPlaneFlag flags;
-
- uint64_t rotation;
-
- struct {
- gboolean is_valid;
- int x;
- int y;
- } cursor_hotspot;
-} MetaKmsPlaneAssignment;
-
-typedef struct _MetaKmsModeSet
-{
- MetaKmsCrtc *crtc;
- GList *connectors;
- MetaKmsMode *mode;
-} MetaKmsModeSet;
-
-typedef struct _MetaKmsConnectorUpdate
-{
- MetaKmsConnector *connector;
-
- struct {
- gboolean has_update;
- gboolean is_active;
- uint64_t hborder;
- uint64_t vborder;
- } underscanning;
-} MetaKmsConnectorUpdate;
-
-typedef struct _MetaKmsPageFlipListener
-{
- MetaKmsCrtc *crtc;
- const MetaKmsPageFlipListenerVtable *vtable;
- MetaKmsPageFlipListenerFlag flags;
- gpointer user_data;
- GDestroyNotify destroy_notify;
-} MetaKmsPageFlipListener;
-
-typedef struct _MetaKmsResultListener
-{
- MetaKmsResultListenerFunc func;
- gpointer user_data;
-} MetaKmsResultListener;
-
-typedef struct _MetaKmsCustomPageFlip
-{
- MetaKmsCustomPageFlipFunc func;
- gpointer user_data;
-} MetaKmsCustomPageFlip;
-
-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 (GList *failed_planes);
-
-MetaKmsFeedback * meta_kms_feedback_new_failed (GList *failed_planes,
- GError *error);
-
-void meta_kms_update_lock (MetaKmsUpdate *update);
-
-void meta_kms_update_unlock (MetaKmsUpdate *update);
-
-gboolean meta_kms_update_is_locked (MetaKmsUpdate *update);
-
-uint64_t meta_kms_update_get_sequence_number (MetaKmsUpdate *update);
-
-MetaKmsDevice * meta_kms_update_get_device (MetaKmsUpdate *update);
-
-void meta_kms_plane_assignment_set_rotation (MetaKmsPlaneAssignment *plane_assignment,
- uint64_t rotation);
-
-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_flip_listeners (MetaKmsUpdate *update);
-
-void meta_kms_update_drop_defunct_page_flip_listeners (MetaKmsUpdate *update);
-
-GList * meta_kms_update_get_connector_updates (MetaKmsUpdate *update);
-
-GList * meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update);
-
-gboolean meta_kms_update_is_power_save (MetaKmsUpdate *update);
-
-MetaKmsCustomPageFlip * meta_kms_update_take_custom_page_flip_func (MetaKmsUpdate *update);
-
-void meta_kms_update_drop_plane_assignment (MetaKmsUpdate *update,
- MetaKmsPlane *plane);
-
-GList * meta_kms_update_take_result_listeners (MetaKmsUpdate *update);
-
-void meta_kms_result_listener_notify (MetaKmsResultListener *listener,
- const MetaKmsFeedback *feedback);
-
-void meta_kms_result_listener_free (MetaKmsResultListener *listener);
-
-void meta_kms_custom_page_flip_free (MetaKmsCustomPageFlip *custom_page_flip);
-
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKmsPlaneFeedback,
- meta_kms_plane_feedback_free)
-
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKmsCustomPageFlip,
- meta_kms_custom_page_flip_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
deleted file mode 100644
index be6eaefcc..000000000
--- a/src/backends/native/meta-kms-update.c
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
- * 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-connector.h"
-#include "backends/native/meta-kms-crtc.h"
-#include "backends/native/meta-kms-mode-private.h"
-#include "backends/native/meta-kms-plane.h"
-
-struct _MetaKmsUpdate
-{
- MetaKmsDevice *device;
-
- gboolean is_locked;
- uint64_t sequence_number;
-
- gboolean power_save;
-
- GList *mode_sets;
- GList *plane_assignments;
- GList *connector_updates;
- GList *crtc_gammas;
-
- MetaKmsCustomPageFlip *custom_page_flip;
-
- GList *page_flip_listeners;
- GList *result_listeners;
-};
-
-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 (GList *failed_planes)
-{
- MetaKmsFeedback *feedback;
-
- feedback = g_new0 (MetaKmsFeedback, 1);
- *feedback = (MetaKmsFeedback) {
- .result = META_KMS_FEEDBACK_PASSED,
- .failed_planes = failed_planes,
- };
-
- 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 (const MetaKmsFeedback *feedback)
-{
- return feedback->result;
-}
-
-GList *
-meta_kms_feedback_get_failed_planes (const MetaKmsFeedback *feedback)
-{
- return feedback->failed_planes;
-}
-
-const GError *
-meta_kms_feedback_get_error (const MetaKmsFeedback *feedback)
-{
- return feedback->error;
-}
-
-static void
-meta_kms_plane_assignment_free (MetaKmsPlaneAssignment *plane_assignment)
-{
- g_free (plane_assignment);
-}
-
-static void
-meta_kms_mode_set_free (MetaKmsModeSet *mode_set)
-{
- g_list_free (mode_set->connectors);
- g_free (mode_set);
-}
-
-static void
-meta_kms_page_flip_listener_free (MetaKmsPageFlipListener *listener)
-{
- g_clear_pointer (&listener->user_data, listener->destroy_notify);
- g_free (listener);
-}
-
-static gboolean
-drop_plane_assignment (MetaKmsUpdate *update,
- MetaKmsPlane *plane,
- MetaKmsAssignPlaneFlag *out_flags)
-{
- GList *l;
-
- for (l = update->plane_assignments; l; l = l->next)
- {
- MetaKmsPlaneAssignment *plane_assignment = l->data;
-
- if (plane_assignment->plane == plane)
- {
- update->plane_assignments =
- g_list_delete_link (update->plane_assignments, l);
- if (out_flags)
- *out_flags = plane_assignment->flags;
- meta_kms_plane_assignment_free (plane_assignment);
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-void
-meta_kms_update_drop_plane_assignment (MetaKmsUpdate *update,
- MetaKmsPlane *plane)
-{
- drop_plane_assignment (update, plane, NULL);
-}
-
-MetaKmsPlaneAssignment *
-meta_kms_update_assign_plane (MetaKmsUpdate *update,
- MetaKmsCrtc *crtc,
- MetaKmsPlane *plane,
- MetaDrmBuffer *buffer,
- MetaFixed16Rectangle src_rect,
- MetaRectangle dst_rect,
- MetaKmsAssignPlaneFlag flags)
-{
- MetaKmsPlaneAssignment *plane_assignment;
- MetaKmsAssignPlaneFlag old_flags;
-
- g_assert (!meta_kms_update_is_locked (update));
- g_assert (meta_kms_crtc_get_device (crtc) == update->device);
- g_assert (!update->power_save);
- g_assert (meta_kms_plane_get_device (plane) == update->device);
- g_assert (meta_kms_plane_get_plane_type (plane) !=
- META_KMS_PLANE_TYPE_PRIMARY ||
- !(flags & META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL));
-
- if (drop_plane_assignment (update, plane, &old_flags))
- {
- if (!(old_flags & META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED))
- flags &= ~META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED;
- }
-
- plane_assignment = g_new0 (MetaKmsPlaneAssignment, 1);
- *plane_assignment = (MetaKmsPlaneAssignment) {
- .update = update,
- .crtc = crtc,
- .plane = plane,
- .buffer = buffer,
- .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_locked (update));
- g_assert (meta_kms_crtc_get_device (crtc) == update->device);
- g_assert (meta_kms_plane_get_device (plane) == update->device);
- g_assert (!update->power_save);
-
- plane_assignment = g_new0 (MetaKmsPlaneAssignment, 1);
- *plane_assignment = (MetaKmsPlaneAssignment) {
- .update = update,
- .crtc = crtc,
- .plane = plane,
- .buffer = NULL,
- };
-
- 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,
- MetaKmsMode *mode)
-{
- MetaKmsModeSet *mode_set;
-
- g_assert (!meta_kms_update_is_locked (update));
- g_assert (meta_kms_crtc_get_device (crtc) == update->device);
- g_assert (!update->power_save);
-
- mode_set = g_new0 (MetaKmsModeSet, 1);
- *mode_set = (MetaKmsModeSet) {
- .crtc = crtc,
- .connectors = connectors,
- .mode = mode,
- };
-
- update->mode_sets = g_list_prepend (update->mode_sets, mode_set);
-}
-
-static MetaKmsConnectorUpdate *
-ensure_connector_update (MetaKmsUpdate *update,
- MetaKmsConnector *connector)
-{
- GList *l;
- MetaKmsConnectorUpdate *connector_update;
-
- for (l = update->connector_updates; l; l = l->next)
- {
- connector_update = l->data;
-
- if (connector_update->connector == connector)
- return connector_update;
- }
-
- connector_update = g_new0 (MetaKmsConnectorUpdate, 1);
- connector_update->connector = connector;
-
- update->connector_updates = g_list_prepend (update->connector_updates,
- connector_update);
-
- return connector_update;
-}
-
-void
-meta_kms_update_set_underscanning (MetaKmsUpdate *update,
- MetaKmsConnector *connector,
- uint64_t hborder,
- uint64_t vborder)
-{
- MetaKmsConnectorUpdate *connector_update;
-
- g_assert (!meta_kms_update_is_locked (update));
- g_assert (meta_kms_connector_get_device (connector) == update->device);
- g_assert (!update->power_save);
-
- connector_update = ensure_connector_update (update, connector);
- connector_update->underscanning.has_update = TRUE;
- connector_update->underscanning.is_active = TRUE;
- connector_update->underscanning.hborder = hborder;
- connector_update->underscanning.vborder = vborder;
-}
-
-void
-meta_kms_update_unset_underscanning (MetaKmsUpdate *update,
- MetaKmsConnector *connector)
-{
- MetaKmsConnectorUpdate *connector_update;
-
- g_assert (!meta_kms_update_is_locked (update));
- g_assert (meta_kms_connector_get_device (connector) == update->device);
- g_assert (!update->power_save);
-
- connector_update = ensure_connector_update (update, connector);
- connector_update->underscanning.has_update = TRUE;
- connector_update->underscanning.is_active = FALSE;
-}
-
-void
-meta_kms_update_set_power_save (MetaKmsUpdate *update)
-{
- g_assert (!meta_kms_update_is_locked (update));
- g_assert (!update->mode_sets);
- g_assert (!update->plane_assignments);
- g_assert (!update->connector_updates);
- g_assert (!update->crtc_gammas);
-
- update->power_save = TRUE;
-}
-
-void
-meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *gamma)
-{
- g_free (gamma->red);
- g_free (gamma->green);
- g_free (gamma->blue);
- g_free (gamma);
-}
-
-MetaKmsCrtcGamma *
-meta_kms_crtc_gamma_new (MetaKmsCrtc *crtc,
- int size,
- const uint16_t *red,
- const uint16_t *green,
- const uint16_t *blue)
-{
- MetaKmsCrtcGamma *gamma;
-
- gamma = g_new0 (MetaKmsCrtcGamma, 1);
- *gamma = (MetaKmsCrtcGamma) {
- .crtc = crtc,
- .size = size,
- .red = g_memdup2 (red, size * sizeof (*red)),
- .green = g_memdup2 (green, size * sizeof (*green)),
- .blue = g_memdup2 (blue, size * sizeof (*blue)),
- };
-
- return 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_locked (update));
- g_assert (meta_kms_crtc_get_device (crtc) == update->device);
- g_assert (!update->power_save);
-
- gamma = meta_kms_crtc_gamma_new (crtc, size, red, green, blue);
-
- update->crtc_gammas = g_list_prepend (update->crtc_gammas, gamma);
-}
-
-void
-meta_kms_update_add_page_flip_listener (MetaKmsUpdate *update,
- MetaKmsCrtc *crtc,
- const MetaKmsPageFlipListenerVtable *vtable,
- MetaKmsPageFlipListenerFlag flags,
- gpointer user_data,
- GDestroyNotify destroy_notify)
-{
- MetaKmsPageFlipListener *listener;
-
- g_assert (!meta_kms_update_is_locked (update));
- g_assert (meta_kms_crtc_get_device (crtc) == update->device);
-
- listener = g_new0 (MetaKmsPageFlipListener, 1);
- *listener = (MetaKmsPageFlipListener) {
- .crtc = crtc,
- .vtable = vtable,
- .flags = flags,
- .user_data = user_data,
- .destroy_notify = destroy_notify,
- };
-
- update->page_flip_listeners = g_list_prepend (update->page_flip_listeners,
- listener);
-}
-
-void
-meta_kms_update_drop_defunct_page_flip_listeners (MetaKmsUpdate *update)
-{
- GList *l;
-
- l = update->page_flip_listeners;
- while (l)
- {
- MetaKmsPageFlipListener *listener = l->data;
- GList *l_next = l->next;
-
- if (listener->flags & META_KMS_PAGE_FLIP_LISTENER_FLAG_DROP_ON_ERROR)
- {
- meta_kms_page_flip_listener_free (listener);
- update->page_flip_listeners =
- g_list_delete_link (update->page_flip_listeners, l);
- }
-
- l = l_next;
- }
-}
-
-void
-meta_kms_update_set_custom_page_flip (MetaKmsUpdate *update,
- MetaKmsCustomPageFlipFunc func,
- gpointer user_data)
-{
- MetaKmsCustomPageFlip *custom_page_flip;
-
- g_assert (!meta_kms_update_is_locked (update));
- g_assert (!update->power_save);
-
- custom_page_flip = g_new0 (MetaKmsCustomPageFlip, 1);
- custom_page_flip->func = func;
- custom_page_flip->user_data = user_data;
-
- update->custom_page_flip = custom_page_flip;
-}
-
-void
-meta_kms_plane_assignment_set_rotation (MetaKmsPlaneAssignment *plane_assignment,
- uint64_t rotation)
-{
- g_assert (!meta_kms_update_is_locked (plane_assignment->update));
- g_warn_if_fail (rotation);
-
- plane_assignment->rotation = rotation;
-}
-
-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;
-}
-
-void
-meta_kms_update_add_result_listener (MetaKmsUpdate *update,
- MetaKmsResultListenerFunc func,
- gpointer user_data)
-{
- MetaKmsResultListener *listener;
-
- listener = g_new0 (MetaKmsResultListener, 1);
- *listener = (MetaKmsResultListener) {
- .func = func,
- .user_data = user_data,
- };
-
- update->result_listeners = g_list_append (update->result_listeners,
- listener);
-}
-
-GList *
-meta_kms_update_take_result_listeners (MetaKmsUpdate *update)
-{
- return g_steal_pointer (&update->result_listeners);
-}
-
-void
-meta_kms_result_listener_notify (MetaKmsResultListener *listener,
- const MetaKmsFeedback *feedback)
-{
- listener->func (feedback, listener->user_data);
-}
-
-void
-meta_kms_result_listener_free (MetaKmsResultListener *listener)
-{
- g_free (listener);
-}
-
-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 (meta_kms_plane_get_plane_type (plane_assignment->plane) !=
- META_KMS_PLANE_TYPE_PRIMARY)
- continue;
-
- if (plane_assignment->crtc != crtc)
- continue;
-
- 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_flip_listeners (MetaKmsUpdate *update)
-{
- return update->page_flip_listeners;
-}
-
-GList *
-meta_kms_update_get_connector_updates (MetaKmsUpdate *update)
-{
- return update->connector_updates;
-}
-
-GList *
-meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update)
-{
- return update->crtc_gammas;
-}
-
-gboolean
-meta_kms_update_is_power_save (MetaKmsUpdate *update)
-{
- return update->power_save;
-}
-
-void
-meta_kms_update_lock (MetaKmsUpdate *update)
-{
- update->is_locked = TRUE;
-}
-
-void
-meta_kms_update_unlock (MetaKmsUpdate *update)
-{
- update->is_locked = FALSE;
-}
-
-gboolean
-meta_kms_update_is_locked (MetaKmsUpdate *update)
-{
- return update->is_locked;
-}
-
-MetaKmsDevice *
-meta_kms_update_get_device (MetaKmsUpdate *update)
-{
- return update->device;
-}
-
-MetaKmsCustomPageFlip *
-meta_kms_update_take_custom_page_flip_func (MetaKmsUpdate *update)
-{
- return g_steal_pointer (&update->custom_page_flip);
-}
-
-void
-meta_kms_custom_page_flip_free (MetaKmsCustomPageFlip *custom_page_flip)
-{
- g_free (custom_page_flip);
-}
-
-uint64_t
-meta_kms_update_get_sequence_number (MetaKmsUpdate *update)
-{
- return update->sequence_number;
-}
-
-MetaKmsUpdate *
-meta_kms_update_new (MetaKmsDevice *device)
-{
- MetaKmsUpdate *update;
- static uint64_t sequence_number = 0;
-
- update = g_new0 (MetaKmsUpdate, 1);
- update->device = device;
- update->sequence_number = sequence_number++;
-
- return update;
-}
-
-void
-meta_kms_update_free (MetaKmsUpdate *update)
-{
- g_list_free_full (update->result_listeners,
- (GDestroyNotify) meta_kms_result_listener_free);
- 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_flip_listeners,
- (GDestroyNotify) meta_kms_page_flip_listener_free);
- g_list_free_full (update->connector_updates, g_free);
- g_list_free_full (update->crtc_gammas, (GDestroyNotify) meta_kms_crtc_gamma_free);
- g_clear_pointer (&update->custom_page_flip, meta_kms_custom_page_flip_free);
-
- g_free (update);
-}
diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h
deleted file mode 100644
index 4a6a8bb43..000000000
--- a/src/backends/native/meta-kms-update.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * 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-drm-buffer.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,
- META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL = 1 << 1,
-} MetaKmsAssignPlaneFlag;
-
-enum _MetaKmsPageFlipListenerFlag
-{
- META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE = 0,
- META_KMS_PAGE_FLIP_LISTENER_FLAG_DROP_ON_ERROR = 1 << 0,
-};
-
-struct _MetaKmsPageFlipListenerVtable
-{
- void (* flipped) (MetaKmsCrtc *crtc,
- unsigned int sequence,
- unsigned int tv_sec,
- unsigned int tv_usec,
- gpointer user_data);
-
- void (* ready) (MetaKmsCrtc *crtc,
- 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;
-
-typedef void (* MetaKmsResultListenerFunc) (const MetaKmsFeedback *feedback,
- gpointer user_data);
-
-void meta_kms_feedback_free (MetaKmsFeedback *feedback);
-
-MetaKmsFeedbackResult meta_kms_feedback_get_result (const MetaKmsFeedback *feedback);
-
-GList * meta_kms_feedback_get_failed_planes (const MetaKmsFeedback *feedback);
-
-const GError * meta_kms_feedback_get_error (const MetaKmsFeedback *feedback);
-
-MetaKmsUpdate * meta_kms_update_new (MetaKmsDevice *device);
-
-void meta_kms_update_free (MetaKmsUpdate *update);
-
-void meta_kms_update_set_underscanning (MetaKmsUpdate *update,
- MetaKmsConnector *connector,
- uint64_t hborder,
- uint64_t vborder);
-
-void meta_kms_update_unset_underscanning (MetaKmsUpdate *update,
- MetaKmsConnector *connector);
-
-void meta_kms_update_set_power_save (MetaKmsUpdate *update);
-
-void meta_kms_update_mode_set (MetaKmsUpdate *update,
- MetaKmsCrtc *crtc,
- GList *connectors,
- MetaKmsMode *mode);
-
-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);
-
-MetaKmsPlaneAssignment * meta_kms_update_assign_plane (MetaKmsUpdate *update,
- MetaKmsCrtc *crtc,
- MetaKmsPlane *plane,
- MetaDrmBuffer *buffer,
- MetaFixed16Rectangle src_rect,
- MetaRectangle dst_rect,
- MetaKmsAssignPlaneFlag flags);
-
-MetaKmsPlaneAssignment * meta_kms_update_unassign_plane (MetaKmsUpdate *update,
- MetaKmsCrtc *crtc,
- MetaKmsPlane *plane);
-
-void meta_kms_update_add_page_flip_listener (MetaKmsUpdate *update,
- MetaKmsCrtc *crtc,
- const MetaKmsPageFlipListenerVtable *vtable,
- MetaKmsPageFlipListenerFlag flags,
- gpointer user_data,
- GDestroyNotify destroy_notify);
-
-void meta_kms_update_set_custom_page_flip (MetaKmsUpdate *update,
- MetaKmsCustomPageFlipFunc func,
- gpointer user_data);
-
-void meta_kms_plane_assignment_set_cursor_hotspot (MetaKmsPlaneAssignment *plane_assignment,
- int x,
- int y);
-
-void meta_kms_update_add_result_listener (MetaKmsUpdate *update,
- MetaKmsResultListenerFunc func,
- gpointer user_data);
-
-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 double
-meta_fixed_16_to_double (MetaFixed16 fixed)
-{
- return fixed / 65536.0;
-}
-
-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
deleted file mode 100644
index 2289cfa91..000000000
--- a/src/backends/native/meta-kms-utils.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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)
-{
- double numerator;
- double denominator;
-
- if (drm_mode->htotal <= 0 || drm_mode->vtotal <= 0)
- return 0.0;
-
- numerator = drm_mode->clock * 1000.0;
- denominator = (double) drm_mode->vtotal * drm_mode->htotal;
- if (drm_mode->vscan > 1)
- denominator *= drm_mode->vscan;
-
- return numerator / denominator;
-}
-
-int64_t
-meta_calculate_drm_mode_vblank_duration_us (const drmModeModeInfo *drm_mode)
-{
- int64_t value;
-
- if (drm_mode->htotal <= 0 || drm_mode->vtotal <= 0)
- return 0;
-
- /* Convert to int64_t early. */
- value = drm_mode->vtotal - drm_mode->vdisplay;
- value *= drm_mode->htotal;
-
- if (drm_mode->flags & DRM_MODE_FLAG_DBLSCAN)
- value *= 2;
-
- /* Round the duration up as it is used for buffer swap deadline computation. */
- value = (value * 1000 + drm_mode->clock - 1) / drm_mode->clock;
-
- return value;
-}
-
-/**
- * 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
deleted file mode 100644
index 2f2bad1f9..000000000
--- a/src/backends/native/meta-kms-utils.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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>
-
-#include "core/util-private.h"
-
-typedef struct _MetaDrmFormatBuf
-{
- char s[5];
-} MetaDrmFormatBuf;
-
-META_EXPORT_TEST
-float meta_calculate_drm_mode_refresh_rate (const drmModeModeInfo *drm_mode);
-
-META_EXPORT_TEST
-int64_t meta_calculate_drm_mode_vblank_duration_us (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
deleted file mode 100644
index 70feccc22..000000000
--- a/src/backends/native/meta-kms.c
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
- * 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-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.
- *
- * #MetaKmsMode:
- *
- * Represents a mode a CRTC and connector can be configured with.
- * Represents both modes directly derived from the devices, as well as
- * fall back modes when the CRTC supports scaling.
- *
- * #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. Each #MetaKmsUpdate deals with
- * updating a single device.
- *
- *
- * There are also these private objects, without public facing API:
- *
- * #MetaKmsImpl:
- *
- * The KMS impl context object, managing things in the impl context.
- *
- * #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.
- *
- * This is an abstract type, with currently #MetaKmsImplDeviceSimple,
- * implementing mode setting and page flipping using legacy DRM API.
- *
- * #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;
-
- MetaKmsFlags flags;
-
- MetaBackend *backend;
-
- gulong hotplug_handler_id;
- gulong removed_handler_id;
-
- MetaKmsImpl *impl;
- gboolean in_impl_task;
- gboolean waiting_for_impl_task;
-
- GList *devices;
-
- GList *pending_updates;
-
- GList *pending_callbacks;
- guint callback_source_id;
-};
-
-G_DEFINE_TYPE (MetaKms, meta_kms, G_TYPE_OBJECT)
-
-static void
-meta_kms_add_pending_update (MetaKms *kms,
- MetaKmsUpdate *update)
-{
- kms->pending_updates = g_list_prepend (kms->pending_updates, update);
-}
-
-MetaKmsUpdate *
-meta_kms_ensure_pending_update (MetaKms *kms,
- MetaKmsDevice *device)
-{
- MetaKmsUpdate *update;
-
- update = meta_kms_get_pending_update (kms, device);
- if (update)
- return update;
-
- update = meta_kms_update_new (device);
- meta_kms_add_pending_update (kms, update);
-
- return update;
-}
-
-MetaKmsUpdate *
-meta_kms_get_pending_update (MetaKms *kms,
- MetaKmsDevice *device)
-{
- GList *l;
-
- for (l = kms->pending_updates; l; l = l->next)
- {
- MetaKmsUpdate *update = l->data;
-
- if (meta_kms_update_get_device (update) == device)
- return update;
- }
-
- return NULL;
-}
-
-static MetaKmsUpdate *
-meta_kms_take_pending_update (MetaKms *kms,
- MetaKmsDevice *device)
-{
- GList *l;
-
- for (l = kms->pending_updates; l; l = l->next)
- {
- MetaKmsUpdate *update = l->data;
-
- if (meta_kms_update_get_device (update) == device)
- {
- kms->pending_updates = g_list_delete_link (kms->pending_updates, l);
- return update;
- }
- }
-
- return NULL;
-}
-
-typedef struct
-{
- MetaKmsUpdate *update;
- MetaKmsUpdateFlag flags;
-} PostUpdateData;
-
-static gpointer
-meta_kms_process_update_in_impl (MetaKmsImpl *impl,
- gpointer user_data,
- GError **error)
-{
- PostUpdateData *data = user_data;
- MetaKmsUpdate *update = data->update;
- MetaKmsFeedback *feedback;
-
- feedback = meta_kms_impl_process_update (impl, data->update, data->flags);
- meta_kms_device_predict_states_in_impl (meta_kms_update_get_device (update),
- update);
-
- return feedback;
-}
-
-MetaKmsFeedback *
-meta_kms_post_pending_update_sync (MetaKms *kms,
- MetaKmsDevice *device,
- MetaKmsUpdateFlag flags)
-{
- MetaKmsUpdate *update;
- PostUpdateData data;
- MetaKmsFeedback *feedback;
- GList *result_listeners;
- GList *l;
-
- COGL_TRACE_BEGIN_SCOPED (MetaKmsPostUpdateSync,
- "KMS (post update)");
-
- update = meta_kms_take_pending_update (kms, device);
- if (!update)
- return NULL;
-
- meta_kms_update_lock (update);
-
- data = (PostUpdateData) {
- .update = update,
- .flags = flags,
- };
- feedback = meta_kms_run_impl_task_sync (kms,
- meta_kms_process_update_in_impl,
- &data,
- NULL);
-
- result_listeners = meta_kms_update_take_result_listeners (update);
-
- if (feedback->error &&
- flags & META_KMS_UPDATE_FLAG_PRESERVE_ON_ERROR)
- {
- GList *l;
-
- meta_kms_update_unlock (update);
-
- for (l = feedback->failed_planes; l; l = l->next)
- {
- MetaKmsPlane *plane = l->data;
-
- meta_kms_update_drop_plane_assignment (update, plane);
- }
-
- meta_kms_update_drop_defunct_page_flip_listeners (update);
-
- meta_kms_add_pending_update (kms, update);
- }
- else
- {
- meta_kms_update_free (update);
- }
-
- for (l = result_listeners; l; l = l->next)
- {
- MetaKmsResultListener *listener = l->data;
-
- meta_kms_result_listener_notify (listener, feedback);
- meta_kms_result_listener_free (listener);
- }
- g_list_free (result_listeners);
-
- return feedback;
-}
-
-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 gpointer
-meta_kms_notify_modes_set_in_impl (MetaKmsImpl *impl,
- gpointer user_data,
- GError **error)
-{
- meta_kms_impl_notify_modes_set (impl);
- return GINT_TO_POINTER (TRUE);
-}
-
-void
-meta_kms_notify_modes_set (MetaKms *kms)
-{
- meta_kms_run_impl_task_sync (kms,
- meta_kms_notify_modes_set_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_free (callback_data);
-}
-
-static int
-flush_callbacks (MetaKms *kms)
-{
- GList *l;
- int callback_count = 0;
-
- meta_assert_not_in_kms_impl (kms);
-
- g_clear_handle_id (&kms->callback_source_id, g_source_remove);
-
- 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_new0 (MetaKmsCallbackData, 1);
- *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);
-}
-
-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);
-}
-
-void
-meta_kms_resume (MetaKms *kms)
-{
- handle_hotplug_event (kms);
-}
-
-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;
-}
-
-GList *
-meta_kms_get_devices (MetaKms *kms)
-{
- return kms->devices;
-}
-
-MetaKmsDevice *
-meta_kms_create_device (MetaKms *kms,
- const char *path,
- MetaKmsDeviceFlag flags,
- GError **error)
-{
- MetaKmsDevice *device;
-
- if (kms->flags & META_KMS_FLAG_NO_MODE_SETTING)
- flags |= META_KMS_DEVICE_FLAG_NO_MODE_SETTING;
-
- device = meta_kms_device_new (kms, path, flags, error);
- if (!device)
- return NULL;
-
- kms->devices = g_list_append (kms->devices, device);
-
- return device;
-}
-
-MetaKms *
-meta_kms_new (MetaBackend *backend,
- MetaKmsFlags flags,
- 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->flags = flags;
- kms->backend = backend;
- kms->impl = meta_kms_impl_new (kms);
- if (!kms->impl)
- {
- g_object_unref (kms);
- return NULL;
- }
-
- if (!(flags & META_KMS_FLAG_NO_MODE_SETTING))
- {
- 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 gpointer
-prepare_shutdown_in_impl (MetaKmsImpl *impl,
- gpointer user_data,
- GError **error)
-{
- meta_kms_impl_prepare_shutdown (impl);
- return GINT_TO_POINTER (TRUE);
-}
-
-void
-meta_kms_prepare_shutdown (MetaKms *kms)
-{
- meta_kms_run_impl_task_sync (kms, prepare_shutdown_in_impl, NULL, NULL);
- flush_callbacks (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
deleted file mode 100644
index 9eae80e3f..000000000
--- a/src/backends/native/meta-kms.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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"
-
-typedef enum _MetaKmsFlags
-{
- META_KMS_FLAG_NONE = 0,
- META_KMS_FLAG_NO_MODE_SETTING = 1 << 0,
-} MetaKmsFlags;
-
-typedef enum _MetaKmsUpdateFlag
-{
- META_KMS_UPDATE_FLAG_NONE = 0,
- META_KMS_UPDATE_FLAG_PRESERVE_ON_ERROR = 1 << 0,
-} MetaKmsUpdateFlag;
-
-#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,
- MetaKmsDevice *device);
-
-MetaKmsUpdate * meta_kms_get_pending_update (MetaKms *kms,
- MetaKmsDevice *device);
-
-MetaKmsFeedback * meta_kms_post_pending_update_sync (MetaKms *kms,
- MetaKmsDevice *device,
- MetaKmsUpdateFlag flags);
-
-void meta_kms_discard_pending_page_flips (MetaKms *kms);
-
-void meta_kms_notify_modes_set (MetaKms *kms);
-
-MetaBackend * meta_kms_get_backend (MetaKms *kms);
-
-GList * meta_kms_get_devices (MetaKms *kms);
-
-void meta_kms_resume (MetaKms *kms);
-
-MetaKmsDevice * meta_kms_create_device (MetaKms *kms,
- const char *path,
- MetaKmsDeviceFlag flags,
- GError **error);
-
-void meta_kms_prepare_shutdown (MetaKms *kms);
-
-MetaKms * meta_kms_new (MetaBackend *backend,
- MetaKmsFlags flags,
- GError **error);
-
-#endif /* META_KMS_H */
diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c
deleted file mode 100644
index 4a63d2feb..000000000
--- a/src/backends/native/meta-launcher.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * 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-input-thread.h"
-#include "backends/native/meta-renderer-native.h"
-#include "clutter/clutter.h"
-
-#include "meta-dbus-login1.h"
-
-struct _MetaLauncher
-{
- MetaDbusLogin1Session *session_proxy;
- MetaDbusLogin1Seat *seat_proxy;
- char *seat_id;
-
- 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 MetaDbusLogin1Session *
-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;
- GDBusProxyFlags flags;
- MetaDbusLogin1Session *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);
-
- flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
- session_proxy =
- meta_dbus_login1_session_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- flags,
- "org.freedesktop.login1",
- proxy_path,
- cancellable, error);
- if (!session_proxy)
- g_prefix_error(error, "Could not get session proxy: ");
-
- return session_proxy;
-}
-
-static MetaDbusLogin1Seat *
-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);
- GDBusProxyFlags flags;
- MetaDbusLogin1Seat *seat;
-
- flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
- seat =
- meta_dbus_login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- flags,
- "org.freedesktop.login1",
- seat_proxy_path,
- cancellable, error);
- if (!seat)
- g_prefix_error(error, "Could not get seat proxy: ");
-
- return seat;
-}
-
-static void
-sync_active (MetaLauncher *self)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
- MetaDbusLogin1Session *session_proxy = self->session_proxy;
- gboolean active;
-
- active = meta_dbus_login1_session_get_active (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 (MetaDbusLogin1Session *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;
-}
-
-MetaDbusLogin1Session *
-meta_launcher_get_session_proxy (MetaLauncher *launcher)
-{
- return launcher->session_proxy;
-}
-
-MetaLauncher *
-meta_launcher_new (GError **error)
-{
- MetaLauncher *self = NULL;
- g_autoptr (MetaDbusLogin1Session) session_proxy = NULL;
- g_autoptr (MetaDbusLogin1Seat) 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 (!meta_dbus_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_new0 (MetaLauncher, 1);
- 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->session_active = TRUE;
-
- g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
-
- return self;
-
- fail:
- if (have_control)
- {
- meta_dbus_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_free (self);
-}
-
-gboolean
-meta_launcher_activate_vt (MetaLauncher *launcher,
- signed char vt,
- GError **error)
-{
- return meta_dbus_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
deleted file mode 100644
index 267b68337..000000000
--- a/src/backends/native/meta-launcher.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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;
-typedef struct _MetaDbusLogin1Session MetaDbusLogin1Session;
-
-MetaLauncher *meta_launcher_new (GError **error);
-void meta_launcher_free (MetaLauncher *self);
-
-gboolean meta_launcher_activate_vt (MetaLauncher *self,
- signed char vt,
- GError **error);
-
-const char * meta_launcher_get_seat_id (MetaLauncher *launcher);
-
-MetaDbusLogin1Session * meta_launcher_get_session_proxy (MetaLauncher *launcher);
-
-
-#endif /* META_LAUNCHER_H */
diff --git a/src/backends/native/meta-monitor-manager-native.c b/src/backends/native/meta-monitor-manager-native.c
deleted file mode 100644
index fd5e7784f..000000000
--- a/src/backends/native/meta-monitor-manager-native.c
+++ /dev/null
@@ -1,825 +0,0 @@
-/* -*- 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-native
- * @title: MetaMonitorManagerNative
- * @short_description: A subclass of #MetaMonitorManager using Linux DRM
- *
- * #MetaMonitorManagerNative 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-native.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 "backends/native/meta-virtual-monitor-native.h"
-#include "clutter/clutter.h"
-#include "meta/main.h"
-#include "meta/meta-x11-errors.h"
-
-enum
-{
- PROP_0,
-
- PROP_NEED_OUTPUTS,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS];
-
-struct _MetaMonitorManagerNative
-{
- MetaMonitorManager parent_instance;
-
- gulong kms_resources_changed_handler_id;
-
- GHashTable *crtc_gamma_cache;
-
- gboolean needs_outputs;
-};
-
-struct _MetaMonitorManagerNativeClass
-{
- MetaMonitorManagerClass parent_class;
-};
-
-#define VIRTUAL_OUTPUT_ID_BIT (((uint64_t) 1) << 63)
-
-static void
-initable_iface_init (GInitableIface *initable_iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaMonitorManagerNative, meta_monitor_manager_native,
- META_TYPE_MONITOR_MANAGER,
- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
- initable_iface_init))
-
-static GBytes *
-meta_monitor_manager_native_read_edid (MetaMonitorManager *manager,
- MetaOutput *output)
-{
- return meta_output_native_read_edid (META_OUTPUT_NATIVE (output));
-}
-
-static void
-meta_monitor_manager_native_read_current_state (MetaMonitorManager *manager)
-{
- MetaMonitorManagerClass *parent_class =
- META_MONITOR_MANAGER_CLASS (meta_monitor_manager_native_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);
-}
-
-uint64_t
-meta_power_save_to_dpms_state (MetaPowerSave power_save)
-{
- switch (power_save)
- {
- case META_POWER_SAVE_ON:
- return DRM_MODE_DPMS_ON;
- case META_POWER_SAVE_STANDBY:
- return DRM_MODE_DPMS_STANDBY;
- case META_POWER_SAVE_SUSPEND:
- return DRM_MODE_DPMS_SUSPEND;
- case META_POWER_SAVE_OFF:
- return DRM_MODE_DPMS_OFF;
- case META_POWER_SAVE_UNSUPPORTED:
- return DRM_MODE_DPMS_ON;
- }
-
- g_warn_if_reached ();
- return DRM_MODE_DPMS_ON;
-}
-
-static void
-meta_monitor_manager_native_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);
- GList *l;
-
- for (l = meta_backend_get_gpus (backend); l; l = l->next)
- {
- MetaGpuKms *gpu_kms = l->data;
-
- switch (mode)
- {
- case META_POWER_SAVE_ON:
- case META_POWER_SAVE_UNSUPPORTED:
- {
- g_list_foreach (meta_gpu_get_crtcs (META_GPU (gpu_kms)),
- (GFunc) meta_crtc_kms_invalidate_gamma,
- NULL);
- break;
- }
- case META_POWER_SAVE_STANDBY:
- case META_POWER_SAVE_SUSPEND:
- case META_POWER_SAVE_OFF:
- {
- MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
- MetaKmsUpdate *kms_update;
- MetaKmsUpdateFlag flags;
- g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
-
- kms_update = meta_kms_ensure_pending_update (kms, kms_device);
- meta_kms_update_set_power_save (kms_update);
-
- flags = META_KMS_UPDATE_FLAG_NONE;
- kms_feedback = meta_kms_post_pending_update_sync (kms,
- kms_device,
- flags);
- if (meta_kms_feedback_get_result (kms_feedback) !=
- META_KMS_FEEDBACK_PASSED)
- {
- g_warning ("Failed to enter power saving mode: %s",
- meta_kms_feedback_get_error (kms_feedback)->message);
- }
- break;
- }
- }
- }
-}
-
-static void
-meta_monitor_manager_native_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,
- MetaCrtcAssignment **crtcs,
- unsigned int n_crtcs,
- MetaOutputAssignment **outputs,
- unsigned int n_outputs)
-{
- MetaBackend *backend = meta_monitor_manager_get_backend (manager);
- g_autoptr (GList) to_configure_outputs = NULL;
- g_autoptr (GList) to_configure_crtcs = NULL;
- unsigned i;
- GList *gpus;
- GList *l;
-
- gpus = meta_backend_get_gpus (backend);
- for (l = gpus; l; l = l->next)
- {
- MetaGpu *gpu = l->data;
- GList *crtcs;
- GList *outputs;
-
- outputs = g_list_copy (meta_gpu_get_outputs (gpu));
- to_configure_outputs = g_list_concat (to_configure_outputs, outputs);
-
- crtcs = g_list_copy (meta_gpu_get_crtcs (gpu));
- to_configure_crtcs = g_list_concat (to_configure_crtcs, crtcs);
- }
-
- for (l = meta_monitor_manager_get_virtual_monitors (manager); l; l = l->next)
- {
- MetaVirtualMonitor *virtual_monitor = l->data;
- MetaOutput *output = meta_virtual_monitor_get_output (virtual_monitor);
- MetaCrtc *crtc = meta_virtual_monitor_get_crtc (virtual_monitor);
-
- to_configure_outputs = g_list_append (to_configure_outputs, output);
- to_configure_crtcs = g_list_append (to_configure_crtcs, crtc);
- }
-
- for (i = 0; i < n_crtcs; i++)
- {
- MetaCrtcAssignment *crtc_assignment = crtcs[i];
- MetaCrtc *crtc = crtc_assignment->crtc;
-
- to_configure_crtcs = g_list_remove (to_configure_crtcs, crtc);
-
- if (crtc_assignment->mode == NULL)
- {
- meta_crtc_unset_config (crtc);
- }
- else
- {
- unsigned int j;
-
- meta_crtc_set_config (crtc,
- &crtc_assignment->layout,
- crtc_assignment->mode,
- crtc_assignment->transform);
-
- for (j = 0; j < crtc_assignment->outputs->len; j++)
- {
- MetaOutput *output = g_ptr_array_index (crtc_assignment->outputs,
- j);
- MetaOutputAssignment *output_assignment;
-
- to_configure_outputs = g_list_remove (to_configure_outputs,
- output);
-
- output_assignment = meta_find_output_assignment (outputs,
- n_outputs,
- output);
- meta_output_assign_crtc (output, crtc, output_assignment);
- }
- }
- }
-
- g_list_foreach (to_configure_crtcs,
- (GFunc) meta_crtc_unset_config,
- NULL);
- g_list_foreach (to_configure_outputs,
- (GFunc) meta_output_unassign_crtc,
- NULL);
-}
-
-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_native_apply_monitors_config (MetaMonitorManager *manager,
- MetaMonitorsConfig *config,
- MetaMonitorsConfigMethod method,
- GError **error)
-{
- GPtrArray *crtc_assignments;
- GPtrArray *output_assignments;
-
- 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_assignments,
- &output_assignments,
- error))
- return FALSE;
-
- if (method == META_MONITORS_CONFIG_METHOD_VERIFY)
- {
- g_ptr_array_free (crtc_assignments, TRUE);
- g_ptr_array_free (output_assignments, TRUE);
- return TRUE;
- }
-
- apply_crtc_assignments (manager,
- (MetaCrtcAssignment **) crtc_assignments->pdata,
- crtc_assignments->len,
- (MetaOutputAssignment **) output_assignments->pdata,
- output_assignments->len);
-
- g_ptr_array_free (crtc_assignments, TRUE);
- g_ptr_array_free (output_assignments, TRUE);
-
- update_screen_size (manager, config);
- meta_monitor_manager_rebuild (manager, config);
-
- return TRUE;
-}
-
-static void
-meta_monitor_manager_native_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;
-
- g_return_if_fail (META_IS_CRTC_KMS (crtc));
-
- kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
- crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
-
- *size = crtc_state->gamma.size;
- *red = g_memdup2 (crtc_state->gamma.red, *size * sizeof **red);
- *green = g_memdup2 (crtc_state->gamma.green, *size * sizeof **green);
- *blue = g_memdup2 (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 = NULL;
- 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_assert (color_ptr);
- 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);
-}
-
-MetaKmsCrtcGamma *
-meta_monitor_manager_native_get_cached_crtc_gamma (MetaMonitorManagerNative *manager_native,
- MetaCrtcKms *crtc_kms)
-{
- uint64_t crtc_id;
-
- crtc_id = meta_crtc_get_id (META_CRTC (crtc_kms));
- return g_hash_table_lookup (manager_native->crtc_gamma_cache,
- GUINT_TO_POINTER (crtc_id));
-}
-
-static void
-meta_monitor_manager_native_set_crtc_gamma (MetaMonitorManager *manager,
- MetaCrtc *crtc,
- gsize size,
- unsigned short *red,
- unsigned short *green,
- unsigned short *blue)
-{
- MetaMonitorManagerNative *manager_native =
- META_MONITOR_MANAGER_NATIVE (manager);
- MetaCrtcKms *crtc_kms;
- MetaKmsCrtc *kms_crtc;
- g_autofree char *gamma_ramp_string = NULL;
- MetaBackend *backend = meta_monitor_manager_get_backend (manager);
- ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
-
- g_return_if_fail (META_IS_CRTC_KMS (crtc));
-
- crtc_kms = META_CRTC_KMS (crtc);
- kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
-
- g_hash_table_replace (manager_native->crtc_gamma_cache,
- GUINT_TO_POINTER (meta_crtc_get_id (crtc)),
- meta_kms_crtc_gamma_new (kms_crtc, size,
- red, green, blue));
-
- gamma_ramp_string = generate_gamma_ramp_string (size, red, green, blue);
- g_debug ("Setting CRTC (%" G_GUINT64_FORMAT ") gamma to %s",
- meta_crtc_get_id (crtc), gamma_ramp_string);
-
- meta_crtc_kms_invalidate_gamma (crtc_kms);
- clutter_stage_schedule_update (stage);
-}
-
-static void
-handle_hotplug_event (MetaMonitorManager *manager)
-{
- meta_monitor_manager_reload (manager);
-}
-
-static void
-on_kms_resources_changed (MetaKms *kms,
- MetaMonitorManager *manager)
-{
- handle_hotplug_event (manager);
-}
-
-static void
-meta_monitor_manager_native_connect_hotplug_handler (MetaMonitorManagerNative *manager_native)
-{
- MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_native);
- 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_native->kms_resources_changed_handler_id =
- g_signal_connect (kms, "resources-changed",
- G_CALLBACK (on_kms_resources_changed), manager);
-}
-
-static void
-meta_monitor_manager_native_disconnect_hotplug_handler (MetaMonitorManagerNative *manager_native)
-{
- MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_native);
- 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_native->kms_resources_changed_handler_id, kms);
-}
-
-void
-meta_monitor_manager_native_pause (MetaMonitorManagerNative *manager_native)
-{
- meta_monitor_manager_native_disconnect_hotplug_handler (manager_native);
-}
-
-void
-meta_monitor_manager_native_resume (MetaMonitorManagerNative *manager_native)
-{
- MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_native);
- MetaBackend *backend = meta_monitor_manager_get_backend (manager);
- GList *l;
-
- meta_monitor_manager_native_connect_hotplug_handler (manager_native);
-
- for (l = meta_backend_get_gpus (backend); l; l = l->next)
- {
- MetaGpu *gpu = l->data;
-
- g_list_foreach (meta_gpu_get_crtcs (gpu),
- (GFunc) meta_crtc_kms_invalidate_gamma,
- NULL);
- }
-}
-
-static gboolean
-meta_monitor_manager_native_is_transform_handled (MetaMonitorManager *manager,
- MetaCrtc *crtc,
- MetaMonitorTransform transform)
-{
- return meta_crtc_native_is_transform_handled (META_CRTC_NATIVE (crtc),
- transform);
-}
-
-static float
-meta_monitor_manager_native_calculate_monitor_mode_scale (MetaMonitorManager *manager,
- MetaMonitor *monitor,
- MetaMonitorMode *monitor_mode)
-{
- return meta_monitor_calculate_mode_scale (monitor, monitor_mode);
-}
-
-static float *
-meta_monitor_manager_native_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:
- 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 MetaMonitorManagerCapability
-meta_monitor_manager_native_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_NONE;
-
- 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_native_get_max_screen_size (MetaMonitorManager *manager,
- int *max_width,
- int *max_height)
-{
- return FALSE;
-}
-
-static MetaLogicalMonitorLayoutMode
-meta_monitor_manager_native_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 MetaVirtualMonitorNative *
-find_virtual_monitor (MetaMonitorManagerNative *manager_native,
- uint64_t id)
-{
- MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_native);
- GList *l;
-
- for (l = meta_monitor_manager_get_virtual_monitors (manager); l; l = l->next)
- {
- MetaVirtualMonitorNative *virtual_monitor_native = l->data;
-
- if (meta_virtual_monitor_native_get_id (virtual_monitor_native) == id)
- return virtual_monitor_native;
- }
-
- return NULL;
-}
-
-static uint64_t
-allocate_virtual_monitor_id (MetaMonitorManagerNative *manager_native)
-{
- uint64_t id;
-
- id = 0;
-
- while (TRUE)
- {
- if (!find_virtual_monitor (manager_native, id))
- return id;
-
- id++;
- }
-}
-
-static MetaVirtualMonitor *
-meta_monitor_manager_native_create_virtual_monitor (MetaMonitorManager *manager,
- const MetaVirtualMonitorInfo *info,
- GError **error)
-{
- MetaMonitorManagerNative *manager_native =
- META_MONITOR_MANAGER_NATIVE (manager);
- MetaVirtualMonitorNative *virtual_monitor_native;
- uint64_t id;
-
- id = allocate_virtual_monitor_id (manager_native);
- virtual_monitor_native = meta_virtual_monitor_native_new (id, info);
- return META_VIRTUAL_MONITOR (virtual_monitor_native);
-}
-
-static void
-meta_monitor_manager_native_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaMonitorManagerNative *manager_native =
- META_MONITOR_MANAGER_NATIVE (object);
-
- switch (prop_id)
- {
- case PROP_NEED_OUTPUTS:
- manager_native->needs_outputs = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_monitor_manager_native_dispose (GObject *object)
-{
- MetaMonitorManagerNative *manager_native =
- META_MONITOR_MANAGER_NATIVE (object);
-
- g_clear_pointer (&manager_native->crtc_gamma_cache,
- g_hash_table_unref);
-
- G_OBJECT_CLASS (meta_monitor_manager_native_parent_class)->dispose (object);
-}
-
-static gboolean
-meta_monitor_manager_native_initable_init (GInitable *initable,
- GCancellable *cancellable,
- GError **error)
-{
- MetaMonitorManagerNative *manager_native =
- META_MONITOR_MANAGER_NATIVE (initable);
- MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_native);
- MetaBackend *backend = meta_monitor_manager_get_backend (manager);
- gboolean can_have_outputs;
- GList *l;
-
- meta_monitor_manager_native_connect_hotplug_handler (manager_native);
-
- 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 (manager_native->needs_outputs && !can_have_outputs)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
- "No GPUs with outputs found");
- return FALSE;
- }
-
- manager_native->crtc_gamma_cache =
- g_hash_table_new_full (NULL, NULL,
- NULL,
- (GDestroyNotify) meta_kms_crtc_gamma_free);
-
- return TRUE;
-}
-
-static void
-initable_iface_init (GInitableIface *initable_iface)
-{
- initable_iface->init = meta_monitor_manager_native_initable_init;
-}
-
-static void
-meta_monitor_manager_native_init (MetaMonitorManagerNative *manager_native)
-{
- manager_native->needs_outputs = TRUE;
-}
-
-static void
-meta_monitor_manager_native_class_init (MetaMonitorManagerNativeClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass);
-
- object_class->set_property = meta_monitor_manager_native_set_property;
- object_class->dispose = meta_monitor_manager_native_dispose;
-
- manager_class->read_edid =
- meta_monitor_manager_native_read_edid;
- manager_class->read_current_state =
- meta_monitor_manager_native_read_current_state;
- manager_class->ensure_initial_config =
- meta_monitor_manager_native_ensure_initial_config;
- manager_class->apply_monitors_config =
- meta_monitor_manager_native_apply_monitors_config;
- manager_class->set_power_save_mode =
- meta_monitor_manager_native_set_power_save_mode;
- manager_class->get_crtc_gamma =
- meta_monitor_manager_native_get_crtc_gamma;
- manager_class->set_crtc_gamma =
- meta_monitor_manager_native_set_crtc_gamma;
- manager_class->is_transform_handled =
- meta_monitor_manager_native_is_transform_handled;
- manager_class->calculate_monitor_mode_scale =
- meta_monitor_manager_native_calculate_monitor_mode_scale;
- manager_class->calculate_supported_scales =
- meta_monitor_manager_native_calculate_supported_scales;
- manager_class->get_capabilities =
- meta_monitor_manager_native_get_capabilities;
- manager_class->get_max_screen_size =
- meta_monitor_manager_native_get_max_screen_size;
- manager_class->get_default_layout_mode =
- meta_monitor_manager_native_get_default_layout_mode;
- manager_class->create_virtual_monitor =
- meta_monitor_manager_native_create_virtual_monitor;
-
- obj_props[PROP_NEED_OUTPUTS] =
- g_param_spec_boolean ("needs-outputs",
- "needs-outputs",
- "Whether any outputs are needed for operation",
- TRUE,
- G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, N_PROPS, obj_props);
-}
diff --git a/src/backends/native/meta-monitor-manager-native.h b/src/backends/native/meta-monitor-manager-native.h
deleted file mode 100644
index 60f899734..000000000
--- a/src/backends/native/meta-monitor-manager-native.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- 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_NATIVE_H
-#define META_MONITOR_MANAGER_NATIVE_H
-
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-
-#include "backends/meta-monitor-manager-private.h"
-#include "backends/native/meta-crtc-kms.h"
-#include "backends/native/meta-kms-crtc.h"
-
-typedef struct _MetaGpuKms MetaGpuKms;
-
-#define META_TYPE_MONITOR_MANAGER_NATIVE (meta_monitor_manager_native_get_type ())
-G_DECLARE_FINAL_TYPE (MetaMonitorManagerNative, meta_monitor_manager_native,
- META, MONITOR_MANAGER_NATIVE,
- MetaMonitorManager)
-
-void meta_monitor_manager_native_pause (MetaMonitorManagerNative *manager_native);
-
-void meta_monitor_manager_native_resume (MetaMonitorManagerNative *manager_native);
-
-uint64_t meta_power_save_to_dpms_state (MetaPowerSave power_save);
-
-MetaKmsCrtcGamma * meta_monitor_manager_native_get_cached_crtc_gamma (MetaMonitorManagerNative *manager_native,
- MetaCrtcKms *crtc_kms);
-
-#endif /* META_MONITOR_MANAGER_NATIVE_H */
diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c
deleted file mode 100644
index 77e5309e1..000000000
--- a/src/backends/native/meta-onscreen-native.c
+++ /dev/null
@@ -1,2137 +0,0 @@
-/*
- * Copyright (C) 2011 Intel Corporation.
- * Copyright (C) 2016-2020 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.
- *
- */
-
-#include "config.h"
-
-#include "backends/native/meta-onscreen-native.h"
-
-#include <drm_fourcc.h>
-
-#include "backends/meta-egl-ext.h"
-#include "backends/native/meta-cogl-utils.h"
-#include "backends/native/meta-crtc-kms.h"
-#include "backends/native/meta-device-pool.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-kms-device.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-private.h"
-
-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 {
- MetaDrmBufferDumb *current_dumb_fb;
- MetaDrmBufferDumb *dumb_fbs[2];
- } cpu;
-
- gboolean noted_primary_gpu_copy_ok;
- gboolean noted_primary_gpu_copy_failed;
- MetaSharedFramebufferImportStatus import_status;
-} MetaOnscreenNativeSecondaryGpuState;
-
-struct _MetaOnscreenNative
-{
- CoglOnscreenEgl parent;
-
- 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;
-
- MetaDrmBufferDumb *dumb_fb;
- } egl;
-#endif
-
- MetaRendererView *view;
-};
-
-G_DEFINE_TYPE (MetaOnscreenNative, meta_onscreen_native,
- COGL_TYPE_ONSCREEN_EGL)
-
-static gboolean
-init_secondary_gpu_state (MetaRendererNative *renderer_native,
- CoglOnscreen *onscreen,
- GError **error);
-
-static void
-swap_secondary_drm_fb (CoglOnscreen *onscreen)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- 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
-free_current_secondary_bo (CoglOnscreen *onscreen)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- 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)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
-
- g_clear_object (&onscreen_native->gbm.current_fb);
- free_current_secondary_bo (onscreen);
-}
-
-static void
-meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
-
- if (!onscreen_native->gbm.next_fb)
- return;
-
- 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
-maybe_update_frame_info (MetaCrtc *crtc,
- CoglFrameInfo *frame_info,
- int64_t time_us,
- CoglFrameInfoFlag flags,
- unsigned int sequence)
-{
- const MetaCrtcConfig *crtc_config;
- const MetaCrtcModeInfo *crtc_mode_info;
- float refresh_rate;
-
- g_return_if_fail (crtc);
-
- crtc_config = meta_crtc_get_config (crtc);
- if (!crtc_config)
- return;
-
- crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode);
- refresh_rate = crtc_mode_info->refresh_rate;
- if (refresh_rate >= frame_info->refresh_rate)
- {
- frame_info->presentation_time_us = time_us;
- frame_info->refresh_rate = refresh_rate;
- frame_info->flags |= flags;
- frame_info->sequence = sequence;
- }
-}
-
-static void
-meta_onscreen_native_notify_frame_complete (CoglOnscreen *onscreen)
-{
- CoglFrameInfo *info;
-
- info = cogl_onscreen_pop_head_frame_info (onscreen);
-
- g_assert (!cogl_onscreen_peek_head_frame_info (onscreen));
-
- _cogl_onscreen_notify_frame_sync (onscreen, info);
- _cogl_onscreen_notify_complete (onscreen, info);
- cogl_object_unref (info);
-}
-
-static void
-notify_view_crtc_presented (MetaRendererView *view,
- MetaKmsCrtc *kms_crtc,
- int64_t time_us,
- CoglFrameInfoFlag flags,
- unsigned int sequence)
-{
- ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (view);
- CoglFramebuffer *framebuffer =
- clutter_stage_view_get_onscreen (stage_view);
- CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
- CoglFrameInfo *frame_info;
- MetaCrtc *crtc;
-
- frame_info = cogl_onscreen_peek_head_frame_info (onscreen);
-
- crtc = META_CRTC (meta_crtc_kms_from_kms_crtc (kms_crtc));
- maybe_update_frame_info (crtc, frame_info, time_us, flags, sequence);
-
- meta_onscreen_native_notify_frame_complete (onscreen);
- meta_onscreen_native_swap_drm_fb (onscreen);
-}
-
-static int64_t
-timeval_to_microseconds (const struct timeval *tv)
-{
- return ((int64_t) tv->tv_sec) * G_USEC_PER_SEC + tv->tv_usec;
-}
-
-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;
- MetaKmsDevice *kms_device;
- int64_t presentation_time_us;
- CoglFrameInfoFlag flags = COGL_FRAME_INFO_FLAG_VSYNC;
-
- page_flip_time = (struct timeval) {
- .tv_sec = tv_sec,
- .tv_usec = tv_usec,
- };
-
- kms_device = meta_kms_crtc_get_device (kms_crtc);
- if (meta_kms_device_uses_monotonic_clock (kms_device))
- {
- presentation_time_us = timeval_to_microseconds (&page_flip_time);
- flags |= COGL_FRAME_INFO_FLAG_HW_CLOCK;
- }
- else
- {
- /*
- * Other parts of the code assume MONOTONIC timestamps. So, if the device
- * timestamp isn't MONOTONIC, don't use it.
- */
- presentation_time_us = g_get_monotonic_time ();
- }
-
- notify_view_crtc_presented (view, kms_crtc,
- presentation_time_us,
- flags,
- sequence);
-}
-
-static void
-page_flip_feedback_ready (MetaKmsCrtc *kms_crtc,
- gpointer user_data)
-{
- MetaRendererView *view = user_data;
- CoglFramebuffer *framebuffer =
- clutter_stage_view_get_onscreen (CLUTTER_STAGE_VIEW (view));
- CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
- CoglFrameInfo *frame_info;
-
- frame_info = cogl_onscreen_peek_head_frame_info (onscreen);
- frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC;
-
- meta_onscreen_native_notify_frame_complete (onscreen);
-}
-
-static void
-page_flip_feedback_mode_set_fallback (MetaKmsCrtc *kms_crtc,
- gpointer user_data)
-{
- MetaRendererView *view = user_data;
- int64_t now_us;
-
- /*
- * 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.
- */
-
- now_us = g_get_monotonic_time ();
-
- notify_view_crtc_presented (view,
- kms_crtc,
- now_us,
- COGL_FRAME_INFO_FLAG_NONE,
- 0);
-}
-
-static void
-page_flip_feedback_discarded (MetaKmsCrtc *kms_crtc,
- gpointer user_data,
- const GError *error)
-{
- MetaRendererView *view = user_data;
- CoglFramebuffer *framebuffer =
- clutter_stage_view_get_onscreen (CLUTTER_STAGE_VIEW (view));
- CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
- CoglFrameInfo *frame_info;
-
- /*
- * Page flipping failed, but we want to fail gracefully, so to avoid freezing
- * the frame clock, emit a symbolic flip.
- */
-
- if (error &&
- !g_error_matches (error,
- G_IO_ERROR,
- G_IO_ERROR_PERMISSION_DENIED))
- g_warning ("Page flip discarded: %s", error->message);
-
- frame_info = cogl_onscreen_peek_head_frame_info (onscreen);
- frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC;
-
- meta_onscreen_native_notify_frame_complete (onscreen);
- meta_onscreen_native_swap_drm_fb (onscreen);
-}
-
-static const MetaKmsPageFlipListenerVtable page_flip_listener_vtable = {
- .flipped = page_flip_feedback_flipped,
- .ready = page_flip_feedback_ready,
- .mode_set_fallback = page_flip_feedback_mode_set_fallback,
- .discarded = page_flip_feedback_discarded,
-};
-
-static MetaEgl *
-meta_onscreen_native_get_egl (MetaOnscreenNative *onscreen_native)
-{
- MetaRendererNative *renderer_native = onscreen_native->renderer_native;
-
- return meta_renderer_native_get_egl (renderer_native);
-}
-
-#ifdef HAVE_EGL_DEVICE
-static int
-custom_egl_stream_page_flip (gpointer custom_page_flip_data,
- gpointer user_data)
-{
- CoglOnscreen *onscreen = custom_page_flip_data;
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- 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 */
-
-void
-meta_onscreen_native_dummy_power_save_page_flip (CoglOnscreen *onscreen)
-{
- CoglFrameInfo *frame_info;
-
- meta_onscreen_native_swap_drm_fb (onscreen);
-
- frame_info = cogl_onscreen_peek_tail_frame_info (onscreen);
- frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC;
- meta_onscreen_native_notify_frame_complete (onscreen);
-}
-
-static void
-meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
- MetaRendererView *view,
- MetaCrtc *crtc,
- MetaKmsPageFlipListenerFlag flags)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- MetaRendererNative *renderer_native = onscreen_native->renderer_native;
- MetaGpuKms *render_gpu = onscreen_native->render_gpu;
- MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
- MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
- MetaRendererNativeGpuData *renderer_gpu_data;
- MetaGpuKms *gpu_kms;
- MetaKmsDevice *kms_device;
- MetaKms *kms;
- MetaKmsUpdate *kms_update;
- MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state = NULL;
- MetaDrmBuffer *buffer;
-
- COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeFlipCrtcs,
- "Onscreen (flip CRTCs)");
-
- gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
- kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
- kms = meta_kms_device_get_kms (kms_device);
- kms_update = meta_kms_ensure_pending_update (kms, kms_device);
-
- 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)
- {
- buffer = onscreen_native->gbm.next_fb;
- }
- else
- {
- secondary_gpu_state = onscreen_native->secondary_gpu_state;
- buffer = secondary_gpu_state->gbm.next_fb;
- }
-
- meta_crtc_kms_assign_primary_plane (crtc_kms, buffer, kms_update);
-
- break;
- case META_RENDERER_NATIVE_MODE_SURFACELESS:
- g_assert_not_reached ();
- break;
-#ifdef HAVE_EGL_DEVICE
- case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
- meta_kms_update_set_custom_page_flip (kms_update,
- custom_egl_stream_page_flip,
- onscreen_native);
- break;
-#endif
- }
-
- meta_kms_update_add_page_flip_listener (kms_update,
- kms_crtc,
- &page_flip_listener_vtable,
- flags,
- g_object_ref (view),
- g_object_unref);
-}
-
-static void
-meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen,
- MetaRendererNativeGpuData *renderer_gpu_data)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- MetaCrtcKms *crtc_kms = META_CRTC_KMS (onscreen_native->crtc);
- MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
- MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
- MetaKms *kms = meta_kms_device_get_kms (kms_device);
- MetaKmsUpdate *kms_update;
-
- COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeSetCrtcModes,
- "Onscreen (set CRTC modes)");
-
- kms_update = meta_kms_ensure_pending_update (kms, kms_device);
-
- switch (renderer_gpu_data->mode)
- {
- case META_RENDERER_NATIVE_MODE_GBM:
- break;
- case META_RENDERER_NATIVE_MODE_SURFACELESS:
- g_assert_not_reached ();
- break;
-#ifdef HAVE_EGL_DEVICE
- case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
- {
- MetaDrmBuffer *buffer;
-
- buffer = META_DRM_BUFFER (onscreen_native->egl.dumb_fb);
- meta_crtc_kms_assign_primary_plane (crtc_kms, buffer, kms_update);
- break;
- }
-#endif
- }
-
- meta_crtc_kms_set_mode (crtc_kms, kms_update);
- meta_output_kms_set_underscan (META_OUTPUT_KMS (onscreen_native->output),
- kms_update);
-}
-
-static void
-secondary_gpu_release_dumb (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
-{
- unsigned i;
-
- for (i = 0; i < G_N_ELEMENTS (secondary_gpu_state->cpu.dumb_fbs); i++)
- g_clear_object (&secondary_gpu_state->cpu.dumb_fbs[i]);
-}
-
-static void
-secondary_gpu_state_free (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
-{
- MetaGpu *gpu = META_GPU (secondary_gpu_state->gpu_kms);
- MetaBackend *backend = meta_gpu_get_backend (gpu);
- 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 gboolean
-import_shared_framebuffer (CoglOnscreen *onscreen,
- MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- MetaGpuKms *gpu_kms;
- MetaDeviceFile *device_file;
- struct gbm_device *gbm_device;
- MetaDrmBufferGbm *buffer_gbm;
- MetaDrmBufferImport *buffer_import;
- g_autoptr (GError) error = NULL;
-
- buffer_gbm = META_DRM_BUFFER_GBM (onscreen_native->gbm.next_fb);
-
- gpu_kms = secondary_gpu_state->gpu_kms;
- device_file = secondary_gpu_state->renderer_gpu_data->device_file;
- gbm_device = meta_gbm_device_from_gpu (gpu_kms);
- buffer_import = meta_drm_buffer_import_new (device_file,
- gbm_device,
- buffer_gbm,
- &error);
- if (!buffer_import)
- {
- meta_topic (META_DEBUG_KMS,
- "Zero-copy disabled for %s, "
- "meta_drm_buffer_import_new failed: %s",
- meta_device_file_get_path (device_file),
- 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);
-
- meta_topic (META_DEBUG_KMS,
- "Using zero-copy for %s succeeded once.",
- meta_device_file_get_path (device_file));
- }
-
- 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)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
- MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
- MetaGles3 *gles3 = meta_renderer_native_get_gles3 (renderer_native);
- GError *error = NULL;
- gboolean use_modifiers;
- MetaDeviceFile *device_file;
- 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,
- 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;
- }
-
- use_modifiers = meta_renderer_native_use_modifiers (renderer_native);
- device_file = secondary_gpu_state->renderer_gpu_data->device_file;
- buffer_gbm =
- meta_drm_buffer_gbm_new_lock_front (device_file,
- secondary_gpu_state->gbm.surface,
- use_modifiers,
- &error);
- if (!buffer_gbm)
- {
- g_warning ("meta_drm_buffer_gbm_new_lock_front failed: %s",
- error->message);
- g_error_free (error);
- return;
- }
-
- secondary_gpu_state->gbm.next_fb = META_DRM_BUFFER (buffer_gbm);
-}
-
-static MetaDrmBufferDumb *
-secondary_gpu_get_next_dumb_buffer (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
-{
- MetaDrmBufferDumb *current_dumb_fb;
-
- current_dumb_fb = secondary_gpu_state->cpu.current_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 gboolean
-copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscreen,
- MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
-{
- CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- MetaRendererNative *renderer_native = onscreen_native->renderer_native;
- MetaGpuKms *primary_gpu;
- MetaRendererNativeGpuData *primary_gpu_data;
- MetaDrmBufferDumb *buffer_dumb;
- MetaDrmBuffer *buffer;
- int width, height, stride;
- uint32_t drm_format;
- 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 = meta_renderer_native_get_primary_gpu (renderer_native);
- primary_gpu_data =
- meta_renderer_native_get_gpu_data (renderer_native, primary_gpu);
- if (!primary_gpu_data->secondary.has_EGL_EXT_image_dma_buf_import_modifiers)
- return FALSE;
-
- buffer_dumb = secondary_gpu_get_next_dumb_buffer (secondary_gpu_state);
- buffer = META_DRM_BUFFER (buffer_dumb);
-
- width = meta_drm_buffer_get_width (buffer);
- height = meta_drm_buffer_get_height (buffer);
- stride = meta_drm_buffer_get_stride (buffer);
- drm_format = meta_drm_buffer_get_format (buffer);
-
- g_assert (cogl_framebuffer_get_width (framebuffer) == width);
- g_assert (cogl_framebuffer_get_height (framebuffer) == height);
-
- ret = meta_cogl_pixel_format_from_drm_format (drm_format,
- &cogl_format,
- NULL);
- g_assert (ret);
-
- dmabuf_fd = meta_drm_buffer_dumb_ensure_dmabuf_fd (buffer_dumb, &error);
- if (!dmabuf_fd)
- {
- meta_topic (META_DEBUG_KMS,
- "Failed to create DMA buffer: %s", error->message);
- return FALSE;
- }
-
- dmabuf_fb =
- meta_renderer_native_create_dma_buf_framebuffer (renderer_native,
- dmabuf_fd,
- width,
- height,
- stride,
- 0, DRM_FORMAT_MOD_LINEAR,
- drm_format,
- &error);
-
- if (error)
- {
- meta_topic (META_DEBUG_KMS,
- "Failed to create DMA buffer for blitting: %s",
- error->message);
- return FALSE;
- }
-
- if (!cogl_blit_framebuffer (framebuffer, COGL_FRAMEBUFFER (dmabuf_fb),
- 0, 0, 0, 0,
- width, height,
- &error))
- {
- g_object_unref (dmabuf_fb);
- return FALSE;
- }
-
- g_object_unref (dmabuf_fb);
-
- g_set_object (&secondary_gpu_state->gbm.next_fb, buffer);
- secondary_gpu_state->cpu.current_dumb_fb = buffer_dumb;
-
- 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 = cogl_framebuffer_get_context (framebuffer);
- MetaDrmBufferDumb *buffer_dumb;
- MetaDrmBuffer *buffer;
- int width, height, stride;
- uint32_t drm_format;
- void *buffer_data;
- CoglBitmap *dumb_bitmap;
- CoglPixelFormat cogl_format;
- gboolean ret;
-
- COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferCpu,
- "FB Copy (CPU)");
-
- buffer_dumb = secondary_gpu_get_next_dumb_buffer (secondary_gpu_state);
- buffer = META_DRM_BUFFER (buffer_dumb);
-
- width = meta_drm_buffer_get_width (buffer);
- height = meta_drm_buffer_get_height (buffer);
- stride = meta_drm_buffer_get_stride (buffer);
- drm_format = meta_drm_buffer_get_format (buffer);
- buffer_data = meta_drm_buffer_dumb_get_data (buffer_dumb);
-
- g_assert (cogl_framebuffer_get_width (framebuffer) == width);
- g_assert (cogl_framebuffer_get_height (framebuffer) == height);
-
- ret = meta_cogl_pixel_format_from_drm_format (drm_format,
- &cogl_format,
- NULL);
- g_assert (ret);
-
- dumb_bitmap = cogl_bitmap_new_for_data (cogl_context,
- width,
- height,
- cogl_format,
- stride,
- buffer_data);
-
- 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);
- secondary_gpu_state->gbm.next_fb = buffer;
- secondary_gpu_state->cpu.current_dumb_fb = buffer_dumb;
-}
-
-static void
-update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- 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;
- MetaDeviceFile *device_file;
-
- renderer_gpu_data = secondary_gpu_state->renderer_gpu_data;
- device_file = renderer_gpu_data->device_file;
- 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)
- {
- meta_topic (META_DEBUG_KMS,
- "Using primary GPU to copy for %s failed once.",
- meta_device_file_get_path (device_file));
- 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)
- {
- meta_topic (META_DEBUG_KMS,
- "Using primary GPU to copy for %s succeeded once.",
- meta_device_file_get_path (device_file));
- 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)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- 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 void
-ensure_crtc_modes (CoglOnscreen *onscreen)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
- CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
- 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;
-
- if (meta_renderer_native_pop_pending_mode_set (renderer_native,
- onscreen_native->view))
- meta_onscreen_native_set_crtc_mode (onscreen, renderer_gpu_data);
-}
-
-static void
-meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
- const int *rectangles,
- int n_rectangles,
- CoglFrameInfo *frame_info,
- gpointer user_data)
-{
- CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
- CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
- 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);
- MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- MetaKms *kms = meta_backend_native_get_kms (backend_native);
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- MetaGpuKms *render_gpu = onscreen_native->render_gpu;
- MetaDeviceFile *render_device_file;
- ClutterFrame *frame = user_data;
- CoglOnscreenClass *parent_class;
- gboolean egl_context_changed = FALSE;
- gboolean use_modifiers;
- MetaPowerSave power_save_mode;
- g_autoptr (GError) error = NULL;
- MetaDrmBufferGbm *buffer_gbm;
- MetaKmsCrtc *kms_crtc;
- MetaKmsDevice *kms_device;
- MetaKmsUpdateFlag flags;
- g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
- const GError *feedback_error;
-
- COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers,
- "Onscreen (swap-buffers)");
-
- update_secondary_gpu_state_pre_swap_buffers (onscreen);
-
- parent_class = COGL_ONSCREEN_CLASS (meta_onscreen_native_parent_class);
- parent_class->swap_buffers_with_damage (onscreen,
- rectangles,
- n_rectangles,
- frame_info,
- user_data);
-
- renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
- render_gpu);
- render_device_file = renderer_gpu_data->device_file;
- 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);
-
- use_modifiers = meta_renderer_native_use_modifiers (renderer_native);
- buffer_gbm =
- meta_drm_buffer_gbm_new_lock_front (render_device_file,
- onscreen_native->gbm.surface,
- use_modifiers,
- &error);
- if (!buffer_gbm)
- {
- g_warning ("Failed to lock front buffer on %s: %s",
- meta_device_file_get_path (render_device_file),
- error->message);
- return;
- }
-
- onscreen_native->gbm.next_fb = META_DRM_BUFFER (buffer_gbm);
-
- break;
- case META_RENDERER_NATIVE_MODE_SURFACELESS:
- g_assert_not_reached ();
- 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 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);
-
- power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
- if (power_save_mode == META_POWER_SAVE_ON)
- {
- ensure_crtc_modes (onscreen);
- meta_onscreen_native_flip_crtc (onscreen,
- onscreen_native->view,
- onscreen_native->crtc,
- META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE);
- }
- else
- {
- meta_renderer_native_queue_power_save_page_flip (renderer_native,
- onscreen);
- clutter_frame_set_result (frame,
- CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
- return;
- }
-
- COGL_TRACE_BEGIN_SCOPED (MetaRendererNativePostKmsUpdate,
- "Onscreen (post pending update)");
- kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc));
- kms_device = meta_kms_crtc_get_device (kms_crtc);
-
- switch (renderer_gpu_data->mode)
- {
- case META_RENDERER_NATIVE_MODE_GBM:
- if (meta_renderer_native_has_pending_mode_sets (renderer_native))
- {
- meta_topic (META_DEBUG_KMS,
- "Postponing primary plane composite update for CRTC %u (%s)",
- meta_kms_crtc_get_id (kms_crtc),
- meta_kms_device_get_path (kms_device));
-
- clutter_frame_set_result (frame,
- CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
- return;
- }
- else if (meta_renderer_native_has_pending_mode_set (renderer_native))
- {
- meta_topic (META_DEBUG_KMS, "Posting global mode set updates on %s",
- meta_kms_device_get_path (kms_device));
-
- meta_renderer_native_notify_mode_sets_reset (renderer_native);
- meta_renderer_native_post_mode_set_updates (renderer_native);
- clutter_frame_set_result (frame,
- CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
- return;
- }
- break;
- case META_RENDERER_NATIVE_MODE_SURFACELESS:
- g_assert_not_reached ();
- break;
-#ifdef HAVE_EGL_DEVICE
- case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
- if (meta_renderer_native_has_pending_mode_set (renderer_native))
- {
- meta_renderer_native_notify_mode_sets_reset (renderer_native);
- meta_renderer_native_post_mode_set_updates (renderer_native);
- clutter_frame_set_result (frame,
- CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
- return;
- }
- break;
-#endif
- }
-
- meta_topic (META_DEBUG_KMS,
- "Posting primary plane composite update for CRTC %u (%s)",
- meta_kms_crtc_get_id (kms_crtc),
- meta_kms_device_get_path (kms_device));
-
- flags = META_KMS_UPDATE_FLAG_NONE;
- kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device, flags);
-
- switch (meta_kms_feedback_get_result (kms_feedback))
- {
- case META_KMS_FEEDBACK_PASSED:
- clutter_frame_set_result (frame,
- CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
- break;
- case META_KMS_FEEDBACK_FAILED:
- clutter_frame_set_result (frame,
- CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
-
- feedback_error = meta_kms_feedback_get_error (kms_feedback);
- if (!g_error_matches (feedback_error,
- G_IO_ERROR,
- G_IO_ERROR_PERMISSION_DENIED))
- g_warning ("Failed to post KMS update: %s", feedback_error->message);
- break;
- }
-}
-
-gboolean
-meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
- uint32_t drm_format,
- uint64_t drm_modifier,
- uint32_t stride)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- const MetaCrtcConfig *crtc_config;
- MetaDrmBuffer *fb;
- struct gbm_bo *gbm_bo;
-
- crtc_config = meta_crtc_get_config (onscreen_native->crtc);
- if (crtc_config->transform != META_MONITOR_TRANSFORM_NORMAL)
- return FALSE;
-
- if (onscreen_native->secondary_gpu_state)
- return FALSE;
-
- if (!onscreen_native->gbm.surface)
- return FALSE;
-
- fb = onscreen_native->gbm.current_fb ? onscreen_native->gbm.current_fb
- : onscreen_native->gbm.next_fb;
- if (!fb)
- return FALSE;
-
- if (!META_IS_DRM_BUFFER_GBM (fb))
- return FALSE;
-
- gbm_bo = meta_drm_buffer_gbm_get_bo (META_DRM_BUFFER_GBM (fb));
-
- if (gbm_bo_get_format (gbm_bo) != drm_format)
- return FALSE;
-
- if (gbm_bo_get_modifier (gbm_bo) != drm_modifier)
- return FALSE;
-
- if (gbm_bo_get_stride (gbm_bo) != stride)
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
- CoglScanout *scanout,
- CoglFrameInfo *frame_info,
- gpointer user_data,
- GError **error)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- MetaGpuKms *render_gpu = onscreen_native->render_gpu;
- CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
- CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
- 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);
- MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
- MetaKms *kms = meta_backend_native_get_kms (backend_native);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- MetaPowerSave power_save_mode;
- ClutterFrame *frame = user_data;
- MetaDrmBuffer *scanout_buffer;
- GError *fill_timings_error = NULL;
- MetaKmsCrtc *kms_crtc;
- MetaKmsDevice *kms_device;
- MetaKmsUpdateFlag flags;
- g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
- const GError *feedback_error;
-
- power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
- if (power_save_mode != META_POWER_SAVE_ON)
- {
- g_set_error_literal (error,
- COGL_SCANOUT_ERROR,
- COGL_SCANOUT_ERROR_INHIBITED,
- "Direct scanout is inhibited during power saving mode");
- return FALSE;
- }
-
- if (meta_renderer_native_has_pending_mode_set (renderer_native))
- {
- g_set_error_literal (error,
- COGL_SCANOUT_ERROR,
- COGL_SCANOUT_ERROR_INHIBITED,
- "Direct scanout is inhibited when a mode set is pending");
- return FALSE;
- }
-
- renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
- render_gpu);
-
- g_warn_if_fail (renderer_gpu_data->mode == META_RENDERER_NATIVE_MODE_GBM);
- g_warn_if_fail (!onscreen_native->gbm.next_fb);
-
- g_set_object (&onscreen_native->gbm.next_fb, META_DRM_BUFFER (scanout));
-
- /* Try to get a measurement of GPU rendering time on the scanout buffer.
- *
- * The successful operation here adds ~0.4 ms to a ~0.1 ms total frame clock
- * dispatch duration when displaying an unredirected client, thus
- * unfortunately bringing it more in line with duration of the regular
- * non-unredirected frame clock dispatch. However, measuring GPU rendering
- * time is important for computing accurate max render time without
- * underestimating. Also this operation should be optimizable by caching
- * EGLImage for each buffer instead of re-creating it every time it's needed.
- * This should also help all other cases which convert the buffer to a
- * EGLImage.
- */
- if (META_IS_DRM_BUFFER (scanout))
- {
- scanout_buffer = META_DRM_BUFFER (scanout);
- if (meta_drm_buffer_supports_fill_timings (scanout_buffer))
- {
- if (!meta_drm_buffer_fill_timings (scanout_buffer, frame_info,
- &fill_timings_error))
- {
- g_warning ("Failed to fill timings for a scanout buffer: %s",
- fill_timings_error->message);
- g_error_free (fill_timings_error);
- }
- }
- }
-
- ensure_crtc_modes (onscreen);
- meta_onscreen_native_flip_crtc (onscreen,
- onscreen_native->view,
- onscreen_native->crtc,
- META_KMS_PAGE_FLIP_LISTENER_FLAG_DROP_ON_ERROR);
-
- kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc));
- kms_device = meta_kms_crtc_get_device (kms_crtc);
-
- meta_topic (META_DEBUG_KMS,
- "Posting direct scanout update for CRTC %u (%s)",
- meta_kms_crtc_get_id (kms_crtc),
- meta_kms_device_get_path (kms_device));
-
- flags = META_KMS_UPDATE_FLAG_PRESERVE_ON_ERROR;
- kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device, flags);
- switch (meta_kms_feedback_get_result (kms_feedback))
- {
- case META_KMS_FEEDBACK_PASSED:
- clutter_frame_set_result (frame,
- CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
- break;
- case META_KMS_FEEDBACK_FAILED:
- feedback_error = meta_kms_feedback_get_error (kms_feedback);
-
- if (g_error_matches (feedback_error,
- G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED))
- break;
-
- g_clear_object (&onscreen_native->gbm.next_fb);
- g_propagate_error (error, g_error_copy (feedback_error));
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-add_onscreen_frame_info (MetaCrtc *crtc)
-{
- MetaGpu *gpu = meta_crtc_get_gpu (crtc);
- MetaBackend *backend = meta_gpu_get_backend (gpu);
- ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
- ClutterStageWindow *stage_window = _clutter_stage_get_window (stage);
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
- MetaRendererView *view = meta_renderer_get_view_for_crtc (renderer, crtc);
-
- meta_stage_impl_add_onscreen_frame_info (META_STAGE_IMPL (stage_window),
- CLUTTER_STAGE_VIEW (view));
-}
-
-void
-meta_onscreen_native_finish_frame (CoglOnscreen *onscreen,
- ClutterFrame *frame)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- MetaCrtc *crtc = onscreen_native->crtc;
- MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
- MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);;
- MetaKms *kms = meta_kms_device_get_kms (kms_device);
- MetaKmsUpdateFlag flags;
- MetaKmsUpdate *kms_update;
- g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
- const GError *error;
-
- kms_update = meta_kms_get_pending_update (kms, kms_device);
- if (!kms_update)
- {
- clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_IDLE);
- return;
- }
-
- meta_kms_update_add_page_flip_listener (kms_update,
- kms_crtc,
- &page_flip_listener_vtable,
- META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE,
- g_object_ref (onscreen_native->view),
- g_object_unref);
-
- flags = META_KMS_UPDATE_FLAG_NONE;
- kms_feedback = meta_kms_post_pending_update_sync (kms,
- kms_device,
- flags);
- switch (meta_kms_feedback_get_result (kms_feedback))
- {
- case META_KMS_FEEDBACK_PASSED:
- add_onscreen_frame_info (crtc);
- clutter_frame_set_result (frame,
- CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
- break;
- case META_KMS_FEEDBACK_FAILED:
- add_onscreen_frame_info (crtc);
- clutter_frame_set_result (frame,
- CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
-
- 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);
- break;
- }
-}
-
-static gboolean
-should_surface_be_sharable (CoglOnscreen *onscreen)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
-
- if (META_GPU_KMS (meta_crtc_get_gpu (onscreen_native->crtc)) ==
- onscreen_native->render_gpu)
- return FALSE;
- else
- return TRUE;
-}
-
-static uint32_t
-get_gbm_format_from_egl (MetaEgl *egl,
- EGLDisplay egl_display,
- EGLConfig egl_config)
-{
- uint32_t gbm_format;
- EGLint native_visual_id;
-
- if (meta_egl_get_config_attrib (egl,
- egl_display,
- egl_config,
- EGL_NATIVE_VISUAL_ID,
- &native_visual_id,
- NULL))
- gbm_format = (uint32_t) native_visual_id;
- else
- g_assert_not_reached ();
-
- return gbm_format;
-}
-
-static GArray *
-get_supported_kms_modifiers (MetaCrtcKms *crtc_kms,
- uint32_t format)
-{
- GArray *modifiers;
- GArray *crtc_mods;
- unsigned int i;
-
- crtc_mods = meta_crtc_kms_get_modifiers (crtc_kms, 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,
- MetaCrtcKms *crtc_kms,
- uint32_t format)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- 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 (META_CRTC (crtc_kms));
- 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)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- MetaCrtcKms *crtc_kms = META_CRTC_KMS (onscreen_native->crtc);
- MetaGpu *gpu;
- g_autoptr (GArray) modifiers = NULL;
-
- gpu = meta_crtc_get_gpu (META_CRTC (crtc_kms));
- if (gpu == META_GPU (onscreen_native->render_gpu))
- modifiers = get_supported_kms_modifiers (crtc_kms, format);
- else
- modifiers = get_supported_egl_modifiers (onscreen, crtc_kms, format);
-
- return g_steal_pointer (&modifiers);
-}
-
-static GArray *
-get_supported_kms_formats (CoglOnscreen *onscreen)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- MetaCrtcKms *crtc_kms = META_CRTC_KMS (onscreen_native->crtc);
-
- return meta_crtc_kms_copy_drm_format_list (crtc_kms);
-}
-
-static gboolean
-create_surfaces_gbm (CoglOnscreen *onscreen,
- int width,
- int height,
- struct gbm_surface **gbm_surface,
- EGLSurface *egl_surface,
- GError **error)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- MetaRendererNative *renderer_native = onscreen_native->renderer_native;
- MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native);
- CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
- CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
- 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;
- GArray *modifiers;
-
- renderer_gpu_data =
- meta_renderer_native_get_gpu_data (renderer_native,
- onscreen_native->render_gpu);
-
- format = get_gbm_format_from_egl (egl,
- cogl_renderer_egl->edpy,
- cogl_display_egl->egl_config);
-
- if (meta_renderer_native_use_modifiers (renderer_native))
- 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
-create_surfaces_egl_device (CoglOnscreen *onscreen,
- int width,
- int height,
- EGLStreamKHR *out_egl_stream,
- EGLSurface *out_egl_surface,
- GError **error)
-{
- CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
- 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] = meta_crtc_get_id (onscreen_native->crtc);
- 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 */
-
-void
-meta_onscreen_native_set_view (CoglOnscreen *onscreen,
- MetaRendererView *view)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- onscreen_native->view = view;
-}
-
-static gboolean
-meta_onscreen_native_allocate (CoglFramebuffer *framebuffer,
- GError **error)
-{
- CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen);
- MetaRendererNativeGpuData *renderer_gpu_data;
- struct gbm_surface *gbm_surface;
- EGLSurface egl_surface;
- int width;
- int height;
-#ifdef HAVE_EGL_DEVICE
- MetaDeviceFile *render_device_file;
- EGLStreamKHR egl_stream;
-#endif
- CoglFramebufferClass *parent_class;
-
- if (META_GPU_KMS (meta_crtc_get_gpu (onscreen_native->crtc)) !=
- onscreen_native->render_gpu)
- {
- if (!init_secondary_gpu_state (onscreen_native->renderer_native,
- onscreen, error))
- return FALSE;
- }
-
- width = cogl_framebuffer_get_width (framebuffer);
- height = cogl_framebuffer_get_height (framebuffer);
-
- 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 (!create_surfaces_gbm (onscreen,
- width, height,
- &gbm_surface,
- &egl_surface,
- error))
- return FALSE;
-
- onscreen_native->gbm.surface = gbm_surface;
- cogl_onscreen_egl_set_egl_surface (onscreen_egl, egl_surface);
- break;
- case META_RENDERER_NATIVE_MODE_SURFACELESS:
- g_assert_not_reached ();
- break;
-#ifdef HAVE_EGL_DEVICE
- case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
- render_device_file = renderer_gpu_data->device_file;
- onscreen_native->egl.dumb_fb =
- meta_drm_buffer_dumb_new (render_device_file,
- width, height,
- DRM_FORMAT_XRGB8888,
- error);
- if (!onscreen_native->egl.dumb_fb)
- return FALSE;
-
- if (!create_surfaces_egl_device (onscreen,
- width, height,
- &egl_stream,
- &egl_surface,
- error))
- return FALSE;
-
- onscreen_native->egl.stream = egl_stream;
- cogl_onscreen_egl_set_egl_surface (onscreen_egl, egl_surface);
- break;
-#endif /* HAVE_EGL_DEVICE */
- }
-
- parent_class = COGL_FRAMEBUFFER_CLASS (meta_onscreen_native_parent_class);
- return parent_class->allocate (framebuffer, error);
-}
-
-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);
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- 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;
- uint32_t format;
-
- width = cogl_framebuffer_get_width (framebuffer);
- height = cogl_framebuffer_get_height (framebuffer);
- format = get_gbm_format_from_egl (egl,
- renderer_gpu_data->egl_display,
- renderer_gpu_data->secondary.egl_config);
-
- gbm_surface = gbm_surface_create (renderer_gpu_data->gbm.device,
- width, height,
- format,
- 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 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 (meta_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 (meta_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);
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state;
- MetaGpuKms *gpu_kms;
- MetaDeviceFile *device_file;
- 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));
- device_file = renderer_gpu_data->device_file;
- meta_topic (META_DEBUG_KMS,
- "Secondary GPU %s using DRM format '%s' (0x%x) for a %dx%d output.",
- meta_device_file_get_path (device_file),
- 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++)
- {
- secondary_gpu_state->cpu.dumb_fbs[i] =
- meta_drm_buffer_dumb_new (device_file,
- width, height,
- drm_format,
- error);
- if (!secondary_gpu_state->cpu.dumb_fbs[i])
- {
- 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)
-{
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- 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;
-}
-
-MetaOnscreenNative *
-meta_onscreen_native_new (MetaRendererNative *renderer_native,
- MetaGpuKms *render_gpu,
- MetaOutput *output,
- MetaCrtc *crtc,
- CoglContext *cogl_context,
- int width,
- int height)
-{
- MetaOnscreenNative *onscreen_native;
- CoglFramebufferDriverConfig driver_config;
-
- driver_config = (CoglFramebufferDriverConfig) {
- .type = COGL_FRAMEBUFFER_DRIVER_TYPE_BACK,
- };
- onscreen_native = g_object_new (META_TYPE_ONSCREEN_NATIVE,
- "context", cogl_context,
- "driver-config", &driver_config,
- "width", width,
- "height", height,
- NULL);
-
- onscreen_native->renderer_native = renderer_native;
- onscreen_native->render_gpu = render_gpu;
- onscreen_native->output = output;
- onscreen_native->crtc = crtc;
-
- return onscreen_native;
-}
-
-static void
-meta_onscreen_native_dispose (GObject *object)
-{
- CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object);
- CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
- MetaRendererNative *renderer_native = onscreen_native->renderer_native;
- MetaRendererNativeGpuData *renderer_gpu_data;
-
- 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_warn_if_fail (onscreen_native->gbm.next_fb == NULL);
-
- free_current_bo (onscreen);
- break;
- case META_RENDERER_NATIVE_MODE_SURFACELESS:
- g_assert_not_reached ();
- break;
-#ifdef HAVE_EGL_DEVICE
- case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
- g_clear_object (&onscreen_native->egl.dumb_fb);
-
- if (onscreen_native->egl.stream != EGL_NO_STREAM_KHR)
- {
- MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native);
- CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
- 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_OBJECT_CLASS (meta_onscreen_native_parent_class)->dispose (object);
-
- g_clear_pointer (&onscreen_native->gbm.surface, gbm_surface_destroy);
- g_clear_pointer (&onscreen_native->secondary_gpu_state,
- secondary_gpu_state_free);
-}
-
-static void
-meta_onscreen_native_init (MetaOnscreenNative *onscreen_native)
-{
-}
-
-static void
-meta_onscreen_native_class_init (MetaOnscreenNativeClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass);
- CoglOnscreenClass *onscreen_class = COGL_ONSCREEN_CLASS (klass);
-
- object_class->dispose = meta_onscreen_native_dispose;
-
- framebuffer_class->allocate = meta_onscreen_native_allocate;
-
- onscreen_class->swap_buffers_with_damage =
- meta_onscreen_native_swap_buffers_with_damage;
- onscreen_class->direct_scanout = meta_onscreen_native_direct_scanout;
-}
diff --git a/src/backends/native/meta-onscreen-native.h b/src/backends/native/meta-onscreen-native.h
deleted file mode 100644
index 020fc8a14..000000000
--- a/src/backends/native/meta-onscreen-native.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2016-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.
- *
- */
-
-#ifndef META_ONSCREEN_NATIVE_H
-#define META_ONSCREEN_NATIVE_H
-
-#include <glib.h>
-
-#include "backends/meta-backend-types.h"
-#include "backends/native/meta-backend-native-types.h"
-#include "clutter/clutter.h"
-#include "cogl/cogl.h"
-
-#define META_TYPE_ONSCREEN_NATIVE (meta_onscreen_native_get_type ())
-G_DECLARE_FINAL_TYPE (MetaOnscreenNative, meta_onscreen_native,
- META, ONSCREEN_NATIVE,
- CoglOnscreenEgl)
-
-void meta_renderer_native_release_onscreen (CoglOnscreen *onscreen);
-
-void meta_onscreen_native_finish_frame (CoglOnscreen *onscreen,
- ClutterFrame *frame);
-
-void meta_onscreen_native_dummy_power_save_page_flip (CoglOnscreen *onscreen);
-
-gboolean meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
- uint32_t drm_format,
- uint64_t drm_modifier,
- uint32_t stride);
-
-void meta_onscreen_native_set_view (CoglOnscreen *onscreen,
- MetaRendererView *view);
-
-MetaOnscreenNative * meta_onscreen_native_new (MetaRendererNative *renderer_native,
- MetaGpuKms *render_gpu,
- MetaOutput *output,
- MetaCrtc *crtc,
- CoglContext *cogl_context,
- int width,
- int height);
-
-#endif /* META_ONSCREEN_NATIVE_H */
diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c
deleted file mode 100644
index f35cdf04e..000000000
--- a/src/backends/native/meta-output-kms.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/* -*- 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-device.h"
-#include "backends/native/meta-kms-mode.h"
-#include "backends/native/meta-kms-update.h"
-#include "backends/native/meta-kms-utils.h"
-#include "backends/native/meta-crtc-kms.h"
-#include "backends/native/meta-crtc-mode-kms.h"
-
-#define SYNC_TOLERANCE 0.01 /* 1 percent */
-
-struct _MetaOutputKms
-{
- MetaOutputNative parent;
-
- MetaKmsConnector *kms_connector;
-};
-
-G_DEFINE_TYPE (MetaOutputKms, meta_output_kms, META_TYPE_OUTPUT_NATIVE)
-
-MetaKmsConnector *
-meta_output_kms_get_kms_connector (MetaOutputKms *output_kms)
-{
- return output_kms->kms_connector;
-}
-
-void
-meta_output_kms_set_underscan (MetaOutputKms *output_kms,
- MetaKmsUpdate *kms_update)
-{
- MetaOutput *output = META_OUTPUT (output_kms);
- const MetaOutputInfo *output_info = meta_output_get_info (output);
-
- if (!output_info->supports_underscanning)
- return;
-
- if (meta_output_is_underscanning (output))
- {
- MetaCrtc *crtc;
- const MetaCrtcConfig *crtc_config;
- const MetaCrtcModeInfo *crtc_mode_info;
- uint64_t hborder, vborder;
-
- crtc = meta_output_get_assigned_crtc (output);
- crtc_config = meta_crtc_get_config (crtc);
- crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode);
-
- hborder = MIN (128, (uint64_t) round (crtc_mode_info->width * 0.05));
- vborder = MIN (128, (uint64_t) round (crtc_mode_info->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_update_set_underscanning (kms_update,
- output_kms->kms_connector,
- hborder, vborder);
- }
- else
- {
- g_debug ("Unsetting underscan of connector %s",
- meta_kms_connector_get_name (output_kms->kms_connector));
-
- meta_kms_update_unset_underscanning (kms_update,
- output_kms->kms_connector);
- }
-}
-
-uint32_t
-meta_output_kms_get_connector_id (MetaOutputKms *output_kms)
-{
- return meta_kms_connector_get_id (output_kms->kms_connector);
-}
-
-gboolean
-meta_output_kms_can_clone (MetaOutputKms *output_kms,
- MetaOutputKms *other_output_kms)
-{
- return meta_kms_connector_can_clone (output_kms->kms_connector,
- other_output_kms->kms_connector);
-}
-
-static GBytes *
-meta_output_kms_read_edid (MetaOutputNative *output_native)
-{
- MetaOutputKms *output_kms = META_OUTPUT_KMS (output_native);
- 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
-add_common_modes (MetaOutputInfo *output_info,
- MetaGpuKms *gpu_kms)
-{
- MetaCrtcMode *crtc_mode;
- GPtrArray *array;
- float refresh_rate;
- unsigned i;
- unsigned max_hdisplay = 0;
- unsigned max_vdisplay = 0;
- float max_refresh_rate = 0.0;
- float max_bandwidth = 0.0;
- MetaKmsDevice *kms_device;
- MetaKmsModeFlag flag_filter;
- GList *l;
-
- for (i = 0; i < output_info->n_modes; i++)
- {
- MetaCrtcMode *crtc_mode = output_info->modes[i];
- MetaCrtcModeKms *crtc_mode_kms = META_CRTC_MODE_KMS (crtc_mode);
- MetaKmsMode *kms_mode = meta_crtc_mode_kms_get_kms_mode (crtc_mode_kms);
- const drmModeModeInfo *drm_mode = meta_kms_mode_get_drm_mode (kms_mode);
- float bandwidth;
-
- refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
- bandwidth = refresh_rate * drm_mode->hdisplay * drm_mode->vdisplay;
- 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_bandwidth = MAX (max_bandwidth, bandwidth);
- }
-
- max_refresh_rate = MAX (max_refresh_rate, 60.0);
- max_refresh_rate *= (1 + SYNC_TOLERANCE);
-
- kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
-
- array = g_ptr_array_new ();
-
- if (max_hdisplay > max_vdisplay)
- flag_filter = META_KMS_MODE_FLAG_FALLBACK_LANDSCAPE;
- else
- flag_filter = META_KMS_MODE_FLAG_FALLBACK_PORTRAIT;
-
- for (l = meta_kms_device_get_fallback_modes (kms_device); l; l = l->next)
- {
- MetaKmsMode *fallback_mode = l->data;
- const drmModeModeInfo *drm_mode;
- float bandwidth;
-
- if (!(meta_kms_mode_get_flags (fallback_mode) & flag_filter))
- continue;
-
- drm_mode = meta_kms_mode_get_drm_mode (fallback_mode);
- refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
- bandwidth = refresh_rate * drm_mode->hdisplay * drm_mode->vdisplay;
- if (drm_mode->hdisplay > max_hdisplay ||
- drm_mode->vdisplay > max_vdisplay ||
- refresh_rate > max_refresh_rate ||
- bandwidth > max_bandwidth)
- continue;
-
- crtc_mode = meta_gpu_kms_get_mode_from_kms_mode (gpu_kms, fallback_mode);
- g_ptr_array_add (array, crtc_mode);
- }
-
- output_info->modes = g_renew (MetaCrtcMode *, output_info->modes,
- output_info->n_modes + array->len);
- memcpy (output_info->modes + output_info->n_modes, array->pdata,
- array->len * sizeof (MetaCrtcMode *));
- output_info->n_modes += array->len;
-
- g_ptr_array_free (array, TRUE);
-}
-
-static int
-compare_modes (const void *one,
- const void *two)
-{
- MetaCrtcMode *crtc_mode_one = *(MetaCrtcMode **) one;
- MetaCrtcMode *crtc_mode_two = *(MetaCrtcMode **) two;
- const MetaCrtcModeInfo *crtc_mode_info_one =
- meta_crtc_mode_get_info (crtc_mode_one);
- const MetaCrtcModeInfo *crtc_mode_info_two =
- meta_crtc_mode_get_info (crtc_mode_two);
-
- if (crtc_mode_info_one->width != crtc_mode_info_two->width)
- return crtc_mode_info_one->width > crtc_mode_info_two->width ? -1 : 1;
- if (crtc_mode_info_one->height != crtc_mode_info_two->height)
- return crtc_mode_info_one->height > crtc_mode_info_two->height ? -1 : 1;
- if (crtc_mode_info_one->refresh_rate != crtc_mode_info_two->refresh_rate)
- return (crtc_mode_info_one->refresh_rate > crtc_mode_info_two->refresh_rate
- ? -1 : 1);
-
- return g_strcmp0 (meta_crtc_mode_get_name (crtc_mode_one),
- meta_crtc_mode_get_name (crtc_mode_two));
-}
-
-static gboolean
-init_output_modes (MetaOutputInfo *output_info,
- MetaGpuKms *gpu_kms,
- MetaKmsConnector *kms_connector,
- GError **error)
-{
- const MetaKmsConnectorState *connector_state;
- GList *l;
- int i;
-
- connector_state = meta_kms_connector_get_current_state (kms_connector);
-
- output_info->preferred_mode = NULL;
-
- output_info->n_modes = g_list_length (connector_state->modes);
- output_info->modes = g_new0 (MetaCrtcMode *, output_info->n_modes);
- for (l = connector_state->modes, i = 0; l; l = l->next, i++)
- {
- MetaKmsMode *kms_mode = l->data;
- const drmModeModeInfo *drm_mode = meta_kms_mode_get_drm_mode (kms_mode);
- MetaCrtcMode *crtc_mode;
-
- crtc_mode = meta_gpu_kms_get_mode_from_kms_mode (gpu_kms, kms_mode);
- output_info->modes[i] = crtc_mode;
- if (drm_mode->type & DRM_MODE_TYPE_PREFERRED)
- output_info->preferred_mode = output_info->modes[i];
- }
-
- if (connector_state->has_scaling)
- {
- meta_topic (META_DEBUG_KMS, "Adding common modes to connector %u on %s",
- meta_kms_connector_get_id (kms_connector),
- meta_gpu_kms_get_file_path (gpu_kms));
- add_common_modes (output_info, gpu_kms);
- }
-
- if (!output_info->modes)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "No modes available");
- return FALSE;
- }
-
- qsort (output_info->modes, output_info->n_modes,
- sizeof (MetaCrtcMode *), compare_modes);
-
- if (!output_info->preferred_mode)
- output_info->preferred_mode = output_info->modes[0];
-
- return TRUE;
-}
-
-static MetaConnectorType
-meta_kms_connector_type_from_drm (uint32_t drm_connector_type)
-{
- g_warn_if_fail (drm_connector_type < META_CONNECTOR_TYPE_META);
-
- return (MetaConnectorType) drm_connector_type;
-}
-
-MetaOutputKms *
-meta_output_kms_new (MetaGpuKms *gpu_kms,
- MetaKmsConnector *kms_connector,
- MetaOutput *old_output,
- GError **error)
-{
- MetaGpu *gpu = META_GPU (gpu_kms);
- uint32_t connector_id;
- uint32_t gpu_id;
- g_autoptr (MetaOutputInfo) output_info = NULL;
- MetaOutput *output;
- MetaOutputKms *output_kms;
- uint32_t drm_connector_type;
- const MetaKmsConnectorState *connector_state;
- GArray *crtcs;
- GList *l;
-
- gpu_id = meta_gpu_kms_get_id (gpu_kms);
- connector_id = meta_kms_connector_get_id (kms_connector);
-
- output_info = meta_output_info_new ();
- output_info->name = g_strdup (meta_kms_connector_get_name (kms_connector));
-
- connector_state = meta_kms_connector_get_current_state (kms_connector);
-
- output_info->panel_orientation_transform =
- connector_state->panel_orientation_transform;
- if (meta_monitor_transform_is_rotated (output_info->panel_orientation_transform))
- {
- output_info->width_mm = connector_state->height_mm;
- output_info->height_mm = connector_state->width_mm;
- }
- else
- {
- output_info->width_mm = connector_state->width_mm;
- output_info->height_mm = connector_state->height_mm;
- }
-
- if (!init_output_modes (output_info, gpu_kms, kms_connector, error))
- return NULL;
-
- crtcs = g_array_new (FALSE, FALSE, sizeof (MetaCrtc *));
-
- for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
- {
- MetaCrtcKms *crtc_kms = META_CRTC_KMS (l->data);
- MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
- 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_kms);
- }
-
- output_info->n_possible_crtcs = crtcs->len;
- output_info->possible_crtcs = (MetaCrtc **) g_array_free (crtcs, FALSE);
-
- output_info->suggested_x = connector_state->suggested_x;
- output_info->suggested_y = connector_state->suggested_y;
- output_info->hotplug_mode_update = connector_state->hotplug_mode_update;
- output_info->supports_underscanning =
- meta_kms_connector_is_underscanning_supported (kms_connector);
-
- meta_output_info_parse_edid (output_info, connector_state->edid_data);
-
- drm_connector_type = meta_kms_connector_get_connector_type (kms_connector);
- output_info->connector_type =
- meta_kms_connector_type_from_drm (drm_connector_type);
-
- output_info->tile_info = connector_state->tile_info;
-
- output = g_object_new (META_TYPE_OUTPUT_KMS,
- "id", ((uint64_t) gpu_id << 32) | connector_id,
- "gpu", gpu,
- "info", output_info,
- NULL);
- output_kms = META_OUTPUT_KMS (output);
- output_kms->kms_connector = kms_connector;
-
- if (connector_state->current_crtc_id)
- {
- for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
- {
- MetaCrtc *crtc = l->data;
-
- if (meta_crtc_get_id (crtc) == connector_state->current_crtc_id)
- {
- MetaOutputAssignment output_assignment;
-
- if (old_output)
- {
- output_assignment = (MetaOutputAssignment) {
- .is_primary = meta_output_is_primary (old_output),
- .is_presentation = meta_output_is_presentation (old_output),
- };
- }
- else
- {
- output_assignment = (MetaOutputAssignment) {
- .is_primary = FALSE,
- .is_presentation = FALSE,
- };
- }
- meta_output_assign_crtc (output, crtc, &output_assignment);
- break;
- }
- }
- }
- else
- {
- meta_output_unassign_crtc (output);
- }
-
- return output_kms;
-}
-
-static void
-meta_output_kms_init (MetaOutputKms *output_kms)
-{
-}
-
-static void
-meta_output_kms_class_init (MetaOutputKmsClass *klass)
-{
- MetaOutputNativeClass *output_native_class = META_OUTPUT_NATIVE_CLASS (klass);
-
- output_native_class->read_edid = meta_output_kms_read_edid;
-}
diff --git a/src/backends/native/meta-output-kms.h b/src/backends/native/meta-output-kms.h
deleted file mode 100644
index 52acc6032..000000000
--- a/src/backends/native/meta-output-kms.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- 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"
-#include "backends/native/meta-output-native.h"
-
-#define META_TYPE_OUTPUT_KMS (meta_output_kms_get_type ())
-G_DECLARE_FINAL_TYPE (MetaOutputKms, meta_output_kms,
- META, OUTPUT_KMS,
- MetaOutputNative)
-
-void meta_output_kms_set_power_save_mode (MetaOutputKms *output_kms,
- uint64_t dpms_state,
- MetaKmsUpdate *kms_update);
-
-void meta_output_kms_set_underscan (MetaOutputKms *output_kms,
- MetaKmsUpdate *kms_update);
-
-gboolean meta_output_kms_can_clone (MetaOutputKms *output_kms,
- MetaOutputKms *other_output_kms);
-
-MetaKmsConnector * meta_output_kms_get_kms_connector (MetaOutputKms *output_kms);
-
-uint32_t meta_output_kms_get_connector_id (MetaOutputKms *output_kms);
-
-MetaOutputKms * meta_output_kms_new (MetaGpuKms *gpu_kms,
- MetaKmsConnector *kms_connector,
- MetaOutput *old_output,
- GError **error);
-
-#endif /* META_OUTPUT_KMS_H */
diff --git a/src/backends/native/meta-output-native.c b/src/backends/native/meta-output-native.c
deleted file mode 100644
index f21b2ebc6..000000000
--- a/src/backends/native/meta-output-native.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.
- */
-
-#include "config.h"
-
-#include "backends/native/meta-output-native.h"
-
-G_DEFINE_ABSTRACT_TYPE (MetaOutputNative, meta_output_native,
- META_TYPE_OUTPUT)
-
-GBytes *
-meta_output_native_read_edid (MetaOutputNative *output_native)
-{
- MetaOutputNativeClass *klass = META_OUTPUT_NATIVE_GET_CLASS (output_native);
-
- return klass->read_edid (output_native);
-}
-
-static void
-meta_output_native_init (MetaOutputNative *output_native)
-{
-}
-
-static void
-meta_output_native_class_init (MetaOutputNativeClass *klass)
-{
-}
diff --git a/src/backends/native/meta-output-native.h b/src/backends/native/meta-output-native.h
deleted file mode 100644
index f0475ae3b..000000000
--- a/src/backends/native/meta-output-native.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef META_OUTPUT_NATIVE_H
-#define META_OUTPUT_NATIVE_H
-
-#include "backends/meta-output.h"
-
-#define META_TYPE_OUTPUT_NATIVE (meta_output_native_get_type ())
-G_DECLARE_DERIVABLE_TYPE (MetaOutputNative, meta_output_native,
- META, OUTPUT_NATIVE,
- MetaOutput)
-
-struct _MetaOutputNativeClass
-{
- MetaOutputClass parent_class;
-
- GBytes * (* read_edid) (MetaOutputNative *output_native);
-};
-
-GBytes * meta_output_native_read_edid (MetaOutputNative *output_native);
-
-#endif /* META_OUTPUT_NATIVE_H */
diff --git a/src/backends/native/meta-output-virtual.c b/src/backends/native/meta-output-virtual.c
deleted file mode 100644
index 12efb3338..000000000
--- a/src/backends/native/meta-output-virtual.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2021 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-output-virtual.h"
-
-#include "backends/native/meta-crtc-mode-virtual.h"
-#include "backends/native/meta-crtc-virtual.h"
-#include "backends/meta-virtual-monitor.h"
-
-struct _MetaOutputVirtual
-{
- MetaOutputNative parent;
-};
-
-#define META_OUTPUT_VIRTUAL_ID_BIT (((uint64_t) 1) << 63)
-
-G_DEFINE_TYPE (MetaOutputVirtual, meta_output_virtual, META_TYPE_OUTPUT_NATIVE)
-
-MetaOutputVirtual *
-meta_output_virtual_new (uint64_t id,
- const MetaVirtualMonitorInfo *info,
- MetaCrtcVirtual *crtc_virtual,
- MetaCrtcModeVirtual *crtc_mode_virtual)
-{
- g_autoptr (MetaOutputInfo) output_info = NULL;
-
- output_info = meta_output_info_new ();
- output_info->name = g_strdup_printf ("Meta-%" G_GUINT64_FORMAT, id);
-
- output_info->n_possible_crtcs = 1;
- output_info->possible_crtcs = g_new0 (MetaCrtc *, 1);
- output_info->possible_crtcs[0] = META_CRTC (crtc_virtual);
-
- output_info->hotplug_mode_update = FALSE;
- output_info->suggested_x = -1;
- output_info->suggested_y = -1;
-
- output_info->connector_type = META_CONNECTOR_TYPE_META;
- output_info->vendor = g_strdup (info->vendor);
- output_info->product = g_strdup (info->product);
- output_info->serial = g_strdup (info->serial);
-
- output_info->n_modes = 1;
- output_info->modes = g_new0 (MetaCrtcMode *, 1);
- output_info->modes[0] = META_CRTC_MODE (crtc_mode_virtual);
- output_info->preferred_mode = output_info->modes[0];
-
- return g_object_new (META_TYPE_OUTPUT_VIRTUAL,
- "id", META_OUTPUT_VIRTUAL_ID_BIT | id,
- "info", output_info,
- NULL);
-}
-
-static void
-meta_output_virtual_init (MetaOutputVirtual *output_virtual)
-{
-}
-
-static void
-meta_output_virtual_class_init (MetaOutputVirtualClass *klass)
-{
-}
diff --git a/src/backends/native/meta-output-virtual.h b/src/backends/native/meta-output-virtual.h
deleted file mode 100644
index b04579f0d..000000000
--- a/src/backends/native/meta-output-virtual.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2021 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_VIRTUAL_H
-#define META_OUTPUT_VIRTUAL_H
-
-#include "backends/native/meta-backend-native-types.h"
-#include "backends/native/meta-output-native.h"
-
-#define META_TYPE_OUTPUT_VIRTUAL (meta_output_virtual_get_type ())
-G_DECLARE_FINAL_TYPE (MetaOutputVirtual, meta_output_virtual,
- META, OUTPUT_VIRTUAL,
- MetaOutputNative)
-
-MetaOutputVirtual * meta_output_virtual_new (uint64_t id,
- const MetaVirtualMonitorInfo *info,
- MetaCrtcVirtual *crtc_virtual,
- MetaCrtcModeVirtual *crtc_mode_virtual);
-
-#endif /* META_OUTPUT_VIRTUAL_H */
diff --git a/src/backends/native/meta-pointer-constraint-native.c b/src/backends/native/meta-pointer-constraint-native.c
deleted file mode 100644
index 6a1c066ad..000000000
--- a/src/backends/native/meta-pointer-constraint-native.c
+++ /dev/null
@@ -1,694 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2015-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:
- * Jonas Ådahl <jadahl@gmail.com>
- */
-
-#include "config.h"
-
-#include <glib-object.h>
-#include <wayland-server.h>
-
-#include "core/meta-border.h"
-#include "meta-pointer-constraint-native.h"
-
-struct _MetaPointerConstraintImplNative
-{
- MetaPointerConstraintImpl parent;
- MetaPointerConstraint *constraint;
- cairo_region_t *region;
-};
-
-G_DEFINE_TYPE (MetaPointerConstraintImplNative,
- meta_pointer_constraint_impl_native,
- META_TYPE_POINTER_CONSTRAINT_IMPL);
-
-typedef struct _MetaBox
-{
- int x1;
- int y1;
- int x2;
- int y2;
-} MetaBox;
-
-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_constraint_impl_native_constraint (MetaPointerConstraintImpl *constraint_impl,
- ClutterInputDevice *device,
- uint32_t time,
- float prev_x,
- float prev_y,
- float *x_inout,
- float *y_inout)
-{
- MetaPointerConstraintImplNative *constraint_impl_native;
- cairo_region_t *region;
- float x, y;
- GArray *borders;
- MetaLine2 motion;
- MetaBorder *closest_border;
- uint32_t directions;
-
- constraint_impl_native = META_POINTER_CONSTRAINT_IMPL_NATIVE (constraint_impl);
-
- region = cairo_region_reference (constraint_impl_native->region);
- x = *x_inout;
- y = *y_inout;
-
- /* 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 (x > prev_x)
- x += (float) wl_fixed_to_double(1);
- if (y > prev_y)
- y += (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_to_outline (region, borders);
- cairo_region_destroy (region);
-
- motion = (MetaLine2) {
- .a = (MetaVector2) {
- .x = prev_x,
- .y = prev_y,
- },
- .b = (MetaVector2) {
- .x = x,
- .y = y,
- },
- };
- 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;
- }
-
- *x_inout = motion.b.x;
- *y_inout = motion.b.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
-closest_point_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_constraint_impl_native_ensure_constrained (MetaPointerConstraintImpl *constraint_impl,
- ClutterInputDevice *device)
-{
- MetaPointerConstraintImplNative *constraint_impl_native;
- graphene_point_t point;
- cairo_region_t *region;
- float x;
- float y;
-
- constraint_impl_native = META_POINTER_CONSTRAINT_IMPL_NATIVE (constraint_impl);
- region = cairo_region_reference (constraint_impl_native->region);
-
- clutter_seat_query_state (clutter_input_device_get_seat (device),
- device, NULL, &point, NULL);
- x = point.x;
- y = point.y;
-
- if (!cairo_region_contains_point (region, (int) x, (int) y))
- {
- GArray *borders;
- float closest_distance_2 = FLT_MAX;
- MetaBorder *closest_border = NULL;
- ClutterSeat *seat;
- unsigned int i;
-
- 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, x, y);
- if (distance_2 < closest_distance_2)
- {
- closest_border = border;
- closest_distance_2 = distance_2;
- }
- }
-
- closest_point_behind_border (closest_border, &x, &y);
-
- seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
- clutter_seat_warp_pointer (seat, x, y);
- }
-
- cairo_region_destroy (region);
-}
-
-static void
-meta_pointer_constraint_impl_native_finalize (GObject *object)
-{
- MetaPointerConstraintImplNative *constraint_impl_native;
-
- constraint_impl_native = META_POINTER_CONSTRAINT_IMPL_NATIVE (object);
- g_clear_pointer (&constraint_impl_native->region, cairo_region_destroy);
-
- G_OBJECT_CLASS (meta_pointer_constraint_impl_native_parent_class)->finalize (object);
-}
-
-static void
-meta_pointer_constraint_impl_native_init (MetaPointerConstraintImplNative *constraint_impl_native)
-{
-}
-
-static void
-meta_pointer_constraint_impl_native_class_init (MetaPointerConstraintImplNativeClass *klass)
-{
- MetaPointerConstraintImplClass *constraint_impl_class;
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = meta_pointer_constraint_impl_native_finalize;
-
- constraint_impl_class = META_POINTER_CONSTRAINT_IMPL_CLASS (klass);
- constraint_impl_class->constrain = meta_pointer_constraint_impl_native_constraint;
- constraint_impl_class->ensure_constrained =
- meta_pointer_constraint_impl_native_ensure_constrained;
-}
-
-
-MetaPointerConstraintImpl *
-meta_pointer_constraint_impl_native_new (MetaPointerConstraint *constraint,
- const cairo_region_t *region)
-{
- MetaPointerConstraintImplNative *constraint_impl;
-
- constraint_impl = g_object_new (META_TYPE_POINTER_CONSTRAINT_IMPL_NATIVE,
- NULL);
- constraint_impl->constraint = constraint;
- constraint_impl->region = cairo_region_copy (region);
-
- return META_POINTER_CONSTRAINT_IMPL (constraint_impl);
-}
diff --git a/src/backends/native/meta-pointer-constraint-native.h b/src/backends/native/meta-pointer-constraint-native.h
deleted file mode 100644
index 83a2e575d..000000000
--- a/src/backends/native/meta-pointer-constraint-native.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * 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_POINTER_CONSTRAINT_NATIVE_H
-#define META_POINTER_CONSTRAINT_NATIVE_H
-
-#include <glib-object.h>
-
-#include "clutter/clutter.h"
-#include "backends/meta-pointer-constraint.h"
-
-G_BEGIN_DECLS
-
-#define META_TYPE_POINTER_CONSTRAINT_IMPL_NATIVE (meta_pointer_constraint_impl_native_get_type ())
-G_DECLARE_FINAL_TYPE (MetaPointerConstraintImplNative,
- meta_pointer_constraint_impl_native,
- META, POINTER_CONSTRAINT_IMPL_NATIVE,
- MetaPointerConstraintImpl)
-
-MetaPointerConstraintImpl * meta_pointer_constraint_impl_native_new (MetaPointerConstraint *constraint_impl,
- const cairo_region_t *region);
-
-G_END_DECLS
-
-#endif /* META_POINTER_CONSTRAINT_NATIVE_H */
diff --git a/src/backends/native/meta-renderer-native-gles3.c b/src/backends/native/meta-renderer-native-gles3.c
deleted file mode 100644
index c0eb77554..000000000
--- a/src/backends/native/meta-renderer-native-gles3.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* -*- 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 conflict 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
deleted file mode 100644
index 4e7324c8d..000000000
--- a/src/backends/native/meta-renderer-native-gles3.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- 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-private.h b/src/backends/native/meta-renderer-native-private.h
deleted file mode 100644
index acadb3fff..000000000
--- a/src/backends/native/meta-renderer-native-private.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2011 Intel Corporation.
- * Copyright (C) 2016-2020 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.
- *
- */
-
-#ifndef META_RENDERER_NATIVE_PRIVATE_H
-#define META_RENDERER_NATIVE_PRIVATE_H
-
-#include "backends/meta-gles3.h"
-#include "backends/native/meta-renderer-native.h"
-
-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;
-
- MetaDeviceFile *device_file;
-
- 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;
-
-MetaEgl * meta_renderer_native_get_egl (MetaRendererNative *renderer_native);
-
-MetaGles3 * meta_renderer_native_get_gles3 (MetaRendererNative *renderer_native);
-
-MetaRendererNativeGpuData * meta_renderer_native_get_gpu_data (MetaRendererNative *renderer_native,
- MetaGpuKms *gpu_kms);
-
-gboolean meta_renderer_native_has_pending_mode_sets (MetaRendererNative *renderer_native);
-
-gboolean meta_renderer_native_has_pending_mode_set (MetaRendererNative *renderer_native);
-
-void meta_renderer_native_notify_mode_sets_reset (MetaRendererNative *renderer_native);
-
-void meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native);
-
-void meta_renderer_native_queue_power_save_page_flip (MetaRendererNative *renderer_native,
- CoglOnscreen *onscreen);
-
-CoglFramebuffer * meta_renderer_native_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);
-
-gboolean meta_renderer_native_pop_pending_mode_set (MetaRendererNative *renderer_native,
- MetaRendererView *view);
-
-const CoglWinsysVtable * meta_get_renderer_native_parent_vtable (void);
-
-#endif /* META_RENDERER_NATIVE_PRIVATE_H */
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
deleted file mode 100644
index eb6771b80..000000000
--- a/src/backends/native/meta-renderer-native.c
+++ /dev/null
@@ -1,2264 +0,0 @@
-/* -*- 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 <gbm.h>
-#include <gio/gio.h>
-#include <glib-object.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "backends/meta-gles3.h"
-#include "backends/meta-logical-monitor.h"
-#include "backends/native/meta-backend-native-private.h"
-#include "backends/native/meta-cogl-utils.h"
-#include "backends/native/meta-crtc-kms.h"
-#include "backends/native/meta-crtc-virtual.h"
-#include "backends/native/meta-device-pool.h"
-#include "backends/native/meta-kms-device.h"
-#include "backends/native/meta-kms.h"
-#include "backends/native/meta-onscreen-native.h"
-#include "backends/native/meta-renderer-native-private.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
-
-struct _MetaRendererNative
-{
- MetaRenderer parent;
-
- MetaGpuKms *primary_gpu_kms;
-
- MetaGles3 *gles3;
-
- gboolean use_modifiers;
-
- GHashTable *gpu_datas;
-
- GList *pending_mode_set_views;
- gboolean pending_mode_set;
-
- GList *kept_alive_onscreens;
-
- 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 gboolean
-meta_renderer_native_ensure_gpu_data (MetaRendererNative *renderer_native,
- MetaGpuKms *gpu_kms,
- GError **error);
-
-static void
-meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native);
-
-const CoglWinsysVtable *
-meta_get_renderer_native_parent_vtable (void)
-{
- return parent_vtable;
-}
-
-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->secondary.egl_context != EGL_NO_CONTEXT)
- {
- meta_egl_destroy_context (egl,
- renderer_gpu_data->egl_display,
- renderer_gpu_data->secondary.egl_context,
- NULL);
- }
-
- 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_clear_pointer (&renderer_gpu_data->device_file, meta_device_file_release);
- g_free (renderer_gpu_data);
-}
-
-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;
-}
-
-MetaGpuKms *
-meta_renderer_native_get_primary_gpu (MetaRendererNative *renderer_native)
-{
- return renderer_native->primary_gpu_kms;
-}
-
-MetaDeviceFile *
-meta_renderer_native_get_primary_device_file (MetaRendererNative *renderer_native)
-{
- MetaGpuKms *gpu_kms = renderer_native->primary_gpu_kms;
- MetaRendererNativeGpuData *renderer_gpu_data;
-
- renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
- gpu_kms);
- return renderer_gpu_data->device_file;
-}
-
-static MetaRendererNativeGpuData *
-meta_create_renderer_native_gpu_data (void)
-{
- return g_new0 (MetaRendererNativeGpuData, 1);
-}
-
-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));
-}
-
-gboolean
-meta_renderer_native_use_modifiers (MetaRendererNative *renderer_native)
-{
- return renderer_native->use_modifiers;
-}
-
-MetaGles3 *
-meta_renderer_native_get_gles3 (MetaRendererNative *renderer_native)
-{
- return renderer_native->gles3;
-}
-
-gboolean
-meta_renderer_native_has_pending_mode_sets (MetaRendererNative *renderer_native)
-{
- return !!renderer_native->pending_mode_set_views;
-}
-
-gboolean
-meta_renderer_native_has_pending_mode_set (MetaRendererNative *renderer_native)
-{
- return renderer_native->pending_mode_set;
-}
-
-static void
-meta_renderer_native_disconnect (CoglRenderer *cogl_renderer)
-{
- CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
-
- g_free (cogl_renderer_egl);
-}
-
-static gboolean
-meta_renderer_native_connect (CoglRenderer *cogl_renderer,
- GError **error)
-{
- CoglRendererEGL *cogl_renderer_egl;
- MetaRendererNative *renderer_native = cogl_renderer->custom_winsys_user_data;
- MetaGpuKms *gpu_kms;
- MetaRendererNativeGpuData *renderer_gpu_data;
-
- cogl_renderer->winsys = g_new0 (CoglRendererEGL, 1);
- cogl_renderer_egl = cogl_renderer->winsys;
-
- gpu_kms = meta_renderer_native_get_primary_gpu (renderer_native);
- 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,
- const 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;
- case META_RENDERER_NATIVE_MODE_SURFACELESS:
- attributes[i++] = EGL_SURFACE_TYPE;
- attributes[i++] = EGL_PBUFFER_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);
- case META_RENDERER_NATIVE_MODE_SURFACELESS:
- *out_config = EGL_NO_CONFIG_KHR;
- return TRUE;
-#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 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);
-}
-
-CoglFramebuffer *
-meta_renderer_native_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 = meta_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))
- {
- g_object_unref (cogl_fbo);
- return NULL;
- }
-
- return COGL_FRAMEBUFFER (cogl_fbo);
-}
-
-static void
-configure_disabled_crtcs (MetaKmsDevice *kms_device)
-{
- MetaKms *kms = meta_kms_device_get_kms (kms_device);
- GList *l;
-
- for (l = meta_kms_device_get_crtcs (kms_device); l; l = l->next)
- {
- MetaKmsCrtc *kms_crtc = l->data;
- MetaCrtcKms *crtc_kms = meta_crtc_kms_from_kms_crtc (kms_crtc);
- MetaKmsUpdate *kms_update;
-
- if (meta_crtc_get_config (META_CRTC (crtc_kms)))
- continue;
-
- if (!meta_kms_crtc_is_active (kms_crtc))
- continue;
-
- kms_update = meta_kms_ensure_pending_update (kms, kms_device);
- meta_kms_update_mode_set (kms_update, kms_crtc, NULL, NULL);
- }
-}
-
-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) meta_onscreen_native_dummy_power_save_page_flip,
- NULL);
- g_clear_list (&renderer_native->power_save_page_flip_onscreens,
- g_object_unref);
- renderer_native->power_save_page_flip_source_id = 0;
-
- return G_SOURCE_REMOVE;
-}
-
-void
-meta_renderer_native_queue_power_save_page_flip (MetaRendererNative *renderer_native,
- CoglOnscreen *onscreen)
-{
- 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,
- g_object_ref (onscreen));
-}
-
-static void
-clear_kept_alive_onscreens (MetaRendererNative *renderer_native)
-{
- g_clear_list (&renderer_native->kept_alive_onscreens,
- g_object_unref);
-}
-
-static gboolean
-is_gpu_unused (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- GHashTable *used_gpus = user_data;
-
- return !g_hash_table_contains (used_gpus, key);
-}
-
-static void
-free_unused_gpu_datas (MetaRendererNative *renderer_native)
-{
- MetaRenderer *renderer = META_RENDERER (renderer_native);
- g_autoptr (GHashTable) used_gpus = NULL;
- GList *l;
-
- used_gpus = g_hash_table_new (NULL, NULL);
- g_hash_table_add (used_gpus, renderer_native->primary_gpu_kms);
-
- for (l = meta_renderer_get_views (renderer); l; l = l->next)
- {
- MetaRendererView *view = l->data;
- MetaCrtc *crtc = meta_renderer_view_get_crtc (view);
- MetaGpu *gpu;
-
- gpu = meta_crtc_get_gpu (crtc);
- if (!gpu)
- continue;
-
- g_hash_table_add (used_gpus, gpu);
- }
-
- g_hash_table_foreach_remove (renderer_native->gpu_datas,
- is_gpu_unused,
- used_gpus);
-}
-
-void
-meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native)
-{
- MetaRenderer *renderer = META_RENDERER (renderer_native);
- MetaBackend *backend = meta_renderer_get_backend (renderer);
- MetaKms *kms = meta_backend_native_get_kms (META_BACKEND_NATIVE (backend));
- GList *l;
-
- for (l = meta_kms_get_devices (kms); l; l = l->next)
- {
- MetaKmsDevice *kms_device = l->data;
- MetaKmsUpdate *kms_update;
- MetaKmsUpdateFlag flags;
- g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
- const GError *feedback_error;
-
- configure_disabled_crtcs (kms_device);
-
- kms_update = meta_kms_get_pending_update (kms, kms_device);
- if (!kms_update)
- continue;
-
- flags = META_KMS_UPDATE_FLAG_NONE;
- kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device, flags);
-
- switch (meta_kms_feedback_get_result (kms_feedback))
- {
- case META_KMS_FEEDBACK_PASSED:
- break;
- case META_KMS_FEEDBACK_FAILED:
- feedback_error = meta_kms_feedback_get_error (kms_feedback);
- if (!g_error_matches (feedback_error,
- G_IO_ERROR,
- G_IO_ERROR_PERMISSION_DENIED))
- g_warning ("Failed to post KMS update: %s", feedback_error->message);
- break;
- }
- }
-
- clear_kept_alive_onscreens (renderer_native);
-
- meta_kms_notify_modes_set (kms);
-
- free_unused_gpu_datas (renderer_native);
-}
-
-static void
-unset_disabled_crtcs (MetaBackend *backend,
- MetaKms *kms)
-{
- GList *l;
-
- meta_topic (META_DEBUG_KMS, "Disabling all disabled CRTCs");
-
- for (l = meta_backend_get_gpus (backend); l; l = l->next)
- {
- MetaGpu *gpu = l->data;
- MetaKmsDevice *kms_device =
- meta_gpu_kms_get_kms_device (META_GPU_KMS (gpu));
- GList *k;
- gboolean did_mode_set = FALSE;
- MetaKmsUpdateFlag flags;
- g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
-
- for (k = meta_gpu_get_crtcs (gpu); k; k = k->next)
- {
- MetaCrtc *crtc = k->data;
- MetaKmsUpdate *kms_update;
-
- if (meta_crtc_get_config (crtc))
- continue;
-
- kms_update = meta_kms_ensure_pending_update (kms, kms_device);
- meta_crtc_kms_set_mode (META_CRTC_KMS (crtc), kms_update);
-
- did_mode_set = TRUE;
- }
-
- if (!did_mode_set)
- continue;
-
- flags = META_KMS_UPDATE_FLAG_NONE;
- kms_feedback = meta_kms_post_pending_update_sync (kms,
- kms_device,
- flags);
- 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 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 stride;
- int offset;
- int bpp;
- 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;
- }
-
- stride = gbm_bo_get_stride (new_bo);
- offset = gbm_bo_get_offset (new_bo, 0);
- bpp = 4;
- dmabuf_fb =
- meta_renderer_native_create_dma_buf_framebuffer (renderer_native,
- dmabuf_fd,
- width, height,
- stride,
- offset,
- DRM_FORMAT_MOD_LINEAR,
- DRM_FORMAT_XRGB8888,
- error);
-
- if (!dmabuf_fb)
- return NULL;
-
- dmabuf_handle =
- cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd,
- width, height, stride, offset, bpp,
- new_bo,
- (GDestroyNotify) gbm_bo_destroy);
- g_object_unref (dmabuf_fb);
- return dmabuf_handle;
- }
- break;
- case META_RENDERER_NATIVE_MODE_SURFACELESS:
-#ifdef HAVE_EGL_DEVICE
- case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
-#endif
- break;
- }
-
- 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->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);
-
-#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 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;
-
- g_clear_list (&renderer_native->pending_mode_set_views, NULL);
- 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);
-
- if (COGL_IS_ONSCREEN (framebuffer))
- {
- renderer_native->pending_mode_set_views =
- g_list_prepend (renderer_native->pending_mode_set_views,
- stage_view);
- }
- }
- renderer_native->pending_mode_set = TRUE;
-
- meta_topic (META_DEBUG_KMS, "Queue mode set");
-}
-
-void
-meta_renderer_native_notify_mode_sets_reset (MetaRendererNative *renderer_native)
-{
- renderer_native->pending_mode_set = FALSE;
-}
-
-gboolean
-meta_renderer_native_pop_pending_mode_set (MetaRendererNative *renderer_native,
- MetaRendererView *view)
-{
- MetaRenderer *renderer = META_RENDERER (renderer_native);
- MetaBackend *backend = meta_renderer_get_backend (renderer);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- MetaPowerSave power_save_mode;
- GList *link;
-
- g_assert (META_IS_RENDERER_VIEW (view));
-
- power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
- if (power_save_mode != META_POWER_SAVE_ON)
- return FALSE;
-
- link = g_list_find (renderer_native->pending_mode_set_views, view);
- if (!link)
- return FALSE;
-
- renderer_native->pending_mode_set_views =
- g_list_delete_link (renderer_native->pending_mode_set_views, link);
- return TRUE;
-}
-
-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))
- {
- g_object_unref (fb);
- return FALSE;
- }
-
- return fb;
-}
-
-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_inited = TRUE;
- }
-
- return &vtable;
-}
-
-static CoglRenderer *
-meta_renderer_native_create_cogl_renderer (MetaRenderer *renderer)
-{
- CoglRenderer *cogl_renderer;
-
- cogl_renderer = cogl_renderer_new ();
- cogl_renderer_set_custom_winsys (cogl_renderer,
- get_native_cogl_winsys_vtable,
- renderer);
- return cogl_renderer;
-}
-
-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);
- CoglContext *cogl_context =
- cogl_context_from_renderer_native (renderer_native);
- MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (primary_gpu);
-
- if (meta_renderer_is_hardware_accelerated (renderer))
- return FALSE;
-
- if (!cogl_has_feature (cogl_context, COGL_FEATURE_ID_BLIT_FRAMEBUFFER))
- return FALSE;
-
- return meta_kms_device_prefers_shadow_buffer (kms_device);
-}
-
-static CoglFramebuffer *
-create_fallback_offscreen (MetaRendererNative *renderer_native,
- CoglContext *cogl_context,
- int width,
- int height)
-{
- CoglOffscreen *fallback_offscreen;
- GError *error = NULL;
-
- fallback_offscreen = meta_renderer_native_create_offscreen (renderer_native,
- cogl_context,
- width,
- height,
- &error);
- if (!fallback_offscreen)
- {
- g_error ("Failed to create fallback offscreen framebuffer: %s",
- error->message);
- }
-
- return COGL_FRAMEBUFFER (fallback_offscreen);
-}
-
-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);
- const MetaCrtcConfig *crtc_config;
- const MetaCrtcModeInfo *crtc_mode_info;
- MetaMonitorTransform view_transform;
- g_autoptr (CoglFramebuffer) framebuffer = NULL;
- g_autoptr (CoglOffscreen) offscreen = NULL;
- gboolean use_shadowfb;
- float scale;
- int onscreen_width;
- int onscreen_height;
- MetaRectangle view_layout;
- MetaRendererView *view;
- EGLSurface egl_surface;
- GError *error = NULL;
-
- crtc_config = meta_crtc_get_config (crtc);
- crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode);
- onscreen_width = crtc_mode_info->width;
- onscreen_height = crtc_mode_info->height;
-
- if (META_IS_CRTC_KMS (crtc))
- {
- MetaGpuKms *gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
- MetaOnscreenNative *onscreen_native;
-
- if (!meta_renderer_native_ensure_gpu_data (renderer_native,
- gpu_kms,
- &error))
- {
- g_warning ("Failed to create secondary GPU data for %s: %s",
- meta_gpu_kms_get_file_path (gpu_kms),
- error->message);
- use_shadowfb = FALSE;
- framebuffer = create_fallback_offscreen (renderer_native,
- cogl_context,
- onscreen_width,
- onscreen_height);
- }
- else
- {
- MetaGpuKms *primary_gpu_kms = renderer_native->primary_gpu_kms;
-
- onscreen_native = meta_onscreen_native_new (renderer_native,
- primary_gpu_kms,
- output,
- crtc,
- cogl_context,
- onscreen_width,
- onscreen_height);
-
- if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (onscreen_native), &error))
- {
- g_warning ("Failed to allocate onscreen framebuffer for %s: %s",
- meta_gpu_kms_get_file_path (gpu_kms),
- error->message);
- use_shadowfb = FALSE;
- framebuffer = create_fallback_offscreen (renderer_native,
- cogl_context,
- onscreen_width,
- onscreen_height);
- }
- else
- {
- use_shadowfb = should_force_shadow_fb (renderer_native,
- primary_gpu_kms);
- framebuffer = COGL_FRAMEBUFFER (onscreen_native);
- }
- }
- }
- else
- {
- CoglOffscreen *virtual_onscreen;
-
- g_assert (META_IS_CRTC_VIRTUAL (crtc));
-
- virtual_onscreen = meta_renderer_native_create_offscreen (renderer_native,
- cogl_context,
- onscreen_width,
- onscreen_height,
- &error);
- if (!virtual_onscreen)
- g_error ("Failed to allocate back buffer texture: %s", error->message);
- use_shadowfb = FALSE;
- framebuffer = COGL_FRAMEBUFFER (virtual_onscreen);
- }
-
- 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 (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,
- "name", meta_output_get_name (output),
- "stage", meta_backend_get_stage (backend),
- "layout", &view_layout,
- "crtc", crtc,
- "scale", scale,
- "framebuffer", framebuffer,
- "offscreen", offscreen,
- "use-shadowfb", use_shadowfb,
- "transform", view_transform,
- "refresh-rate", crtc_mode_info->refresh_rate,
- "vblank-duration-us", crtc_mode_info->vblank_duration_us,
- NULL);
-
- if (META_IS_ONSCREEN_NATIVE (framebuffer))
- {
- CoglDisplayEGL *cogl_display_egl;
- CoglOnscreenEgl *onscreen_egl;
-
- meta_onscreen_native_set_view (COGL_ONSCREEN (framebuffer), view);
-
- /* Ensure we don't point to stale surfaces when creating the offscreen */
- cogl_display_egl = cogl_display->winsys;
- onscreen_egl = COGL_ONSCREEN_EGL (framebuffer);
- egl_surface = cogl_onscreen_egl_get_egl_surface (onscreen_egl);
- _cogl_winsys_egl_make_current (cogl_display,
- egl_surface,
- egl_surface,
- cogl_display_egl->egl_context);
- }
-
- return view;
-}
-
-static void
-keep_current_onscreens_alive (MetaRenderer *renderer)
-{
- MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
- GList *views;
- GList *l;
-
- views = meta_renderer_get_views (renderer);
- for (l = views; l; l = l->next)
- {
- ClutterStageView *stage_view = l->data;
- CoglFramebuffer *onscreen = clutter_stage_view_get_onscreen (stage_view);
-
- renderer_native->kept_alive_onscreens =
- g_list_prepend (renderer_native->kept_alive_onscreens,
- g_object_ref (onscreen));
- }
-}
-
-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);
-
- keep_current_onscreens_alive (renderer);
-
- parent_renderer_class->rebuild_views (renderer);
-
- meta_renderer_native_queue_modes_reset (META_RENDERER_NATIVE (renderer));
-}
-
-void
-meta_renderer_native_prepare_frame (MetaRendererNative *renderer_native,
- MetaRendererView *view,
- ClutterFrame *frame)
-{
- MetaRenderer *renderer = META_RENDERER (renderer_native);
- MetaBackend *backend = meta_renderer_get_backend (renderer);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- MetaCrtc *crtc = meta_renderer_view_get_crtc (view);
- MetaPowerSave power_save_mode;
- MetaCrtcKms *crtc_kms;
- MetaKmsCrtc *kms_crtc;
- MetaKmsDevice *kms_device;
-
- if (!META_IS_CRTC_KMS (crtc))
- return;
-
- power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
- if (power_save_mode != META_POWER_SAVE_ON)
- return;
-
- crtc_kms = META_CRTC_KMS (crtc);
- kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
- kms_device = meta_kms_crtc_get_device (kms_crtc);
-
- meta_crtc_kms_maybe_set_gamma (crtc_kms, kms_device);
-}
-
-void
-meta_renderer_native_finish_frame (MetaRendererNative *renderer_native,
- MetaRendererView *view,
- ClutterFrame *frame)
-{
- if (!clutter_frame_has_result (frame))
- {
- CoglFramebuffer *framebuffer =
- clutter_stage_view_get_onscreen (CLUTTER_STAGE_VIEW (view));
-
- if (COGL_IS_ONSCREEN (framebuffer))
- {
- CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
-
- meta_onscreen_native_finish_frame (onscreen, frame);
- }
- }
-}
-
-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:
- case META_RENDERER_NATIVE_MODE_SURFACELESS:
- 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 void
-maybe_restore_cogl_egl_api (MetaRendererNative *renderer_native)
-{
- CoglContext *cogl_context;
- CoglDisplay *cogl_display;
- CoglRenderer *cogl_renderer;
-
- cogl_context = cogl_context_from_renderer_native (renderer_native);
- if (!cogl_context)
- return;
-
- cogl_display = cogl_context_get_display (cogl_context);
- cogl_renderer = cogl_display_get_renderer (cogl_display);
- cogl_renderer_bind_api (cogl_renderer);
-}
-
-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;
-
- meta_egl_bind_api (egl, EGL_OPENGL_ES_API, NULL);
-
- if (!create_secondary_egl_config (egl, renderer_gpu_data->mode, egl_display,
- &egl_config, error))
- goto err;
-
- egl_context = create_secondary_egl_context (egl, egl_display, egl_config, error);
- if (egl_context == EGL_NO_CONTEXT)
- goto err;
-
- 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);
- goto err;
- }
-
- 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 err_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 err_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);
-
- maybe_restore_cogl_egl_api (renderer_native);
-
- return TRUE;
-
-err_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);
-
-err:
- maybe_restore_cogl_egl_api (renderer_native);
-
- 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_message ("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,
- MetaDeviceFile *device_file,
- GError **error)
-{
- struct gbm_device *gbm_device;
- MetaRendererNativeGpuData *renderer_gpu_data;
- g_autoptr (GError) local_error = NULL;
-
- gbm_device = gbm_create_device (meta_device_file_get_fd (device_file));
- 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 ();
- renderer_gpu_data->device_file = meta_device_file_acquire (device_file);
- 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_device_file_get_path (device_file),
- 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;
-}
-
-static EGLDisplay
-init_surfaceless_egl_display (MetaRendererNative *renderer_native,
- 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_surfaceless",
- NULL))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Missing EGL platform required for surfaceless context: "
- "EGL_MESA_platform_surfaceless");
- return EGL_NO_DISPLAY;
- }
-
- egl_display = meta_egl_get_platform_display (egl,
- EGL_PLATFORM_SURFACELESS_MESA,
- EGL_DEFAULT_DISPLAY,
- NULL, error);
- if (egl_display == EGL_NO_DISPLAY)
- return EGL_NO_DISPLAY;
-
- if (!meta_egl_initialize (egl, egl_display, error))
- return EGL_NO_DISPLAY;
-
- if (!meta_egl_has_extensions (egl, egl_display, NULL,
- "EGL_KHR_no_config_context",
- NULL))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Missing EGL extension required for surfaceless context: "
- "EGL_KHR_no_config_context");
- return EGL_NO_DISPLAY;
- }
-
- return egl_display;
-}
-
-static MetaRendererNativeGpuData *
-create_renderer_gpu_data_surfaceless (MetaRendererNative *renderer_native,
- GError **error)
-{
- MetaRendererNativeGpuData *renderer_gpu_data;
- EGLDisplay egl_display;
-
- egl_display = init_surfaceless_egl_display (renderer_native, error);
- if (egl_display == EGL_NO_DISPLAY)
- return NULL;
-
- renderer_gpu_data = meta_create_renderer_native_gpu_data ();
- renderer_gpu_data->renderer_native = renderer_native;
- renderer_gpu_data->mode = META_RENDERER_NATIVE_MODE_SURFACELESS;
- renderer_gpu_data->egl_display = egl_display;
-
- 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,
- MetaDeviceFile *device_file,
- 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_device_file_get_path (device_file);
-
- 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,
- MetaDeviceFile *device_file,
- EGLDeviceEXT egl_device,
- GError **error)
-{
- MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
- int kms_fd = meta_device_file_get_fd (device_file);
- 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,
- MetaDeviceFile *device_file,
- 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, device_file, error);
- if (egl_device == EGL_NO_DEVICE_EXT)
- return NULL;
-
- egl_display = get_egl_device_display (renderer_native, device_file,
- 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 ();
- renderer_gpu_data->device_file = meta_device_file_acquire (device_file);
- 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)
-{
- MetaRenderer *renderer = META_RENDERER (renderer_native);
- MetaBackend *backend = meta_renderer_get_backend (renderer);
- MetaDevicePool *device_pool =
- meta_backend_native_get_device_pool (META_BACKEND_NATIVE (backend));
- MetaRendererNativeGpuData *renderer_gpu_data;
- MetaDeviceFileFlags device_file_flags = META_DEVICE_FILE_FLAG_NONE;
- g_autoptr (MetaDeviceFile) device_file = NULL;
- GError *gbm_error = NULL;
-#ifdef HAVE_EGL_DEVICE
- GError *egl_device_error = NULL;
-#endif
-
- if (!gpu_kms)
- return create_renderer_gpu_data_surfaceless (renderer_native, error);
-
- if (!(meta_kms_device_get_flags (meta_gpu_kms_get_kms_device (gpu_kms)) &
- META_KMS_DEVICE_FLAG_NO_MODE_SETTING))
- device_file_flags = META_DEVICE_FILE_FLAG_TAKE_CONTROL;
-
- device_file = meta_device_pool_open (device_pool,
- meta_gpu_kms_get_file_path (gpu_kms),
- device_file_flags,
- error);
- if (!device_file)
- return NULL;
-
-#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,
- device_file,
- &egl_device_error);
- if (renderer_gpu_data)
- return renderer_gpu_data;
-#endif
-
- renderer_gpu_data = create_renderer_gpu_data_gbm (renderer_native,
- device_file,
- &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 gboolean
-meta_renderer_native_ensure_gpu_data (MetaRendererNative *renderer_native,
- MetaGpuKms *gpu_kms,
- GError **error)
-{
- MetaRendererNativeGpuData *renderer_gpu_data;
-
- renderer_gpu_data = g_hash_table_lookup (renderer_native->gpu_datas, gpu_kms);
- if (renderer_gpu_data)
- return TRUE;
-
- return create_renderer_gpu_data (renderer_native, gpu_kms, error);
-}
-
-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);
-
- unset_disabled_crtcs (backend, 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++)
- {
- /* First check if one was explicitly configured. */
- for (l = gpus; l; l = l->next)
- {
- MetaGpuKms *gpu_kms = META_GPU_KMS (l->data);
- MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
-
- if (meta_kms_device_get_flags (kms_device) &
- META_KMS_DEVICE_FLAG_PREFERRED_PRIMARY)
- {
- g_message ("GPU %s selected primary given udev rule",
- meta_gpu_kms_get_file_path (gpu_kms));
- return gpu_kms;
- }
- }
-
- /* 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)))
- {
- g_message ("Integrated GPU %s selected as primary",
- meta_gpu_kms_get_file_path (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)))
- {
- g_message ("Boot VGA GPU %s selected as primary",
- meta_gpu_kms_get_file_path (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))
- {
- g_message ("GPU %s selected as primary",
- meta_gpu_kms_get_file_path (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);
- if (gpus)
- {
- const char *use_kms_modifiers_debug_env;
-
- 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;
-
- use_kms_modifiers_debug_env = g_getenv ("MUTTER_DEBUG_USE_KMS_MODIFIERS");
- if (use_kms_modifiers_debug_env)
- {
- renderer_native->use_modifiers =
- g_strcmp0 (use_kms_modifiers_debug_env, "1") == 0;
- }
- else
- {
- renderer_native->use_modifiers =
- !meta_gpu_kms_disable_modifiers (renderer_native->primary_gpu_kms);
- }
-
- meta_topic (META_DEBUG_KMS, "Usage of KMS modifiers is %s",
- renderer_native->use_modifiers ? "enabled" : "disabled");
- }
- else
- {
- if (!create_renderer_gpu_data (renderer_native, NULL, error))
- 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);
-
- clear_kept_alive_onscreens (renderer_native);
-
- g_clear_list (&renderer_native->power_save_page_flip_onscreens,
- g_object_unref);
- g_clear_handle_id (&renderer_native->power_save_page_flip_source_id,
- g_source_remove);
-
- g_list_free (renderer_native->pending_mode_set_views);
-
- 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
deleted file mode 100644
index 2c23c651a..000000000
--- a/src/backends/native/meta-renderer-native.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- 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-native.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,
- META_RENDERER_NATIVE_MODE_SURFACELESS,
-#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);
-
-MetaGpuKms * meta_renderer_native_get_primary_gpu (MetaRendererNative *renderer_native);
-
-MetaDeviceFile * meta_renderer_native_get_primary_device_file (MetaRendererNative *renderer_native);
-
-void meta_renderer_native_prepare_frame (MetaRendererNative *renderer_native,
- MetaRendererView *view,
- ClutterFrame *frame);
-
-void meta_renderer_native_finish_frame (MetaRendererNative *renderer_native,
- MetaRendererView *view,
- ClutterFrame *frame);
-
-void meta_renderer_native_reset_modes (MetaRendererNative *renderer_native);
-
-gboolean meta_renderer_native_use_modifiers (MetaRendererNative *renderer_native);
-
-#endif /* META_RENDERER_NATIVE_H */
diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c
deleted file mode 100644
index 26db30bd4..000000000
--- a/src/backends/native/meta-seat-impl.c
+++ /dev/null
@@ -1,3542 +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 <http://www.gnu.org/licenses/>.
- *
- * Author: Damien Lespiau <damien.lespiau@intel.com>
- * Author: Jonas Ådahl <jadahl@gmail.com>
- * Author: Carlos Garnacho <carlosg@gnome.org>
- */
-
-#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-backend-native-private.h"
-#include "backends/native/meta-barrier-native.h"
-#include "backends/native/meta-device-pool.h"
-#include "backends/native/meta-input-thread.h"
-#include "backends/native/meta-virtual-input-device-native.h"
-#include "clutter/clutter-mutter.h"
-#include "core/bell.h"
-
-#include "meta-private-enum-types.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
-
-struct _MetaEventSource
-{
- GSource source;
-
- MetaSeatImpl *seat_impl;
- GPollFD event_poll_fd;
-};
-
-enum
-{
- PROP_0,
- PROP_SEAT,
- PROP_SEAT_ID,
- PROP_FLAGS,
- N_PROPS,
-};
-
-static GParamSpec *props[N_PROPS] = { NULL };
-
-enum
-{
- KBD_A11Y_FLAGS_CHANGED,
- KBD_A11Y_MODS_STATE_CHANGED,
- TOUCH_MODE,
- BELL,
- MODS_STATE_CHANGED,
- N_SIGNALS
-};
-
-static guint signals[N_SIGNALS] = { 0 };
-
-typedef struct _MetaSeatImplPrivate
-{
- GHashTable *device_files;
-} MetaSeatImplPrivate;
-
-static void meta_seat_impl_initable_iface_init (GInitableIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaSeatImpl, meta_seat_impl, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
- meta_seat_impl_initable_iface_init)
- G_ADD_PRIVATE (MetaSeatImpl))
-
-static void process_events (MetaSeatImpl *seat_impl);
-void meta_seat_impl_constrain_pointer (MetaSeatImpl *seat_impl,
- ClutterInputDevice *core_pointer,
- uint64_t time_us,
- float x,
- float y,
- float *new_x,
- float *new_y);
-void meta_seat_impl_filter_relative_motion (MetaSeatImpl *seat_impl,
- ClutterInputDevice *device,
- float x,
- float y,
- float *dx,
- float *dy);
-void meta_seat_impl_clear_repeat_source (MetaSeatImpl *seat_impl);
-
-void
-meta_seat_impl_run_input_task (MetaSeatImpl *seat_impl,
- GTask *task,
- GSourceFunc dispatch_func)
-{
- GSource *source;
-
- source = g_idle_source_new ();
- g_source_set_priority (source, G_PRIORITY_HIGH);
- g_source_set_callback (source,
- dispatch_func,
- g_object_ref (task),
- g_object_unref);
- g_source_attach (source, seat_impl->input_context);
- g_source_unref (source);
-}
-
-void
-meta_seat_impl_sync_leds_in_impl (MetaSeatImpl *seat_impl)
-{
- GSList *iter;
- MetaInputDeviceNative *device_native;
- int caps_lock, num_lock, scroll_lock;
- enum libinput_led leds = 0;
-
- caps_lock = xkb_state_led_index_is_active (seat_impl->xkb,
- seat_impl->caps_lock_led);
- num_lock = xkb_state_led_index_is_active (seat_impl->xkb,
- seat_impl->num_lock_led);
- scroll_lock = xkb_state_led_index_is_active (seat_impl->xkb,
- seat_impl->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_impl->devices; iter; iter = iter->next)
- {
- device_native = iter->data;
- meta_input_device_native_update_leds_in_impl (device_native, leds);
- }
-}
-
-MetaTouchState *
-meta_seat_impl_lookup_touch_state_in_impl (MetaSeatImpl *seat_impl,
- int seat_slot)
-{
- if (!seat_impl->touch_states)
- return NULL;
-
- return g_hash_table_lookup (seat_impl->touch_states,
- GINT_TO_POINTER (seat_slot));
-}
-
-static void
-meta_touch_state_free (MetaTouchState *state)
-{
- g_free (state);
-}
-
-MetaTouchState *
-meta_seat_impl_acquire_touch_state_in_impl (MetaSeatImpl *seat_impl,
- int seat_slot)
-{
- MetaTouchState *touch_state;
-
- if (!seat_impl->touch_states)
- {
- seat_impl->touch_states =
- g_hash_table_new_full (NULL, NULL, NULL,
- (GDestroyNotify) meta_touch_state_free);
- }
-
- g_assert (!g_hash_table_contains (seat_impl->touch_states,
- GINT_TO_POINTER (seat_slot)));
-
- touch_state = g_new0 (MetaTouchState, 1);
- *touch_state = (MetaTouchState) {
- .seat_impl = seat_impl,
- .seat_slot = seat_slot,
- };
-
- g_hash_table_insert (seat_impl->touch_states, GINT_TO_POINTER (seat_slot),
- touch_state);
-
- return touch_state;
-}
-
-void
-meta_seat_impl_release_touch_state_in_impl (MetaSeatImpl *seat_impl,
- int seat_slot)
-{
- if (!seat_impl->touch_states)
- return;
- g_hash_table_remove (seat_impl->touch_states, GINT_TO_POINTER (seat_slot));
-}
-
-void
-meta_seat_impl_clear_repeat_source (MetaSeatImpl *seat_impl)
-{
- if (seat_impl->repeat_source)
- {
- g_source_destroy (seat_impl->repeat_source);
- g_clear_pointer (&seat_impl->repeat_source, g_source_unref);
- }
-
- g_clear_object (&seat_impl->repeat_device);
-}
-
-static void
-dispatch_libinput (MetaSeatImpl *seat_impl)
-{
- libinput_dispatch (seat_impl->libinput);
- process_events (seat_impl);
-}
-
-static gboolean
-keyboard_repeat (gpointer data)
-{
- MetaSeatImpl *seat_impl = data;
-
- /* There might be events queued in libinput that could cancel the
- repeat timer. */
- if (seat_impl->libinput)
- {
- dispatch_libinput (seat_impl);
- if (!seat_impl->repeat_source)
- return G_SOURCE_REMOVE;
- }
-
- g_return_val_if_fail (seat_impl->repeat_device != NULL, G_SOURCE_REMOVE);
-
- meta_seat_impl_notify_key_in_impl (seat_impl,
- seat_impl->repeat_device,
- g_source_get_time (seat_impl->repeat_source),
- seat_impl->repeat_key,
- AUTOREPEAT_VALUE,
- FALSE);
-
- return G_SOURCE_CONTINUE;
-}
-
-static void
-queue_event (MetaSeatImpl *seat_impl,
- ClutterEvent *event)
-{
- _clutter_event_push (event, FALSE);
-}
-
-static int
-update_button_count (MetaSeatImpl *seat_impl,
- uint32_t button,
- uint32_t state)
-{
- if (state)
- {
- return ++seat_impl->button_count[button];
- }
- else
- {
- /* Handle cases where we newer saw the initial pressed event. */
- if (seat_impl->button_count[button] == 0)
- {
- meta_topic (META_DEBUG_INPUT,
- "Counting release of key 0x%x and count is already 0",
- button);
- return 0;
- }
-
- return --seat_impl->button_count[button];
- }
-}
-
-void
-meta_seat_impl_queue_main_thread_idle (MetaSeatImpl *seat_impl,
- GSourceFunc func,
- gpointer user_data,
- GDestroyNotify destroy_notify)
-{
- GSource *source;
-
- source = g_idle_source_new ();
- g_source_set_priority (source, G_PRIORITY_HIGH);
- g_source_set_callback (source, func, user_data, destroy_notify);
-
- g_source_attach (source, seat_impl->main_context);
- g_source_unref (source);
-}
-
-typedef struct
-{
- MetaSeatImpl *seat_impl;
- guint signal_id;
- GArray *args;
-} MetaSeatSignalData;
-
-static gboolean
-emit_signal_in_main (MetaSeatSignalData *data)
-{
- g_signal_emitv ((GValue *) data->args->data,
- data->signal_id,
- 0, NULL);
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-signal_data_free (MetaSeatSignalData *data)
-{
- g_array_unref (data->args);
- g_free (data);
-}
-
-static void
-emit_signal (MetaSeatImpl *seat_impl,
- guint signal_id,
- GValue *args,
- int n_args)
-{
- MetaSeatSignalData *emit_signal_data;
- GArray *array;
- GValue self = G_VALUE_INIT;
-
- g_value_init (&self, META_TYPE_SEAT_IMPL);
- g_value_set_object (&self, seat_impl);
-
- array = g_array_new (FALSE, FALSE, sizeof (GValue));
- g_array_append_val (array, self);
- if (args && n_args > 0)
- g_array_append_vals (array, args, n_args);
-
- emit_signal_data = g_new0 (MetaSeatSignalData, 1);
- emit_signal_data->seat_impl = seat_impl;
- emit_signal_data->signal_id = signal_id;
- emit_signal_data->args = array;
-
- meta_seat_impl_queue_main_thread_idle (seat_impl,
- (GSourceFunc) emit_signal_in_main,
- emit_signal_data,
- (GDestroyNotify) signal_data_free);
-}
-
-void
-meta_seat_impl_notify_key_in_impl (MetaSeatImpl *seat_impl,
- ClutterInputDevice *device,
- uint64_t time_us,
- uint32_t key,
- uint32_t state,
- gboolean update_keys)
-{
- ClutterEvent *event = NULL;
- enum xkb_state_component changed_state;
- uint32_t keycode;
-
- if (state != AUTOREPEAT_VALUE)
- {
- /* Drop any repeated button press (for example from virtual devices. */
- int count = update_button_count (seat_impl, 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",
- state ? "press" : "release", key, count, state);
- return;
- }
- }
-
- event = meta_key_event_new_from_evdev (device,
- seat_impl->core_keyboard,
- seat_impl->xkb,
- seat_impl->button_state,
- us2ms (time_us), key, state);
- event->key.evdev_code = key;
-
- keycode = meta_xkb_evdev_to_keycode (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_impl->xkb, keycode,
- state ? XKB_KEY_DOWN : XKB_KEY_UP);
- }
- else
- {
- changed_state = 0;
- clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_REPEATED);
- }
-
- if (!meta_input_device_native_process_kbd_a11y_event_in_impl (seat_impl->core_keyboard,
- event))
- queue_event (seat_impl, event);
- else
- clutter_event_free (event);
-
- if (update_keys && (changed_state & XKB_STATE_LEDS))
- {
- MetaInputDeviceNative *keyboard_native;
- gboolean numlock_active;
-
- meta_keymap_native_update_in_impl (seat_impl->keymap,
- seat_impl,
- seat_impl->xkb);
- meta_seat_impl_sync_leds_in_impl (seat_impl);
-
- numlock_active =
- xkb_state_mod_name_is_active (seat_impl->xkb, XKB_MOD_NAME_NUM,
- XKB_STATE_MODS_LATCHED |
- XKB_STATE_MODS_LOCKED);
- meta_input_settings_maybe_save_numlock_state (seat_impl->input_settings,
- numlock_active);
-
- keyboard_native = META_INPUT_DEVICE_NATIVE (seat_impl->core_keyboard);
- meta_input_device_native_a11y_maybe_notify_toggle_keys_in_impl (keyboard_native);
- }
-
- if (state == 0 || /* key release */
- !seat_impl->repeat ||
- !xkb_keymap_key_repeats (xkb_state_get_keymap (seat_impl->xkb),
- keycode))
- {
- seat_impl->repeat_count = 0;
- meta_seat_impl_clear_repeat_source (seat_impl);
- return;
- }
-
- if (state == 1) /* key press */
- seat_impl->repeat_count = 0;
-
- seat_impl->repeat_count += 1;
- seat_impl->repeat_key = key;
-
- switch (seat_impl->repeat_count)
- {
- case 1:
- case 2:
- {
- uint32_t interval;
-
- meta_seat_impl_clear_repeat_source (seat_impl);
- seat_impl->repeat_device = g_object_ref (device);
-
- if (seat_impl->repeat_count == 1)
- interval = seat_impl->repeat_delay;
- else
- interval = seat_impl->repeat_interval;
-
- seat_impl->repeat_source = g_timeout_source_new (interval);
- g_source_set_priority (seat_impl->repeat_source, CLUTTER_PRIORITY_EVENTS);
- g_source_set_callback (seat_impl->repeat_source,
- keyboard_repeat, seat_impl, NULL);
- g_source_attach (seat_impl->repeat_source, seat_impl->input_context);
- return;
- }
- default:
- return;
- }
-}
-
-static ClutterEvent *
-new_absolute_motion_event (MetaSeatImpl *seat_impl,
- ClutterInputDevice *input_device,
- uint64_t time_us,
- float x,
- float y,
- double *axes)
-{
- ClutterEvent *event;
-
- event = clutter_event_new (CLUTTER_MOTION);
-
- if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE)
- {
- meta_seat_impl_constrain_pointer (seat_impl,
- seat_impl->core_pointer,
- time_us,
- seat_impl->pointer_x,
- seat_impl->pointer_y,
- &x, &y);
- }
- else
- {
- /* This may happen early at startup */
- if (seat_impl->viewports)
- {
- meta_input_device_native_translate_coordinates_in_impl (input_device,
- seat_impl->viewports,
- &x,
- &y);
- }
- }
-
- event->motion.time_us = time_us;
- event->motion.time = us2ms (time_us);
- meta_xkb_translate_state (event, seat_impl->xkb, seat_impl->button_state);
- event->motion.x = x;
- event->motion.y = y;
-
- event->motion.axes = axes;
- clutter_event_set_device (event, seat_impl->core_pointer);
- clutter_event_set_source_device (event, input_device);
-
- g_rw_lock_writer_lock (&seat_impl->state_lock);
-
- if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
- {
- MetaInputDeviceNative *device_native =
- META_INPUT_DEVICE_NATIVE (input_device);
-
- clutter_event_set_device_tool (event, device_native->last_tool);
- clutter_event_set_device (event, input_device);
- meta_input_device_native_set_coords_in_impl (META_INPUT_DEVICE_NATIVE (input_device),
- x, y);
- }
- else
- {
- clutter_event_set_device (event, seat_impl->core_pointer);
- meta_input_device_native_set_coords_in_impl (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer),
- x, y);
- }
-
- if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE)
- {
- seat_impl->pointer_x = x;
- seat_impl->pointer_y = y;
- }
-
- g_rw_lock_writer_unlock (&seat_impl->state_lock);
-
- return event;
-}
-
-void
-meta_seat_impl_notify_relative_motion_in_impl (MetaSeatImpl *seat_impl,
- ClutterInputDevice *input_device,
- uint64_t time_us,
- float dx,
- float dy,
- float dx_unaccel,
- float dy_unaccel)
-{
- float new_x, new_y;
- ClutterEvent *event;
-
- meta_seat_impl_filter_relative_motion (seat_impl,
- input_device,
- seat_impl->pointer_x,
- seat_impl->pointer_y,
- &dx,
- &dy);
-
- new_x = seat_impl->pointer_x + dx;
- new_y = seat_impl->pointer_y + dy;
- event = new_absolute_motion_event (seat_impl, input_device,
- time_us, new_x, new_y, NULL);
-
- event->motion.flags |= CLUTTER_EVENT_FLAG_RELATIVE_MOTION;
- event->motion.dx = dx;
- event->motion.dy = dy;
- event->motion.dx_unaccel = dx_unaccel;
- event->motion.dy_unaccel = dy_unaccel;
-
- queue_event (seat_impl, event);
-}
-
-void
-meta_seat_impl_notify_absolute_motion_in_impl (MetaSeatImpl *seat_impl,
- ClutterInputDevice *input_device,
- uint64_t time_us,
- float x,
- float y,
- double *axes)
-{
- ClutterEvent *event;
-
- event = new_absolute_motion_event (seat_impl, input_device, time_us, x, y, axes);
-
- queue_event (seat_impl, event);
-}
-
-void
-meta_seat_impl_notify_button_in_impl (MetaSeatImpl *seat_impl,
- ClutterInputDevice *input_device,
- uint64_t time_us,
- uint32_t button,
- uint32_t state)
-{
- MetaInputDeviceNative *device_native = (MetaInputDeviceNative *) input_device;
- 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_impl, 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",
- state ? "press" : "release", button, button_count);
- 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_impl->button_state |= maskmap[button_nr - 1];
- else
- seat_impl->button_state &= ~maskmap[button_nr - 1];
- }
-
- event->button.time = us2ms (time_us);
- meta_xkb_translate_state (event, seat_impl->xkb, seat_impl->button_state);
- event->button.button = button_nr;
-
- if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
- {
- meta_input_device_native_get_coords_in_impl (device_native,
- &event->button.x,
- &event->button.y);
- }
- else
- {
- meta_input_device_native_get_coords_in_impl (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer),
- &event->button.x,
- &event->button.y);
- }
-
- clutter_event_set_device (event, seat_impl->core_pointer);
- clutter_event_set_source_device (event, input_device);
-
- if (device_native->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_in_impl (device_native->last_tool,
- button_nr);
- if (mapped_button != 0)
- button = mapped_button;
- }
-
- event->button.evdev_code = button;
-
- if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
- {
- clutter_event_set_device_tool (event, device_native->last_tool);
- clutter_event_set_device (event, input_device);
- }
- else
- {
- clutter_event_set_device (event, seat_impl->core_pointer);
- }
-
- queue_event (seat_impl, event);
-}
-
-static MetaSeatImpl *
-seat_impl_from_device (ClutterInputDevice *device)
-{
- MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
-
- return meta_input_device_native_get_seat_impl (device_native);
-}
-
-static void
-notify_scroll (ClutterInputDevice *input_device,
- uint64_t time_us,
- double dx,
- double dy,
- ClutterScrollSource scroll_source,
- ClutterScrollFinishFlags flags,
- gboolean emulated)
-{
- MetaSeatImpl *seat_impl;
- ClutterEvent *event = NULL;
- double scroll_factor;
-
- seat_impl = seat_impl_from_device (input_device);
-
- event = clutter_event_new (CLUTTER_SCROLL);
-
- event->scroll.time = us2ms (time_us);
- meta_xkb_translate_state (event, seat_impl->xkb, seat_impl->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_impl->pointer_x;
- event->scroll.y = seat_impl->pointer_y;
- clutter_event_set_device (event, seat_impl->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 (seat_impl, event);
-}
-
-static void
-notify_discrete_scroll (ClutterInputDevice *input_device,
- uint64_t time_us,
- ClutterScrollDirection direction,
- ClutterScrollSource scroll_source,
- gboolean emulated)
-{
- MetaSeatImpl *seat_impl;
- ClutterEvent *event = NULL;
-
- if (direction == CLUTTER_SCROLL_SMOOTH)
- return;
-
- seat_impl = seat_impl_from_device (input_device);
-
- event = clutter_event_new (CLUTTER_SCROLL);
-
- event->scroll.time = us2ms (time_us);
- meta_xkb_translate_state (event, seat_impl->xkb, seat_impl->button_state);
-
- event->scroll.direction = direction;
-
- event->scroll.x = seat_impl->pointer_x;
- event->scroll.y = seat_impl->pointer_y;
- clutter_event_set_device (event, seat_impl->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 (seat_impl, event);
-}
-
-static void
-check_notify_discrete_scroll (MetaSeatImpl *seat_impl,
- ClutterInputDevice *device,
- uint64_t time_us,
- ClutterScrollSource scroll_source)
-{
- int i, n_xscrolls, n_yscrolls;
-
- n_xscrolls = floor ((fabs (seat_impl->accum_scroll_dx) + DBL_EPSILON) /
- DISCRETE_SCROLL_STEP);
- n_yscrolls = floor ((fabs (seat_impl->accum_scroll_dy) + DBL_EPSILON) /
- DISCRETE_SCROLL_STEP);
-
- for (i = 0; i < n_xscrolls; i++)
- {
- notify_discrete_scroll (device, time_us,
- seat_impl->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_impl->accum_scroll_dy > 0 ?
- CLUTTER_SCROLL_DOWN : CLUTTER_SCROLL_UP,
- scroll_source, TRUE);
- }
-
- seat_impl->accum_scroll_dx =
- fmodf (seat_impl->accum_scroll_dx, DISCRETE_SCROLL_STEP);
- seat_impl->accum_scroll_dy =
- fmodf (seat_impl->accum_scroll_dy, DISCRETE_SCROLL_STEP);
-}
-
-void
-meta_seat_impl_notify_scroll_continuous_in_impl (MetaSeatImpl *seat_impl,
- 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_impl->accum_scroll_dx = 0;
- else
- seat_impl->accum_scroll_dx += dx;
-
- if (finish_flags & CLUTTER_SCROLL_FINISHED_VERTICAL)
- seat_impl->accum_scroll_dy = 0;
- else
- seat_impl->accum_scroll_dy += dy;
-
- notify_scroll (input_device, time_us, dx, dy, scroll_source,
- finish_flags, FALSE);
- check_notify_discrete_scroll (seat_impl, 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_impl_notify_discrete_scroll_in_impl (MetaSeatImpl *seat_impl,
- 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_impl_notify_touch_event_in_impl (MetaSeatImpl *seat_impl,
- ClutterInputDevice *input_device,
- ClutterEventType evtype,
- uint64_t time_us,
- int slot,
- double x,
- double y)
-{
- ClutterEvent *event = NULL;
-
- event = clutter_event_new (evtype);
-
- event->touch.time = us2ms (time_us);
- event->touch.x = x;
- event->touch.y = y;
- meta_input_device_native_translate_coordinates_in_impl (input_device,
- seat_impl->viewports,
- &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_impl->xkb, seat_impl->button_state);
-
- if (evtype == CLUTTER_TOUCH_BEGIN ||
- evtype == CLUTTER_TOUCH_UPDATE)
- event->touch.modifier_state |= CLUTTER_BUTTON1_MASK;
-
- clutter_event_set_device (event, seat_impl->core_pointer);
- clutter_event_set_source_device (event, input_device);
-
- queue_event (seat_impl, event);
-}
-
-/*
- * MetaEventSource for reading input devices
- */
-
-static gboolean
-meta_event_prepare (GSource *g_source,
- int *timeout_ms)
-{
- MetaEventSource *source = (MetaEventSource *) g_source;
- MetaSeatImpl *seat_impl = source->seat_impl;
-
- *timeout_ms = -1;
-
- switch (libinput_next_event_type (seat_impl->libinput))
- {
- case LIBINPUT_EVENT_NONE:
- return FALSE;
- default:
- return TRUE;
- }
-}
-
-static gboolean
-meta_event_check (GSource *source)
-{
- MetaEventSource *event_source = (MetaEventSource *) source;
- gboolean retval;
-
- retval = !!(event_source->event_poll_fd.revents & G_IO_IN);
-
- return retval;
-}
-
-static void
-constrain_to_barriers (MetaSeatImpl *seat_impl,
- ClutterInputDevice *device,
- uint32_t time,
- float *new_x,
- float *new_y)
-{
- meta_barrier_manager_native_process_in_impl (seat_impl->barrier_manager,
- device,
- time,
- new_x, new_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,
- MetaViewportInfo *viewports,
- float *x,
- float *y)
-{
- float cx, cy;
- int i, n_views;
-
- meta_input_device_native_get_coords_in_impl (META_INPUT_DEVICE_NATIVE (device),
- &cx, &cy);
-
- /* if we're trying to escape, clamp to the CRTC we're coming from */
-
- n_views = meta_viewport_info_get_num_views (viewports);
-
- for (i = 0; i < n_views; i++)
- {
- int left, right, top, bottom;
- cairo_rectangle_int_t rect;
-
- meta_viewport_info_get_view_info (viewports, i, &rect, NULL);
-
- left = rect.x;
- right = left + rect.width;
- top = rect.y;
- bottom = top + 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;
- }
- }
-}
-
-void
-meta_seat_impl_constrain_pointer (MetaSeatImpl *seat_impl,
- ClutterInputDevice *core_pointer,
- uint64_t time_us,
- float x,
- float y,
- float *new_x,
- float *new_y)
-{
- /* Constrain to barriers */
- constrain_to_barriers (seat_impl, core_pointer,
- us2ms (time_us),
- new_x, new_y);
-
- /* Bar to constraints */
- if (seat_impl->pointer_constraint)
- {
- meta_pointer_constraint_impl_constrain (seat_impl->pointer_constraint,
- core_pointer,
- us2ms (time_us),
- x, y,
- new_x, new_y);
- }
-
- if (seat_impl->viewports)
- {
- /* if we're moving inside a monitor, we're fine */
- if (meta_viewport_info_get_view_at (seat_impl->viewports,
- *new_x, *new_y) >= 0)
- return;
-
- /* if we're trying to escape, clamp to the CRTC we're coming from */
- constrain_all_screen_monitors (core_pointer, seat_impl->viewports,
- new_x, new_y);
- }
-}
-
-static void
-relative_motion_across_outputs (MetaViewportInfo *viewports,
- int view,
- float cur_x,
- float cur_y,
- float *dx_inout,
- float *dy_inout)
-{
- int cur_view = view;
- 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_view >= 0)
- {
- MetaLine2 left, right, top, bottom, motion;
- MetaVector2 intersection;
- cairo_rectangle_int_t rect;
- float scale;
-
- meta_viewport_info_get_view_info (viewports, cur_view, &rect, &scale);
-
- motion = (MetaLine2) {
- .a = { x, y },
- .b = { x + (dx * scale), y + (dy * scale) }
- };
- left = (MetaLine2) {
- { rect.x, rect.y },
- { rect.x, rect.y + rect.height }
- };
- right = (MetaLine2) {
- { rect.x + rect.width, rect.y },
- { rect.x + rect.width, rect.y + rect.height }
- };
- top = (MetaLine2) {
- { rect.x, rect.y },
- { rect.x + rect.width, rect.y }
- };
- bottom = (MetaLine2) {
- { rect.x, rect.y + rect.height },
- { rect.x + rect.width, rect.y + 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_view = meta_viewport_info_get_neighbor (viewports, cur_view,
- direction);
- }
-
- *dx_inout = target_x - cur_x;
- *dy_inout = target_y - cur_y;
-}
-
-void
-meta_seat_impl_filter_relative_motion (MetaSeatImpl *seat_impl,
- ClutterInputDevice *device,
- float x,
- float y,
- float *dx,
- float *dy)
-{
- int view, dest_view;
- float new_dx, new_dy, scale;
-
- if (!seat_impl->viewports)
- return;
- if (meta_viewport_info_is_views_scaled (seat_impl->viewports))
- return;
-
- view = meta_viewport_info_get_view_at (seat_impl->viewports, x, y);
- if (view < 0)
- return;
-
- meta_viewport_info_get_view_info (seat_impl->viewports, view, NULL, &scale);
- new_dx = (*dx) * scale;
- new_dy = (*dy) * scale;
-
- dest_view = meta_viewport_info_get_view_at (seat_impl->viewports,
- x + new_dx,
- y + new_dy);
- if (dest_view >= 0 && dest_view != view)
- {
- /* 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 (seat_impl->viewports, view,
- x, y, &new_dx, &new_dy);
- }
-
- *dx = new_dx;
- *dy = new_dy;
-}
-
-static void
-notify_absolute_motion_in_impl (ClutterInputDevice *input_device,
- uint64_t time_us,
- float x,
- float y,
- double *axes)
-{
- MetaSeatImpl *seat_impl;
- ClutterEvent *event;
-
- seat_impl = seat_impl_from_device (input_device);
- event = new_absolute_motion_event (seat_impl, input_device, time_us, x, y, axes);
-
- queue_event (seat_impl, event);
-}
-
-static void
-notify_relative_tool_motion_in_impl (ClutterInputDevice *input_device,
- uint64_t time_us,
- float dx,
- float dy,
- double *axes)
-{
- MetaInputDeviceNative *device_native;
- ClutterEvent *event;
- MetaSeatImpl *seat_impl;
- float x, y;
-
- device_native = META_INPUT_DEVICE_NATIVE (input_device);
- seat_impl = seat_impl_from_device (input_device);
- x = device_native->pointer_x + dx;
- y = device_native->pointer_y + dy;
-
- meta_seat_impl_filter_relative_motion (seat_impl,
- input_device,
- seat_impl->pointer_x,
- seat_impl->pointer_y,
- &dx,
- &dy);
-
- event = new_absolute_motion_event (seat_impl, input_device, time_us,
- x, y, axes);
-
- event->motion.flags |= CLUTTER_EVENT_FLAG_RELATIVE_MOTION;
- event->motion.dx = dx;
- event->motion.dy = dy;
-
- queue_event (seat_impl, event);
-}
-
-static void
-notify_pinch_gesture_event (ClutterInputDevice *input_device,
- ClutterTouchpadGesturePhase phase,
- uint64_t time_us,
- double dx,
- double dy,
- double dx_unaccel,
- double dy_unaccel,
- double angle_delta,
- double scale,
- uint32_t n_fingers)
-{
- MetaSeatImpl *seat_impl;
- ClutterEvent *event = NULL;
-
- seat_impl = seat_impl_from_device (input_device);
-
- event = clutter_event_new (CLUTTER_TOUCHPAD_PINCH);
-
- meta_input_device_native_get_coords_in_impl (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer),
- &event->touchpad_pinch.x,
- &event->touchpad_pinch.y);
-
- event->touchpad_pinch.phase = phase;
- event->touchpad_pinch.time = us2ms (time_us);
- event->touchpad_pinch.dx = dx;
- event->touchpad_pinch.dy = dy;
- event->touchpad_pinch.dx_unaccel = dx_unaccel;
- event->touchpad_pinch.dy_unaccel = dy_unaccel;
- 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_impl->xkb, seat_impl->button_state);
-
- clutter_event_set_device (event, seat_impl->core_pointer);
- clutter_event_set_source_device (event, input_device);
-
- queue_event (seat_impl, event);
-}
-
-static void
-notify_swipe_gesture_event (ClutterInputDevice *input_device,
- ClutterTouchpadGesturePhase phase,
- uint64_t time_us,
- uint32_t n_fingers,
- double dx,
- double dy,
- double dx_unaccel,
- double dy_unaccel)
-{
- MetaSeatImpl *seat_impl;
- ClutterEvent *event = NULL;
-
- seat_impl = seat_impl_from_device (input_device);
-
- event = clutter_event_new (CLUTTER_TOUCHPAD_SWIPE);
-
- event->touchpad_swipe.phase = phase;
- event->touchpad_swipe.time = us2ms (time_us);
-
- meta_input_device_native_get_coords_in_impl (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer),
- &event->touchpad_swipe.x,
- &event->touchpad_swipe.y);
- event->touchpad_swipe.dx = dx;
- event->touchpad_swipe.dy = dy;
- event->touchpad_swipe.dx_unaccel = dx_unaccel;
- event->touchpad_swipe.dy_unaccel = dy_unaccel;
- event->touchpad_swipe.n_fingers = n_fingers;
-
- meta_xkb_translate_state (event, seat_impl->xkb, seat_impl->button_state);
-
- clutter_event_set_device (event, seat_impl->core_pointer);
- clutter_event_set_source_device (event, input_device);
-
- queue_event (seat_impl, event);
-}
-
-static void
-notify_proximity (ClutterInputDevice *input_device,
- uint64_t time_us,
- gboolean in)
-{
- MetaInputDeviceNative *device_native;
- MetaSeatImpl *seat_impl;
- ClutterEvent *event = NULL;
-
- device_native = META_INPUT_DEVICE_NATIVE (input_device);
- seat_impl = seat_impl_from_device (input_device);
-
- if (in)
- event = clutter_event_new (CLUTTER_PROXIMITY_IN);
- else
- event = clutter_event_new (CLUTTER_PROXIMITY_OUT);
-
- event->proximity.time = us2ms (time_us);
- clutter_event_set_device_tool (event, device_native->last_tool);
- clutter_event_set_device (event, seat_impl->core_pointer);
- clutter_event_set_source_device (event, input_device);
-
- queue_event (seat_impl, 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)
-{
- MetaSeatImpl *seat_impl;
- ClutterEvent *event;
-
- seat_impl = seat_impl_from_device (input_device);
-
- if (pressed)
- event = clutter_event_new (CLUTTER_PAD_BUTTON_PRESS);
- else
- event = clutter_event_new (CLUTTER_PAD_BUTTON_RELEASE);
-
- 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));
-
- queue_event (seat_impl, 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)
-{
- ClutterInputDevicePadSource source;
- MetaSeatImpl *seat_impl;
- ClutterEvent *event;
-
- seat_impl = seat_impl_from_device (input_device);
-
- if (strip_source == LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER)
- source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER;
- else
- source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN;
-
- event = clutter_event_new (CLUTTER_PAD_STRIP);
- event->pad_strip.strip_source = source;
- 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));
-
- queue_event (seat_impl, 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)
-{
- ClutterInputDevicePadSource source;
- MetaSeatImpl *seat_impl;
- ClutterEvent *event;
-
- seat_impl = seat_impl_from_device (input_device);
-
- if (ring_source == LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER)
- source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER;
- else
- source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN;
-
- event = clutter_event_new (CLUTTER_PAD_RING);
- event->pad_ring.ring_source = source;
- 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));
-
- queue_event (seat_impl, event);
-}
-
-static gboolean
-meta_event_dispatch (GSource *g_source,
- GSourceFunc callback,
- gpointer user_data)
-{
- MetaEventSource *source = (MetaEventSource *) g_source;
- MetaSeatImpl *seat_impl;
-
- seat_impl = source->seat_impl;
-
- dispatch_libinput (seat_impl);
-
- return TRUE;
-}
-
-static GSourceFuncs event_funcs = {
- meta_event_prepare,
- meta_event_check,
- meta_event_dispatch,
- NULL
-};
-
-static MetaEventSource *
-meta_event_source_new (MetaSeatImpl *seat_impl)
-{
- GSource *source;
- MetaEventSource *event_source;
- int fd;
-
- source = g_source_new (&event_funcs, sizeof (MetaEventSource));
- event_source = (MetaEventSource *) source;
-
- /* setup the source */
- event_source->seat_impl = seat_impl;
-
- fd = libinput_get_fd (seat_impl->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, seat_impl->input_context);
-
- 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 (MetaSeatImpl *seat_impl)
-{
- GSList *l;
-
- for (l = seat_impl->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 inline gboolean
-device_type_is_pointer (ClutterInputDeviceType device_type)
-{
- return device_type == CLUTTER_POINTER_DEVICE ||
- device_type == CLUTTER_TOUCHPAD_DEVICE;
-}
-
-static gboolean
-has_pointer (MetaSeatImpl *seat_impl)
-{
- GSList *l;
-
- for (l = seat_impl->devices; l; l = l->next)
- {
- ClutterInputDeviceType device_type;
-
- device_type = clutter_input_device_get_device_type (l->data);
- if (device_type_is_pointer (device_type))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-device_is_tablet_switch (MetaInputDeviceNative *device_native)
-{
- 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))
- return TRUE;
-
- return FALSE;
-}
-
-static gboolean
-has_tablet_switch (MetaSeatImpl *seat_impl)
-{
- GSList *l;
-
- for (l = seat_impl->devices; l; l = l->next)
- {
- MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (l->data);
-
- if (device_is_tablet_switch (device_native))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-update_touch_mode (MetaSeatImpl *seat_impl)
-{
- gboolean touch_mode;
-
- /* No touch mode if we don't have a touchscreen, easy */
- if (!seat_impl->has_touchscreen)
- touch_mode = FALSE;
- /* If we have a tablet mode switch, honor it being unset */
- else if (seat_impl->has_tablet_switch && !seat_impl->tablet_mode_switch_state)
- touch_mode = FALSE;
- /* If tablet mode is enabled, go for it */
- else if (seat_impl->has_tablet_switch && seat_impl->tablet_mode_switch_state)
- touch_mode = TRUE;
- /* If there is no tablet mode switch (eg. kiosk machines),
- * assume touch-mode is mutually exclusive with pointers.
- */
- else
- touch_mode = !seat_impl->has_pointer;
-
- if (seat_impl->touch_mode != touch_mode)
- {
- GValue value = G_VALUE_INIT;
-
- g_value_init (&value, G_TYPE_BOOLEAN);
- g_value_set_boolean (&value, touch_mode);
- seat_impl->touch_mode = touch_mode;
- emit_signal (seat_impl, signals[TOUCH_MODE], &value, 1);
- g_value_unset (&value);
- }
-}
-
-static ClutterInputDevice *
-evdev_add_device (MetaSeatImpl *seat_impl,
- struct libinput_device *libinput_device)
-{
- ClutterInputDeviceType type;
- ClutterInputDevice *device;
- gboolean is_touchscreen, is_tablet_switch, is_pointer;
-
- device = meta_input_device_native_new_in_impl (seat_impl, libinput_device);
-
- seat_impl->devices = g_slist_prepend (seat_impl->devices, device);
- meta_seat_impl_sync_leds_in_impl (seat_impl);
-
- /* Clutter assumes that device types are exclusive in the
- * ClutterInputDevice API */
- type = meta_input_device_native_determine_type_in_impl (libinput_device);
-
- is_touchscreen = type == CLUTTER_TOUCHSCREEN_DEVICE;
- is_tablet_switch =
- device_is_tablet_switch (META_INPUT_DEVICE_NATIVE (device));
- is_pointer = device_type_is_pointer (type);
-
- seat_impl->has_touchscreen |= is_touchscreen;
- seat_impl->has_tablet_switch |= is_tablet_switch;
- seat_impl->has_pointer |= is_pointer;
-
- if (is_touchscreen || is_tablet_switch || is_pointer)
- update_touch_mode (seat_impl);
-
- return device;
-}
-
-static void
-evdev_remove_device (MetaSeatImpl *seat_impl,
- MetaInputDeviceNative *device_native)
-{
- ClutterInputDevice *device;
- ClutterInputDeviceType device_type;
- gboolean is_touchscreen, is_tablet_switch, is_pointer;
-
- device = CLUTTER_INPUT_DEVICE (device_native);
- seat_impl->devices = g_slist_remove (seat_impl->devices, device);
-
- device_type = clutter_input_device_get_device_type (device);
-
- is_touchscreen = device_type == CLUTTER_TOUCHSCREEN_DEVICE;
- is_tablet_switch = device_is_tablet_switch (device_native);
- is_pointer = device_type_is_pointer (device_type);
-
- if (is_touchscreen)
- seat_impl->has_touchscreen = has_touchscreen (seat_impl);
- if (is_tablet_switch)
- seat_impl->has_tablet_switch = has_tablet_switch (seat_impl);
- if (is_pointer)
- seat_impl->has_pointer = has_pointer (seat_impl);
-
- if (is_touchscreen || is_tablet_switch || is_pointer)
- update_touch_mode (seat_impl);
-
- if (seat_impl->repeat_source && seat_impl->repeat_device == device)
- meta_seat_impl_clear_repeat_source (seat_impl);
-
- meta_input_device_native_detach_libinput_in_impl (device_native);
-
- g_object_unref (device);
-}
-
-static gboolean
-process_base_event (MetaSeatImpl *seat_impl,
- struct libinput_event *event)
-{
- ClutterInputDevice *device;
- ClutterEvent *device_event = NULL;
- struct libinput_device *libinput_device;
- MetaInputSettings *input_settings;
-
- input_settings = seat_impl->input_settings;
-
- switch (libinput_event_get_type (event))
- {
- case LIBINPUT_EVENT_DEVICE_ADDED:
- libinput_device = libinput_event_get_device (event);
-
- device = evdev_add_device (seat_impl, libinput_device);
- device_event = clutter_event_new (CLUTTER_DEVICE_ADDED);
- clutter_event_set_device (device_event, device);
- meta_input_settings_add_device (input_settings, 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);
- meta_input_settings_remove_device (input_settings, device);
- evdev_remove_device (seat_impl,
- META_INPUT_DEVICE_NATIVE (device));
- break;
-
- default:
- break;
- }
-
- if (device_event)
- {
- queue_event (seat_impl, 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 (MetaSeatImpl *seat_impl,
- ClutterInputDevice *input_device,
- struct libinput_tablet_tool *libinput_tool)
-{
- MetaInputDeviceNative *evdev_device = META_INPUT_DEVICE_NATIVE (input_device);
- ClutterInputDeviceTool *tool = NULL;
- MetaInputSettings *input_settings;
-
- if (libinput_tool)
- {
- if (!seat_impl->tools)
- {
- seat_impl->tools =
- g_hash_table_new_full (NULL, NULL, NULL,
- (GDestroyNotify) g_object_unref);
- }
-
- tool = g_hash_table_lookup (seat_impl->tools, libinput_tool);
-
- if (!tool)
- {
- ClutterInputDeviceToolType tool_type;
- uint64_t tool_serial;
-
- tool_serial = libinput_tablet_tool_get_serial (libinput_tool);
- tool_type = translate_tool_type (libinput_tool);
- tool = meta_input_device_tool_native_new (libinput_tool,
- tool_serial, tool_type);
- g_hash_table_insert (seat_impl->tools, libinput_tool, tool);
- }
- }
-
- if (evdev_device->last_tool != tool)
- {
- evdev_device->last_tool = tool;
- input_settings = seat_impl->input_settings;
- meta_input_settings_notify_tool_change (input_settings, input_device, tool);
- }
-}
-
-static double *
-translate_tablet_axes (struct libinput_event_tablet_tool *tablet_event,
- ClutterInputDeviceTool *tool)
-{
- double *axes = g_new0 (double, CLUTTER_INPUT_AXIS_LAST);
- struct libinput_tablet_tool *libinput_tool;
- double value;
-
- libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event);
-
- value = libinput_event_tablet_tool_get_x (tablet_event);
- axes[CLUTTER_INPUT_AXIS_X] = value;
- value = libinput_event_tablet_tool_get_y (tablet_event);
- axes[CLUTTER_INPUT_AXIS_Y] = value;
-
- if (libinput_tablet_tool_has_distance (libinput_tool))
- {
- value = libinput_event_tablet_tool_get_distance (tablet_event);
- axes[CLUTTER_INPUT_AXIS_DISTANCE] = 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_in_impl (tool, value);
- axes[CLUTTER_INPUT_AXIS_PRESSURE] = value;
- }
-
- if (libinput_tablet_tool_has_tilt (libinput_tool))
- {
- value = libinput_event_tablet_tool_get_tilt_x (tablet_event);
- axes[CLUTTER_INPUT_AXIS_XTILT] = value;
- value = libinput_event_tablet_tool_get_tilt_y (tablet_event);
- axes[CLUTTER_INPUT_AXIS_YTILT] = value;
- }
-
- if (libinput_tablet_tool_has_rotation (libinput_tool))
- {
- value = libinput_event_tablet_tool_get_rotation (tablet_event);
- axes[CLUTTER_INPUT_AXIS_ROTATION] = value;
- }
-
- if (libinput_tablet_tool_has_slider (libinput_tool))
- {
- value = libinput_event_tablet_tool_get_slider_position (tablet_event);
- axes[CLUTTER_INPUT_AXIS_SLIDER] = value;
- }
-
- if (libinput_tablet_tool_has_wheel (libinput_tool))
- {
- value = libinput_event_tablet_tool_get_wheel_delta (tablet_event);
- axes[CLUTTER_INPUT_AXIS_WHEEL] = value;
- }
-
- return axes;
-}
-
-static void
-notify_continuous_axis (MetaSeatImpl *seat_impl,
- ClutterInputDevice *device,
- uint64_t time_us,
- ClutterScrollSource scroll_source,
- struct libinput_event_pointer *axis_event)
-{
- double 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_impl_notify_scroll_continuous_in_impl (seat_impl, device, time_us,
- dx, dy,
- scroll_source, finish_flags);
-}
-
-static void
-notify_discrete_axis (MetaSeatImpl *seat_impl,
- ClutterInputDevice *device,
- uint64_t time_us,
- ClutterScrollSource scroll_source,
- struct libinput_event_pointer *axis_event)
-{
- double 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_impl_notify_discrete_scroll_in_impl (seat_impl, device,
- time_us,
- discrete_dx, discrete_dy,
- scroll_source);
-}
-
-static void
-process_tablet_axis (MetaSeatImpl *seat_impl,
- 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;
- 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);
-
- axes = translate_tablet_axes (tablet_event,
- evdev_device->last_tool);
-
- meta_viewport_info_get_extents (seat_impl->viewports,
- &stage_width, &stage_height);
-
- time = libinput_event_tablet_tool_get_time_usec (tablet_event);
-
- if (meta_input_device_native_get_mapping_mode_in_impl (device) == META_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_in_impl (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_in_impl (device, time, x, y, axes);
- }
-}
-
-static gboolean
-process_device_event (MetaSeatImpl *seat_impl,
- struct libinput_event *event)
-{
- gboolean handled = TRUE;
- struct libinput_device *libinput_device = libinput_event_get_device(event);
- ClutterInputDevice *device;
- MetaInputDeviceNative *device_native;
-
- 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",
- key_state == LIBINPUT_KEY_STATE_PRESSED ? "press" : "release",
- key, seat_key_count);
- break;
- }
-
- meta_seat_impl_notify_key_in_impl (seat_impl,
- 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_impl_notify_relative_motion_in_impl (seat_impl,
- 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;
- struct libinput_event_pointer *motion_event =
- libinput_event_get_pointer_event (event);
- device = libinput_device_get_user_data (libinput_device);
-
- meta_viewport_info_get_extents (seat_impl->viewports,
- &stage_width, &stage_height);
-
- 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_impl_notify_absolute_motion_in_impl (seat_impl,
- 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",
- button_state == LIBINPUT_BUTTON_STATE_PRESSED ? "press" : "release",
- button, seat_button_count);
- break;
- }
-
- meta_seat_impl_notify_button_in_impl (seat_impl, 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);
- ClutterScrollSource scroll_source;
-
- device = libinput_device_get_user_data (libinput_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_impl, 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_impl, device, time_us, scroll_source,
- axis_event);
- break;
- }
- break;
- }
-
- case LIBINPUT_EVENT_TOUCH_DOWN:
- {
- int seat_slot;
- uint64_t time_us;
- double x, y;
- float stage_width, stage_height;
- MetaTouchState *touch_state;
- struct libinput_event_touch *touch_event =
- libinput_event_get_touch_event (event);
-
- device = libinput_device_get_user_data (libinput_device);
- device_native = META_INPUT_DEVICE_NATIVE (device);
-
- meta_viewport_info_get_extents (seat_impl->viewports,
- &stage_width, &stage_height);
-
- seat_slot = libinput_event_touch_get_seat_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);
-
- g_rw_lock_writer_lock (&seat_impl->state_lock);
-
- touch_state = meta_seat_impl_acquire_touch_state_in_impl (seat_impl, seat_slot);
- touch_state->coords.x = x;
- touch_state->coords.y = y;
-
- g_rw_lock_writer_unlock (&seat_impl->state_lock);
-
- meta_seat_impl_notify_touch_event_in_impl (seat_impl, 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 seat_slot;
- uint64_t time_us;
- MetaTouchState *touch_state;
- struct libinput_event_touch *touch_event =
- libinput_event_get_touch_event (event);
-
- device = libinput_device_get_user_data (libinput_device);
- device_native = META_INPUT_DEVICE_NATIVE (device);
-
- seat_slot = libinput_event_touch_get_seat_slot (touch_event);
- time_us = libinput_event_touch_get_time_usec (touch_event);
- touch_state = meta_seat_impl_lookup_touch_state_in_impl (seat_impl, seat_slot);
- if (!touch_state)
- break;
-
- meta_seat_impl_notify_touch_event_in_impl (seat_impl, device,
- CLUTTER_TOUCH_END, time_us,
- touch_state->seat_slot,
- touch_state->coords.x,
- touch_state->coords.y);
-
- g_rw_lock_writer_lock (&seat_impl->state_lock);
- meta_seat_impl_release_touch_state_in_impl (seat_impl, seat_slot);
- g_rw_lock_writer_unlock (&seat_impl->state_lock);
- break;
- }
-
- case LIBINPUT_EVENT_TOUCH_MOTION:
- {
- int seat_slot;
- uint64_t time_us;
- double x, y;
- float stage_width, stage_height;
- MetaTouchState *touch_state;
- struct libinput_event_touch *touch_event =
- libinput_event_get_touch_event (event);
-
- device = libinput_device_get_user_data (libinput_device);
- device_native = META_INPUT_DEVICE_NATIVE (device);
-
- meta_viewport_info_get_extents (seat_impl->viewports,
- &stage_width, &stage_height);
-
- seat_slot = libinput_event_touch_get_seat_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);
-
- g_rw_lock_writer_lock (&seat_impl->state_lock);
- touch_state = meta_seat_impl_lookup_touch_state_in_impl (seat_impl, seat_slot);
- if (touch_state)
- {
- touch_state->coords.x = x;
- touch_state->coords.y = y;
- }
- g_rw_lock_writer_unlock (&seat_impl->state_lock);
-
- if (!touch_state)
- break;
-
- meta_seat_impl_notify_touch_event_in_impl (seat_impl, device,
- CLUTTER_TOUCH_UPDATE,
- time_us,
- touch_state->seat_slot,
- touch_state->coords.x,
- touch_state->coords.y);
- break;
- }
- case LIBINPUT_EVENT_TOUCH_CANCEL:
- {
- int seat_slot;
- MetaTouchState *touch_state;
- 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_native = META_INPUT_DEVICE_NATIVE (device);
- time_us = libinput_event_touch_get_time_usec (touch_event);
-
- seat_slot = libinput_event_touch_get_seat_slot (touch_event);
- touch_state = meta_seat_impl_lookup_touch_state_in_impl (seat_impl, seat_slot);
- if (!touch_state)
- break;
-
- meta_seat_impl_notify_touch_event_in_impl (touch_state->seat_impl,
- CLUTTER_INPUT_DEVICE (device_native),
- CLUTTER_TOUCH_CANCEL,
- time_us,
- touch_state->seat_slot,
- touch_state->coords.x,
- touch_state->coords.y);
-
- meta_seat_impl_release_touch_state_in_impl (seat_impl, seat_slot);
- 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, 0, 0, n_fingers);
- break;
- }
- case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
- {
- struct libinput_event_gesture *gesture_event =
- libinput_event_get_gesture_event (event);
- double angle_delta, scale, dx, dy, dx_unaccel, dy_unaccel;
- 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);
- dx_unaccel = libinput_event_gesture_get_dx_unaccelerated (gesture_event);
- dy_unaccel = libinput_event_gesture_get_dy_unaccelerated (gesture_event);
-
- notify_pinch_gesture_event (device,
- CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE,
- time_us, dx, dy, dx_unaccel, dy_unaccel,
- 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, 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, dx_unaccel, dy_unaccel;
-
- 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);
- dx_unaccel = libinput_event_gesture_get_dx_unaccelerated (gesture_event);
- dy_unaccel = libinput_event_gesture_get_dy_unaccelerated (gesture_event);
-
- notify_swipe_gesture_event (device,
- CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE,
- time_us, n_fingers, dx, dy, dx_unaccel, dy_unaccel);
- break;
- }
- case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
- {
- process_tablet_axis (seat_impl, 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;
- gboolean in;
-
- 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);
- in = state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN;
-
- libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event);
-
- if (in)
- input_device_update_tool (seat_impl, device, libinput_tool);
- notify_proximity (device, time, in);
- if (!in)
- input_device_update_tool (seat_impl, 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_impl, 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_impl_notify_button_in_impl (seat_impl, 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_impl, event);
-
- meta_seat_impl_notify_button_in_impl (seat_impl, device,
- time_us, BTN_TOUCH, button_state);
- if (!button_state)
- process_tablet_axis (seat_impl, 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_impl->tablet_mode_switch_state = (state == LIBINPUT_SWITCH_STATE_ON);
- update_touch_mode (seat_impl);
- }
- break;
- }
- default:
- handled = FALSE;
- }
-
- return handled;
-}
-
-static void
-process_event (MetaSeatImpl *seat_impl,
- struct libinput_event *event)
-{
- if (process_base_event (seat_impl, event))
- return;
- if (process_device_event (seat_impl, event))
- return;
-}
-
-static void
-process_events (MetaSeatImpl *seat_impl)
-{
- struct libinput_event *event;
-
- while ((event = libinput_get_event (seat_impl->libinput)))
- {
- process_event(seat_impl, event);
- libinput_event_destroy(event);
- }
-}
-
-static int
-open_restricted (const char *path,
- int open_flags,
- void *user_data)
-{
- MetaSeatImpl *seat_impl = user_data;
- MetaSeatImplPrivate *priv = meta_seat_impl_get_instance_private (seat_impl);
- MetaBackend *backend = meta_seat_native_get_backend (seat_impl->seat_native);
- MetaDevicePool *device_pool =
- meta_backend_native_get_device_pool (META_BACKEND_NATIVE (backend));
- MetaDeviceFileFlags flags;
- g_autoptr (GError) error = NULL;
- MetaDeviceFile *device_file;
- int fd;
-
- flags = META_DEVICE_FILE_FLAG_NONE;
- if (!(open_flags & (O_RDWR | O_WRONLY)))
- flags |= META_DEVICE_FILE_FLAG_READ_ONLY;
-
- if (!g_str_has_prefix (path, "/sys/"))
- flags |= META_DEVICE_FILE_FLAG_TAKE_CONTROL;
-
- device_file = meta_device_pool_open (device_pool, path, flags, &error);
- if (!device_file)
- {
- g_warning ("Could not open device %s: %s", path, error->message);
- return -1;
- }
-
- fd = meta_device_file_get_fd (device_file);
- g_hash_table_insert (priv->device_files, GINT_TO_POINTER (fd), device_file);
-
- return fd;
-}
-
-static void
-close_restricted (int fd,
- void *user_data)
-{
- MetaSeatImpl *seat_impl = user_data;
- MetaSeatImplPrivate *priv = meta_seat_impl_get_instance_private (seat_impl);
-
- g_hash_table_remove (priv->device_files, GINT_TO_POINTER (fd));
-}
-
-static const struct libinput_interface libinput_interface = {
- open_restricted,
- close_restricted
-};
-
-static void
-kbd_a11y_changed_cb (MetaInputSettings *input_settings,
- MetaKbdA11ySettings *a11y_settings,
- MetaSeatImpl *seat_impl)
-{
- MetaInputDeviceNative *keyboard;
-
- keyboard = META_INPUT_DEVICE_NATIVE (seat_impl->core_keyboard);
- meta_input_device_native_apply_kbd_a11y_settings_in_impl (keyboard, a11y_settings);
-}
-
-static void
-meta_seat_impl_set_keyboard_numlock_in_impl (MetaSeatImpl *seat_impl,
- 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;
- MetaKeymapNative *keymap;
-
- keymap = seat_impl->keymap;
- xkb_keymap = meta_keymap_native_get_keyboard_map_in_impl (keymap);
-
- numlock = (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod2"));
-
- depressed_mods =
- xkb_state_serialize_mods (seat_impl->xkb, XKB_STATE_MODS_DEPRESSED);
- latched_mods =
- xkb_state_serialize_mods (seat_impl->xkb, XKB_STATE_MODS_LATCHED);
- locked_mods =
- xkb_state_serialize_mods (seat_impl->xkb, XKB_STATE_MODS_LOCKED);
- group_mods =
- xkb_state_serialize_layout (seat_impl->xkb, XKB_STATE_LAYOUT_EFFECTIVE);
-
- if (numlock_state)
- locked_mods |= numlock;
- else
- locked_mods &= ~numlock;
-
- xkb_state_update_mask (seat_impl->xkb,
- depressed_mods,
- latched_mods,
- locked_mods,
- 0, 0,
- group_mods);
-
- meta_seat_impl_sync_leds_in_impl (seat_impl);
- meta_keymap_native_update_in_impl (seat_impl->keymap,
- seat_impl,
- seat_impl->xkb);
-}
-
-static gboolean
-init_libinput (MetaSeatImpl *seat_impl,
- GError **error)
-{
- MetaEventSource *source;
- struct udev *udev;
- struct libinput *libinput;
-
- udev = udev_new ();
- if (G_UNLIKELY (udev == NULL))
- {
- g_warning ("Failed to create udev object");
- seat_impl->input_thread_initialized = TRUE;
- return FALSE;
- }
-
- libinput = libinput_udev_create_context (&libinput_interface,
- seat_impl, udev);
- udev_unref (udev);
-
- if (libinput == NULL)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Failed to create the libinput object.");
- return FALSE;
- }
-
- if (libinput_udev_assign_seat (libinput, seat_impl->seat_id) == -1)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Failed to assign a seat to the libinput object.");
- libinput_unref (seat_impl->libinput);
- return FALSE;
- }
-
- seat_impl->libinput = libinput;
- source = meta_event_source_new (seat_impl);
- seat_impl->event_source = source;
-
- return TRUE;
-}
-
-static gpointer
-input_thread (MetaSeatImpl *seat_impl)
-{
- MetaSeatImplPrivate *priv = meta_seat_impl_get_instance_private (seat_impl);
- struct xkb_keymap *xkb_keymap;
-
- g_main_context_push_thread_default (seat_impl->input_context);
-
- priv->device_files =
- g_hash_table_new_full (NULL, NULL,
- NULL,
- (GDestroyNotify) meta_device_file_release);
-
- if (!(seat_impl->flags & META_SEAT_NATIVE_FLAG_NO_LIBINPUT))
- {
- g_autoptr (GError) error = NULL;
-
- if (!init_libinput (seat_impl, &error))
- {
- g_critical ("Failed to initialize seat: %s", error->message);
- seat_impl->input_thread_initialized = TRUE;
- return NULL;
- }
- }
-
- seat_impl->input_settings = meta_input_settings_native_new_in_impl (seat_impl);
- g_signal_connect_object (seat_impl->input_settings, "kbd-a11y-changed",
- G_CALLBACK (kbd_a11y_changed_cb), seat_impl, 0);
-
- seat_impl->keymap = g_object_new (META_TYPE_KEYMAP_NATIVE, NULL);
-
- xkb_keymap = meta_keymap_native_get_keyboard_map_in_impl (seat_impl->keymap);
-
- if (xkb_keymap)
- {
- seat_impl->xkb = xkb_state_new (xkb_keymap);
-
- seat_impl->caps_lock_led =
- xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_CAPS);
- seat_impl->num_lock_led =
- xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_NUM);
- seat_impl->scroll_lock_led =
- xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL);
- }
-
- if (meta_input_settings_maybe_restore_numlock_state (seat_impl->input_settings))
- meta_seat_impl_set_keyboard_numlock_in_impl (seat_impl, TRUE);
-
- seat_impl->has_touchscreen = has_touchscreen (seat_impl);
- seat_impl->has_tablet_switch = has_tablet_switch (seat_impl);
- update_touch_mode (seat_impl);
-
- g_mutex_lock (&seat_impl->init_mutex);
- seat_impl->input_thread_initialized = TRUE;
- g_cond_signal (&seat_impl->init_cond);
- g_mutex_unlock (&seat_impl->init_mutex);
-
- seat_impl->input_loop = g_main_loop_new (seat_impl->input_context, FALSE);
- g_main_loop_run (seat_impl->input_loop);
- g_main_loop_unref (seat_impl->input_loop);
-
- g_main_context_pop_thread_default (seat_impl->input_context);
-
- return NULL;
-}
-
-static gboolean
-meta_seat_impl_initable_init (GInitable *initable,
- GCancellable *cancellable,
- GError **error)
-{
- MetaSeatImpl *seat_impl = META_SEAT_IMPL (initable);
-
- seat_impl->input_context = g_main_context_new ();
- seat_impl->main_context = g_main_context_ref_thread_default ();
- g_assert (seat_impl->main_context == g_main_context_default ());
-
- seat_impl->input_thread =
- g_thread_try_new ("Mutter Input Thread",
- (GThreadFunc) input_thread,
- initable,
- error);
- if (!seat_impl->input_thread)
- return FALSE;
-
- /* Initialize thread synchronously */
- g_mutex_lock (&seat_impl->init_mutex);
- while (!seat_impl->input_thread_initialized)
- g_cond_wait (&seat_impl->init_cond, &seat_impl->init_mutex);
- g_mutex_unlock (&seat_impl->init_mutex);
-
- return TRUE;
-}
-
-static void
-meta_seat_impl_constructed (GObject *object)
-{
- MetaSeatImpl *seat_impl = META_SEAT_IMPL (object);
- ClutterInputDevice *device;
-
- device = meta_input_device_native_new_virtual (
- seat_impl, CLUTTER_POINTER_DEVICE,
- CLUTTER_INPUT_MODE_LOGICAL);
- seat_impl->pointer_x = INITIAL_POINTER_X;
- seat_impl->pointer_y = INITIAL_POINTER_Y;
- meta_input_device_native_set_coords_in_impl (META_INPUT_DEVICE_NATIVE (device),
- seat_impl->pointer_x,
- seat_impl->pointer_y);
- seat_impl->core_pointer = device;
-
- device = meta_input_device_native_new_virtual (
- seat_impl, CLUTTER_KEYBOARD_DEVICE,
- CLUTTER_INPUT_MODE_LOGICAL);
- seat_impl->core_keyboard = device;
-
- if (G_OBJECT_CLASS (meta_seat_impl_parent_class)->constructed)
- G_OBJECT_CLASS (meta_seat_impl_parent_class)->constructed (object);
-}
-
-static void
-meta_seat_impl_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaSeatImpl *seat_impl = META_SEAT_IMPL (object);
-
- switch (prop_id)
- {
- case PROP_SEAT:
- seat_impl->seat_native = g_value_get_object (value);
- break;
- case PROP_SEAT_ID:
- seat_impl->seat_id = g_value_dup_string (value);
- break;
- case PROP_FLAGS:
- seat_impl->flags = g_value_get_flags (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-meta_seat_impl_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaSeatImpl *seat_impl = META_SEAT_IMPL (object);
-
- switch (prop_id)
- {
- case PROP_SEAT:
- g_value_set_object (value, seat_impl->seat_native);
- break;
- case PROP_SEAT_ID:
- g_value_set_string (value, seat_impl->seat_id);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static gboolean
-destroy_in_impl (GTask *task)
-{
- MetaSeatImpl *seat_impl = g_task_get_source_object (task);
- MetaSeatImplPrivate *priv = meta_seat_impl_get_instance_private (seat_impl);
- gboolean numlock_active;
-
- g_slist_foreach (seat_impl->devices,
- (GFunc) meta_input_device_native_detach_libinput_in_impl,
- NULL);
- g_slist_free_full (seat_impl->devices, g_object_unref);
- seat_impl->devices = NULL;
-
- g_clear_pointer (&seat_impl->libinput, libinput_unref);
- g_clear_pointer (&seat_impl->tools, g_hash_table_unref);
- g_clear_pointer (&seat_impl->touch_states, g_hash_table_destroy);
- g_clear_pointer (&seat_impl->event_source, meta_event_source_free);
-
- numlock_active =
- xkb_state_mod_name_is_active (seat_impl->xkb, XKB_MOD_NAME_NUM,
- XKB_STATE_MODS_LATCHED |
- XKB_STATE_MODS_LOCKED);
- meta_input_settings_maybe_save_numlock_state (seat_impl->input_settings,
- numlock_active);
-
- g_clear_pointer (&seat_impl->xkb, xkb_state_unref);
-
- meta_seat_impl_clear_repeat_source (seat_impl);
-
- g_clear_pointer (&priv->device_files, g_hash_table_destroy);
-
- g_main_loop_quit (seat_impl->input_loop);
- g_task_return_boolean (task, TRUE);
-
- return G_SOURCE_REMOVE;
-}
-
-void
-meta_seat_impl_destroy (MetaSeatImpl *seat_impl)
-{
- if (seat_impl->libinput)
- {
- GTask *task;
-
- task = g_task_new (seat_impl, NULL, NULL, NULL);
- meta_seat_impl_run_input_task (seat_impl, task,
- (GSourceFunc) destroy_in_impl);
- g_object_unref (task);
-
- g_thread_join (seat_impl->input_thread);
- g_assert (!seat_impl->libinput);
- }
-
- g_object_unref (seat_impl);
-}
-
-static void
-meta_seat_impl_finalize (GObject *object)
-{
- MetaSeatImpl *seat_impl = META_SEAT_IMPL (object);
-
- g_assert (!seat_impl->libinput);
- g_assert (!seat_impl->tools);
- g_assert (!seat_impl->event_source);
-
- g_free (seat_impl->seat_id);
-
- g_rw_lock_clear (&seat_impl->state_lock);
-
- G_OBJECT_CLASS (meta_seat_impl_parent_class)->finalize (object);
-}
-
-ClutterInputDevice *
-meta_seat_impl_get_pointer (MetaSeatImpl *seat_impl)
-{
- return seat_impl->core_pointer;
-}
-
-ClutterInputDevice *
-meta_seat_impl_get_keyboard (MetaSeatImpl *seat_impl)
-{
- return seat_impl->core_keyboard;
-}
-
-GSList *
-meta_seat_impl_get_devices_in_impl (MetaSeatImpl *seat_impl)
-{
- return g_slist_copy_deep (seat_impl->devices,
- (GCopyFunc) g_object_ref,
- NULL);
-}
-
-MetaKeymapNative *
-meta_seat_impl_get_keymap (MetaSeatImpl *seat_impl)
-{
- return g_object_ref (seat_impl->keymap);
-}
-
-static gboolean
-warp_pointer_in_impl (GTask *task)
-{
- MetaSeatImpl *seat_impl = g_task_get_source_object (task);
- graphene_point_t *point;
-
- point = g_task_get_task_data (task);
- notify_absolute_motion_in_impl (seat_impl->core_pointer, 0,
- point->x, point->y, NULL);
- g_task_return_boolean (task, TRUE);
-
- return G_SOURCE_REMOVE;
-}
-
-void
-meta_seat_impl_warp_pointer (MetaSeatImpl *seat_impl,
- int x,
- int y)
-{
- graphene_point_t *point;
- GTask *task;
-
- point = graphene_point_alloc ();
- point->x = x;
- point->y = y;
-
- task = g_task_new (seat_impl, NULL, NULL, NULL);
- g_task_set_task_data (task, point, (GDestroyNotify) graphene_point_free);
- meta_seat_impl_run_input_task (seat_impl, task,
- (GSourceFunc) warp_pointer_in_impl);
- g_object_unref (task);
-}
-
-gboolean
-meta_seat_impl_query_state (MetaSeatImpl *seat_impl,
- ClutterInputDevice *device,
- ClutterEventSequence *sequence,
- graphene_point_t *coords,
- ClutterModifierType *modifiers)
-{
- MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
- gboolean retval = FALSE;
- ClutterModifierType mods = 0;
-
- g_rw_lock_reader_lock (&seat_impl->state_lock);
-
- if (sequence)
- {
- MetaTouchState *touch_state;
- int slot;
-
- slot = clutter_event_sequence_get_slot (sequence);
- touch_state = meta_seat_impl_lookup_touch_state_in_impl (seat_impl, slot);
- if (!touch_state)
- goto out;
-
- if (coords)
- {
- coords->x = touch_state->coords.x;
- coords->y = touch_state->coords.y;
- }
-
- if (seat_impl->xkb)
- mods = meta_xkb_translate_modifiers (seat_impl->xkb, 0);
-
- retval = TRUE;
- }
- else
- {
- if (coords)
- {
- coords->x = device_native->pointer_x;
- coords->y = device_native->pointer_y;
- }
-
- if (seat_impl->xkb)
- {
- mods = meta_xkb_translate_modifiers (seat_impl->xkb,
- seat_impl->button_state);
- }
-
- retval = TRUE;
- }
-
- if (modifiers)
- *modifiers = mods;
-
- out:
- g_rw_lock_reader_unlock (&seat_impl->state_lock);
- return retval;
-}
-
-static void
-meta_seat_impl_initable_iface_init (GInitableIface *iface)
-{
- iface->init = meta_seat_impl_initable_init;
-}
-
-static void
-meta_seat_impl_class_init (MetaSeatImplClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->constructed = meta_seat_impl_constructed;
- object_class->set_property = meta_seat_impl_set_property;
- object_class->get_property = meta_seat_impl_get_property;
- object_class->finalize = meta_seat_impl_finalize;
-
- props[PROP_SEAT] =
- g_param_spec_object ("seat",
- "Seat",
- "Seat",
- META_TYPE_SEAT_NATIVE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
-
- props[PROP_SEAT_ID] =
- g_param_spec_string ("seat-id",
- "Seat ID",
- "Seat ID",
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY);
-
- props[PROP_FLAGS] =
- g_param_spec_flags ("flags",
- "Flags",
- "Flags",
- META_TYPE_SEAT_NATIVE_FLAG,
- META_SEAT_NATIVE_FLAG_NONE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY);
-
- signals[KBD_A11Y_FLAGS_CHANGED] =
- g_signal_new ("kbd-a11y-flags-changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, NULL,
- G_TYPE_NONE, 2,
- G_TYPE_UINT, G_TYPE_UINT);
- signals[KBD_A11Y_MODS_STATE_CHANGED] =
- g_signal_new ("kbd-a11y-mods-state-changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, NULL,
- G_TYPE_NONE, 2,
- G_TYPE_UINT, G_TYPE_UINT);
- signals[TOUCH_MODE] =
- g_signal_new ("touch-mode",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__BOOLEAN,
- G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
- signals[BELL] =
- g_signal_new ("bell",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, NULL,
- G_TYPE_NONE, 0);
- signals[MODS_STATE_CHANGED] =
- g_signal_new ("mods-state-changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
- g_object_class_install_properties (object_class, N_PROPS, props);
-}
-
-static void
-meta_seat_impl_init (MetaSeatImpl *seat_impl)
-{
- g_rw_lock_init (&seat_impl->state_lock);
-
- seat_impl->repeat = TRUE;
- seat_impl->repeat_delay = 250; /* ms */
- seat_impl->repeat_interval = 33; /* ms */
-
- g_mutex_init (&seat_impl->init_mutex);
- g_cond_init (&seat_impl->init_cond);
-
- seat_impl->barrier_manager = meta_barrier_manager_native_new ();
-}
-
-void
-meta_seat_impl_update_xkb_state_in_impl (MetaSeatImpl *seat_impl)
-{
- xkb_mod_mask_t latched_mods = 0;
- xkb_mod_mask_t locked_mods = 0;
- struct xkb_keymap *xkb_keymap;
-
- g_rw_lock_writer_lock (&seat_impl->state_lock);
-
- xkb_keymap = meta_keymap_native_get_keyboard_map_in_impl (seat_impl->keymap);
-
- if (seat_impl->xkb)
- {
- latched_mods = xkb_state_serialize_mods (seat_impl->xkb,
- XKB_STATE_MODS_LATCHED);
- locked_mods = xkb_state_serialize_mods (seat_impl->xkb,
- XKB_STATE_MODS_LOCKED);
- xkb_state_unref (seat_impl->xkb);
- }
-
- seat_impl->xkb = xkb_state_new (xkb_keymap);
-
- xkb_state_update_mask (seat_impl->xkb,
- 0, /* depressed */
- latched_mods,
- locked_mods,
- 0, 0, seat_impl->layout_idx);
-
- seat_impl->caps_lock_led =
- xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_CAPS);
- seat_impl->num_lock_led =
- xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_NUM);
- seat_impl->scroll_lock_led =
- xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL);
-
- meta_seat_impl_sync_leds_in_impl (seat_impl);
- meta_keymap_native_update_in_impl (seat_impl->keymap,
- seat_impl,
- seat_impl->xkb);
-
- g_rw_lock_writer_unlock (&seat_impl->state_lock);
-}
-
-static gboolean
-release_devices (GTask *task)
-{
- MetaSeatImpl *seat_impl = g_task_get_source_object (task);
-
- if (seat_impl->released)
- {
- g_warning ("meta_seat_impl_release_devices() shouldn't be called "
- "multiple times without a corresponding call to "
- "meta_seat_impl_reclaim_devices() first");
- }
- else
- {
- libinput_suspend (seat_impl->libinput);
- process_events (seat_impl);
-
- seat_impl->released = TRUE;
- }
-
- g_task_return_boolean (task, TRUE);
-
- return G_SOURCE_REMOVE;
-}
-
-/**
- * meta_seat_impl_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_impl_reclaim_devices().
- *
- * This function should only be called after clutter has been initialized.
- */
-void
-meta_seat_impl_release_devices (MetaSeatImpl *seat_impl)
-{
- GTask *task;
-
- g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
-
- task = g_task_new (seat_impl, NULL, NULL, NULL);
- meta_seat_impl_run_input_task (seat_impl, task,
- (GSourceFunc) release_devices);
- g_object_unref (task);
-}
-
-static gboolean
-reclaim_devices (GTask *task)
-{
- MetaSeatImpl *seat_impl = g_task_get_source_object (task);
-
- if (seat_impl->released)
- {
- libinput_resume (seat_impl->libinput);
- meta_seat_impl_update_xkb_state_in_impl (seat_impl);
- process_events (seat_impl);
-
- seat_impl->released = FALSE;
- }
- else
- {
- g_warning ("Spurious call to meta_seat_impl_reclaim_devices() without "
- "previous call to meta_seat_impl_release_devices");
- }
-
- g_task_return_boolean (task, TRUE);
-
- return G_SOURCE_REMOVE;
-}
-
-/**
- * meta_seat_impl_reclaim_devices:
- *
- * This causes Clutter to re-probe for evdev devices. This is must only be
- * called after a corresponding call to meta_seat_impl_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_impl_reclaim_devices (MetaSeatImpl *seat_impl)
-{
- GTask *task;
-
- g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
-
- task = g_task_new (seat_impl, NULL, NULL, NULL);
- meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) reclaim_devices);
- g_object_unref (task);
-}
-
-static gboolean
-set_keyboard_map (GTask *task)
-{
- MetaSeatImpl *seat_impl = g_task_get_source_object (task);
- struct xkb_keymap *xkb_keymap = g_task_get_task_data (task);
- MetaKeymapNative *keymap;
-
- keymap = seat_impl->keymap;
- meta_keymap_native_set_keyboard_map_in_impl (keymap, xkb_keymap);
-
- meta_seat_impl_update_xkb_state_in_impl (seat_impl);
- g_task_return_boolean (task, TRUE);
-
- return G_SOURCE_REMOVE;
-}
-
-/**
- * meta_seat_impl_set_keyboard_map: (skip)
- * @seat_impl: 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_impl_set_keyboard_map (MetaSeatImpl *seat_impl,
- struct xkb_keymap *xkb_keymap)
-{
- GTask *task;
-
- g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
- g_return_if_fail (xkb_keymap != NULL);
-
- task = g_task_new (seat_impl, NULL, NULL, NULL);
- g_task_set_task_data (task,
- xkb_keymap_ref (xkb_keymap),
- (GDestroyNotify) xkb_keymap_unref);
- meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) set_keyboard_map);
- g_object_unref (task);
-}
-
-static gboolean
-set_keyboard_layout_index (GTask *task)
-{
- MetaSeatImpl *seat_impl = g_task_get_source_object (task);
- xkb_layout_index_t idx = GPOINTER_TO_UINT (g_task_get_task_data (task));
- xkb_mod_mask_t depressed_mods;
- xkb_mod_mask_t latched_mods;
- xkb_mod_mask_t locked_mods;
- struct xkb_state *state;
-
- g_rw_lock_writer_lock (&seat_impl->state_lock);
-
- state = seat_impl->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);
- meta_keymap_native_update_in_impl (seat_impl->keymap,
- seat_impl,
- seat_impl->xkb);
-
- seat_impl->layout_idx = idx;
-
- g_rw_lock_writer_unlock (&seat_impl->state_lock);
-
- g_task_return_boolean (task, TRUE);
-
- return G_SOURCE_REMOVE;
-}
-
-/**
- * meta_seat_impl_set_keyboard_layout_index: (skip)
- * @seat_impl: 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_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl,
- xkb_layout_index_t idx)
-{
- GTask *task;
-
- g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
-
- task = g_task_new (seat_impl, NULL, NULL, NULL);
- g_task_set_task_data (task, GUINT_TO_POINTER (idx), NULL);
- meta_seat_impl_run_input_task (seat_impl, task,
- (GSourceFunc) set_keyboard_layout_index);
- g_object_unref (task);
-}
-
-/**
- * meta_seat_impl_set_keyboard_repeat_in_impl:
- * @seat_impl: 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_impl_set_keyboard_repeat_in_impl (MetaSeatImpl *seat_impl,
- gboolean repeat,
- uint32_t delay,
- uint32_t interval)
-{
- g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
-
- seat_impl->repeat = repeat;
- seat_impl->repeat_delay = delay;
- seat_impl->repeat_interval = interval;
-}
-
-struct xkb_state *
-meta_seat_impl_get_xkb_state_in_impl (MetaSeatImpl *seat_impl)
-{
- return seat_impl->xkb;
-}
-
-MetaBarrierManagerNative *
-meta_seat_impl_get_barrier_manager (MetaSeatImpl *seat_impl)
-{
- return seat_impl->barrier_manager;
-}
-
-static gboolean
-set_pointer_constraint (GTask *task)
-{
- MetaSeatImpl *seat_impl = g_task_get_source_object (task);
- MetaPointerConstraintImpl *constraint_impl = g_task_get_task_data (task);
-
- if (!g_set_object (&seat_impl->pointer_constraint, constraint_impl))
- return G_SOURCE_REMOVE;
-
- if (constraint_impl)
- {
- meta_pointer_constraint_impl_ensure_constrained (constraint_impl,
- seat_impl->core_pointer);
- }
-
- g_task_return_boolean (task, TRUE);
-
- return G_SOURCE_REMOVE;
-}
-
-void
-meta_seat_impl_set_pointer_constraint (MetaSeatImpl *seat_impl,
- MetaPointerConstraintImpl *constraint_impl)
-{
- GTask *task;
-
- g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
-
- task = g_task_new (seat_impl, NULL, NULL, NULL);
- if (constraint_impl)
- g_task_set_task_data (task, g_object_ref (constraint_impl), g_object_unref);
- meta_seat_impl_run_input_task (seat_impl, task,
- (GSourceFunc) set_pointer_constraint);
- g_object_unref (task);
-}
-
-static gboolean
-set_viewports (GTask *task)
-{
- MetaSeatImpl *seat_impl = g_task_get_source_object (task);
- MetaViewportInfo *viewports = g_task_get_task_data (task);
-
- g_set_object (&seat_impl->viewports, viewports);
- g_task_return_boolean (task, TRUE);
-
- return G_SOURCE_REMOVE;
-}
-
-void
-meta_seat_impl_set_viewports (MetaSeatImpl *seat_impl,
- MetaViewportInfo *viewports)
-{
- GTask *task;
-
- g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
-
- task = g_task_new (seat_impl, NULL, NULL, NULL);
- g_task_set_task_data (task, g_object_ref (viewports), g_object_unref);
- meta_seat_impl_run_input_task (seat_impl, task,
- (GSourceFunc) set_viewports);
- g_object_unref (task);
-}
-
-MetaSeatImpl *
-meta_seat_impl_new (MetaSeatNative *seat_native,
- const char *seat_id,
- MetaSeatNativeFlag flags)
-{
- return g_initable_new (META_TYPE_SEAT_IMPL,
- NULL, NULL,
- "seat", seat_native,
- "seat-id", seat_id,
- "flags", flags,
- NULL);
-}
-
-void
-meta_seat_impl_notify_kbd_a11y_flags_changed_in_impl (MetaSeatImpl *seat_impl,
- MetaKeyboardA11yFlags new_flags,
- MetaKeyboardA11yFlags what_changed)
-{
- MetaInputSettings *input_settings;
- GValue values[] = { G_VALUE_INIT, G_VALUE_INIT };
-
- input_settings = seat_impl->input_settings;
- meta_input_settings_notify_kbd_a11y_change (input_settings,
- new_flags, what_changed);
- g_value_init (&values[0], G_TYPE_UINT);
- g_value_set_uint (&values[0], new_flags);
- g_value_init (&values[1], G_TYPE_UINT);
- g_value_set_uint (&values[1], what_changed);
-
- emit_signal (seat_impl, signals[KBD_A11Y_FLAGS_CHANGED],
- values, G_N_ELEMENTS (values));
-}
-
-void
-meta_seat_impl_notify_kbd_a11y_mods_state_changed_in_impl (MetaSeatImpl *seat_impl,
- xkb_mod_mask_t new_latched_mods,
- xkb_mod_mask_t new_locked_mods)
-{
- GValue values[] = { G_VALUE_INIT, G_VALUE_INIT };
-
- g_value_init (&values[0], G_TYPE_UINT);
- g_value_set_uint (&values[0], new_latched_mods);
- g_value_init (&values[1], G_TYPE_UINT);
- g_value_set_uint (&values[1], new_locked_mods);
-
- emit_signal (seat_impl, signals[KBD_A11Y_MODS_STATE_CHANGED],
- values, G_N_ELEMENTS (values));
-}
-
-void
-meta_seat_impl_notify_bell_in_impl (MetaSeatImpl *seat_impl)
-{
- emit_signal (seat_impl, signals[BELL], NULL, 0);
-}
-
-MetaInputSettings *
-meta_seat_impl_get_input_settings (MetaSeatImpl *seat_impl)
-{
- return seat_impl->input_settings;
-}
diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h
deleted file mode 100644
index d3e2ab860..000000000
--- a/src/backends/native/meta-seat-impl.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * 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_IMPL_H
-#define META_SEAT_IMPL_H
-
-#ifndef META_INPUT_THREAD_H_INSIDE
-#error "This header cannot be included directly. Use "backends/native/meta-input-thread.h""
-#endif /* META_INPUT_THREAD_H_INSIDE */
-
-#include <gudev/gudev.h>
-#include <libinput.h>
-#include <linux/input-event-codes.h>
-
-#include "backends/meta-input-settings-private.h"
-#include "backends/meta-viewport-info.h"
-#include "backends/native/meta-backend-native-types.h"
-#include "backends/native/meta-barrier-native.h"
-#include "backends/native/meta-cursor-renderer-native.h"
-#include "backends/native/meta-keymap-native.h"
-#include "backends/native/meta-pointer-constraint-native.h"
-#include "backends/native/meta-xkb-utils.h"
-#include "clutter/clutter.h"
-
-typedef struct _MetaTouchState MetaTouchState;
-typedef struct _MetaSeatImpl MetaSeatImpl;
-typedef struct _MetaEventSource MetaEventSource;
-
-struct _MetaTouchState
-{
- MetaSeatImpl *seat_impl;
-
- int device_slot;
- int seat_slot;
- graphene_point_t coords;
-};
-
-struct _MetaSeatImpl
-{
- GObject parent_instance;
-
- GMainContext *main_context;
- GMainContext *input_context;
- GMainLoop *input_loop;
- GThread *input_thread;
- GMutex init_mutex;
- GCond init_cond;
-
- MetaSeatNative *seat_native;
- char *seat_id;
- MetaSeatNativeFlag flags;
- MetaEventSource *event_source;
- struct libinput *libinput;
- GRWLock state_lock;
-
- GSList *devices;
- GHashTable *tools;
-
- ClutterInputDevice *core_pointer;
- ClutterInputDevice *core_keyboard;
-
- GHashTable *touch_states;
- GHashTable *cursor_renderers;
-
- 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];
-
- MetaBarrierManagerNative *barrier_manager;
- MetaPointerConstraintImpl *pointer_constraint;
-
- MetaKeymapNative *keymap;
- MetaInputSettings *input_settings;
-
- MetaViewportInfo *viewports;
-
- gboolean tablet_mode_switch_state;
- gboolean has_touchscreen;
- gboolean has_tablet_switch;
- gboolean has_pointer;
- gboolean touch_mode;
- gboolean input_thread_initialized;
-
- /* keyboard repeat */
- gboolean repeat;
- uint32_t repeat_delay;
- uint32_t repeat_interval;
- uint32_t repeat_key;
- uint32_t repeat_count;
- ClutterInputDevice *repeat_device;
- GSource *repeat_source;
-
- 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_IMPL meta_seat_impl_get_type ()
-G_DECLARE_FINAL_TYPE (MetaSeatImpl, meta_seat_impl,
- META, SEAT_IMPL, GObject)
-
-MetaSeatImpl * meta_seat_impl_new (MetaSeatNative *seat_native,
- const char *seat_id,
- MetaSeatNativeFlag flags);
-
-void meta_seat_impl_destroy (MetaSeatImpl *seat_impl);
-
-void meta_seat_impl_run_input_task (MetaSeatImpl *seat_impl,
- GTask *task,
- GSourceFunc dispatch_func);
-
-void meta_seat_impl_notify_key_in_impl (MetaSeatImpl *seat_impl,
- ClutterInputDevice *device,
- uint64_t time_us,
- uint32_t key,
- uint32_t state,
- gboolean update_keys);
-
-void meta_seat_impl_notify_relative_motion_in_impl (MetaSeatImpl *seat_impl,
- ClutterInputDevice *input_device,
- uint64_t time_us,
- float dx,
- float dy,
- float dx_unaccel,
- float dy_unaccel);
-
-void meta_seat_impl_notify_absolute_motion_in_impl (MetaSeatImpl *seat_impl,
- ClutterInputDevice *input_device,
- uint64_t time_us,
- float x,
- float y,
- double *axes);
-
-void meta_seat_impl_notify_button_in_impl (MetaSeatImpl *seat_impl,
- ClutterInputDevice *input_device,
- uint64_t time_us,
- uint32_t button,
- uint32_t state);
-
-void meta_seat_impl_notify_scroll_continuous_in_impl (MetaSeatImpl *seat_impl,
- ClutterInputDevice *input_device,
- uint64_t time_us,
- double dx,
- double dy,
- ClutterScrollSource source,
- ClutterScrollFinishFlags flags);
-
-void meta_seat_impl_notify_discrete_scroll_in_impl (MetaSeatImpl *seat_impl,
- ClutterInputDevice *input_device,
- uint64_t time_us,
- double discrete_dx,
- double discrete_dy,
- ClutterScrollSource source);
-
-void meta_seat_impl_notify_touch_event_in_impl (MetaSeatImpl *seat_impl,
- ClutterInputDevice *input_device,
- ClutterEventType evtype,
- uint64_t time_us,
- int slot,
- double x,
- double y);
-
-void meta_seat_impl_sync_leds_in_impl (MetaSeatImpl *seat_impl);
-
-MetaTouchState * meta_seat_impl_acquire_touch_state_in_impl (MetaSeatImpl *seat_impl,
- int seat_slot);
-MetaTouchState * meta_seat_impl_lookup_touch_state_in_impl (MetaSeatImpl *seat_impl,
- int seat_slot);
-void meta_seat_impl_release_touch_state_in_impl (MetaSeatImpl *seat_impl,
- int seat_slot);
-
-void meta_seat_impl_update_xkb_state_in_impl (MetaSeatImpl *seat_impl);
-
-void meta_seat_impl_release_devices (MetaSeatImpl *seat_impl);
-void meta_seat_impl_reclaim_devices (MetaSeatImpl *seat_impl);
-
-struct xkb_state * meta_seat_impl_get_xkb_state_in_impl (MetaSeatImpl *seat_impl);
-
-void meta_seat_impl_set_keyboard_map (MetaSeatImpl *seat_impl,
- struct xkb_keymap *keymap);
-
-void meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl,
- xkb_layout_index_t idx);
-
-void meta_seat_impl_set_keyboard_repeat_in_impl (MetaSeatImpl *seat_impl,
- gboolean repeat,
- uint32_t delay,
- uint32_t interval);
-
-MetaBarrierManagerNative * meta_seat_impl_get_barrier_manager (MetaSeatImpl *seat_impl);
-
-void meta_seat_impl_set_pointer_constraint (MetaSeatImpl *seat_impl,
- MetaPointerConstraintImpl *constraint_impl);
-void meta_seat_impl_set_viewports (MetaSeatImpl *seat_impl,
- MetaViewportInfo *viewports);
-
-void meta_seat_impl_warp_pointer (MetaSeatImpl *seat_impl,
- int x,
- int y);
-gboolean meta_seat_impl_query_state (MetaSeatImpl *seat_impl,
- ClutterInputDevice *device,
- ClutterEventSequence *sequence,
- graphene_point_t *coords,
- ClutterModifierType *modifiers);
-ClutterInputDevice * meta_seat_impl_get_pointer (MetaSeatImpl *seat_impl);
-ClutterInputDevice * meta_seat_impl_get_keyboard (MetaSeatImpl *seat_impl);
-GSList * meta_seat_impl_get_devices_in_impl (MetaSeatImpl *seat_impl);
-
-MetaKeymapNative * meta_seat_impl_get_keymap (MetaSeatImpl *seat_impl);
-
-void meta_seat_impl_notify_kbd_a11y_flags_changed_in_impl (MetaSeatImpl *seat_impl,
- MetaKeyboardA11yFlags new_flags,
- MetaKeyboardA11yFlags what_changed);
-void meta_seat_impl_notify_kbd_a11y_mods_state_changed_in_impl (MetaSeatImpl *seat_impl,
- xkb_mod_mask_t new_latched_mods,
- xkb_mod_mask_t new_locked_mods);
-void meta_seat_impl_notify_bell_in_impl (MetaSeatImpl *seat_impl);
-
-MetaInputSettings * meta_seat_impl_get_input_settings (MetaSeatImpl *seat_impl);
-
-void meta_seat_impl_queue_main_thread_idle (MetaSeatImpl *seat_impl,
- GSourceFunc func,
- gpointer user_data,
- GDestroyNotify destroy_notify);
-
-#endif /* META_SEAT_IMPL_H */
diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c
deleted file mode 100644
index 12fead1fb..000000000
--- a/src/backends/native/meta-seat-native.c
+++ /dev/null
@@ -1,634 +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 <http://www.gnu.org/licenses/>.
- *
- * Author: Damien Lespiau <damien.lespiau@intel.com>
- * Author: Jonas Ådahl <jadahl@gmail.com>
- */
-
-#include "config.h"
-
-#include "backends/native/meta-seat-native.h"
-
-#include "backends/meta-cursor-tracker-private.h"
-#include "backends/meta-keymap-utils.h"
-#include "backends/native/meta-barrier-native.h"
-#include "backends/native/meta-input-thread.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"
-
-#include "meta-private-enum-types.h"
-
-enum
-{
- PROP_0,
- PROP_SEAT_ID,
- PROP_FLAGS,
- PROP_BACKEND,
- N_PROPS,
-
- /* This property is overridden */
- PROP_TOUCH_MODE,
-};
-
-static GParamSpec *props[N_PROPS] = { NULL };
-
-G_DEFINE_TYPE (MetaSeatNative, meta_seat_native, CLUTTER_TYPE_SEAT)
-
-static gboolean
-meta_seat_native_handle_event_post (ClutterSeat *seat,
- const ClutterEvent *event)
-{
- MetaSeatNative *seat_native = META_SEAT_NATIVE (seat);
- ClutterInputDevice *device = clutter_event_get_source_device (event);
- ClutterEventType event_type = event->type;
-
- if (event_type == CLUTTER_PROXIMITY_IN)
- {
- MetaCursorRenderer *cursor_renderer;
-
- if (!seat_native->tablet_cursors)
- {
- seat_native->tablet_cursors = g_hash_table_new_full (NULL, NULL, NULL,
- g_object_unref);
- }
-
- cursor_renderer = meta_cursor_renderer_new (meta_get_backend (), device);
- g_hash_table_insert (seat_native->tablet_cursors,
- device, cursor_renderer);
- return TRUE;
- }
- else if (event_type == CLUTTER_PROXIMITY_OUT)
- {
- if (seat_native->tablet_cursors)
- g_hash_table_remove (seat_native->tablet_cursors, device);
- return TRUE;
- }
- else if (event_type == CLUTTER_DEVICE_ADDED)
- {
- if (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_LOGICAL)
- seat_native->devices = g_list_prepend (seat_native->devices, g_object_ref (device));
- }
- else if (event_type == CLUTTER_DEVICE_REMOVED)
- {
- GList *l = g_list_find (seat_native->devices, device);
-
- if (l)
- {
- seat_native->devices = g_list_delete_link (seat_native->devices, l);
- g_object_unref (device);
- }
- }
-
- return FALSE;
-}
-
-static void
-proxy_kbd_a11y_flags_changed (MetaSeatImpl *seat_impl,
- MetaKeyboardA11yFlags new_flags,
- MetaKeyboardA11yFlags what_changed,
- MetaSeatNative *seat_native)
-{
- g_signal_emit_by_name (seat_native,
- "kbd-a11y-flags-changed",
- new_flags, what_changed);
-}
-
-static void
-proxy_kbd_a11y_mods_state_changed (MetaSeatImpl *seat_impl,
- xkb_mod_mask_t new_latched_mods,
- xkb_mod_mask_t new_locked_mods,
- MetaSeatNative *seat_native)
-{
- g_signal_emit_by_name (seat_native,
- "kbd-a11y-mods-state-changed",
- new_latched_mods,
- new_locked_mods);
-}
-
-static void
-proxy_touch_mode_changed (MetaSeatImpl *seat_impl,
- gboolean enabled,
- MetaSeatNative *seat_native)
-{
- seat_native->touch_mode = enabled;
- g_object_notify (G_OBJECT (seat_native), "touch-mode");
-}
-
-static void
-proxy_bell (MetaSeatImpl *seat_impl,
- MetaSeatNative *seat_native)
-{
- clutter_seat_bell_notify (CLUTTER_SEAT (seat_native));
-}
-
-static void
-proxy_mods_state_changed (MetaSeatImpl *seat_impl,
- ClutterSeat *seat)
-{
- ClutterKeymap *keymap;
-
- keymap = clutter_seat_get_keymap (seat);
- g_signal_emit_by_name (keymap, "state-changed");
-}
-
-static void
-meta_seat_native_constructed (GObject *object)
-{
- MetaSeatNative *seat = META_SEAT_NATIVE (object);
-
- seat->impl = meta_seat_impl_new (seat, seat->seat_id, seat->flags);
- g_signal_connect (seat->impl, "kbd-a11y-flags-changed",
- G_CALLBACK (proxy_kbd_a11y_flags_changed), seat);
- g_signal_connect (seat->impl, "kbd-a11y-mods-state-changed",
- G_CALLBACK (proxy_kbd_a11y_mods_state_changed), seat);
- g_signal_connect (seat->impl, "touch-mode",
- G_CALLBACK (proxy_touch_mode_changed), seat);
- g_signal_connect (seat->impl, "bell",
- G_CALLBACK (proxy_bell), seat);
- g_signal_connect (seat->impl, "mods-state-changed",
- G_CALLBACK (proxy_mods_state_changed), seat);
-
- seat->core_pointer = meta_seat_impl_get_pointer (seat->impl);
- seat->core_keyboard = meta_seat_impl_get_keyboard (seat->impl);
-
- meta_seat_native_set_keyboard_map (seat, "us", "", "");
-
- 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_FLAGS:
- seat_native->flags = g_value_get_flags (value);
- break;
- case PROP_BACKEND:
- seat_native->backend = g_value_get_object (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;
- case PROP_FLAGS:
- g_value_set_flags (value, seat_native->flags);
- break;
- case PROP_BACKEND:
- g_value_set_object (value, seat_native->backend);
- 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_pointer (&seat->xkb_keymap, xkb_keymap_unref);
- g_clear_object (&seat->core_pointer);
- g_clear_object (&seat->core_keyboard);
- g_clear_pointer (&seat->impl, meta_seat_impl_destroy);
- g_list_free_full (g_steal_pointer (&seat->devices), g_object_unref);
- g_clear_pointer (&seat->reserved_virtual_slots, g_hash_table_destroy);
- g_clear_pointer (&seat->tablet_cursors, g_hash_table_unref);
- g_clear_object (&seat->cursor_renderer);
-
- g_clear_pointer (&seat->seat_id, g_free);
-
- G_OBJECT_CLASS (meta_seat_native_parent_class)->dispose (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 const GList *
-meta_seat_native_peek_devices (ClutterSeat *seat)
-{
- MetaSeatNative *seat_native = META_SEAT_NATIVE (seat);
-
- return (const GList *) seat_native->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);
-
- if (!seat_native->keymap)
- seat_native->keymap = meta_seat_impl_get_keymap (seat_native->impl);
-
- return CLUTTER_KEYMAP (seat_native->keymap);
-}
-
-static guint
-bump_virtual_touch_slot_base (MetaSeatNative *seat_native)
-{
- while (TRUE)
- {
- if (seat_native->virtual_touch_slot_base < 0x100)
- seat_native->virtual_touch_slot_base = 0x100;
-
- seat_native->virtual_touch_slot_base +=
- CLUTTER_VIRTUAL_INPUT_DEVICE_MAX_TOUCH_SLOTS;
-
- if (!g_hash_table_lookup (seat_native->reserved_virtual_slots,
- GUINT_TO_POINTER (seat_native->virtual_touch_slot_base)))
- break;
- }
-
- return seat_native->virtual_touch_slot_base;
-}
-
-static ClutterVirtualInputDevice *
-meta_seat_native_create_virtual_device (ClutterSeat *seat,
- ClutterInputDeviceType device_type)
-{
- MetaSeatNative *seat_native = META_SEAT_NATIVE (seat);
- guint slot_base;
-
- slot_base = bump_virtual_touch_slot_base (seat_native);
- g_hash_table_add (seat_native->reserved_virtual_slots,
- GUINT_TO_POINTER (slot_base));
-
- return g_object_new (META_TYPE_VIRTUAL_INPUT_DEVICE_NATIVE,
- "seat", seat,
- "slot-base", slot_base,
- "device-type", device_type,
- NULL);
-}
-
-void
-meta_seat_native_release_touch_slots (MetaSeatNative *seat,
- guint base_slot)
-{
- g_hash_table_remove (seat->reserved_virtual_slots,
- GUINT_TO_POINTER (base_slot));
-}
-
-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_warp_pointer (ClutterSeat *seat,
- int x,
- int y)
-{
- MetaSeatNative *seat_native = META_SEAT_NATIVE (seat);
-
- meta_seat_impl_warp_pointer (seat_native->impl, x, y);
-}
-
-static gboolean
-meta_seat_native_query_state (ClutterSeat *seat,
- ClutterInputDevice *device,
- ClutterEventSequence *sequence,
- graphene_point_t *coords,
- ClutterModifierType *modifiers)
-{
- MetaSeatNative *seat_native = META_SEAT_NATIVE (seat);
-
- return meta_seat_impl_query_state (seat_native->impl, device, sequence,
- coords, modifiers);
-}
-
-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;
-
- seat_class->get_pointer = meta_seat_native_get_pointer;
- seat_class->get_keyboard = meta_seat_native_get_keyboard;
- seat_class->peek_devices = meta_seat_native_peek_devices;
- seat_class->bell_notify = meta_seat_native_bell_notify;
- seat_class->get_keymap = meta_seat_native_get_keymap;
- 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->warp_pointer = meta_seat_native_warp_pointer;
- seat_class->handle_event_post = meta_seat_native_handle_event_post;
- seat_class->query_state = meta_seat_native_query_state;
-
- props[PROP_SEAT_ID] =
- g_param_spec_string ("seat-id",
- "Seat ID",
- "Seat ID",
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY);
-
- props[PROP_FLAGS] =
- g_param_spec_flags ("flags",
- "Flags",
- "Flags",
- META_TYPE_SEAT_NATIVE_FLAG,
- META_SEAT_NATIVE_FLAG_NONE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY);
-
- props[PROP_BACKEND] =
- g_param_spec_object ("backend",
- "Backend",
- "Backend",
- META_TYPE_BACKEND,
- 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_init (MetaSeatNative *seat)
-{
- seat->reserved_virtual_slots = g_hash_table_new (NULL, NULL);
-}
-
-/**
- * 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;
- }
-
- meta_seat_impl_release_devices (seat->impl);
- 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;
- }
-
- meta_seat_impl_reclaim_devices (seat->impl);
- seat->released = FALSE;
-}
-
-static struct xkb_keymap *
-create_keymap (const char *layouts,
- const char *variants,
- const char *options)
-{
- 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 = layouts;
- names.variant = variants;
- names.options = options;
-
- context = meta_create_xkb_context ();
- keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
- xkb_context_unref (context);
-
- return keymap;
-}
-
-/**
- * meta_seat_native_set_keyboard_map: (skip)
- * @seat: the #ClutterSeat created by the evdev backend
- * @keymap: the new keymap
- *
- * Instructs @evdev to use the specified 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,
- const char *layouts,
- const char *variants,
- const char *options)
-{
- struct xkb_keymap *keymap, *impl_keymap;
-
- keymap = create_keymap (layouts, variants, options);
- impl_keymap = create_keymap (layouts, variants, options);
-
- if (keymap == NULL)
- {
- g_warning ("Unable to load configured keymap: rules=%s, model=%s, layout=%s, variant=%s, options=%s",
- DEFAULT_XKB_RULES_FILE, DEFAULT_XKB_MODEL, layouts,
- variants, options);
- return;
- }
-
- if (seat->xkb_keymap)
- xkb_keymap_unref (seat->xkb_keymap);
- seat->xkb_keymap = keymap;
-
- meta_seat_impl_set_keyboard_map (seat->impl, impl_keymap);
- xkb_keymap_unref (impl_keymap);
-}
-
-/**
- * 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 seat->xkb_keymap;
-}
-
-/**
- * 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)
-{
- g_return_if_fail (META_IS_SEAT_NATIVE (seat));
-
- seat->xkb_layout_index = idx;
- meta_seat_impl_set_keyboard_layout_index (seat->impl, idx);
-}
-
-/**
- * meta_seat_native_get_keyboard_layout_index: (skip)
- */
-xkb_layout_index_t
-meta_seat_native_get_keyboard_layout_index (MetaSeatNative *seat)
-{
- return seat->xkb_layout_index;
-}
-
-MetaBarrierManagerNative *
-meta_seat_native_get_barrier_manager (MetaSeatNative *seat)
-{
- return meta_seat_impl_get_barrier_manager (seat->impl);
-}
-
-MetaBackend *
-meta_seat_native_get_backend (MetaSeatNative *seat_native)
-{
- return seat_native->backend;
-}
-
-void
-meta_seat_native_set_pointer_constraint (MetaSeatNative *seat,
- MetaPointerConstraintImpl *constraint_impl)
-{
- meta_seat_impl_set_pointer_constraint (seat->impl, constraint_impl);
-}
-
-MetaCursorRenderer *
-meta_seat_native_maybe_ensure_cursor_renderer (MetaSeatNative *seat_native,
- ClutterInputDevice *device)
-{
- if (device == seat_native->core_pointer)
- {
- if (!seat_native->cursor_renderer)
- {
- MetaCursorRendererNative *cursor_renderer_native;
-
- cursor_renderer_native =
- meta_cursor_renderer_native_new (meta_get_backend (),
- seat_native->core_pointer);
- seat_native->cursor_renderer =
- META_CURSOR_RENDERER (cursor_renderer_native);
- }
-
- return seat_native->cursor_renderer;
- }
-
- if (seat_native->tablet_cursors &&
- clutter_input_device_get_device_type (device) == CLUTTER_TABLET_DEVICE)
- return g_hash_table_lookup (seat_native->tablet_cursors, device);
-
- return NULL;
-}
-
-void
-meta_seat_native_set_viewports (MetaSeatNative *seat,
- MetaViewportInfo *viewports)
-{
- meta_seat_impl_set_viewports (seat->impl, viewports);
-}
diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h
deleted file mode 100644
index 53ba00f51..000000000
--- a/src/backends/native/meta-seat-native.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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/meta-input-settings-private.h"
-#include "backends/meta-viewport-info.h"
-#include "backends/native/meta-backend-native-types.h"
-#include "backends/native/meta-barrier-native.h"
-#include "backends/native/meta-cursor-renderer-native.h"
-#include "backends/native/meta-pointer-constraint-native.h"
-#include "backends/native/meta-xkb-utils.h"
-#include "clutter/clutter.h"
-
-typedef struct _MetaSeatNative MetaSeatNative;
-
-struct _MetaSeatNative
-{
- ClutterSeat parent_instance;
-
- MetaBackend *backend;
-
- MetaSeatImpl *impl;
- char *seat_id;
- MetaSeatNativeFlag flags;
-
- GList *devices;
- struct xkb_keymap *xkb_keymap;
- xkb_layout_index_t xkb_layout_index;
-
- ClutterInputDevice *core_pointer;
- ClutterInputDevice *core_keyboard;
-
- guint virtual_touch_slot_base;
- GHashTable *reserved_virtual_slots;
-
- MetaKeymapNative *keymap;
- MetaCursorRenderer *cursor_renderer;
- GHashTable *tablet_cursors;
-
- gboolean released;
- gboolean touch_mode;
-};
-
-#define META_TYPE_SEAT_NATIVE meta_seat_native_get_type ()
-G_DECLARE_FINAL_TYPE (MetaSeatNative, meta_seat_native,
- META, SEAT_NATIVE, ClutterSeat)
-
-void meta_seat_native_set_libinput_seat (MetaSeatNative *seat,
- struct libinput_seat *libinput_seat);
-
-void meta_seat_native_sync_leds (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_keyboard_map (MetaSeatNative *seat,
- const char *layouts,
- const char *variants,
- const char *options);
-
-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_repeat (MetaSeatNative *seat,
- gboolean repeat,
- uint32_t delay,
- uint32_t interval);
-
-void meta_seat_native_release_touch_slots (MetaSeatNative *seat,
- guint base_slot);
-
-MetaBarrierManagerNative * meta_seat_native_get_barrier_manager (MetaSeatNative *seat);
-
-MetaBackend * meta_seat_native_get_backend (MetaSeatNative *seat);
-
-void meta_seat_native_set_pointer_constraint (MetaSeatNative *seat,
- MetaPointerConstraintImpl *constraint_impl);
-MetaCursorRenderer * meta_seat_native_maybe_ensure_cursor_renderer (MetaSeatNative *seat,
- ClutterInputDevice *device);
-
-void meta_seat_native_set_viewports (MetaSeatNative *seat,
- MetaViewportInfo *viewports);
-
-#endif /* META_SEAT_NATIVE_H */
diff --git a/src/backends/native/meta-stage-native.c b/src/backends/native/meta-stage-native.c
deleted file mode 100644
index e1f9fedb2..000000000
--- a/src/backends/native/meta-stage-native.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/* -*- 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-crtc-virtual.h"
-#include "backends/native/meta-cursor-renderer-native.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
-{
- MetaStageImpl parent;
-
- CoglClosure *frame_closure;
-
- int64_t presented_frame_counter_sync;
- int64_t presented_frame_counter_complete;
-};
-
-static ClutterStageWindowInterface *clutter_stage_window_parent_iface = NULL;
-
-static void
-clutter_stage_window_iface_init (ClutterStageWindowInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaStageNative, meta_stage_native,
- META_TYPE_STAGE_IMPL,
- G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
- clutter_stage_window_iface_init))
-
-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_clear_stage_views (CLUTTER_STAGE (stage));
-}
-
-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 void
-meta_stage_native_prepare_frame (ClutterStageWindow *stage_window,
- ClutterStageView *stage_view,
- ClutterFrame *frame)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
- MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
- MetaCursorRenderer *cursor_renderer =
- meta_backend_get_cursor_renderer (backend);
- MetaCursorRendererNative *cursor_renderer_native =
- META_CURSOR_RENDERER_NATIVE (cursor_renderer);
-
- meta_renderer_native_prepare_frame (renderer_native,
- META_RENDERER_VIEW (stage_view),
- frame);
- meta_cursor_renderer_native_prepare_frame (cursor_renderer_native,
- META_RENDERER_VIEW (stage_view));
-}
-
-static void
-meta_stage_native_redraw_view (ClutterStageWindow *stage_window,
- ClutterStageView *view,
- ClutterFrame *frame)
-{
- MetaCrtc *crtc;
-
- clutter_stage_window_parent_iface->redraw_view (stage_window, view, frame);
-
- crtc = meta_renderer_view_get_crtc (META_RENDERER_VIEW (view));
- if (META_IS_CRTC_VIRTUAL (crtc))
- {
- g_warn_if_fail (!clutter_frame_has_result (frame));
-
- clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
- }
-}
-
-static void
-meta_stage_native_finish_frame (ClutterStageWindow *stage_window,
- ClutterStageView *stage_view,
- ClutterFrame *frame)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
-
- meta_renderer_native_finish_frame (META_RENDERER_NATIVE (renderer),
- META_RENDERER_VIEW (stage_view),
- frame);
-
- if (!clutter_frame_has_result (frame))
- clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_IDLE);
-}
-
-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)
-{
- clutter_stage_window_parent_iface = g_type_interface_peek_parent (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->prepare_frame = meta_stage_native_prepare_frame;
- iface->redraw_view = meta_stage_native_redraw_view;
- 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
deleted file mode 100644
index 5f33e1f9a..000000000
--- a/src/backends/native/meta-stage-native.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- 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 "backends/meta-stage-impl-private.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, MetaStageImpl)
-
-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
deleted file mode 100644
index 9fd84e98b..000000000
--- a/src/backends/native/meta-udev.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * 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;
-}
-
-static gboolean
-meta_has_udev_device_tag (GUdevDevice *device,
- const char *tag)
-{
- const char * const * tags;
- g_autoptr (GUdevDevice) platform_device = NULL;
-
- tags = g_udev_device_get_tags (device);
- if (tags && g_strv_contains (tags, tag))
- return TRUE;
-
- platform_device = g_udev_device_get_parent_with_subsystem (device,
- "platform",
- NULL);
-
- if (platform_device)
- return meta_has_udev_device_tag (platform_device, tag);
- else
- return FALSE;
-}
-
-gboolean
-meta_is_udev_device_disable_modifiers (GUdevDevice *device)
-{
- return meta_has_udev_device_tag (device,
- "mutter-device-disable-kms-modifiers");
-}
-
-gboolean
-meta_is_udev_device_ignore (GUdevDevice *device)
-{
- return meta_has_udev_device_tag (device, "mutter-device-ignore");
-}
-
-gboolean
-meta_is_udev_device_preferred_primary (GUdevDevice *device)
-{
- const char * const * tags;
-
- tags = g_udev_device_get_tags (device);
- if (!tags)
- return FALSE;
-
- return g_strv_contains (tags, "mutter-device-preferred-primary");
-}
-
-gboolean
-meta_udev_is_drm_device (MetaUdev *udev,
- GUdevDevice *device)
-{
- 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_backend_native_get_seat_id (udev->backend_native);
- 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)
- return NULL;
-
- 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
deleted file mode 100644
index 7b179329e..000000000
--- a/src/backends/native/meta-udev.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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_is_udev_device_disable_modifiers (GUdevDevice *device);
-
-gboolean meta_is_udev_device_ignore (GUdevDevice *device);
-
-gboolean meta_is_udev_device_preferred_primary (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
deleted file mode 100644
index d2d13748a..000000000
--- a/src/backends/native/meta-virtual-input-device-native.c
+++ /dev/null
@@ -1,1110 +0,0 @@
-/*
- * 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-thread.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_SLOT_BASE,
-
- PROP_LAST
-};
-
-static GParamSpec *obj_props[PROP_LAST];
-
-typedef struct _ImplState ImplState;
-
-struct _ImplState
-{
- ClutterInputDevice *device;
- int button_count[KEY_CNT];
-};
-
-struct _MetaVirtualInputDeviceNative
-{
- ClutterVirtualInputDevice parent;
-
- MetaSeatNative *seat;
- guint slot_base;
- ImplState *impl_state;
-};
-
-typedef struct
-{
- uint64_t time_us;
- double x;
- double y;
-} MetaVirtualEventMotion;
-
-typedef struct
-{
- uint64_t time_us;
- uint32_t button;
- ClutterButtonState button_state;
-} MetaVirtualEventButton;
-
-typedef struct
-{
- uint64_t time_us;
- double dx;
- double dy;
- ClutterScrollDirection direction;
- ClutterScrollSource scroll_source;
- ClutterScrollFinishFlags finish_flags;
-} MetaVirtualEventScroll;
-
-typedef struct
-{
- uint64_t time_us;
- uint32_t key;
- ClutterKeyState key_state;
-} MetaVirtualEventKey;
-
-typedef struct
-{
- uint64_t time_us;
- int device_slot;
- double x;
- double y;
-} MetaVirtualEventTouch;
-
-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_in_impl (MetaVirtualInputDeviceNative *virtual_evdev,
- uint32_t button,
- uint32_t state)
-{
- if (state)
- return ++virtual_evdev->impl_state->button_count[button];
- else
- return --virtual_evdev->impl_state->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 gboolean
-release_device_in_impl (GTask *task)
-{
- ImplState *impl_state = g_task_get_task_data (task);
- MetaInputDeviceNative *device_native;
- MetaSeatImpl *seat_impl;
- int code;
- uint64_t time_us;
- ClutterEvent *device_event;
-
- device_native = META_INPUT_DEVICE_NATIVE (impl_state->device);
- seat_impl = meta_input_device_native_get_seat_impl (device_native);
- time_us = g_get_monotonic_time ();
-
- meta_topic (META_DEBUG_INPUT,
- "Releasing pressed buttons while destroying virtual input device "
- "(device %p)", device_native);
-
- for (code = 0; code < G_N_ELEMENTS (impl_state->button_count); code++)
- {
- if (impl_state->button_count[code] == 0)
- continue;
-
- switch (get_button_type (code))
- {
- case EVDEV_BUTTON_TYPE_KEY:
- meta_seat_impl_notify_key_in_impl (seat_impl,
- impl_state->device,
- time_us,
- code,
- CLUTTER_KEY_STATE_RELEASED,
- TRUE);
- break;
- case EVDEV_BUTTON_TYPE_BUTTON:
- meta_seat_impl_notify_button_in_impl (seat_impl,
- impl_state->device,
- time_us,
- code,
- CLUTTER_BUTTON_STATE_RELEASED);
- break;
- case EVDEV_BUTTON_TYPE_NONE:
- g_assert_not_reached ();
- }
- }
-
- device_event = clutter_event_new (CLUTTER_DEVICE_REMOVED);
- clutter_event_set_device (device_event, impl_state->device);
- _clutter_event_push (device_event, FALSE);
-
- g_clear_object (&impl_state->device);
- g_task_return_boolean (task, TRUE);
-
- return G_SOURCE_REMOVE;
-}
-
-static gboolean
-notify_relative_motion_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventMotion *event = g_task_get_task_data (task);
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- meta_seat_impl_notify_relative_motion_in_impl (seat,
- virtual_evdev->impl_state->device,
- event->time_us,
- event->x, event->y,
- event->x, event->y);
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_relative_motion (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- double dx,
- double dy)
-{
- MetaVirtualEventMotion *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventMotion, 1);
- event->time_us = time_us;
- event->x = dx;
- event->y = dy;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_relative_motion_in_impl);
- g_object_unref (task);
-}
-
-static gboolean
-notify_absolute_motion_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventMotion *event = g_task_get_task_data (task);
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- meta_seat_impl_notify_absolute_motion_in_impl (seat,
- virtual_evdev->impl_state->device,
- event->time_us,
- event->x, event->y,
- NULL);
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- double x,
- double y)
-{
- MetaVirtualEventMotion *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventMotion, 1);
- event->time_us = time_us;
- event->x = x;
- event->y = y;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_absolute_motion_in_impl);
- g_object_unref (task);
-}
-
-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 gboolean
-notify_button_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventButton *event = g_task_get_task_data (task);
- int button_count;
- int evdev_button;
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- evdev_button = translate_to_evdev_button (event->button);
-
- if (get_button_type (evdev_button) != EVDEV_BUTTON_TYPE_BUTTON)
- {
- g_warning ("Unknown/invalid virtual device button 0x%x pressed",
- evdev_button);
- goto out;
- }
-
- button_count = update_button_count_in_impl (virtual_evdev, evdev_button,
- event->button_state);
- if (button_count < 0 || button_count > 1)
- {
- g_warning ("Received multiple virtual 0x%x button %s (ignoring)", evdev_button,
- event->button_state == CLUTTER_BUTTON_STATE_PRESSED ?
- "presses" : "releases");
- update_button_count_in_impl (virtual_evdev, evdev_button, 1 - event->button_state);
- goto out;
- }
-
- meta_topic (META_DEBUG_INPUT,
- "Emitting virtual button-%s of button 0x%x (device %p)",
- event->button_state == CLUTTER_BUTTON_STATE_PRESSED ?
- "press" : "release",
- evdev_button, virtual_evdev);
-
- meta_seat_impl_notify_button_in_impl (seat,
- virtual_evdev->impl_state->device,
- event->time_us,
- evdev_button,
- event->button_state);
- out:
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_button (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- uint32_t button,
- ClutterButtonState button_state)
-{
- MetaVirtualEventButton *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventButton, 1);
- event->time_us = time_us;
- event->button = button;
- event->button_state = button_state;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_button_in_impl);
- g_object_unref (task);
-}
-
-static gboolean
-notify_key_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventKey *event = g_task_get_task_data (task);
- int key_count;
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- if (get_button_type (event->key) != EVDEV_BUTTON_TYPE_KEY)
- {
- g_warning ("Unknown/invalid virtual device key 0x%x pressed", event->key);
- goto out;
- }
-
- key_count = update_button_count_in_impl (virtual_evdev, event->key, event->key_state);
- if (key_count < 0 || key_count > 1)
- {
- g_warning ("Received multiple virtual 0x%x key %s (ignoring)", event->key,
- event->key_state == CLUTTER_KEY_STATE_PRESSED ?
- "presses" : "releases");
- update_button_count_in_impl (virtual_evdev, event->key, 1 - event->key_state);
- goto out;
- }
-
- meta_topic (META_DEBUG_INPUT,
- "Emitting virtual key-%s of key 0x%x (device %p)",
- event->key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release",
- event->key, virtual_evdev);
-
- meta_seat_impl_notify_key_in_impl (seat,
- virtual_evdev->impl_state->device,
- event->time_us,
- event->key,
- event->key_state,
- TRUE);
-
- out:
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_key (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- uint32_t key,
- ClutterKeyState key_state)
-{
- MetaVirtualEventKey *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventKey, 1);
- event->time_us = time_us;
- event->key = key;
- event->key_state = key_state;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_key_in_impl);
- g_object_unref (task);
-}
-
-static gboolean
-pick_keycode_for_keyval_in_current_group_in_impl (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_in_impl (META_KEYMAP_NATIVE (keymap));
- state = meta_seat_impl_get_xkb_state_in_impl (virtual_evdev->seat->impl);
-
- 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_in_impl (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", level);
- return;
- }
-
- if (!pick_keycode_for_keyval_in_current_group_in_impl (virtual_device, keysym,
- &keycode, NULL))
- return;
-
- evcode = meta_xkb_keycode_to_evdev (keycode);
-
- meta_topic (META_DEBUG_INPUT,
- "Emitting virtual key-%s of modifier key 0x%x (device %p)",
- key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release",
- evcode, virtual_device);
-
- meta_seat_impl_notify_key_in_impl (virtual_evdev->seat->impl,
- virtual_evdev->impl_state->device,
- time_us,
- evcode,
- key_state,
- TRUE);
-}
-
-static gboolean
-notify_keyval_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- ClutterVirtualInputDevice *virtual_device =
- CLUTTER_VIRTUAL_INPUT_DEVICE (virtual_evdev);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventKey *event = g_task_get_task_data (task);
- int key_count;
- guint keycode = 0, level = 0, evcode = 0;
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- if (!pick_keycode_for_keyval_in_current_group_in_impl (virtual_device,
- event->key,
- &keycode, &level))
- {
- g_warning ("No keycode found for keyval %x in current group", event->key);
- goto out;
- }
-
- evcode = meta_xkb_keycode_to_evdev (keycode);
-
- if (get_button_type (evcode) != EVDEV_BUTTON_TYPE_KEY)
- {
- g_warning ("Unknown/invalid virtual device key 0x%x pressed", evcode);
- goto out;
- }
-
- key_count = update_button_count_in_impl (virtual_evdev, evcode, event->key_state);
- if (key_count < 0 || key_count > 1)
- {
- g_warning ("Received multiple virtual 0x%x key %s (ignoring)", evcode,
- event->key_state == CLUTTER_KEY_STATE_PRESSED ?
- "presses" : "releases");
- update_button_count_in_impl (virtual_evdev, evcode, 1 - event->key_state);
- goto out;
- }
-
- meta_topic (META_DEBUG_INPUT,
- "Emitting virtual key-%s of key 0x%x with modifier level %d, "
- "press count %d (device %p)",
- event->key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release",
- evcode, level, key_count, virtual_evdev);
-
- if (event->key_state)
- {
- apply_level_modifiers_in_impl (virtual_device, event->time_us,
- level, event->key_state);
- }
-
- meta_seat_impl_notify_key_in_impl (seat,
- virtual_evdev->impl_state->device,
- event->time_us,
- evcode,
- event->key_state,
- TRUE);
-
- if (!event->key_state)
- {
- apply_level_modifiers_in_impl (virtual_device, event->time_us,
- level, event->key_state);
- }
-
- out:
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_keyval (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- uint32_t keyval,
- ClutterKeyState key_state)
-{
- MetaVirtualEventKey *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventKey, 1);
- event->time_us = time_us;
- event->key = keyval;
- event->key_state = key_state;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_keyval_in_impl);
- g_object_unref (task);
-}
-
-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 gboolean
-notify_discrete_scroll_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventScroll *event = g_task_get_task_data (task);
- double discrete_dx = 0.0, discrete_dy = 0.0;
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- direction_to_discrete (event->direction, &discrete_dx, &discrete_dy);
-
- meta_seat_impl_notify_discrete_scroll_in_impl (seat,
- virtual_evdev->impl_state->device,
- event->time_us,
- discrete_dx, discrete_dy,
- event->scroll_source);
-
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- ClutterScrollDirection direction,
- ClutterScrollSource scroll_source)
-{
- MetaVirtualEventScroll *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventScroll, 1);
- event->time_us = time_us;
- event->direction = direction;
- event->scroll_source = scroll_source;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_discrete_scroll_in_impl);
- g_object_unref (task);
-}
-
-static gboolean
-notify_scroll_continuous_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventScroll *event = g_task_get_task_data (task);
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- meta_seat_impl_notify_scroll_continuous_in_impl (seat,
- virtual_evdev->impl_state->device,
- event->time_us,
- event->dx, event->dy,
- event->scroll_source,
- CLUTTER_SCROLL_FINISHED_NONE);
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-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)
-{
- MetaVirtualEventScroll *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventScroll, 1);
- event->time_us = time_us;
- event->dx = dx;
- event->dy = dy;
- event->scroll_source = scroll_source;
- event->finish_flags = finish_flags;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_scroll_continuous_in_impl);
- g_object_unref (task);
-}
-
-static gboolean
-notify_touch_down_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventTouch *event = g_task_get_task_data (task);
- MetaTouchState *touch_state;
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- touch_state = meta_seat_impl_acquire_touch_state_in_impl (seat,
- event->device_slot);
- if (!touch_state)
- goto out;
-
- touch_state->coords.x = event->x;
- touch_state->coords.y = event->y;
-
- meta_seat_impl_notify_touch_event_in_impl (seat,
- virtual_evdev->impl_state->device,
- CLUTTER_TOUCH_BEGIN,
- event->time_us,
- touch_state->seat_slot,
- touch_state->coords.x,
- touch_state->coords.y);
-
- out:
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_touch_down (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- int device_slot,
- double x,
- double y)
-{
- MetaVirtualEventTouch *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventTouch, 1);
- event->time_us = time_us;
- event->device_slot = virtual_evdev->slot_base + (guint) device_slot;
- event->x = x;
- event->y = y;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_touch_down_in_impl);
- g_object_unref (task);
-}
-
-static gboolean
-notify_touch_motion_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventTouch *event = g_task_get_task_data (task);
- MetaTouchState *touch_state;
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- touch_state = meta_seat_impl_lookup_touch_state_in_impl (seat,
- event->device_slot);
- if (!touch_state)
- goto out;
-
- touch_state->coords.x = event->x;
- touch_state->coords.y = event->y;
-
- meta_seat_impl_notify_touch_event_in_impl (seat,
- virtual_evdev->impl_state->device,
- CLUTTER_TOUCH_UPDATE,
- event->time_us,
- touch_state->seat_slot,
- touch_state->coords.x,
- touch_state->coords.y);
-
- out:
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_touch_motion (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- int device_slot,
- double x,
- double y)
-{
- MetaVirtualEventTouch *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventTouch, 1);
- event->time_us = time_us;
- event->device_slot = virtual_evdev->slot_base + (guint) device_slot;
- event->x = x;
- event->y = y;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_touch_motion_in_impl);
- g_object_unref (task);
-}
-
-static gboolean
-notify_touch_up_in_impl (GTask *task)
-{
- MetaVirtualInputDeviceNative *virtual_evdev =
- g_task_get_source_object (task);
- MetaSeatImpl *seat = virtual_evdev->seat->impl;
- MetaVirtualEventTouch *event = g_task_get_task_data (task);
- MetaTouchState *touch_state;
-
- if (event->time_us == CLUTTER_CURRENT_TIME)
- event->time_us = g_get_monotonic_time ();
-
- touch_state = meta_seat_impl_lookup_touch_state_in_impl (seat,
- event->device_slot);
- if (!touch_state)
- goto out;
-
- meta_seat_impl_notify_touch_event_in_impl (seat,
- virtual_evdev->impl_state->device,
- CLUTTER_TOUCH_END,
- event->time_us,
- touch_state->seat_slot,
- touch_state->coords.x,
- touch_state->coords.y);
-
- meta_seat_impl_release_touch_state_in_impl (virtual_evdev->seat->impl,
- touch_state->seat_slot);
-
- out:
- g_task_return_boolean (task, TRUE);
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_virtual_input_device_native_notify_touch_up (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- int device_slot)
-{
- MetaVirtualEventTouch *event;
- MetaVirtualInputDeviceNative *virtual_evdev =
- META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
- GTask *task;
-
- g_return_if_fail (virtual_evdev->impl_state->device != NULL);
-
- event = g_new0 (MetaVirtualEventTouch, 1);
- event->time_us = time_us;
- event->device_slot = virtual_evdev->slot_base + (guint) device_slot;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, event, g_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) notify_touch_up_in_impl);
- g_object_unref (task);
-}
-
-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;
- case PROP_SLOT_BASE:
- g_value_set_uint (value, virtual_evdev->slot_base);
- 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;
- case PROP_SLOT_BASE:
- virtual_evdev->slot_base = g_value_get_uint (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;
- ClutterEvent *device_event = NULL;
-
- 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)",
- device_type, virtual_device);
-
- virtual_evdev->impl_state = g_new0 (ImplState, 1);
- virtual_evdev->impl_state->device =
- meta_input_device_native_new_virtual (virtual_evdev->seat->impl,
- device_type,
- CLUTTER_INPUT_MODE_PHYSICAL);
-
- device_event = clutter_event_new (CLUTTER_DEVICE_ADDED);
- clutter_event_set_device (device_event, virtual_evdev->impl_state->device);
- _clutter_event_push (device_event, FALSE);
-}
-
-static void
-impl_state_free (ImplState *impl_state)
-{
- g_warn_if_fail (!impl_state->device);
- g_free (impl_state);
-}
-
-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->impl_state)
- {
- GTask *task;
-
- task = g_task_new (virtual_device, NULL, NULL, NULL);
- g_task_set_task_data (task, virtual_evdev->impl_state,
- (GDestroyNotify) impl_state_free);
- meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
- (GSourceFunc) release_device_in_impl);
- g_object_unref (task);
-
- virtual_evdev->impl_state = NULL;
- }
-
- meta_seat_native_release_touch_slots (virtual_evdev->seat,
- virtual_evdev->slot_base);
-
- 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);
- obj_props[PROP_SLOT_BASE] = g_param_spec_uint ("slot-base",
- "Slot base",
- "Base for touch slots",
- 0, G_MAXUINT, 0,
- CLUTTER_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY);
- g_object_class_install_properties (object_class, PROP_LAST, obj_props);
-}
diff --git a/src/backends/native/meta-virtual-input-device-native.h b/src/backends/native/meta-virtual-input-device-native.h
deleted file mode 100644
index 28d218abb..000000000
--- a/src/backends/native/meta-virtual-input-device-native.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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>
- */
-
-#ifndef META_VIRTUAL_INPUT_DEVICE_NATIVE_H
-#define META_VIRTUAL_INPUT_DEVICE_NATIVE_H
-
-#include "clutter/clutter-virtual-input-device.h"
-
-#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 /* META_VIRTUAL_INPUT_DEVICE_NATIVE_H */
diff --git a/src/backends/native/meta-virtual-monitor-native.c b/src/backends/native/meta-virtual-monitor-native.c
deleted file mode 100644
index 3f81f4180..000000000
--- a/src/backends/native/meta-virtual-monitor-native.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2021 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-virtual-monitor-native.h"
-
-#include "backends/native/meta-crtc-mode-virtual.h"
-#include "backends/native/meta-crtc-virtual.h"
-#include "backends/native/meta-output-virtual.h"
-
-struct _MetaVirtualMonitorNative
-{
- MetaVirtualMonitor parent;
-
- uint64_t id;
-};
-
-#define VIRTUAL_OUTPUT_ID_BIT (((uint64_t) 1) << 63)
-
-G_DEFINE_TYPE (MetaVirtualMonitorNative, meta_virtual_monitor_native,
- META_TYPE_VIRTUAL_MONITOR)
-
-uint64_t
-meta_virtual_monitor_native_get_id (MetaVirtualMonitorNative *virtual_monitor_native)
-{
- return virtual_monitor_native->id;
-}
-
-MetaVirtualMonitorNative *
-meta_virtual_monitor_native_new (uint64_t id,
- const MetaVirtualMonitorInfo *info)
-{
- MetaVirtualMonitorNative *virtual_monitor_native;
- MetaCrtcVirtual *crtc_virtual;
- MetaCrtcModeVirtual *crtc_mode_virtual;
- MetaOutputVirtual *output_virtual;
-
- crtc_virtual = meta_crtc_virtual_new (id);
- crtc_mode_virtual = meta_crtc_mode_virtual_new (id, info);
- output_virtual = meta_output_virtual_new (id, info,
- crtc_virtual,
- crtc_mode_virtual);
-
- virtual_monitor_native = g_object_new (META_TYPE_VIRTUAL_MONITOR_NATIVE,
- "crtc", crtc_virtual,
- "crtc-mode", crtc_mode_virtual,
- "output", output_virtual,
- NULL);
- virtual_monitor_native->id = id;
-
- return virtual_monitor_native;
-}
-
-static void
-meta_virtual_monitor_native_init (MetaVirtualMonitorNative *virtual_monitor_native)
-{
-}
-
-static void
-meta_virtual_monitor_native_class_init (MetaVirtualMonitorNativeClass *klass)
-{
-}
diff --git a/src/backends/native/meta-virtual-monitor-native.h b/src/backends/native/meta-virtual-monitor-native.h
deleted file mode 100644
index d1a0ced64..000000000
--- a/src/backends/native/meta-virtual-monitor-native.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2021 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_VIRTUAL_MONITOR_NATIVE_H
-#define META_VIRTUAL_MONITOR_NATIVE_H
-
-#include <stdint.h>
-
-#include "backends/meta-virtual-monitor.h"
-#include "backends/meta-backend-types.h"
-
-#define META_TYPE_VIRTUAL_MONITOR_NATIVE (meta_virtual_monitor_native_get_type ())
-G_DECLARE_FINAL_TYPE (MetaVirtualMonitorNative, meta_virtual_monitor_native,
- META, VIRTUAL_MONITOR_NATIVE,
- MetaVirtualMonitor)
-
-uint64_t meta_virtual_monitor_native_get_id (MetaVirtualMonitorNative *virtual_monitor_native);
-
-MetaCrtcMode * meta_virtual_monitor_native_get_crtc_mode (MetaVirtualMonitorNative *virtual_monitor_native);
-
-MetaCrtc * meta_virtual_monitor_native_get_crtc (MetaVirtualMonitorNative *virtual_monitor_native);
-
-MetaOutput * meta_virtual_monitor_native_get_output (MetaVirtualMonitorNative *virtual_monitor_native);
-
-MetaVirtualMonitorNative * meta_virtual_monitor_native_new (uint64_t id,
- const MetaVirtualMonitorInfo *info);
-
-#endif /* META_VIRTUAL_MONITOR_NATIVE_H */
diff --git a/src/backends/native/meta-xkb-utils.c b/src/backends/native/meta-xkb-utils.c
deleted file mode 100644
index 45f89bec7..000000000
--- a/src/backends/native/meta-xkb-utils.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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:
- * Kristian Høgsberg
- * Damien Lespiau <damien.lespiau@intel.com>
- */
-
-#include "config.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
- * @device: a ClutterInputDevice
- * @xkb: XKB rules to translate the event
- * @_time: timestamp of the event
- * @key: a key code coming from a Linux input device
- * @state: TRUE if a press event, FALSE if a release event
- * @modifer_state: in/out
- *
- * Translate @key to a #ClutterKeyEvent using rules from xbbcommon.
- *
- * Return value: the new #ClutterEvent
- */
-ClutterEvent *
-meta_key_event_new_from_evdev (ClutterInputDevice *device,
- ClutterInputDevice *core_device,
- 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;
- const xkb_keysym_t *syms;
- char buffer[8];
- int n;
-
- if (state)
- event = clutter_event_new (CLUTTER_KEY_PRESS);
- else
- event = clutter_event_new (CLUTTER_KEY_RELEASE);
-
- /* We use a fixed offset of 8 because evdev starts KEY_* numbering from
- * 0, whereas X11's minimum keycode, for really stupid reasons, is 8.
- * So the evdev XKB rules are based on the keycodes all being shifted
- * upwards by 8. */
- key = meta_xkb_evdev_to_keycode (key);
-
- n = xkb_key_get_syms (xkb_state, key, &syms);
- if (n == 1)
- sym = syms[0];
- else
- sym = XKB_KEY_NoSymbol;
-
- event->key.time = _time;
- 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));
-
- if (n == 0)
- {
- /* not printable */
- event->key.unicode_value = (gunichar) '\0';
- }
- else
- {
- event->key.unicode_value = g_utf8_get_char_validated (buffer, n);
- if (event->key.unicode_value == -1 || event->key.unicode_value == -2)
- event->key.unicode_value = (gunichar) '\0';
- }
-
- return event;
-}
-
-void
-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);
-}
-
-ClutterModifierType
-meta_xkb_translate_modifiers (struct xkb_state *state,
- ClutterModifierType button_state)
-{
- ClutterModifierType modifiers;
-
- modifiers = xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE);
- modifiers |= button_state;
-
- return modifiers;
-}
-
-uint32_t
-meta_xkb_keycode_to_evdev (uint32_t xkb_keycode)
-{
- /* The keycodes from the evdev backend are almost evdev
- * keycodes: we use the evdev keycode file, but xkb rules have an
- * offset by 8. See the comment in _clutter_key_event_new_from_evdev()
- */
- return xkb_keycode - 8;
-}
-
-uint32_t
-meta_xkb_evdev_to_keycode (uint32_t evcode)
-{
- /* The inverse of meta_xkb_keycode_to_evdev */
- return evcode + 8;
-}
diff --git a/src/backends/native/meta-xkb-utils.h b/src/backends/native/meta-xkb-utils.h
deleted file mode 100644
index d605813e6..000000000
--- a/src/backends/native/meta-xkb-utils.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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,
- 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);
-ClutterModifierType meta_xkb_translate_modifiers (struct xkb_state *state,
- ClutterModifierType button_state);
-uint32_t meta_xkb_keycode_to_evdev (uint32_t hardware_keycode);
-uint32_t meta_xkb_evdev_to_keycode (uint32_t evcode);
-
-#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
deleted file mode 100644
index ed2b7bb8b..000000000
--- a/src/backends/x11/cm/meta-backend-x11-cm.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
- * 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-cursor-tracker-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"
-
-enum
-{
- PROP_0,
-
- PROP_DISPLAY_NAME,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS];
-
-struct _MetaBackendX11Cm
-{
- MetaBackendX11 parent;
-
- char *display_name;
-
- MetaCursorRenderer *cursor_renderer;
- char *keymap_layouts;
- char *keymap_variants;
- char *keymap_options;
- int locked_group;
-
- MetaInputSettings *input_settings;
-};
-
-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);
- MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (backend);
- ClutterSeat *seat;
-
- seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
- g_signal_connect_object (seat, "device-added",
- G_CALLBACK (on_device_added), backend, 0);
-
- x11_cm->input_settings = g_object_new (META_TYPE_INPUT_SETTINGS_X11, NULL);
-
- parent_backend_class->post_init (backend);
- 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_get_cursor_renderer (MetaBackend *backend,
- ClutterInputDevice *device)
-{
- MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (backend);
-
- if (!x11_cm->cursor_renderer)
- {
- x11_cm->cursor_renderer =
- g_object_new (META_TYPE_CURSOR_RENDERER_X11,
- "backend", backend,
- "device", device,
- NULL);
- }
-
- return x11_cm->cursor_renderer;
-}
-
-static MetaCursorTracker *
-meta_backend_x11_cm_create_cursor_tracker (MetaBackend *backend)
-{
- return g_object_new (META_TYPE_CURSOR_TRACKER_X11,
- "backend", backend,
- NULL);
-}
-
-static MetaInputSettings *
-meta_backend_x11_cm_get_input_settings (MetaBackend *backend)
-{
- MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (backend);
-
- return x11_cm->input_settings;
-}
-
-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_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaBackendX11Cm *backend_x11_cm = META_BACKEND_X11_CM (object);
-
- switch (prop_id)
- {
- case PROP_DISPLAY_NAME:
- backend_x11_cm->display_name = g_value_dup_string (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_backend_x11_cm_finalize (GObject *object)
-{
- MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (object);
-
- g_clear_pointer (&x11_cm->display_name, g_free);
-
- G_OBJECT_CLASS (meta_backend_x11_cm_parent_class)->finalize (object);
-}
-
-static void
-meta_backend_x11_cm_constructed (GObject *object)
-{
- MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (object);
- const char *display_name;
-
- if (x11_cm->display_name)
- display_name = (const char *) x11_cm->display_name;
- else
- display_name = g_getenv ("MUTTER_DISPLAY");
-
- if (display_name)
- g_setenv ("DISPLAY", display_name, TRUE);
-
- G_OBJECT_CLASS (meta_backend_x11_cm_parent_class)->constructed (object);
-}
-
-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)
-{
- 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->set_property = meta_backend_x11_cm_set_property;
- object_class->finalize = meta_backend_x11_cm_finalize;
- object_class->constructed = meta_backend_x11_cm_constructed;
-
- 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->get_cursor_renderer = meta_backend_x11_cm_get_cursor_renderer;
- backend_class->create_cursor_tracker = meta_backend_x11_cm_create_cursor_tracker;
- backend_class->get_input_settings = meta_backend_x11_cm_get_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;
-
- obj_props[PROP_DISPLAY_NAME] =
- g_param_spec_string ("display-name",
- "display name",
- "X11 display name",
- NULL,
- G_PARAM_WRITABLE |
- 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-backend-x11-cm.h b/src/backends/x11/cm/meta-backend-x11-cm.h
deleted file mode 100644
index 5332da13d..000000000
--- a/src/backends/x11/cm/meta-backend-x11-cm.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 0c524668e..000000000
--- a/src/backends/x11/cm/meta-cursor-sprite-xfixes.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * 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
deleted file mode 100644
index c7073fc2c..000000000
--- a/src/backends/x11/cm/meta-cursor-sprite-xfixes.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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
deleted file mode 100644
index afed2e377..000000000
--- a/src/backends/x11/cm/meta-renderer-x11-cm.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- 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_init_screen_view (MetaRendererX11Cm *renderer_x11_cm,
- CoglOnscreen *onscreen,
- int width,
- int height)
-{
- MetaRenderer *renderer = META_RENDERER (renderer_x11_cm);
- MetaBackend *backend = meta_renderer_get_backend (renderer);
- ClutterActor *stage = meta_backend_get_stage (backend);
- cairo_rectangle_int_t view_layout;
-
- g_return_if_fail (!renderer_x11_cm->screen_view);
-
- view_layout = (cairo_rectangle_int_t) {
- .width = width,
- .height = height,
- };
- renderer_x11_cm->screen_view = g_object_new (META_TYPE_RENDERER_VIEW,
- "name", "X11 screen",
- "stage", stage,
- "layout", &view_layout,
- "framebuffer", onscreen,
- 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);
-}
-
-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 GList *
-meta_renderer_x11_cm_get_views_for_monitor (MetaRenderer *renderer,
- MetaMonitor *monitor)
-{
- return g_list_prepend (NULL, meta_renderer_get_views (renderer)->data);
-}
-
-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;
- renderer_class->get_views_for_monitor =
- meta_renderer_x11_cm_get_views_for_monitor;
-}
diff --git a/src/backends/x11/cm/meta-renderer-x11-cm.h b/src/backends/x11/cm/meta-renderer-x11-cm.h
deleted file mode 100644
index 7ddb3445d..000000000
--- a/src/backends/x11/cm/meta-renderer-x11-cm.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- 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_init_screen_view (MetaRendererX11Cm *renderer_x11_cm,
- CoglOnscreen *onscreen,
- int width,
- int height);
-
-void meta_renderer_x11_cm_resize (MetaRendererX11Cm *renderer_x11_cm,
- int width,
- int height);
-
-#endif /* META_RENDERER_X11_CM_H */
diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
deleted file mode 100644
index 09a13505d..000000000
--- a/src/backends/x11/meta-backend-x11.c
+++ /dev/null
@@ -1,996 +0,0 @@
-/* -*- 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-keymap-utils.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 "backends/x11/meta-xkb-a11y-x11.h"
-#include "clutter/clutter.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;
-
- gulong keymap_state_changed_id;
-
- 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
-on_kbd_a11y_changed (MetaInputSettings *input_settings,
- MetaKbdA11ySettings *a11y_settings,
- MetaBackend *backend)
-{
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
-
- meta_seat_x11_apply_kbd_a11y_settings (seat, a11y_settings);
-}
-
-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;
- MetaInputSettings *input_settings;
- 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");
-
- 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",
- 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)));
-
- input_settings = meta_backend_get_input_settings (backend);
-
- if (input_settings)
- {
- g_signal_connect_object (meta_backend_get_input_settings (backend),
- "kbd-a11y-changed",
- G_CALLBACK (on_kbd_a11y_changed), backend, 0);
-
- if (meta_input_settings_maybe_restore_numlock_state (input_settings))
- {
- unsigned int num_mask;
-
- num_mask = XkbKeysymToModifiers (priv->xdisplay, XK_Num_Lock);
- XkbLockModifiers (priv->xdisplay, XkbUseCoreKbd, num_mask, num_mask);
- }
- }
-}
-
-static ClutterBackend *
-meta_backend_x11_create_clutter_backend (MetaBackend *backend)
-{
- return g_object_new (META_TYPE_CLUTTER_BACKEND_X11, NULL);
-}
-
-static ClutterSeat *
-meta_backend_x11_create_default_seat (MetaBackend *backend,
- GError **error)
-{
- MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
- MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
- int event_base, first_event, first_error;
- int major, minor;
- MetaSeatX11 *seat_x11;
-
- if (!XQueryExtension (priv->xdisplay,
- "XInputExtension",
- &event_base,
- &first_event,
- &first_error))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Failed to query XInputExtension");
- return NULL;
- }
-
- major = 2;
- minor = 3;
- if (XIQueryVersion (priv->xdisplay, &major, &minor) == BadRequest)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Incompatible XInputExtension version");
- return NULL;
- }
-
- seat_x11 = meta_seat_x11_new (event_base,
- META_VIRTUAL_CORE_POINTER_ID,
- META_VIRTUAL_CORE_KEYBOARD_ID);
- return CLUTTER_SEAT (seat_x11);
-}
-
-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,
- clutter_event_sequence_get_slot (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;
- graphene_point_t point;
- 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, &point, NULL);
- monitor_manager = meta_backend_get_monitor_manager (backend);
- logical_monitor =
- meta_monitor_manager_get_logical_monitor_at (monitor_manager,
- point.x, point.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 = meta_create_xkb_context ();
- 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;
-}
-
-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);
- meta_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_dispose (GObject *object)
-{
- MetaBackend *backend = META_BACKEND (object);
- MetaBackendX11 *x11 = META_BACKEND_X11 (object);
- MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
-
- if (priv->keymap_state_changed_id)
- {
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
- ClutterKeymap *keymap;
-
- seat = clutter_backend_get_default_seat (clutter_backend);
- keymap = clutter_seat_get_keymap (seat);
- g_clear_signal_handler (&priv->keymap_state_changed_id, keymap);
- }
-
- 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)->dispose (object);
-}
-
-static void
-meta_backend_x11_finalize (GObject *object)
-{
- MetaBackendX11 *x11 = META_BACKEND_X11 (object);
- MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
-
- g_clear_pointer (&priv->keymap, xkb_keymap_unref);
-
- 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->dispose = meta_backend_x11_dispose;
- object_class->finalize = meta_backend_x11_finalize;
- backend_class->create_clutter_backend = meta_backend_x11_create_clutter_backend;
- backend_class->create_default_seat = meta_backend_x11_create_default_seat;
- 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;
-}
-
-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);
-}
-
-void
-meta_backend_x11_sync_pointer (MetaBackendX11 *backend_x11)
-{
- MetaBackend *backend = META_BACKEND (backend_x11);
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
- ClutterInputDevice *pointer = clutter_seat_get_pointer (seat);
- ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
- ClutterModifierType modifiers;
- ClutterEvent *event;
- graphene_point_t pos;
-
- event = clutter_event_new (CLUTTER_MOTION);
- clutter_seat_query_state (seat, pointer, NULL, &pos, &modifiers);
- clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_SYNTHETIC);
- clutter_event_set_coords (event, pos.x, pos.y);
- clutter_event_set_device (event, pointer);
- clutter_event_set_state (event, modifiers);
- clutter_event_set_source_device (event, NULL);
- clutter_event_set_stage (event, stage);
-
- clutter_event_put (event);
- clutter_event_free (event);
-}
diff --git a/src/backends/x11/meta-backend-x11.h b/src/backends/x11/meta-backend-x11.h
deleted file mode 100644
index 2815015d1..000000000
--- a/src/backends/x11/meta-backend-x11.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- 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);
-
-void meta_backend_x11_sync_pointer (MetaBackendX11 *backend_x11);
-
-#endif /* META_BACKEND_X11_H */
diff --git a/src/backends/x11/meta-barrier-x11.c b/src/backends/x11/meta-barrier-x11.c
deleted file mode 100644
index 998aefb38..000000000
--- a/src/backends/x11/meta-barrier-x11.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/* -*- 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_new0 (MetaBarrierEvent, 1);
-
- 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
deleted file mode 100644
index 3562d106f..000000000
--- a/src/backends/x11/meta-barrier-x11.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- 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
deleted file mode 100644
index d94987879..000000000
--- a/src/backends/x11/meta-clutter-backend-x11.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/* -*- 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 "cogl/cogl-xlib.h"
-#include "core/bell.h"
-#include "meta/meta-backend.h"
-
-typedef struct _MetaX11EventFilter MetaX11EventFilter;
-
-struct _MetaX11EventFilter
-{
- MetaX11FilterFunc func;
- gpointer data;
-};
-
-G_DEFINE_TYPE (MetaClutterBackendX11, meta_clutter_backend_x11,
- CLUTTER_TYPE_BACKEND)
-
-
-/* atoms; remember to add the code that assigns the atom value to
- * the member of the MetaClutterBackendX11 structure if you add an
- * atom name here. do not change the order!
- */
-static const gchar *atom_names[] = {
- "_NET_WM_PID",
- "_NET_WM_PING",
- "_NET_WM_STATE",
- "_NET_WM_USER_TIME",
- "WM_PROTOCOLS",
- "WM_DELETE_WINDOW",
- "_XEMBED",
- "_XEMBED_INFO",
- "_NET_WM_NAME",
- "UTF8_STRING",
-};
-
-#define N_ATOM_NAMES G_N_ELEMENTS (atom_names)
-
-/* various flags corresponding to pre init setup calls */
-static gboolean clutter_enable_xinput = TRUE;
-static gboolean clutter_enable_stereo = FALSE;
-static Display *_foreign_dpy = NULL;
-
-/* options */
-static gchar *clutter_display_name = NULL;
-static gint clutter_screen = -1;
-static gboolean clutter_synchronise = FALSE;
-
-/* X error trap */
-static int TrappedErrorCode = 0;
-static int (* old_error_handler) (Display *, XErrorEvent *);
-
-static MetaX11FilterReturn
-cogl_xlib_filter (XEvent *xevent,
- ClutterEvent *event,
- gpointer data)
-{
- ClutterBackend *backend = data;
- MetaX11FilterReturn retval;
- CoglFilterReturn ret;
-
- ret = cogl_xlib_renderer_handle_event (backend->cogl_renderer, xevent);
- switch (ret)
- {
- case COGL_FILTER_REMOVE:
- retval = META_X11_FILTER_REMOVE;
- break;
-
- case COGL_FILTER_CONTINUE:
- default:
- retval = META_X11_FILTER_CONTINUE;
- break;
- }
-
- return retval;
-}
-
-static gboolean
-meta_clutter_backend_x11_pre_parse (ClutterBackend *backend,
- GError **error)
-{
- const gchar *env_string;
-
- /* we don't fail here if DISPLAY is not set, as the user
- * might pass the --display command line switch
- */
- env_string = g_getenv ("DISPLAY");
- if (env_string)
- {
- clutter_display_name = g_strdup (env_string);
- env_string = NULL;
- }
-
- env_string = g_getenv ("CLUTTER_DISABLE_XINPUT");
- if (env_string)
- {
- clutter_enable_xinput = FALSE;
- env_string = NULL;
- }
-
- return TRUE;
-}
-
-static gboolean
-meta_clutter_backend_x11_post_parse (ClutterBackend *backend,
- GError **error)
-{
- MetaClutterBackendX11 *backend_x11 = META_CLUTTER_BACKEND_X11 (backend);
- Atom atoms[N_ATOM_NAMES];
-
- if (_foreign_dpy)
- backend_x11->xdisplay = _foreign_dpy;
-
- /* Only open connection if not already set by prior call to
- * clutter_x11_set_display()
- */
- if (backend_x11->xdisplay == NULL)
- {
- if (clutter_display_name != NULL &&
- *clutter_display_name != '\0')
- {
- g_debug ("XOpenDisplay on '%s'", clutter_display_name);
-
- backend_x11->xdisplay = XOpenDisplay (clutter_display_name);
- if (backend_x11->xdisplay == NULL)
- {
- g_set_error (error, CLUTTER_INIT_ERROR,
- CLUTTER_INIT_ERROR_BACKEND,
- "Unable to open display '%s'",
- clutter_display_name);
- return FALSE;
- }
- }
- else
- {
- g_set_error_literal (error, CLUTTER_INIT_ERROR,
- CLUTTER_INIT_ERROR_BACKEND,
- "Unable to open display. You have to set the "
- "DISPLAY environment variable, or use the "
- "--display command line argument");
- return FALSE;
- }
- }
-
- g_assert (backend_x11->xdisplay != NULL);
-
- g_debug ("Getting the X screen");
-
- /* add event filter for Cogl events */
- meta_clutter_x11_add_filter (cogl_xlib_filter, backend);
-
- if (clutter_screen == -1)
- backend_x11->xscreen = DefaultScreenOfDisplay (backend_x11->xdisplay);
- else
- backend_x11->xscreen = ScreenOfDisplay (backend_x11->xdisplay,
- clutter_screen);
-
- backend_x11->xscreen_num = XScreenNumberOfScreen (backend_x11->xscreen);
- backend_x11->xscreen_width = WidthOfScreen (backend_x11->xscreen);
- backend_x11->xscreen_height = HeightOfScreen (backend_x11->xscreen);
-
- backend_x11->xwin_root = RootWindow (backend_x11->xdisplay,
- backend_x11->xscreen_num);
-
- backend_x11->display_name = g_strdup (clutter_display_name);
-
- if (clutter_synchronise)
- XSynchronize (backend_x11->xdisplay, True);
-
- XInternAtoms (backend_x11->xdisplay,
- (char **) atom_names, N_ATOM_NAMES,
- False, atoms);
-
- 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_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];
-
- g_free (clutter_display_name);
-
- g_debug ("X Display '%s'[%p] opened (screen:%d, root:%u, dpi:%f)",
- backend_x11->display_name,
- backend_x11->xdisplay,
- backend_x11->xscreen_num,
- (unsigned int) backend_x11->xwin_root,
- clutter_backend_get_resolution (backend));
-
- return TRUE;
-}
-
-static const GOptionEntry entries[] =
-{
- {
- "display", 0,
- G_OPTION_FLAG_IN_MAIN,
- G_OPTION_ARG_STRING, &clutter_display_name,
- N_("X display to use"), "DISPLAY"
- },
- {
- "screen", 0,
- G_OPTION_FLAG_IN_MAIN,
- G_OPTION_ARG_INT, &clutter_screen,
- N_("X screen to use"), "SCREEN"
- },
- { "synch", 0,
- 0,
- G_OPTION_ARG_NONE, &clutter_synchronise,
- N_("Make X calls synchronous"), NULL
- },
- {
- "disable-xinput", 0,
- G_OPTION_FLAG_REVERSE,
- G_OPTION_ARG_NONE, &clutter_enable_xinput,
- N_("Disable XInput support"), NULL
- },
- { NULL }
-};
-
-static void
-meta_clutter_backend_x11_add_options (ClutterBackend *backend,
- GOptionGroup *group)
-{
- g_option_group_add_entries (group, entries);
-}
-
-static void
-meta_clutter_backend_x11_finalize (GObject *gobject)
-{
- MetaClutterBackendX11 *backend_x11 = META_CLUTTER_BACKEND_X11 (gobject);
-
- g_free (backend_x11->display_name);
-
- meta_clutter_x11_remove_filter (cogl_xlib_filter, gobject);
-
- XCloseDisplay (backend_x11->xdisplay);
-
- G_OBJECT_CLASS (meta_clutter_backend_x11_parent_class)->finalize (gobject);
-}
-
-static ClutterFeatureFlags
-meta_clutter_backend_x11_get_features (ClutterBackend *backend)
-{
- ClutterFeatureFlags flags = CLUTTER_FEATURE_STAGE_CURSOR;
-
- flags |=
- CLUTTER_BACKEND_CLASS (meta_clutter_backend_x11_parent_class)->get_features (backend);
-
- return flags;
-}
-
-static void
-update_last_event_time (MetaClutterBackendX11 *backend_x11,
- XEvent *xevent)
-{
- Time current_time = CurrentTime;
- Time last_time = backend_x11->last_event_time;
-
- switch (xevent->type)
- {
- case KeyPress:
- case KeyRelease:
- current_time = xevent->xkey.time;
- break;
-
- case ButtonPress:
- case ButtonRelease:
- current_time = xevent->xbutton.time;
- break;
-
- case MotionNotify:
- current_time = xevent->xmotion.time;
- break;
-
- case EnterNotify:
- case LeaveNotify:
- current_time = xevent->xcrossing.time;
- break;
-
- case PropertyNotify:
- current_time = xevent->xproperty.time;
- break;
-
- default:
- break;
- }
-
- /* only change the current event time if it's after the previous event
- * time, or if it is at least 30 seconds earlier - in case the system
- * clock was changed
- */
- if ((current_time != CurrentTime) &&
- (current_time > last_time || (last_time - current_time > (30 * 1000))))
- backend_x11->last_event_time = current_time;
-}
-
-static gboolean
-check_onscreen_template (CoglRenderer *renderer,
- CoglOnscreenTemplate *onscreen_template,
- gboolean enable_stereo,
- GError **error)
-{
- GError *internal_error = NULL;
-
- cogl_onscreen_template_set_stereo_enabled (onscreen_template,
- clutter_enable_stereo);
-
- /* cogl_renderer_check_onscreen_template() is actually just a
- * shorthand for creating a CoglDisplay, and calling
- * cogl_display_setup() on it, then throwing the display away. If we
- * could just return that display, then it would be more efficient
- * not to use cogl_renderer_check_onscreen_template(). However, the
- * backend API requires that we return an CoglDisplay that has not
- * yet been setup, so one way or the other we'll have to discard the
- * first display and make a new fresh one.
- */
- if (cogl_renderer_check_onscreen_template (renderer, onscreen_template, &internal_error))
- {
- clutter_enable_stereo = enable_stereo;
-
- return TRUE;
- }
- else
- {
- g_set_error_literal (error, CLUTTER_INIT_ERROR,
- CLUTTER_INIT_ERROR_BACKEND,
- internal_error != NULL
- ? internal_error->message
- : "Creation of a CoglDisplay failed");
-
- g_clear_error (&internal_error);
-
- return FALSE;
- }
-}
-
-static CoglDisplay *
-meta_clutter_backend_x11_get_display (ClutterBackend *backend,
- CoglRenderer *renderer,
- CoglSwapChain *swap_chain,
- GError **error)
-{
- CoglOnscreenTemplate *onscreen_template;
- CoglDisplay *display = NULL;
- gboolean res = FALSE;
-
- onscreen_template = cogl_onscreen_template_new (swap_chain);
-
- /* It's possible that the current renderer doesn't support transparency
- * or doesn't support stereo, so we try the different combinations.
- */
- if (clutter_enable_stereo)
- res = check_onscreen_template (renderer, onscreen_template,
- TRUE, error);
-
- if (!res)
- res = check_onscreen_template (renderer, onscreen_template,
- FALSE, error);
-
- if (res)
- display = cogl_display_new (renderer, onscreen_template);
-
- cogl_object_unref (onscreen_template);
-
- return display;
-}
-
-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_process_event_filters (MetaClutterBackendX11 *backend_x11,
- gpointer native,
- ClutterEvent *event)
-{
- XEvent *xevent = native;
-
- /* X11 filter functions have a higher priority */
- if (backend_x11->event_filters != NULL)
- {
- GSList *node = backend_x11->event_filters;
-
- while (node != NULL)
- {
- MetaX11EventFilter *filter = node->data;
-
- switch (filter->func (xevent, event, filter->data))
- {
- case META_X11_FILTER_CONTINUE:
- break;
-
- case META_X11_FILTER_TRANSLATE:
- return TRUE;
-
- case META_X11_FILTER_REMOVE:
- return FALSE;
-
- default:
- break;
- }
-
- node = node->next;
- }
- }
-
- return FALSE;
-}
-
-static gboolean
-meta_clutter_backend_x11_translate_event (ClutterBackend *clutter_backend,
- gpointer native,
- ClutterEvent *event)
-{
- MetaClutterBackendX11 *backend_x11 =
- META_CLUTTER_BACKEND_X11 (clutter_backend);
- MetaBackend *backend = meta_get_backend ();
- MetaStageX11 *stage_x11;
- ClutterSeat *seat;
-
- if (meta_clutter_backend_x11_process_event_filters (backend_x11,
- native,
- event))
- return TRUE;
-
- /* we update the event time only for events that can
- * actually reach Clutter's event queue
- */
- update_last_event_time (backend_x11, native);
-
- stage_x11 =
- META_STAGE_X11 (clutter_backend_get_stage_window (clutter_backend));
- if (meta_stage_x11_translate_event (stage_x11, native, event))
- return TRUE;
-
- seat = meta_backend_get_default_seat (backend);
- if (meta_seat_x11_translate_event (META_SEAT_X11 (seat), native, event))
- return TRUE;
-
- return FALSE;
-}
-
-static ClutterSeat *
-meta_clutter_backend_x11_get_default_seat (ClutterBackend *clutter_backend)
-{
- MetaBackend *backend = meta_get_backend ();
-
- return meta_backend_get_default_seat (backend);
-}
-
-static gboolean
-meta_clutter_backend_x11_is_display_server (ClutterBackend *backend)
-{
- return meta_is_wayland_compositor ();
-}
-
-static void
-meta_clutter_backend_x11_init (MetaClutterBackendX11 *clutter_backend_x11)
-{
- clutter_backend_x11->last_event_time = CurrentTime;
-}
-
-static void
-meta_clutter_backend_x11_class_init (MetaClutterBackendX11Class *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- ClutterBackendClass *clutter_backend_class = CLUTTER_BACKEND_CLASS (klass);
-
- gobject_class->finalize = meta_clutter_backend_x11_finalize;
-
- clutter_backend_class->pre_parse = meta_clutter_backend_x11_pre_parse;
- clutter_backend_class->post_parse = meta_clutter_backend_x11_post_parse;
- clutter_backend_class->add_options = meta_clutter_backend_x11_add_options;
- clutter_backend_class->get_features = meta_clutter_backend_x11_get_features;
-
- clutter_backend_class->get_display = meta_clutter_backend_x11_get_display;
- 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->get_default_seat = meta_clutter_backend_x11_get_default_seat;
- clutter_backend_class->is_display_server = meta_clutter_backend_x11_is_display_server;
-}
-
-static int
-error_handler (Display *xdisplay,
- XErrorEvent *error)
-{
- TrappedErrorCode = error->error_code;
- return 0;
-}
-
-void
-meta_clutter_x11_trap_x_errors (void)
-{
- TrappedErrorCode = 0;
- old_error_handler = XSetErrorHandler (error_handler);
-}
-
-gint
-meta_clutter_x11_untrap_x_errors (void)
-{
- XSetErrorHandler (old_error_handler);
-
- return TrappedErrorCode;
-}
-
-Display *
-meta_clutter_x11_get_default_display (void)
-{
- ClutterBackend *backend = clutter_get_default_backend ();
-
- if (backend == NULL)
- {
- g_critical ("The Clutter backend has not been initialised");
- return NULL;
- }
-
- if (!META_IS_CLUTTER_BACKEND_X11 (backend))
- {
- g_critical ("The Clutter backend is not a X11 backend");
- return NULL;
- }
-
- return META_CLUTTER_BACKEND_X11 (backend)->xdisplay;
-}
-
-void
-meta_clutter_x11_set_display (Display *xdisplay)
-{
- if (_clutter_context_is_initialized ())
- {
- g_warning ("%s() can only be used before calling clutter_init()",
- G_STRFUNC);
- return;
- }
-
- _foreign_dpy= xdisplay;
-}
-
-int
-meta_clutter_x11_get_default_screen (void)
-{
- ClutterBackend *backend = clutter_get_default_backend ();
-
- if (backend == NULL)
- {
- g_critical ("The Clutter backend has not been initialised");
- return 0;
- }
-
- if (!META_IS_CLUTTER_BACKEND_X11 (backend))
- {
- g_critical ("The Clutter backend is not a X11 backend");
- return 0;
- }
-
- return META_CLUTTER_BACKEND_X11 (backend)->xscreen_num;
-}
-
-Window
-meta_clutter_x11_get_root_window (void)
-{
- ClutterBackend *backend = clutter_get_default_backend ();
-
- if (backend == NULL)
- {
- g_critical ("The Clutter backend has not been initialised");
- return None;
- }
-
- if (!META_IS_CLUTTER_BACKEND_X11 (backend))
- {
- g_critical ("The Clutter backend is not a X11 backend");
- return None;
- }
-
- return META_CLUTTER_BACKEND_X11 (backend)->xwin_root;
-}
-
-void
-meta_clutter_x11_add_filter (MetaX11FilterFunc func,
- gpointer data)
-{
- MetaX11EventFilter *filter;
- ClutterBackend *backend = clutter_get_default_backend ();
- MetaClutterBackendX11 *backend_x11;
-
- g_return_if_fail (func != NULL);
-
- if (backend == NULL)
- {
- g_critical ("The Clutter backend has not been initialised");
- return;
- }
-
- if (!META_IS_CLUTTER_BACKEND_X11 (backend))
- {
- g_critical ("The Clutter backend is not a X11 backend");
- return;
- }
-
- backend_x11 = META_CLUTTER_BACKEND_X11 (backend);
-
- filter = g_new0 (MetaX11EventFilter, 1);
- filter->func = func;
- filter->data = data;
-
- backend_x11->event_filters =
- g_slist_append (backend_x11->event_filters, filter);
-
- return;
-}
-
-void
-meta_clutter_x11_remove_filter (MetaX11FilterFunc func,
- gpointer data)
-{
- GSList *tmp_list, *this;
- MetaX11EventFilter *filter;
- ClutterBackend *backend = clutter_get_default_backend ();
- MetaClutterBackendX11 *backend_x11;
-
- g_return_if_fail (func != NULL);
-
- if (backend == NULL)
- {
- g_critical ("The Clutter backend has not been initialised");
- return;
- }
-
- if (!META_IS_CLUTTER_BACKEND_X11 (backend))
- {
- g_critical ("The Clutter backend is not a X11 backend");
- return;
- }
-
- backend_x11 = META_CLUTTER_BACKEND_X11 (backend);
-
- tmp_list = backend_x11->event_filters;
-
- while (tmp_list)
- {
- filter = tmp_list->data;
- this = tmp_list;
- tmp_list = tmp_list->next;
-
- if (filter->func == func && filter->data == data)
- {
- backend_x11->event_filters =
- g_slist_remove_link (backend_x11->event_filters, this);
-
- g_slist_free_1 (this);
- g_free (filter);
-
- return;
- }
- }
-}
-
-void
-meta_clutter_x11_set_use_stereo_stage (gboolean use_stereo)
-{
- if (_clutter_context_is_initialized ())
- {
- g_warning ("%s() can only be used before calling clutter_init()",
- G_STRFUNC);
- return;
- }
-
- g_debug ("STEREO stages are %s",
- use_stereo ? "enabled" : "disabled");
-
- clutter_enable_stereo = use_stereo;
-}
-
-gboolean
-meta_clutter_x11_get_use_stereo_stage (void)
-{
- return clutter_enable_stereo;
-}
diff --git a/src/backends/x11/meta-clutter-backend-x11.h b/src/backends/x11/meta-clutter-backend-x11.h
deleted file mode 100644
index d91a2f3af..000000000
--- a/src/backends/x11/meta-clutter-backend-x11.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- 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-mutter.h"
-
-struct _MetaClutterBackendX11
-{
- ClutterBackend parent_instance;
-
- Display *xdisplay;
- char *display_name;
-
- Screen *xscreen;
- int xscreen_num;
- int xscreen_width;
- int xscreen_height;
-
- Window xwin_root;
-
- /* 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_USER_TIME;
- Atom atom_WM_PROTOCOLS;
- Atom atom_WM_DELETE_WINDOW;
- Atom atom_XEMBED;
- Atom atom_XEMBED_INFO;
- Atom atom_NET_WM_NAME;
- Atom atom_UTF8_STRING;
-
- Time last_event_time;
-};
-
-#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,
- ClutterBackend)
-
-typedef enum
-{
- META_X11_FILTER_CONTINUE,
- META_X11_FILTER_TRANSLATE,
- META_X11_FILTER_REMOVE
-} MetaX11FilterReturn;
-
-typedef MetaX11FilterReturn (*MetaX11FilterFunc) (XEvent *xev,
- ClutterEvent *cev,
- gpointer data);
-
-void meta_clutter_x11_trap_x_errors (void);
-gint meta_clutter_x11_untrap_x_errors (void);
-
-Display *meta_clutter_x11_get_default_display (void);
-int meta_clutter_x11_get_default_screen (void);
-Window meta_clutter_x11_get_root_window (void);
-void meta_clutter_x11_set_display (Display * xdpy);
-
-void meta_clutter_x11_add_filter (MetaX11FilterFunc func,
- gpointer data);
-void meta_clutter_x11_remove_filter (MetaX11FilterFunc func,
- gpointer data);
-
-void meta_clutter_x11_set_use_stereo_stage (gboolean use_stereo);
-gboolean meta_clutter_x11_get_use_stereo_stage (void);
-
-#endif /* META_CLUTTER_BACKEND_X11_H */
diff --git a/src/backends/x11/meta-crtc-xrandr.c b/src/backends/x11/meta-crtc-xrandr.c
deleted file mode 100644
index e06448b6e..000000000
--- a/src/backends/x11/meta-crtc-xrandr.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/* -*- 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 <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"
-
-struct _MetaCrtcXrandr
-{
- MetaCrtc parent;
-
- MetaRectangle rect;
- MetaMonitorTransform transform;
- MetaCrtcMode *current_mode;
-};
-
-G_DEFINE_TYPE (MetaCrtcXrandr, meta_crtc_xrandr, META_TYPE_CRTC)
-
-gboolean
-meta_crtc_xrandr_set_config (MetaCrtcXrandr *crtc_xrandr,
- 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 (META_CRTC (crtc_xrandr));
- 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;
-}
-
-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 META_MONITOR_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 (MetaCrtcXrandr *crtc_xrandr,
- MetaCrtcAssignment *crtc_assignment)
-{
- unsigned int i;
-
- if (crtc_xrandr->current_mode != crtc_assignment->mode)
- return TRUE;
-
- if (crtc_xrandr->rect.x != (int) roundf (crtc_assignment->layout.origin.x))
- return TRUE;
-
- if (crtc_xrandr->rect.y != (int) roundf (crtc_assignment->layout.origin.y))
- return TRUE;
-
- if (crtc_xrandr->transform != crtc_assignment->transform)
- return TRUE;
-
- for (i = 0; i < crtc_assignment->outputs->len; i++)
- {
- MetaOutput *output = ((MetaOutput**) crtc_assignment->outputs->pdata)[i];
- MetaCrtc *assigned_crtc;
-
- assigned_crtc = meta_output_get_assigned_crtc (output);
- if (assigned_crtc != META_CRTC (crtc_xrandr))
- return TRUE;
- }
-
- return FALSE;
-}
-
-MetaCrtcMode *
-meta_crtc_xrandr_get_current_mode (MetaCrtcXrandr *crtc_xrandr)
-{
- return crtc_xrandr->current_mode;
-}
-
-MetaCrtcXrandr *
-meta_crtc_xrandr_new (MetaGpuXrandr *gpu_xrandr,
- XRRCrtcInfo *xrandr_crtc,
- RRCrtc crtc_id,
- XRRScreenResources *resources)
-{
- 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);
- MetaMonitorTransform all_transforms;
- MetaCrtcXrandr *crtc_xrandr;
- XRRPanning *panning;
- unsigned int i;
- GList *modes;
-
- all_transforms =
- meta_monitor_transform_from_xrandr_all (xrandr_crtc->rotations);
- crtc_xrandr = g_object_new (META_TYPE_CRTC_XRANDR,
- "id", (uint64_t) crtc_id,
- "gpu", gpu,
- "all-transforms", all_transforms,
- NULL);
-
- crtc_xrandr->transform =
- meta_monitor_transform_from_xrandr (xrandr_crtc->rotation);
-
- 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,
- };
- }
- XRRFreePanning (panning);
-
- modes = meta_gpu_get_modes (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 (META_CRTC (crtc_xrandr),
- &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_xrandr;
-}
-
-static void
-meta_crtc_xrandr_init (MetaCrtcXrandr *crtc_xrandr)
-{
-}
-
-static void
-meta_crtc_xrandr_class_init (MetaCrtcXrandrClass *klass)
-{
-}
diff --git a/src/backends/x11/meta-crtc-xrandr.h b/src/backends/x11/meta-crtc-xrandr.h
deleted file mode 100644
index dbf5da0c6..000000000
--- a/src/backends/x11/meta-crtc-xrandr.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* -*- 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"
-
-#define META_TYPE_CRTC_XRANDR (meta_crtc_xrandr_get_type ())
-G_DECLARE_FINAL_TYPE (MetaCrtcXrandr, meta_crtc_xrandr,
- META, CRTC_XRANDR,
- MetaCrtc)
-
-gboolean meta_crtc_xrandr_set_config (MetaCrtcXrandr *crtc_xrandr,
- 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 (MetaCrtcXrandr *crtc_xrandr,
- MetaCrtcAssignment *crtc_assignment);
-
-MetaCrtcMode * meta_crtc_xrandr_get_current_mode (MetaCrtcXrandr *crtc_xrandr);
-
-MetaCrtcXrandr * meta_crtc_xrandr_new (MetaGpuXrandr *gpu_xrandr,
- XRRCrtcInfo *xrandr_crtc,
- RRCrtc crtc_id,
- XRRScreenResources *resources);
-
-#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
deleted file mode 100644
index 4d81f8027..000000000
--- a/src/backends/x11/meta-cursor-renderer-x11.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- 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 (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
deleted file mode 100644
index b52834375..000000000
--- a/src/backends/x11/meta-cursor-renderer-x11.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- 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-cursor-tracker-x11.c b/src/backends/x11/meta-cursor-tracker-x11.c
deleted file mode 100644
index 7355f828e..000000000
--- a/src/backends/x11/meta-cursor-tracker-x11.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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.
- *
- */
-
-#include "config.h"
-
-#include "backends/x11/meta-cursor-tracker-x11.h"
-
-#include "backends/x11/cm/meta-cursor-sprite-xfixes.h"
-#include "clutter/clutter-private.h"
-#include "meta/meta-x11-errors.h"
-#include "x11/meta-x11-display-private.h"
-
-#define UPDATE_POSITION_TIMEOUT_MS (ms (100))
-
-struct _MetaCursorTrackerX11
-{
- MetaCursorTracker parent;
-
- gboolean is_force_track_position_enabled;
- guint update_position_timeout_id;
-
- MetaCursorSpriteXfixes *xfixes_cursor;
-};
-
-G_DEFINE_TYPE (MetaCursorTrackerX11, meta_cursor_tracker_x11,
- META_TYPE_CURSOR_TRACKER)
-
-static gboolean
-ensure_xfixes_cursor (MetaCursorTrackerX11 *tracker_x11);
-
-gboolean
-meta_cursor_tracker_x11_handle_xevent (MetaCursorTrackerX11 *tracker_x11,
- XEvent *xevent)
-{
- MetaX11Display *x11_display = meta_get_display ()->x11_display;
- XFixesCursorNotifyEvent *notify_event;
-
- 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_x11->xfixes_cursor);
- meta_cursor_tracker_notify_cursor_changed (META_CURSOR_TRACKER (tracker_x11));
-
- return TRUE;
-}
-
-static void
-update_position (MetaCursorTrackerX11 *tracker_x11)
-{
- MetaCursorTracker *tracker = META_CURSOR_TRACKER (tracker_x11);
-
- meta_cursor_tracker_invalidate_position (tracker);
-}
-
-static gboolean
-ensure_xfixes_cursor (MetaCursorTrackerX11 *tracker_x11)
-{
- MetaDisplay *display = meta_get_display ();
- g_autoptr (GError) error = NULL;
-
- if (tracker_x11->xfixes_cursor)
- return FALSE;
-
- tracker_x11->xfixes_cursor = meta_cursor_sprite_xfixes_new (display, &error);
- if (!tracker_x11->xfixes_cursor)
- g_warning ("Failed to create XFIXES cursor: %s", error->message);
-
- return TRUE;
-}
-
-static gboolean
-update_cursor_timeout (gpointer user_data)
-{
- MetaCursorTrackerX11 *tracker_x11 = user_data;
- MetaCursorTracker *tracker = META_CURSOR_TRACKER (tracker_x11);
- MetaBackend *backend = meta_cursor_tracker_get_backend (tracker);
- MetaCursorRenderer *cursor_renderer =
- meta_backend_get_cursor_renderer (backend);
- gboolean cursor_changed;
- MetaCursorSprite *cursor_sprite;
-
- update_position (tracker_x11);
-
- cursor_changed = ensure_xfixes_cursor (tracker_x11);
-
- if (tracker_x11->xfixes_cursor)
- cursor_sprite = META_CURSOR_SPRITE (tracker_x11->xfixes_cursor);
- else
- cursor_sprite = NULL;
-
- meta_cursor_renderer_update_stage_overlay (cursor_renderer, cursor_sprite);
-
- if (cursor_changed)
- meta_cursor_tracker_notify_cursor_changed (tracker);
-
- return G_SOURCE_CONTINUE;
-}
-
-static void
-meta_cursor_tracker_x11_set_force_track_position (MetaCursorTracker *tracker,
- gboolean is_enabled)
-{
- MetaCursorTrackerX11 *tracker_x11 = META_CURSOR_TRACKER_X11 (tracker);
-
- if (tracker_x11->is_force_track_position_enabled == is_enabled)
- return;
-
- tracker_x11->is_force_track_position_enabled = is_enabled;
-
- if (is_enabled)
- {
- tracker_x11->update_position_timeout_id =
- g_timeout_add (UPDATE_POSITION_TIMEOUT_MS,
- update_cursor_timeout,
- tracker_x11);
- update_position (tracker_x11);
- }
- else
- {
- g_clear_handle_id (&tracker_x11->update_position_timeout_id,
- g_source_remove);
- }
-}
-
-static MetaCursorSprite *
-meta_cursor_tracker_x11_get_sprite (MetaCursorTracker *tracker)
-{
- MetaCursorTrackerX11 *tracker_x11 = META_CURSOR_TRACKER_X11 (tracker);
-
- ensure_xfixes_cursor (META_CURSOR_TRACKER_X11 (tracker));
- if (tracker_x11->xfixes_cursor)
- return META_CURSOR_SPRITE (tracker_x11->xfixes_cursor);
- else
- return NULL;
-}
-
-static void
-meta_cursor_tracker_x11_dispose (GObject *object)
-{
- MetaCursorTrackerX11 *tracker_x11 = META_CURSOR_TRACKER_X11 (object);
-
- g_clear_handle_id (&tracker_x11->update_position_timeout_id, g_source_remove);
- g_clear_object (&tracker_x11->xfixes_cursor);
-
- G_OBJECT_CLASS (meta_cursor_tracker_x11_parent_class)->dispose (object);
-}
-
-static void
-meta_cursor_tracker_x11_init (MetaCursorTrackerX11 *tracker_x11)
-{
-}
-
-static void
-meta_cursor_tracker_x11_class_init (MetaCursorTrackerX11Class *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- MetaCursorTrackerClass *tracker_class = META_CURSOR_TRACKER_CLASS (klass);
-
- object_class->dispose = meta_cursor_tracker_x11_dispose;
-
- tracker_class->set_force_track_position =
- meta_cursor_tracker_x11_set_force_track_position;
- tracker_class->get_sprite =
- meta_cursor_tracker_x11_get_sprite;
-}
diff --git a/src/backends/x11/meta-cursor-tracker-x11.h b/src/backends/x11/meta-cursor-tracker-x11.h
deleted file mode 100644
index a4b462844..000000000
--- a/src/backends/x11/meta-cursor-tracker-x11.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.
- *
- */
-
-#ifndef META_CURSOR_TRACKER_X11_H
-#define META_CURSOR_TRACKER_X11_H
-
-#include "backends/meta-cursor-tracker-private.h"
-
-#define META_TYPE_CURSOR_TRACKER_X11 (meta_cursor_tracker_x11_get_type ())
-G_DECLARE_FINAL_TYPE (MetaCursorTrackerX11, meta_cursor_tracker_x11,
- META, CURSOR_TRACKER_X11,
- MetaCursorTracker)
-
-gboolean meta_cursor_tracker_x11_handle_xevent (MetaCursorTrackerX11 *tracker_x11,
- XEvent *xevent);
-
-#endif /* META_CURSOR_TRACKER_X11_H */
diff --git a/src/backends/x11/meta-event-x11.c b/src/backends/x11/meta-event-x11.c
deleted file mode 100644
index d1a94bb56..000000000
--- a/src/backends/x11/meta-event-x11.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* 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"
-
-/**
- * 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: #MetaX11FilterReturn. %META_X11_FILTER_REMOVE
- * indicates that Clutter has internally handled the event and the
- * caller should do no further processing. %META_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. %META_X11_FILTER_TRANSLATE will not
- * occur.
- *
- * Since: 0.8
- */
-MetaX11FilterReturn
-meta_x11_handle_event (XEvent *xevent)
-{
- MetaX11FilterReturn result;
- ClutterBackend *backend;
- ClutterEvent *event;
- gint spin = 1;
- MetaClutterBackendX11 *backend_x11;
- Display *xdisplay;
- gboolean allocated_event;
-
- /* The return values here are someone approximate; we return
- * META_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
- * %META_X11_FILTER_REMOVE when more processing is needed.
- */
-
- result = META_X11_FILTER_CONTINUE;
-
- backend = clutter_get_default_backend ();
-
- event = clutter_event_new (CLUTTER_NOTHING);
-
- backend_x11 = META_CLUTTER_BACKEND_X11 (backend);
- xdisplay = backend_x11->xdisplay;
-
- allocated_event = XGetEventData (xdisplay, &xevent->xcookie);
-
- if (_clutter_backend_translate_event (backend, xevent, event))
- {
- _clutter_event_push (event, FALSE);
-
- result = META_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);
-
- return result;
-}
diff --git a/src/backends/x11/meta-event-x11.h b/src/backends/x11/meta-event-x11.h
deleted file mode 100644
index 3ddd0fd5d..000000000
--- a/src/backends/x11/meta-event-x11.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* 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 "backends/x11/meta-clutter-backend-x11.h"
-
-MetaX11FilterReturn 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
deleted file mode 100644
index bc3292d36..000000000
--- a/src/backends/x11/meta-gpu-xrandr.c
+++ /dev/null
@@ -1,277 +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
- * 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 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_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)
-{
- MetaOutput *o_one = (MetaOutput *) one;
- MetaOutput *o_two = (MetaOutput *) two;
- const MetaOutputInfo *output_info_one = meta_output_get_info (o_one);
- const MetaOutputInfo *output_info_two = meta_output_get_info (o_two);
-
- return strcmp (output_info_one->name, output_info_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 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;
- int min_width, min_height;
- Screen *screen;
- GList *outputs = NULL;
- GList *modes = NULL;
- GList *crtcs = NULL;
-
- if (gpu_xrandr->resources)
- XRRFreeScreenResources (gpu_xrandr->resources);
- gpu_xrandr->resources = NULL;
-
- XRRGetScreenSizeRange (xdisplay, DefaultRootWindow (xdisplay),
- &min_width,
- &min_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];
- g_autofree char *crtc_mode_name = NULL;
- MetaCrtcMode *mode;
- g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL;
-
- crtc_mode_info = meta_crtc_mode_info_new ();
- crtc_mode_info->width = xmode->width;
- crtc_mode_info->height = xmode->height;
- crtc_mode_info->refresh_rate = (xmode->dotClock /
- ((float)xmode->hTotal * xmode->vTotal));
- crtc_mode_info->flags = xmode->modeFlags;
-
- crtc_mode_name = get_xmode_name (xmode);
- mode = g_object_new (META_TYPE_CRTC_MODE,
- "id", (uint64_t) xmode->id,
- "name", crtc_mode_name,
- "info", crtc_mode_info,
- NULL);
- modes = g_list_append (modes, mode);
- }
- meta_gpu_take_modes (gpu, modes);
-
- for (i = 0; i < (unsigned)resources->ncrtc; i++)
- {
- XRRCrtcInfo *xrandr_crtc;
- RRCrtc crtc_id;
- MetaCrtcXrandr *crtc_xrandr;
-
- crtc_id = resources->crtcs[i];
- xrandr_crtc = XRRGetCrtcInfo (xdisplay,
- resources, crtc_id);
- crtc_xrandr = meta_crtc_xrandr_new (gpu_xrandr,
- xrandr_crtc, crtc_id, resources);
- XRRFreeCrtcInfo (xrandr_crtc);
-
- crtcs = g_list_append (crtcs, crtc_xrandr);
- }
-
- meta_gpu_take_crtcs (gpu, crtcs);
-
- 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)
- {
- MetaOutputXrandr *output_xrandr;
-
- output_xrandr = meta_output_xrandr_new (gpu_xrandr,
- xrandr_output,
- output_id,
- primary_output);
- if (output_xrandr)
- outputs = g_list_prepend (outputs, output_xrandr);
- }
-
- 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;
- const MetaOutputInfo *output_info = meta_output_get_info (output);
- GList *k;
-
- for (j = 0; j < output_info->n_possible_clones; j++)
- {
- RROutput clone = GPOINTER_TO_INT (output_info->possible_clones[j]);
-
- for (k = outputs; k; k = k->next)
- {
- MetaOutput *possible_clone = k->data;
-
- if (clone == (XID) meta_output_get_id (possible_clone))
- {
- output_info->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
deleted file mode 100644
index 2086f8632..000000000
--- a/src/backends/x11/meta-gpu-xrandr.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- 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_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/src/backends/x11/meta-input-device-tool-x11.c b/src/backends/x11/meta-input-device-tool-x11.c
deleted file mode 100644
index bec4d1fad..000000000
--- a/src/backends/x11/meta-input-device-tool-x11.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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>
- */
-
-#include "config.h"
-
-#include "meta-input-device-tool-x11.h"
-
-G_DEFINE_TYPE (MetaInputDeviceToolX11, meta_input_device_tool_x11,
- CLUTTER_TYPE_INPUT_DEVICE_TOOL)
-
-static void
-meta_input_device_tool_x11_class_init (MetaInputDeviceToolX11Class *klass)
-{
-}
-
-static void
-meta_input_device_tool_x11_init (MetaInputDeviceToolX11 *tool)
-{
-}
-
-ClutterInputDeviceTool *
-meta_input_device_tool_x11_new (guint serial,
- ClutterInputDeviceToolType type)
-{
- ClutterInputAxisFlags axes =
- CLUTTER_INPUT_AXIS_FLAG_PRESSURE |
- CLUTTER_INPUT_AXIS_FLAG_DISTANCE |
- CLUTTER_INPUT_AXIS_FLAG_XTILT |
- CLUTTER_INPUT_AXIS_FLAG_YTILT |
- CLUTTER_INPUT_AXIS_FLAG_WHEEL |
- CLUTTER_INPUT_AXIS_FLAG_DISTANCE |
- CLUTTER_INPUT_AXIS_FLAG_ROTATION |
- CLUTTER_INPUT_AXIS_FLAG_SLIDER;
-
- return g_object_new (META_TYPE_INPUT_DEVICE_TOOL_X11,
- "type", type,
- "serial", serial,
- "axes", axes,
- NULL);
-}
diff --git a/src/backends/x11/meta-input-device-tool-x11.h b/src/backends/x11/meta-input-device-tool-x11.h
deleted file mode 100644
index e52803da9..000000000
--- a/src/backends/x11/meta-input-device-tool-x11.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 81a932e93..000000000
--- a/src/backends/x11/meta-input-device-x11.c
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- * 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 "backends/x11/meta-clutter-backend-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;
-
- GArray *axes;
- GArray *scroll_info;
-
-#ifdef HAVE_LIBWACOM
- GArray *group_modes;
-#endif
-};
-
-typedef struct _MetaX11AxisInfo
-{
- ClutterInputAxis axis;
-
- double min_axis;
- double max_axis;
-
- double min_value;
- double max_value;
-
- double resolution;
-} MetaX11AxisInfo;
-
-typedef struct _MetaX11ScrollInfo
-{
- guint axis_id;
- ClutterScrollDirection direction;
- double increment;
-
- double last_value;
- guint last_value_valid : 1;
-} MetaX11ScrollInfo;
-
-struct _MetaInputDeviceX11Class
-{
- ClutterInputDeviceClass device_class;
-};
-
-#define N_BUTTONS 5
-
-enum
-{
- PROP_0,
- PROP_ID,
- N_PROPS
-};
-
-static GParamSpec *props[N_PROPS] = { 0 };
-
-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);
-
- 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_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);
-
- g_clear_pointer (&device_xi2->axes, g_array_unref);
- g_clear_pointer (&device_xi2->scroll_info, g_array_unref);
-
-#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 void
-meta_input_device_x11_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (object);
-
- switch (prop_id)
- {
- case PROP_ID:
- device_x11->device_id = g_value_get_int (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-meta_input_device_x11_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (object);
-
- switch (prop_id)
- {
- case PROP_ID:
- g_value_set_int (value, device_x11->device_id);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-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;
- gobject_class->set_property = meta_input_device_x11_set_property;
- gobject_class->get_property = meta_input_device_x11_get_property;
-
- 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;
-
- props[PROP_ID] =
- g_param_spec_int ("id",
- "Id",
- "Unique identifier of the device",
- -1, G_MAXINT,
- 0,
- CLUTTER_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY);
-
- g_object_class_install_properties (gobject_class, N_PROPS, props);
-}
-
-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 = { 0 };
- XIModifierState mod_state;
- XIGroupState group_state;
- int result;
-
- meta_clutter_x11_trap_x_errors ();
- result = XIQueryPointer (meta_clutter_x11_get_default_display (),
- device_xi2->device_id,
- meta_clutter_x11_get_root_window (),
- &xroot_window,
- &xchild_window,
- &xroot_x, &xroot_y,
- &xwin_x, &xwin_y,
- &button_state,
- &mod_state,
- &group_state);
- meta_clutter_x11_untrap_x_errors ();
-
- g_free (button_state.mask);
-
- 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 (clutter_input_device_get_device_type (device) ==
- 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;
-}
-
-int
-meta_input_device_x11_get_device_id (ClutterInputDevice *device)
-{
- MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device);
-
- g_return_val_if_fail (META_IS_INPUT_DEVICE_X11 (device), 0);
-
- return device_xi2->device_id;
-}
-
-void
-meta_input_device_x11_reset_axes (ClutterInputDevice *device)
-{
- MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device);
-
- g_clear_pointer (&device_x11->axes, g_array_unref);
-}
-
-int
-meta_input_device_x11_add_axis (ClutterInputDevice *device,
- ClutterInputAxis axis,
- double minimum,
- double maximum,
- double resolution)
-{
- MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device);
- MetaX11AxisInfo info;
- guint pos;
-
- if (device_x11->axes == NULL)
- device_x11->axes = g_array_new (FALSE, TRUE, sizeof (MetaX11AxisInfo));
-
- info.axis = axis;
- info.min_value = minimum;
- info.max_value = maximum;
- info.resolution = resolution;
-
- switch (axis)
- {
- case CLUTTER_INPUT_AXIS_X:
- case CLUTTER_INPUT_AXIS_Y:
- info.min_axis = 0;
- info.max_axis = 0;
- break;
-
- case CLUTTER_INPUT_AXIS_XTILT:
- case CLUTTER_INPUT_AXIS_YTILT:
- info.min_axis = -1;
- info.max_axis = 1;
- break;
-
- default:
- info.min_axis = 0;
- info.max_axis = 1;
- break;
- }
-
- g_array_append_val (device_x11->axes, info);
- pos = device_x11->axes->len - 1;
-
- return pos;
-}
-
-gboolean
-meta_input_device_x11_get_axis (ClutterInputDevice *device,
- int idx,
- ClutterInputAxis *use)
-{
- MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device);
- MetaX11AxisInfo *info;
-
- if (device_x11->axes == NULL)
- return FALSE;
-
- if (idx < 0 || idx >= device_x11->axes->len)
- return FALSE;
-
- info = &g_array_index (device_x11->axes, MetaX11AxisInfo, idx);
-
- if (use)
- *use = info->axis;
-
- return TRUE;
-}
-
-gboolean
-meta_input_device_x11_translate_axis (ClutterInputDevice *device,
- int idx,
- double value,
- double *axis_value)
-{
- MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device);
- MetaX11AxisInfo *info;
- double width;
- double real_value;
-
- if (device_x11->axes == NULL || idx < 0 || idx >= device_x11->axes->len)
- return FALSE;
-
- info = &g_array_index (device_x11->axes, MetaX11AxisInfo, idx);
-
- if (info->axis == CLUTTER_INPUT_AXIS_X ||
- info->axis == CLUTTER_INPUT_AXIS_Y)
- return FALSE;
-
- if (fabs (info->max_value - info->min_value) < 0.0000001)
- return FALSE;
-
- width = info->max_value - info->min_value;
- real_value = (info->max_axis * (value - info->min_value)
- + info->min_axis * (info->max_value - value))
- / width;
-
- if (axis_value)
- *axis_value = real_value;
-
- return TRUE;
-}
-
-int
-meta_input_device_x11_get_n_axes (ClutterInputDevice *device)
-{
- MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device);
-
- return device_x11->axes->len;
-}
-
-void
-meta_input_device_x11_add_scroll_info (ClutterInputDevice *device,
- int idx,
- ClutterScrollDirection direction,
- double increment)
-{
- MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device);
- MetaX11ScrollInfo info;
-
- g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
-
- info.axis_id = idx;
- info.direction = direction;
- info.increment = increment;
- info.last_value_valid = FALSE;
-
- if (device_x11->scroll_info == NULL)
- {
- device_x11->scroll_info = g_array_new (FALSE,
- FALSE,
- sizeof (MetaX11ScrollInfo));
- }
-
- g_array_append_val (device_x11->scroll_info, info);
-}
-
-gboolean
-meta_input_device_x11_get_scroll_delta (ClutterInputDevice *device,
- int idx,
- double value,
- ClutterScrollDirection *direction_p,
- double *delta_p)
-{
- MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device);
- int i;
-
- if (device_x11->scroll_info == NULL)
- return FALSE;
-
- for (i = 0; i < device_x11->scroll_info->len; i++)
- {
- MetaX11ScrollInfo *info = &g_array_index (device_x11->scroll_info,
- MetaX11ScrollInfo,
- i);
-
- if (info->axis_id == idx)
- {
- if (direction_p != NULL)
- *direction_p = info->direction;
-
- if (delta_p != NULL)
- *delta_p = 0.0;
-
- if (info->last_value_valid)
- {
- if (delta_p != NULL)
- {
- *delta_p = (value - info->last_value)
- / info->increment;
- }
-
- info->last_value = value;
- }
- else
- {
- info->last_value = value;
- info->last_value_valid = TRUE;
- }
-
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-void
-meta_input_device_x11_reset_scroll_info (ClutterInputDevice *device)
-{
- MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device);
- int i;
-
- if (device_x11->scroll_info == NULL)
- return;
-
- for (i = 0; i < device_x11->scroll_info->len; i++)
- {
- MetaX11ScrollInfo *info = &g_array_index (device_x11->scroll_info,
- MetaX11ScrollInfo,
- i);
-
- info->last_value_valid = FALSE;
- }
-}
-
-#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
deleted file mode 100644
index 66e03f581..000000000
--- a/src/backends/x11/meta-input-device-x11.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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);
-int meta_input_device_x11_get_device_id (ClutterInputDevice *device);
-
-int meta_input_device_x11_get_n_axes (ClutterInputDevice *device);
-void meta_input_device_x11_reset_axes (ClutterInputDevice *device);
-int meta_input_device_x11_add_axis (ClutterInputDevice *device,
- ClutterInputAxis axis,
- double minimum,
- double maximum,
- double resolution);
-gboolean meta_input_device_x11_get_axis (ClutterInputDevice *device,
- int idx,
- ClutterInputAxis *use);
-gboolean meta_input_device_x11_translate_axis (ClutterInputDevice *device,
- int idx,
- double value,
- double *axis_value);
-
-void meta_input_device_x11_add_scroll_info (ClutterInputDevice *device,
- int idx,
- ClutterScrollDirection direction,
- double increment);
-gboolean meta_input_device_x11_get_scroll_delta (ClutterInputDevice *device,
- int idx,
- gdouble value,
- ClutterScrollDirection *direction_p,
- double *delta_p);
-void meta_input_device_x11_reset_scroll_info (ClutterInputDevice *device);
-
-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
deleted file mode 100644
index 26048f803..000000000
--- a/src/backends/x11/meta-input-settings-x11.c
+++ /dev/null
@@ -1,948 +0,0 @@
-/* -*- 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/x11/meta-backend-x11.h"
-#include "backends/x11/meta-input-device-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)
-
-typedef enum
-{
- SCROLL_METHOD_FIELD_2FG,
- SCROLL_METHOD_FIELD_EDGE,
- SCROLL_METHOD_FIELD_BUTTON,
- SCROLL_METHOD_NUM_FIELDS
-} ScrollMethod;
-
-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 = meta_input_device_x11_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 = meta_input_device_x11_get_device_id (device);
-
- meta_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);
- meta_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 = meta_input_device_x11_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,
- GDesktopDeviceSendEvents 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);
- if (!available)
- return;
-
- switch (mode)
- {
- case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED:
- values[0] = 1;
- break;
- case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
- values[1] = 1;
- break;
- default:
- break;
- }
-
- if ((values[0] && !available[0]) || (values[1] && !available[1]))
- g_warning ("Device '%s' does not support sendevents mode %d",
- 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,
- const float 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 value = speed;
-
- change_property (device, "libinput Accel Speed",
- XInternAtom (xdisplay, "FLOAT", False),
- 32, &value, 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);
-}
-
-static void
-meta_input_settings_x11_set_tap_enabled (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean enabled)
-{
- guchar value = (enabled) ? 1 : 0;
-
- change_property (device, "libinput Tapping Enabled",
- XA_INTEGER, 8, &value, 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);
-}
-
-static void
-meta_input_settings_x11_set_tap_and_drag_lock_enabled (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean enabled)
-{
- guchar value = (enabled) ? 1 : 0;
-
- change_property (device, "libinput Tapping Drag Lock Enabled",
- XA_INTEGER, 8, &value, 1);
-}
-
-static void
-meta_input_settings_x11_set_invert_scroll (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean inverted)
-{
- guchar value = (inverted) ? 1 : 0;
-
- change_property (device, "libinput Natural Scrolling Enabled",
- XA_INTEGER, 8, &value, 1);
-}
-
-static void
-change_scroll_method (ClutterInputDevice *device,
- ScrollMethod method,
- gboolean enabled)
-{
- guchar values[SCROLL_METHOD_NUM_FIELDS] = { 0 }; /* 2fg, edge, button. The last value is unused */
- guchar *current = NULL;
- guchar *available = NULL;
-
- available = get_property (device, "libinput Scroll Methods Available",
- XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS);
- if (!available || !available[method])
- 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[method] = !!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_edge_scroll (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean edge_scroll_enabled)
-{
- change_scroll_method (device, SCROLL_METHOD_FIELD_EDGE, edge_scroll_enabled);
-}
-
-static void
-meta_input_settings_x11_set_two_finger_scroll (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gboolean two_finger_scroll_enabled)
-{
- change_scroll_method (device, SCROLL_METHOD_FIELD_2FG, two_finger_scroll_enabled);
-}
-
-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, "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,
- gboolean button_lock)
-{
- gchar lock = button_lock;
-
- change_scroll_method (device, SCROLL_METHOD_FIELD_BUTTON, button != 0);
- change_property (device, "libinput Button Scrolling Button",
- XA_CARDINAL, 32, &button, 1);
- change_property (device, "libinput Button Scrolling Button Lock Enabled",
- XA_INTEGER, 8, &lock, 1);
-}
-
-static void
-meta_input_settings_x11_set_click_method (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopTouchpadClickMethod mode)
-{
- guchar values[2] = { 0 }; /* buttonareas, clickfinger */
- guchar *defaults, *available;
-
- available = get_property (device, "libinput Click Methods Available",
- XA_INTEGER, 8, 2);
- if (!available)
- return;
-
- switch (mode)
- {
- case G_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 G_DESKTOP_TOUCHPAD_CLICK_METHOD_NONE:
- break;
- case G_DESKTOP_TOUCHPAD_CLICK_METHOD_AREAS:
- values[0] = 1;
- break;
- case G_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",
- 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_tap_button_map (MetaInputSettings *settings,
- ClutterInputDevice *device,
- GDesktopTouchpadTapButtonMap mode)
-{
- guchar values[2] = { 0 }; /* lrm, lmr */
- guchar *defaults;
-
- switch (mode)
- {
- case G_DESKTOP_TOUCHPAD_BUTTON_TAP_MAP_DEFAULT:
- defaults = get_property (device, "libinput Tapping Button Mapping Default",
- XA_INTEGER, 8, 2);
- if (!defaults)
- break;
- memcpy (values, defaults, 2);
- meta_XFree (defaults);
- break;
- case G_DESKTOP_TOUCHPAD_BUTTON_TAP_MAP_LRM:
- values[0] = 1;
- break;
- case G_DESKTOP_TOUCHPAD_BUTTON_TAP_MAP_LMR:
- values[1] = 1;
- break;
- default:
- g_assert_not_reached ();
- return;
- }
-
- if (values[0] || values[1])
- change_property (device, "libinput Tapping Button Mapping Enabled",
- XA_INTEGER, 8, &values, 2);
-}
-
-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,
- GDesktopPointerAccelProfile 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 G_DESKTOP_POINTER_ACCEL_PROFILE_FLAT:
- values[0] = 0;
- values[1] = 1;
- break;
- case G_DESKTOP_POINTER_ACCEL_PROFILE_ADAPTIVE:
- values[0] = 1;
- values[1] = 0;
- break;
- default:
- g_warn_if_reached ();
- case G_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,
- GDesktopPointerAccelProfile 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,
- GDesktopPointerAccelProfile 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,
- GDesktopTabletMapping 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 == G_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));
- }
-}
-
-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 = meta_input_device_x11_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_aspect_ratio (MetaInputSettings *settings,
- ClutterInputDevice *device,
- gdouble aspect_ratio)
-{
- int32_t 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 (aspect_ratio > 0)
- {
- double dev_aspect;
-
- 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 (GDesktopStylusButtonAction action,
- guint button)
-{
- switch (action)
- {
- case G_DESKTOP_STYLUS_BUTTON_ACTION_MIDDLE:
- return CLUTTER_BUTTON_MIDDLE;
- case G_DESKTOP_STYLUS_BUTTON_ACTION_RIGHT:
- return CLUTTER_BUTTON_SECONDARY;
- case G_DESKTOP_STYLUS_BUTTON_ACTION_BACK:
- return 8;
- case G_DESKTOP_STYLUS_BUTTON_ACTION_FORWARD:
- return 9;
- case G_DESKTOP_STYLUS_BUTTON_ACTION_DEFAULT:
- default:
- return button;
- }
-}
-
-static void
-meta_input_settings_x11_set_stylus_button_map (MetaInputSettings *settings,
- ClutterInputDevice *device,
- ClutterInputDeviceTool *tool,
- GDesktopStylusButtonAction primary,
- GDesktopStylusButtonAction secondary,
- GDesktopStylusButtonAction 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_button_map = meta_input_settings_x11_set_tap_button_map;
- input_settings_class->set_tap_and_drag_enabled = meta_input_settings_x11_set_tap_and_drag_enabled;
- input_settings_class->set_tap_and_drag_lock_enabled =
- meta_input_settings_x11_set_tap_and_drag_lock_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_aspect_ratio = meta_input_settings_x11_set_tablet_aspect_ratio;
- 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
deleted file mode 100644
index 2780bb224..000000000
--- a/src/backends/x11/meta-input-settings-x11.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 994ad8594..000000000
--- a/src/backends/x11/meta-keymap-x11.c
+++ /dev/null
@@ -1,949 +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 <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/meta-backend-private.h"
-#include "backends/meta-input-settings-private.h"
-#include "backends/x11/meta-clutter-backend-x11.h"
-#include "backends/x11/meta-keymap-x11.h"
-#include "clutter/clutter.h"
-#include "clutter/clutter-keymap-private.h"
-#include "clutter/clutter-mutter.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 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 = meta_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)
-{
- ClutterKeymap *keymap = CLUTTER_KEYMAP (keymap_x11);
- gboolean caps_lock_state;
- gboolean num_lock_state;
- gboolean old_num_lock_state;
-
- caps_lock_state = !!(locked_mods & CLUTTER_LOCK_MASK);
- num_lock_state = !!(locked_mods & keymap_x11->num_lock_mask);
-
- old_num_lock_state = clutter_keymap_get_num_lock_state (keymap);
- clutter_keymap_set_lock_modifier_state (CLUTTER_KEYMAP (keymap_x11),
- caps_lock_state,
- num_lock_state);
-
- if (num_lock_state != old_num_lock_state)
- {
- MetaBackend *backend;
- MetaInputSettings *input_settings;
-
- backend = meta_get_backend ();
- input_settings = meta_backend_get_input_settings (backend);
-
- if (input_settings)
- {
- meta_input_settings_maybe_save_numlock_state (input_settings,
- num_lock_state);
- }
- }
-}
-
-/* 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 = meta_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 *xdisplay = meta_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 (xdisplay, 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 *xdisplay = meta_clutter_x11_get_default_display ();
- XkbDescPtr xkb = get_xkb (keymap_x11);
- XkbMapChangesRec changes;
-
- XFlush (xdisplay);
-
- 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 (xdisplay, xkb, &changes);
-
- XFlush (xdisplay);
-
- 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 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 (meta_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_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 (meta_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 *xdisplay = meta_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 (xdisplay, 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 (meta_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 (meta_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
deleted file mode 100644
index 67a5f8eb9..000000000
--- a/src/backends/x11/meta-keymap-x11.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 489a9b424..000000000
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ /dev/null
@@ -1,1151 +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
- * Copyright (C) 2013 Red Hat Inc.
- * Copyright (C) 2020 NVIDIA 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, 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
-
-struct _MetaMonitorManagerXrandr
-{
- MetaMonitorManager parent_instance;
-
- Display *xdisplay;
- int rr_event_base;
- int rr_error_base;
- gboolean has_randr15;
-
- xcb_timestamp_t last_xrandr_set_timestamp;
-
- GHashTable *tiled_monitor_atoms;
-
- float *supported_scales;
- int n_supported_scales;
-};
-
-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;
-}
-
-gboolean
-meta_monitor_manager_xrandr_has_randr15 (MetaMonitorManagerXrandr *manager_xrandr)
-{
- return manager_xrandr->has_randr15;
-}
-
-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 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 (META_CRTC_XRANDR (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 gboolean
-is_crtc_assignment_changed (MetaCrtc *crtc,
- MetaCrtcAssignment **crtc_assignments,
- unsigned int n_crtc_assignments)
-{
- unsigned int i;
-
- for (i = 0; i < n_crtc_assignments; i++)
- {
- MetaCrtcAssignment *crtc_assignment = crtc_assignments[i];
-
- if (crtc_assignment->crtc != crtc)
- continue;
-
- return meta_crtc_xrandr_is_assignment_changed (META_CRTC_XRANDR (crtc),
- crtc_assignment);
- }
-
- return !!meta_crtc_xrandr_get_current_mode (META_CRTC_XRANDR (crtc));
-}
-
-static gboolean
-is_output_assignment_changed (MetaOutput *output,
- MetaCrtcAssignment **crtc_assignments,
- unsigned int n_crtc_assignments,
- MetaOutputAssignment **output_assignments,
- unsigned int n_output_assignments)
-{
- MetaCrtc *assigned_crtc;
- gboolean output_is_found = FALSE;
- unsigned int i;
-
- for (i = 0; i < n_output_assignments; i++)
- {
- MetaOutputAssignment *output_assignment = output_assignments[i];
-
- if (output_assignment->output != output)
- continue;
-
- if (meta_output_is_primary (output) != output_assignment->is_primary)
- return TRUE;
-
- if (meta_output_is_presentation (output) !=
- output_assignment->is_presentation)
- return TRUE;
-
- if (meta_output_is_underscanning (output) !=
- output_assignment->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_assignments; i++)
- {
- MetaCrtcAssignment *crtc_assignment = crtc_assignments[i];
- unsigned int j;
-
- for (j = 0; j < crtc_assignment->outputs->len; j++)
- {
- MetaOutput *crtc_assignment_output =
- ((MetaOutput**) crtc_assignment->outputs->pdata)[j];
-
- if (crtc_assignment_output == output &&
- crtc_assignment->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,
- MetaCrtcAssignment **crtc_assignments,
- unsigned int n_crtc_assignments,
- MetaOutputAssignment **output_assignments,
- unsigned int n_output_assignments)
-{
- 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 (crtc, crtc_assignments, n_crtc_assignments))
- return TRUE;
- }
-
- for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
- {
- MetaOutput *output = l->data;
-
- if (is_output_assignment_changed (output,
- crtc_assignments,
- n_crtc_assignments,
- output_assignments,
- n_output_assignments))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-apply_crtc_assignments (MetaMonitorManager *manager,
- gboolean save_timestamp,
- MetaCrtcAssignment **crtcs,
- unsigned int n_crtcs,
- MetaOutputAssignment **outputs,
- unsigned int n_outputs)
-{
- MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
- MetaGpu *gpu = meta_monitor_manager_xrandr_get_gpu (manager_xrandr);
- g_autoptr (GList) to_configure_outputs = NULL;
- g_autoptr (GList) to_disable_crtcs = NULL;
- unsigned i;
- GList *l;
- int width, height, width_mm, height_mm;
-
- to_configure_outputs = g_list_copy (meta_gpu_get_outputs (gpu));
- to_disable_crtcs = g_list_copy (meta_gpu_get_crtcs (gpu));
-
- XGrabServer (manager_xrandr->xdisplay);
-
- /* First compute the new size of the screen (framebuffer) */
- width = 0; height = 0;
- for (i = 0; i < n_crtcs; i++)
- {
- MetaCrtcAssignment *crtc_assignment = crtcs[i];
- MetaCrtc *crtc = crtc_assignment->crtc;
-
- if (crtc_assignment->mode == NULL)
- continue;
-
- to_disable_crtcs = g_list_remove (to_disable_crtcs, crtc);
-
- width = MAX (width, (int) roundf (crtc_assignment->layout.origin.x +
- crtc_assignment->layout.size.width));
- height = MAX (height, (int) roundf (crtc_assignment->layout.origin.y +
- crtc_assignment->layout.size.height));
- }
-
- /* 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++)
- {
- MetaCrtcAssignment *crtc_assignment = crtcs[i];
- MetaCrtc *crtc = crtc_assignment->crtc;
- const MetaCrtcConfig *crtc_config;
- int x2, y2;
-
- crtc_config = meta_crtc_get_config (crtc);
- 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_assignment->mode || x2 > width || y2 > height)
- {
- xrandr_set_crtc_config (manager_xrandr,
- crtc,
- save_timestamp,
- (xcb_randr_crtc_t) meta_crtc_get_id (crtc),
- XCB_CURRENT_TIME,
- 0, 0, XCB_NONE,
- XCB_RANDR_ROTATION_ROTATE_0,
- NULL, 0);
-
- meta_crtc_unset_config (crtc);
- }
- }
-
- for (l = to_disable_crtcs; l; l = l->next)
- {
- MetaCrtc *crtc = l->data;
-
- if (!meta_crtc_get_config (crtc))
- continue;
-
- xrandr_set_crtc_config (manager_xrandr,
- crtc,
- save_timestamp,
- (xcb_randr_crtc_t) meta_crtc_get_id (crtc),
- XCB_CURRENT_TIME,
- 0, 0, XCB_NONE,
- XCB_RANDR_ROTATION_ROTATE_0,
- NULL, 0);
-
- meta_crtc_unset_config (crtc);
- }
-
- if (!n_crtcs)
- goto out;
-
- g_assert (width > 0 && height > 0);
- /* 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) * 25.4 + 0.5;
- height_mm = (height / DPI_FALLBACK) * 25.4 + 0.5;
- XRRSetScreenSize (manager_xrandr->xdisplay, DefaultRootWindow (manager_xrandr->xdisplay),
- width, height, width_mm, height_mm);
-
- for (i = 0; i < n_crtcs; i++)
- {
- MetaCrtcAssignment *crtc_assignment = crtcs[i];
- MetaCrtc *crtc = crtc_assignment->crtc;
-
- if (crtc_assignment->mode != NULL)
- {
- MetaCrtcMode *crtc_mode;
- g_autofree xcb_randr_output_t *output_ids = NULL;
- unsigned int j, n_output_ids;
- xcb_randr_crtc_t crtc_id;
- int x, y;
- xcb_randr_rotation_t rotation;
- xcb_randr_mode_t mode;
-
- crtc_mode = crtc_assignment->mode;
-
- n_output_ids = crtc_assignment->outputs->len;
- output_ids = g_new (xcb_randr_output_t, n_output_ids);
-
- for (j = 0; j < n_output_ids; j++)
- {
- MetaOutput *output;
- MetaOutputAssignment *output_assignment;
-
- output = ((MetaOutput**)crtc_assignment->outputs->pdata)[j];
-
- to_configure_outputs = g_list_remove (to_configure_outputs,
- output);
-
- output_assignment = meta_find_output_assignment (outputs,
- n_outputs,
- output);
- meta_output_assign_crtc (output, crtc, output_assignment);
-
- output_ids[j] = meta_output_get_id (output);
- }
-
- crtc_id = (xcb_randr_crtc_t) meta_crtc_get_id (crtc);
- x = (int) roundf (crtc_assignment->layout.origin.x);
- y = (int) roundf (crtc_assignment->layout.origin.y);
- rotation =
- meta_monitor_transform_to_xrandr (crtc_assignment->transform);
- mode = meta_crtc_mode_get_id (crtc_mode);
- if (!xrandr_set_crtc_config (manager_xrandr,
- crtc,
- save_timestamp,
- crtc_id,
- XCB_CURRENT_TIME,
- x, y,
- mode,
- rotation,
- output_ids, n_output_ids))
- {
- const MetaCrtcModeInfo *crtc_mode_info =
- meta_crtc_mode_get_info (crtc_mode);
-
- meta_warning ("Configuring CRTC %d with mode %d (%d x %d @ %f) at position %d, %d and transform %u failed",
- (unsigned) meta_crtc_get_id (crtc),
- (unsigned) mode,
- crtc_mode_info->width, crtc_mode_info->height,
- (float) crtc_mode_info->refresh_rate,
- (int) roundf (crtc_assignment->layout.origin.x),
- (int) roundf (crtc_assignment->layout.origin.y),
- crtc_assignment->transform);
- continue;
- }
-
- meta_crtc_set_config (crtc,
- &crtc_assignment->layout,
- crtc_mode,
- crtc_assignment->transform);
- }
- }
-
- for (i = 0; i < n_outputs; i++)
- {
- MetaOutputAssignment *output_assignment = outputs[i];
- MetaOutput *output = output_assignment->output;
-
- meta_output_xrandr_apply_mode (META_OUTPUT_XRANDR (output));
- }
-
- g_list_foreach (to_configure_outputs,
- (GFunc) meta_output_unassign_crtc,
- NULL);
-
-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_rebuild_derived (MetaMonitorManager *manager,
- MetaMonitorsConfig *config)
-{
- MetaMonitorManagerXrandr *manager_xrandr =
- META_MONITOR_MANAGER_XRANDR (manager);
-
- g_clear_pointer (&manager_xrandr->supported_scales, g_free);
- meta_monitor_manager_rebuild_derived (manager, config);
-}
-
-static gboolean
-meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *manager,
- MetaMonitorsConfig *config,
- MetaMonitorsConfigMethod method,
- GError **error)
-{
- GPtrArray *crtc_assignments;
- GPtrArray *output_assignments;
-
- if (!config)
- {
- if (!manager->in_init)
- apply_crtc_assignments (manager, TRUE, NULL, 0, NULL, 0);
-
- meta_monitor_manager_xrandr_rebuild_derived (manager, NULL);
- return TRUE;
- }
-
- if (!meta_monitor_config_manager_assign (manager, config,
- &crtc_assignments,
- &output_assignments,
- error))
- return FALSE;
-
- if (method != META_MONITORS_CONFIG_METHOD_VERIFY)
- {
- /*
- * 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 (is_assignments_changed (manager,
- (MetaCrtcAssignment **) crtc_assignments->pdata,
- crtc_assignments->len,
- (MetaOutputAssignment **) output_assignments->pdata,
- output_assignments->len))
- {
- apply_crtc_assignments (manager,
- TRUE,
- (MetaCrtcAssignment **) crtc_assignments->pdata,
- crtc_assignments->len,
- (MetaOutputAssignment **) output_assignments->pdata,
- output_assignments->len);
- }
- else
- {
- meta_monitor_manager_xrandr_rebuild_derived (manager, config);
- }
- }
-
- g_ptr_array_free (crtc_assignments, TRUE);
- g_ptr_array_free (output_assignments, TRUE);
-
- return TRUE;
-}
-
-static void
-meta_monitor_manager_xrandr_change_backlight (MetaMonitorManager *manager,
- MetaOutput *output,
- gint value)
-{
- meta_output_xrandr_change_backlight (META_OUTPUT_XRANDR (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) meta_crtc_get_id (crtc));
-
- *size = gamma->size;
- *red = g_memdup2 (gamma->red, sizeof (unsigned short) * gamma->size);
- *green = g_memdup2 (gamma->green, sizeof (unsigned short) * gamma->size);
- *blue = g_memdup2 (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) meta_crtc_get_id (crtc),
- 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 (manager_xrandr->has_randr15 == FALSE)
- 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] = meta_output_get_id (output);
- }
-
- 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 (manager_xrandr->has_randr15 == FALSE)
- 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)
-{
- XRRMonitorInfo *m;
- int n, i;
-
- if (manager_xrandr->has_randr15 == FALSE)
- 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 ((meta_crtc_get_all_transforms (crtc) & transform) ==
- transform);
-
- return TRUE;
-}
-
-static float
-meta_monitor_manager_xrandr_calculate_monitor_mode_scale (MetaMonitorManager *manager,
- MetaMonitor *monitor,
- MetaMonitorMode *monitor_mode)
-{
- return meta_monitor_calculate_mode_scale (monitor, monitor_mode);
-}
-
-static void
-add_supported_scale (GArray *supported_scales,
- float scale)
-{
- unsigned int i;
-
- for (i = 0; i < supported_scales->len; i++)
- {
- float supported_scale = g_array_index (supported_scales, float, i);
-
- if (scale == supported_scale)
- return;
- }
-
- g_array_append_val (supported_scales, scale);
-}
-
-static int
-compare_scales (gconstpointer a,
- gconstpointer b)
-{
- float f = *(float *) a - *(float *) b;
-
- if (f < 0)
- return -1;
- if (f > 0)
- return 1;
- return 0;
-}
-
-static void
-ensure_supported_monitor_scales (MetaMonitorManager *manager)
-{
- MetaMonitorManagerXrandr *manager_xrandr =
- META_MONITOR_MANAGER_XRANDR (manager);
- MetaMonitorScalesConstraint constraints;
- GList *l;
- GArray *supported_scales;
-
- if (manager_xrandr->supported_scales)
- return;
-
- constraints = META_MONITOR_SCALES_CONSTRAINT_NO_FRAC;
- supported_scales = g_array_new (FALSE, FALSE, sizeof (float));
-
- for (l = manager->monitors; l; l = l->next)
- {
- MetaMonitor *monitor = l->data;
- MetaMonitorMode *monitor_mode;
- float *monitor_scales;
- int n_monitor_scales;
- int i;
-
- monitor_mode = meta_monitor_get_preferred_mode (monitor);
- monitor_scales =
- meta_monitor_calculate_supported_scales (monitor,
- monitor_mode,
- constraints,
- &n_monitor_scales);
-
- for (i = 0; i < n_monitor_scales; i++)
- add_supported_scale (supported_scales, monitor_scales[i]);
- g_array_sort (supported_scales, compare_scales);
- g_free (monitor_scales);
- }
-
- manager_xrandr->supported_scales = (float *) supported_scales->data;
- manager_xrandr->n_supported_scales = supported_scales->len;
- g_array_free (supported_scales, FALSE);
-}
-
-static float *
-meta_monitor_manager_xrandr_calculate_supported_scales (MetaMonitorManager *manager,
- MetaLogicalMonitorLayoutMode layout_mode,
- MetaMonitor *monitor,
- MetaMonitorMode *monitor_mode,
- int *n_supported_scales)
-{
- MetaMonitorManagerXrandr *manager_xrandr =
- META_MONITOR_MANAGER_XRANDR (manager);
-
- ensure_supported_monitor_scales (manager);
-
- *n_supported_scales = manager_xrandr->n_supported_scales;
- return g_memdup2 (manager_xrandr->supported_scales,
- manager_xrandr->n_supported_scales * sizeof (float));
-}
-
-static MetaMonitorManagerCapability
-meta_monitor_manager_xrandr_get_capabilities (MetaMonitorManager *manager)
-{
- return META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED;
-}
-
-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 MetaLogicalMonitorLayoutMode
-meta_monitor_manager_xrandr_get_default_layout_mode (MetaMonitorManager *manager)
-{
- return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
-}
-
-static void
-meta_monitor_manager_xrandr_set_output_ctm (MetaOutput *output,
- const MetaOutputCtm *ctm)
-{
- meta_output_xrandr_set_ctm (META_OUTPUT_XRANDR (output), ctm);
-}
-
-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);
-
- 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);
-
- manager_xrandr->has_randr15 = FALSE;
- XRRQueryVersion (manager_xrandr->xdisplay, &major_version,
- &minor_version);
- if (major_version > 1 ||
- (major_version == 1 &&
- minor_version >= 5))
- {
- manager_xrandr->has_randr15 = TRUE;
- manager_xrandr->tiled_monitor_atoms = g_hash_table_new (NULL, NULL);
- }
- meta_monitor_manager_xrandr_init_monitors (manager_xrandr);
- }
-
- 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_free (manager_xrandr->supported_scales);
-
- 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->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;
- manager_class->set_output_ctm = meta_monitor_manager_xrandr_set_output_ctm;
-
- 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_reconfigure (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_xrandr_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
deleted file mode 100644
index d55b3d2b8..000000000
--- a/src/backends/x11/meta-monitor-manager-xrandr.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- 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_has_randr15 (MetaMonitorManagerXrandr *manager_xrandr);
-
-gboolean meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager,
- XEvent *event);
-
-#endif /* META_MONITOR_MANAGER_XRANDR_H */
diff --git a/src/backends/x11/meta-output-xrandr.c b/src/backends/x11/meta-output-xrandr.c
deleted file mode 100644
index 7265624f4..000000000
--- a/src/backends/x11/meta-output-xrandr.c
+++ /dev/null
@@ -1,987 +0,0 @@
-/* -*- 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.
- * Copyright (C) 2020 NVIDIA 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 "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"
-
-struct _MetaOutputXrandr
-{
- MetaOutput parent;
-
- gboolean ctm_initialized;
- MetaOutputCtm ctm;
-};
-
-G_DEFINE_TYPE (MetaOutputXrandr, meta_output_xrandr, META_TYPE_OUTPUT)
-
-static Display *
-xdisplay_from_gpu (MetaGpu *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);
-
- return meta_monitor_manager_xrandr_get_xdisplay (monitor_manager_xrandr);
-}
-
-static Display *
-xdisplay_from_output (MetaOutput *output)
-{
- return xdisplay_from_gpu (meta_output_get_gpu (output));
-}
-
-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) meta_output_get_id (output),
- 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) meta_output_get_id (output),
- 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;
- const MetaCrtcConfig *crtc_config;
- const MetaCrtcModeInfo *crtc_mode_info;
- uint32_t border_value;
-
- crtc = meta_output_get_assigned_crtc (output);
- crtc_config = meta_crtc_get_config (crtc);
- crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode);
-
- prop = XInternAtom (xdisplay, "underscan hborder", False);
- border_value = crtc_mode_info->width * 0.05;
-
- xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
- (XID) meta_output_get_id (output),
- prop, XCB_ATOM_INTEGER, 32,
- XCB_PROP_MODE_REPLACE,
- 1, &border_value);
-
- prop = XInternAtom (xdisplay, "underscan vborder", False);
- border_value = crtc_mode_info->height * 0.05;
-
- xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
- (XID) meta_output_get_id (output),
- prop, XCB_ATOM_INTEGER, 32,
- XCB_PROP_MODE_REPLACE,
- 1, &border_value);
- }
-}
-
-void
-meta_output_xrandr_apply_mode (MetaOutputXrandr *output_xrandr)
-{
- MetaOutput *output = META_OUTPUT (output_xrandr);
- Display *xdisplay = xdisplay_from_output (output);
-
- if (meta_output_is_primary (output))
- {
- XRRSetOutputPrimary (xdisplay, DefaultRootWindow (xdisplay),
- (XID) meta_output_get_id (output));
- }
-
- output_set_presentation_xrandr (output, meta_output_is_presentation (output));
-
- if (meta_output_get_info (output)->supports_underscanning)
- {
- output_set_underscanning_xrandr (output,
- meta_output_is_underscanning (output));
- }
-}
-
-static int
-normalize_backlight (MetaOutput *output,
- int hw_value)
-{
- const MetaOutputInfo *output_info = meta_output_get_info (output);
-
- return round ((double) (hw_value - output_info->backlight_min) /
- (output_info->backlight_max - output_info->backlight_min) * 100.0);
-}
-
-void
-meta_output_xrandr_change_backlight (MetaOutputXrandr *output_xrandr,
- int value)
-{
- MetaOutput *output = META_OUTPUT (output_xrandr);
- const MetaOutputInfo *output_info = meta_output_get_info (output);
- Display *xdisplay = xdisplay_from_output (output);
- Atom atom;
- int hw_value;
-
- hw_value = round ((double) value / 100.0 * output_info->backlight_max +
- output_info->backlight_min);
-
- atom = XInternAtom (xdisplay, "Backlight", False);
-
- xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
- (XID) meta_output_get_id (output),
- atom, XCB_ATOM_INTEGER, 32,
- XCB_PROP_MODE_REPLACE,
- 1, &hw_value);
-
- /* We're not selecting for property notifies, so update the value immediately */
- meta_output_set_backlight (output, normalize_backlight (output, hw_value));
-}
-
-static gboolean
-ctm_is_equal (const MetaOutputCtm *ctm1,
- const MetaOutputCtm *ctm2)
-{
- int i;
-
- for (i = 0; i < 9; i++)
- {
- if (ctm1->matrix[i] != ctm2->matrix[i])
- return FALSE;
- }
-
- return TRUE;
-}
-
-void
-meta_output_xrandr_set_ctm (MetaOutputXrandr *output_xrandr,
- const MetaOutputCtm *ctm)
-{
- if (!output_xrandr->ctm_initialized ||
- !ctm_is_equal (ctm, &output_xrandr->ctm))
- {
- MetaOutput *output = META_OUTPUT (output_xrandr);
- Display *xdisplay = xdisplay_from_output (output);
- Atom ctm_atom = XInternAtom (xdisplay, "CTM", False);
-
- xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
- (XID) meta_output_get_id (output),
- ctm_atom, XCB_ATOM_INTEGER, 32,
- XCB_PROP_MODE_REPLACE,
- 18, &ctm->matrix);
-
- output_xrandr->ctm = *ctm;
- output_xrandr->ctm_initialized = TRUE;
- }
-}
-
-static gboolean
-output_get_integer_property (Display *xdisplay,
- RROutput output_id,
- const char *propname,
- gint *value)
-{
- 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_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 (Display *xdisplay,
- RROutput output_id,
- const char *propname)
-{
- 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_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) meta_output_get_id (output),
- 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) meta_output_get_id (output),
- 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 (Display *xdisplay,
- RROutput output_id)
-{
- 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_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_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 gboolean
-output_get_supports_color_transform_xrandr (Display *xdisplay,
- RROutput output_id)
-{
- Atom atom, actual_type;
- int actual_format;
- unsigned long nitems, bytes_after;
- g_autofree unsigned char *buffer = NULL;
-
- atom = XInternAtom (xdisplay, "CTM", False);
- XRRGetOutputProperty (xdisplay,
- (XID) output_id,
- atom,
- 0, G_MAXLONG, False, False, XA_INTEGER,
- &actual_type, &actual_format,
- &nitems, &bytes_after, &buffer);
-
- /*
- * X's CTM property is 9 64-bit integers represented as an array of 18 32-bit
- * integers.
- */
- return (actual_type == XA_INTEGER &&
- actual_format == 32 &&
- nitems == 18);
-}
-
-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) meta_output_get_id (output),
- 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_info_init_backlight_limits_xrandr (MetaOutputInfo *output_info,
- Display *xdisplay,
- xcb_randr_output_t output_id)
-{
- 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,
- output_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", output_info->name);
- return;
- }
-
- int32_t *values = xcb_randr_query_output_property_valid_values (reply);
- output_info->backlight_min = values[0];
- output_info->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_memdup2 (prop, nitems);
- if (len)
- *len = nitems;
- }
- else
- {
- result = NULL;
- }
-
- XFree (prop);
-
- return result;
-}
-
-static GBytes *
-read_xrandr_edid (Display *xdisplay,
- RROutput output_id)
-{
- Atom edid_atom;
- guint8 *result;
- gsize len;
-
- edid_atom = XInternAtom (xdisplay, "EDID", FALSE);
- result = get_edid_property (xdisplay, output_id, edid_atom, &len);
-
- if (!result)
- {
- edid_atom = XInternAtom (xdisplay, "EDID_DATA", FALSE);
- result = get_edid_property (xdisplay, output_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;
-}
-
-GBytes *
-meta_output_xrandr_read_edid (MetaOutput *output)
-{
- Display *xdisplay = xdisplay_from_output (output);
- RROutput output_id = (RROutput) meta_output_get_id (output);
-
- return read_xrandr_edid (xdisplay, output_id);
-}
-
-static gboolean
-output_get_hotplug_mode_update (Display *xdisplay,
- RROutput output_id)
-{
- return output_get_property_exists (xdisplay, output_id, "hotplug_mode_update");
-}
-
-static gint
-output_get_suggested_x (Display *xdisplay,
- RROutput output_id)
-{
- gint val;
- if (output_get_integer_property (xdisplay, output_id, "suggested X", &val))
- return val;
-
- return -1;
-}
-
-static gint
-output_get_suggested_y (Display *xdisplay,
- RROutput output_id)
-{
- gint val;
- if (output_get_integer_property (xdisplay, output_id, "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 (Display *xdisplay,
- RROutput output_id)
-{
- 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_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_info_get_connector_type_from_name (const MetaOutputInfo *output_info)
-{
- const char *name = output_info->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_info_get_connector_type (MetaOutputInfo *output_info,
- Display *xdisplay,
- RROutput output_id)
-{
- 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 (xdisplay, output_id);
- if (ret != META_CONNECTOR_TYPE_Unknown)
- return ret;
-
- /* Fall back to heuristics based on the output name. */
- ret = output_info_get_connector_type_from_name (output_info);
- if (ret != META_CONNECTOR_TYPE_Unknown)
- return ret;
-
- return META_CONNECTOR_TYPE_Unknown;
-}
-
-static gint
-output_get_panel_orientation_transform (Display *xdisplay,
- RROutput output_id)
-{
- 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_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_info_init_tile_info (MetaOutputInfo *output_info,
- Display *xdisplay,
- RROutput output_id)
-{
- Atom tile_atom;
- unsigned char *prop;
- unsigned long nitems, bytes_after;
- int actual_format;
- Atom actual_type;
-
- tile_atom = XInternAtom (xdisplay, "TILE", FALSE);
- XRRGetOutputProperty (xdisplay,
- (XID) output_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_info->tile_info.group_id = values[0];
- output_info->tile_info.flags = values[1];
- output_info->tile_info.max_h_tiles = values[2];
- output_info->tile_info.max_v_tiles = values[3];
- output_info->tile_info.loc_h_tile = values[4];
- output_info->tile_info.loc_v_tile = values[5];
- output_info->tile_info.tile_w = values[6];
- output_info->tile_info.tile_h = values[7];
- }
- XFree (prop);
-}
-
-
-static void
-output_info_init_modes (MetaOutputInfo *output_info,
- MetaGpu *gpu,
- XRROutputInfo *xrandr_output)
-{
- unsigned int i;
- unsigned int n_actual_modes;
-
- output_info->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) meta_crtc_mode_get_id (mode))
- {
- output_info->modes[n_actual_modes] = mode;
- n_actual_modes += 1;
- break;
- }
- }
- }
- output_info->n_modes = n_actual_modes;
- if (n_actual_modes > 0)
- output_info->preferred_mode = output_info->modes[0];
-}
-
-static void
-output_info_init_crtcs (MetaOutputInfo *output_info,
- MetaGpu *gpu,
- XRROutputInfo *xrandr_output)
-{
- unsigned int i;
- unsigned int n_actual_crtcs;
- GList *l;
-
- output_info->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) meta_crtc_get_id (crtc) == xrandr_output->crtcs[i])
- {
- output_info->possible_crtcs[n_actual_crtcs] = crtc;
- n_actual_crtcs += 1;
- break;
- }
- }
- }
- output_info->n_possible_crtcs = n_actual_crtcs;
-}
-
-static MetaCrtc *
-find_assigned_crtc (MetaGpu *gpu,
- XRROutputInfo *xrandr_output)
-{
- GList *l;
-
- for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
- {
- MetaCrtc *crtc = l->data;
-
- if ((XID) meta_crtc_get_id (crtc) == xrandr_output->crtc)
- return crtc;
- }
-
- return NULL;
-}
-
-MetaOutputXrandr *
-meta_output_xrandr_new (MetaGpuXrandr *gpu_xrandr,
- XRROutputInfo *xrandr_output,
- RROutput output_id,
- RROutput primary_output)
-{
- 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);
- g_autoptr (MetaOutputInfo) output_info = NULL;
- MetaOutput *output;
- GBytes *edid;
- MetaCrtc *assigned_crtc;
- unsigned int i;
-
- output_info = meta_output_info_new ();
-
- output_info->name = g_strdup (xrandr_output->name);
-
- edid = read_xrandr_edid (xdisplay, output_id);
- meta_output_info_parse_edid (output_info, edid);
- g_bytes_unref (edid);
-
- output_info->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
- output_info->hotplug_mode_update = output_get_hotplug_mode_update (xdisplay,
- output_id);
- output_info->suggested_x = output_get_suggested_x (xdisplay, output_id);
- output_info->suggested_y = output_get_suggested_y (xdisplay, output_id);
- output_info->connector_type = output_info_get_connector_type (output_info,
- xdisplay,
- output_id);
- output_info->panel_orientation_transform =
- output_get_panel_orientation_transform (xdisplay, output_id);
-
- if (meta_monitor_transform_is_rotated (
- output_info->panel_orientation_transform))
- {
- output_info->width_mm = xrandr_output->mm_height;
- output_info->height_mm = xrandr_output->mm_width;
- }
- else
- {
- output_info->width_mm = xrandr_output->mm_width;
- output_info->height_mm = xrandr_output->mm_height;
- }
-
- if (meta_monitor_manager_xrandr_has_randr15 (monitor_manager_xrandr))
- output_info_init_tile_info (output_info, xdisplay, output_id);
- output_info_init_modes (output_info, gpu, xrandr_output);
- output_info_init_crtcs (output_info, gpu, xrandr_output);
-
- output_info->n_possible_clones = xrandr_output->nclone;
- output_info->possible_clones = g_new0 (MetaOutput *,
- output_info->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_info->possible_clones[i] = GINT_TO_POINTER (xrandr_output->clones[i]);
- }
-
- output_info->supports_underscanning =
- output_get_supports_underscanning_xrandr (xdisplay, output_id);
- output_info->supports_color_transform =
- output_get_supports_color_transform_xrandr (xdisplay, output_id);
- output_info_init_backlight_limits_xrandr (output_info, xdisplay, output_id);
-
- output = g_object_new (META_TYPE_OUTPUT_XRANDR,
- "id", (uint64_t) output_id,
- "gpu", gpu_xrandr,
- "info", output_info,
- NULL);
-
- assigned_crtc = find_assigned_crtc (gpu, xrandr_output);
- if (assigned_crtc)
- {
- MetaOutputAssignment output_assignment;
-
- output_assignment = (MetaOutputAssignment) {
- .is_primary = (XID) meta_output_get_id (output) == primary_output,
- .is_presentation = output_get_presentation_xrandr (output),
- .is_underscanning = output_get_underscanning_xrandr (output),
- };
- meta_output_assign_crtc (output, assigned_crtc, &output_assignment);
- }
- else
- {
- meta_output_unassign_crtc (output);
- }
-
- if (!(output_info->backlight_min == 0 && output_info->backlight_max == 0))
- meta_output_set_backlight (output, output_get_backlight_xrandr (output));
-
- if (output_info->n_modes == 0 || output_info->n_possible_crtcs == 0)
- {
- g_object_unref (output);
- return NULL;
- }
- else
- {
- return META_OUTPUT_XRANDR (output);
- }
-}
-
-static void
-meta_output_xrandr_init (MetaOutputXrandr *output_xrandr)
-{
-}
-
-static void
-meta_output_xrandr_class_init (MetaOutputXrandrClass *klass)
-{
-}
diff --git a/src/backends/x11/meta-output-xrandr.h b/src/backends/x11/meta-output-xrandr.h
deleted file mode 100644
index ec5104f30..000000000
--- a/src/backends/x11/meta-output-xrandr.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2017 Red Hat
- * Copyright (C) 2020 NVIDIA 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_OUTPUT_XRANDR_H
-#define META_OUTPUT_XRANDR_H
-
-#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"
-
-#define META_TYPE_OUTPUT_XRANDR (meta_output_xrandr_get_type ())
-G_DECLARE_FINAL_TYPE (MetaOutputXrandr, meta_output_xrandr,
- META, OUTPUT_XRANDR,
- MetaOutput)
-
-void meta_output_xrandr_apply_mode (MetaOutputXrandr *output_xrandr);
-
-void meta_output_xrandr_change_backlight (MetaOutputXrandr *output_xrandr,
- int value);
-
-void meta_output_xrandr_set_ctm (MetaOutputXrandr *output_xrandr,
- const MetaOutputCtm *ctm);
-
-GBytes * meta_output_xrandr_read_edid (MetaOutput *output_xrandr);
-
-MetaOutputXrandr * meta_output_xrandr_new (MetaGpuXrandr *gpu_xrandr,
- XRROutputInfo *xrandr_output,
- RROutput output_id,
- RROutput primary_output);
-
-#endif /* META_OUTPUT_XRANDR_H */
diff --git a/src/backends/x11/meta-renderer-x11.c b/src/backends/x11/meta-renderer-x11.c
deleted file mode 100644
index e31faff53..000000000
--- a/src/backends/x11/meta-renderer-x11.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -*- 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-clutter-backend-x11.h"
-#include "backends/x11/meta-renderer-x11.h"
-#include "cogl/cogl-xlib.h"
-#include "cogl/cogl.h"
-#include "core/boxes-private.h"
-#include "meta/meta-backend.h"
-#include "meta/util.h"
-
-#ifdef COGL_HAS_EGL_SUPPORT
-#include "cogl/winsys/cogl-winsys-egl-x11-private.h"
-#endif
-#ifdef COGL_HAS_GLX_SUPPORT
-#include "cogl/winsys/cogl-winsys-glx-private.h"
-#endif
-
-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 = meta_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
deleted file mode 100644
index 5ec0d4bc4..000000000
--- a/src/backends/x11/meta-renderer-x11.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- 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/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c
deleted file mode 100644
index 2f2637ac8..000000000
--- a/src/backends/x11/meta-seat-x11.c
+++ /dev/null
@@ -1,2422 +0,0 @@
-/*
- * 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>
- */
-#include "config.h"
-
-#include <linux/input-event-codes.h>
-#include <X11/extensions/XInput2.h>
-#include <X11/extensions/XKB.h>
-
-#include "backends/meta-input-settings-private.h"
-#include "backends/x11/meta-backend-x11.h"
-#include "backends/x11/meta-clutter-backend-x11.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 "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,
-};
-
-typedef struct _MetaTouchInfo MetaTouchInfo;
-
-struct _MetaTouchInfo
-{
- ClutterEventSequence *sequence;
- double x;
- double y;
-};
-
-struct _MetaSeatX11
-{
- ClutterSeat parent_instance;
- ClutterInputDevice *core_pointer;
- ClutterInputDevice *core_keyboard;
- GList *devices;
- GHashTable *devices_by_id;
- GHashTable *tools_by_serial;
- GHashTable *touch_coords;
- MetaKeymapX11 *keymap;
-
- int pointer_id;
- int keyboard_id;
- int opcode;
- guint has_touchscreens : 1;
- guint touch_mode : 1;
- guint has_pointer_focus : 1;
-};
-
-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 */
- "Abs Y", /* CLUTTER_INPUT_AXIS_Y */
- "Abs Pressure", /* CLUTTER_INPUT_AXIS_PRESSURE */
- "Abs Tilt X", /* CLUTTER_INPUT_AXIS_XTILT */
- "Abs Tilt Y", /* CLUTTER_INPUT_AXIS_YTILT */
- "Abs Wheel", /* CLUTTER_INPUT_AXIS_WHEEL */
- "Abs Distance", /* CLUTTER_INPUT_AXIS_DISTANCE */
-};
-
-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
-{
- PAD_AXIS_FIRST = 3, /* First axes are always x/y/pressure, ignored in pads */
- PAD_AXIS_STRIP1 = PAD_AXIS_FIRST,
- PAD_AXIS_STRIP2,
- PAD_AXIS_RING1,
- PAD_AXIS_RING2,
-};
-
-#define N_AXIS_ATOMS G_N_ELEMENTS (clutter_input_axis_atom_names)
-
-static Atom clutter_input_axis_atoms[N_AXIS_ATOMS] = { 0, };
-
-static void
-translate_valuator_class (Display *xdisplay,
- ClutterInputDevice *device,
- XIValuatorClassInfo *class)
-{
- static gboolean atoms_initialized = FALSE;
- ClutterInputAxis i, axis = CLUTTER_INPUT_AXIS_IGNORE;
-
- if (G_UNLIKELY (!atoms_initialized))
- {
- XInternAtoms (xdisplay,
- (char **) clutter_input_axis_atom_names, N_AXIS_ATOMS,
- False,
- clutter_input_axis_atoms);
-
- atoms_initialized = TRUE;
- }
-
- for (i = 0;
- i < N_AXIS_ATOMS;
- i += 1)
- {
- if (clutter_input_axis_atoms[i] == class->label)
- {
- axis = i + 1;
- break;
- }
- }
-
- meta_input_device_x11_add_axis (device, axis,
- class->min,
- class->max,
- class->resolution);
-
- 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,
- meta_input_device_x11_get_device_id (device));
-}
-
-static void
-translate_device_classes (Display *xdisplay,
- ClutterInputDevice *device,
- XIAnyClassInfo **classes,
- int n_classes)
-{
- int i;
-
- for (i = 0; i < n_classes; i++)
- {
- XIAnyClassInfo *class_info = classes[i];
-
- switch (class_info->type)
- {
- case XIValuatorClass:
- translate_valuator_class (xdisplay, device,
- (XIValuatorClassInfo *) class_info);
- break;
-
- case XIScrollClass:
- {
- XIScrollClassInfo *scroll_info = (XIScrollClassInfo *) class_info;
- ClutterScrollDirection direction;
-
- if (scroll_info->scroll_type == XIScrollTypeVertical)
- direction = CLUTTER_SCROLL_DOWN;
- else
- direction = CLUTTER_SCROLL_RIGHT;
-
- g_debug ("Scroll valuator %d: %s, increment: %f",
- scroll_info->number,
- scroll_info->scroll_type == XIScrollTypeVertical
- ? "vertical"
- : "horizontal",
- scroll_info->increment);
-
- meta_input_device_x11_add_scroll_info (device,
- scroll_info->number,
- direction,
- scroll_info->increment);
- }
- break;
-
- default:
- break;
- }
- }
-}
-
-static gboolean
-is_touch_device (XIAnyClassInfo **classes,
- int n_classes,
- ClutterInputDeviceType *device_type,
- uint32_t *n_touch_points)
-{
- int i;
-
- for (i = 0; i < n_classes; i++)
- {
- XITouchClassInfo *class = (XITouchClassInfo *) classes[i];
-
- if (class->type != XITouchClass)
- continue;
-
- if (class->num_touches > 0)
- {
- if (class->mode == XIDirectTouch)
- *device_type = CLUTTER_TOUCHSCREEN_DEVICE;
- else if (class->mode == XIDependentTouch)
- *device_type = CLUTTER_TOUCHPAD_DEVICE;
- else
- continue;
-
- *n_touch_points = class->num_touches;
-
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static gboolean
-is_touchpad_device (XIDeviceInfo *info)
-{
- gulong nitems, bytes_after;
- uint32_t *data = NULL;
- int rc, format;
- Atom type;
- Atom prop;
-
- prop = XInternAtom (meta_clutter_x11_get_default_display (),
- "libinput Tapping Enabled", True);
- if (prop == None)
- return FALSE;
-
- meta_clutter_x11_trap_x_errors ();
- rc = XIGetProperty (meta_clutter_x11_get_default_display (),
- info->deviceid,
- prop,
- 0, 1, False, XA_INTEGER, &type, &format, &nitems, &bytes_after,
- (guchar **) &data);
- meta_clutter_x11_untrap_x_errors ();
-
- /* We don't care about the data */
- XFree (data);
-
- if (rc != Success || type != XA_INTEGER || format != 8 || nitems != 1)
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-get_device_ids (XIDeviceInfo *info,
- char **vendor_id,
- char **product_id)
-{
- gulong nitems, bytes_after;
- uint32_t *data = NULL;
- int rc, format;
- Atom type;
-
- meta_clutter_x11_trap_x_errors ();
- rc = XIGetProperty (meta_clutter_x11_get_default_display (),
- info->deviceid,
- XInternAtom (meta_clutter_x11_get_default_display (), "Device Product ID", False),
- 0, 2, False, XA_INTEGER, &type, &format, &nitems, &bytes_after,
- (guchar **) &data);
- meta_clutter_x11_untrap_x_errors ();
-
- if (rc != Success || type != XA_INTEGER || format != 32 || nitems != 2)
- {
- XFree (data);
- return FALSE;
- }
-
- if (vendor_id)
- *vendor_id = g_strdup_printf ("%.4x", data[0]);
- if (product_id)
- *product_id = g_strdup_printf ("%.4x", data[1]);
-
- XFree (data);
-
- return TRUE;
-}
-
-static char *
-get_device_node_path (XIDeviceInfo *info)
-{
- gulong nitems, bytes_after;
- guchar *data;
- int rc, format;
- Atom prop, type;
- char *node_path;
-
- prop = XInternAtom (meta_clutter_x11_get_default_display (), "Device Node", False);
- if (prop == None)
- return NULL;
-
- meta_clutter_x11_trap_x_errors ();
-
- rc = XIGetProperty (meta_clutter_x11_get_default_display (),
- info->deviceid, prop, 0, 1024, False,
- XA_STRING, &type, &format, &nitems, &bytes_after,
- (guchar **) &data);
-
- if (meta_clutter_x11_untrap_x_errors ())
- return NULL;
-
- if (rc != Success || type != XA_STRING || format != 8)
- {
- XFree (data);
- return FALSE;
- }
-
- node_path = g_strdup ((char *) data);
- XFree (data);
-
- return node_path;
-}
-
-static void
-get_pad_features (XIDeviceInfo *info,
- uint32_t *n_rings,
- uint32_t *n_strips)
-{
- int i, rings = 0, strips = 0;
-
- for (i = PAD_AXIS_FIRST; i < info->num_classes; i++)
- {
- XIValuatorClassInfo *valuator = (XIValuatorClassInfo*) info->classes[i];
- int axis = valuator->number;
-
- if (valuator->type != XIValuatorClass)
- continue;
- if (valuator->max <= 1)
- continue;
-
- /* Ring/strip axes are fixed in pad devices as handled by the
- * wacom driver. Match those to detect pad features.
- */
- if (axis == PAD_AXIS_STRIP1 || axis == PAD_AXIS_STRIP2)
- strips++;
- else if (axis == PAD_AXIS_RING1 || axis == PAD_AXIS_RING2)
- rings++;
- }
-
- *n_rings = rings;
- *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 (meta_clutter_x11_get_default_display (), "Wacom Tool Type", True);
- if (prop == None)
- return FALSE;
-
- meta_clutter_x11_trap_x_errors ();
- rc = XIGetProperty (meta_clutter_x11_get_default_display (),
- info->deviceid,
- prop,
- 0, 1, False, XA_ATOM, &type, &format, &nitems, &bytes_after,
- (guchar **) &data);
- meta_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 (meta_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 (MetaSeatX11 *seat_x11,
- ClutterBackend *backend,
- XIDeviceInfo *info)
-{
- ClutterInputDeviceType source, touch_source;
- ClutterInputDevice *retval;
- ClutterInputMode mode;
- 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 (info))
- {
- source = CLUTTER_TOUCHPAD_DEVICE;
- }
- else if (info->use == XISlavePointer &&
- is_touch_device (info->classes, info->num_classes,
- &touch_source,
- &num_touches))
- {
- source = touch_source;
- }
- else if (!guess_source_from_wacom_type (info, &source))
- {
- char *name;
-
- name = g_ascii_strdown (info->name, -1);
-
- if (strstr (name, "eraser") != NULL)
- source = CLUTTER_ERASER_DEVICE;
- else if (strstr (name, "cursor") != NULL)
- source = CLUTTER_CURSOR_DEVICE;
- else if (strstr (name, " pad") != NULL)
- source = CLUTTER_PAD_DEVICE;
- else if (strstr (name, "wacom") != NULL || strstr (name, "pen") != NULL)
- source = CLUTTER_PEN_DEVICE;
- else if (strstr (name, "touchpad") != NULL)
- source = CLUTTER_TOUCHPAD_DEVICE;
- else
- source = CLUTTER_POINTER_DEVICE;
-
- g_free (name);
- }
-
- switch (info->use)
- {
- case XIMasterKeyboard:
- case XIMasterPointer:
- mode = CLUTTER_INPUT_MODE_LOGICAL;
- break;
-
- case XISlaveKeyboard:
- case XISlavePointer:
- mode = CLUTTER_INPUT_MODE_PHYSICAL;
- break;
-
- case XIFloatingSlave:
- default:
- mode = CLUTTER_INPUT_MODE_FLOATING;
- break;
- }
-
- if (info->use != XIMasterKeyboard &&
- info->use != XIMasterPointer)
- {
- get_device_ids (info, &vendor_id, &product_id);
- node_path = get_device_node_path (info);
- }
-
- if (source == CLUTTER_PAD_DEVICE)
- get_pad_features (info, &num_rings, &num_strips);
-
- retval = g_object_new (META_TYPE_INPUT_DEVICE_X11,
- "name", info->name,
- "id", info->deviceid,
- "has-cursor", (info->use == XIMasterPointer),
- "device-type", source,
- "device-mode", mode,
- "backend", backend,
- "vendor-id", vendor_id,
- "product-id", product_id,
- "device-node", node_path,
- "n-rings", num_rings,
- "n-strips", num_strips,
- "n-mode-groups", MAX (num_rings, num_strips),
- "seat", seat_x11,
- NULL);
-
- translate_device_classes (meta_clutter_x11_get_default_display (), retval,
- info->classes,
- info->num_classes);
-
- g_free (vendor_id);
- g_free (product_id);
- g_free (node_path);
-
- g_debug ("Created device '%s' (id: %d, has-cursor: %s)",
- info->name,
- info->deviceid,
- info->use == XIMasterPointer ? "yes" : "no");
-
- return retval;
-}
-
-static void
-pad_passive_button_grab (ClutterInputDevice *device)
-{
- XIGrabModifiers xi_grab_mods = { XIAnyModifier, };
- XIEventMask xi_event_mask;
- int device_id, rc;
-
- device_id = meta_input_device_x11_get_device_id (device);
-
- xi_event_mask.deviceid = device_id;
- xi_event_mask.mask_len = XIMaskLen (XI_LASTEVENT);
- xi_event_mask.mask = g_new0 (unsigned char, xi_event_mask.mask_len);
-
- XISetMask (xi_event_mask.mask, XI_Motion);
- XISetMask (xi_event_mask.mask, XI_ButtonPress);
- XISetMask (xi_event_mask.mask, XI_ButtonRelease);
-
- meta_clutter_x11_trap_x_errors ();
- rc = XIGrabButton (meta_clutter_x11_get_default_display (),
- device_id, XIAnyButton,
- meta_clutter_x11_get_root_window (), None,
- XIGrabModeSync, XIGrabModeSync,
- True, &xi_event_mask, 1, &xi_grab_mods);
- if (rc != 0)
- {
- g_warning ("Could not passively grab pad device: %s",
- clutter_input_device_get_device_name (device));
- }
- else
- {
- XIAllowEvents (meta_clutter_x11_get_default_display (),
- device_id, XIAsyncDevice,
- CLUTTER_CURRENT_TIME);
- }
-
- meta_clutter_x11_untrap_x_errors ();
-
- 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 (MetaSeatX11 *seat_x11,
- ClutterBackend *backend,
- XIDeviceInfo *info)
-{
- ClutterInputDevice *device;
-
- device = create_device (seat_x11, backend, info);
-
- g_hash_table_replace (seat_x11->devices_by_id,
- GINT_TO_POINTER (info->deviceid),
- device);
-
- 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)
- {
- seat_x11->core_keyboard = device;
- }
- else if ((info->use == XISlavePointer &&
- info->attachment == seat_x11->pointer_id) ||
- (info->use == XISlaveKeyboard &&
- info->attachment == seat_x11->keyboard_id))
- {
- seat_x11->devices = g_list_prepend (seat_x11->devices, device);
- }
- else
- {
- 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);
-
- return device;
-}
-
-static gboolean
-has_touchscreens (MetaSeatX11 *seat_x11)
-{
- GList *l;
-
- for (l = seat_x11->devices; l; l = l->next)
- {
- if (clutter_input_device_get_device_type (l->data) == CLUTTER_TOUCHSCREEN_DEVICE)
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-remove_device (MetaSeatX11 *seat_x11,
- 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_event_post (ClutterSeat *seat,
- const ClutterEvent *event)
-{
- MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat);
- ClutterInputDevice *device;
- MetaInputSettings *input_settings;
- gboolean is_touch;
-
- if (event->type != CLUTTER_DEVICE_ADDED &&
- event->type != CLUTTER_DEVICE_REMOVED)
- return TRUE;
-
- device = clutter_event_get_device (event);
- is_touch =
- clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE;
- input_settings = meta_backend_get_input_settings (meta_get_backend ());
-
- switch (event->type)
- {
- case CLUTTER_DEVICE_ADDED:
- meta_input_settings_add_device (input_settings, device);
- seat_x11->has_touchscreens |= is_touch;
- break;
- case CLUTTER_DEVICE_REMOVED:
- if (is_touch)
- seat_x11->has_touchscreens = has_touchscreens (seat_x11);
- meta_input_settings_remove_device (input_settings, device);
- break;
- default:
- break;
- }
-
- if (is_touch)
- update_touch_mode (seat_x11);
-
- return TRUE;
-}
-
-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 (meta_clutter_x11_get_default_display (),
- "Wacom Serial IDs", True);
- if (prop == None)
- return 0;
-
- meta_clutter_x11_trap_x_errors ();
- rc = XIGetProperty (meta_clutter_x11_get_default_display (),
- meta_input_device_x11_get_device_id (device),
- prop, 0, 4, FALSE, XA_INTEGER, &type, &format, &nitems, &bytes_after,
- (guchar **) &data);
- meta_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 (seat_x11->devices_by_id,
- GINT_TO_POINTER (ev->info[i].deviceid)))
- {
- XIDeviceInfo *info;
- int n_devices;
-
- g_debug ("Hierarchy event: device enabled");
-
- meta_clutter_x11_trap_x_errors ();
- info = XIQueryDevice (meta_clutter_x11_get_default_display (),
- ev->info[i].deviceid,
- &n_devices);
- meta_clutter_x11_untrap_x_errors ();
- if (info != NULL)
- {
- ClutterInputDevice *device;
-
- device = add_device (seat_x11, backend, &info[0]);
-
- 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)
- {
- g_autoptr (ClutterInputDevice) device = NULL;
- g_debug ("Hierarchy event: device disabled");
-
- 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))
- {
- g_debug ("Hierarchy event: physical device %s",
- (ev->info[i].flags & XISlaveAttached)
- ? "attached"
- : "detached");
- }
- }
-
- return retval;
-}
-
-static void
-translate_property_event (MetaSeatX11 *seat_x11,
- XIEvent *event)
-{
- XIPropertyEvent *xev = (XIPropertyEvent *) event;
- Atom serial_ids_prop;
- ClutterInputDevice *device;
-
- serial_ids_prop = XInternAtom (meta_clutter_x11_get_default_display (),
- "Wacom Serial IDs", True);
- if (serial_ids_prop == None)
- return;
-
- 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;
- MetaInputSettings *input_settings;
- int serial_id;
-
- 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)
- {
- 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);
- input_settings = meta_backend_get_input_settings (meta_get_backend ());
- meta_input_settings_notify_tool_change (input_settings, device, tool);
- }
-}
-
-static void
-emulate_motion (MetaSeatX11 *seat_x11,
- double x,
- double y)
-{
- ClutterInputDevice *pointer;
- ClutterEvent *event;
- ClutterStage *stage;
-
- pointer = clutter_seat_get_pointer (CLUTTER_SEAT (seat_x11));
- stage = CLUTTER_STAGE (meta_backend_get_stage (meta_get_backend ()));
-
- event = clutter_event_new (CLUTTER_MOTION);
- clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_SYNTHETIC);
- clutter_event_set_coords (event, x, y);
- clutter_event_set_device (event, pointer);
- clutter_event_set_source_device (event, NULL);
- clutter_event_set_stage (event, stage);
-
- clutter_event_put (event);
- clutter_event_free (event);
-}
-
-static void
-translate_raw_event (MetaSeatX11 *seat_x11,
- XEvent *xevent)
-{
- ClutterInputDevice *device;
- XGenericEventCookie *cookie;
- XIEvent *xi_event;
- XIRawEvent *xev;
- float x,y;
-
- 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;
-
- switch (cookie->evtype)
- {
- case XI_RawMotion:
- g_debug ("raw motion: device:%d '%s'",
- meta_input_device_x11_get_device_id (device),
- clutter_input_device_get_device_name (device));
-
- /* 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 explicitly query the pointer here...
- */
- if (meta_input_device_x11_get_pointer_location (device, &x, &y))
- {
- if (_clutter_is_input_pointer_a11y_enabled (device))
- _clutter_input_pointer_a11y_on_motion_event (device, x, y);
- if (!seat_x11->has_pointer_focus)
- emulate_motion (seat_x11, 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",
- meta_input_device_x11_get_device_id (device),
- clutter_input_device_get_device_name (device),
- xev->detail);
- if (_clutter_is_input_pointer_a11y_enabled (device))
- {
- _clutter_input_pointer_a11y_on_button_event (device,
- xev->detail,
- (cookie->evtype == XI_RawButtonPress));
- }
- break;
- }
-}
-
-static gboolean
-translate_pad_axis (ClutterInputDevice *device,
- XIValuatorState *valuators,
- ClutterEventType *evtype,
- uint32_t *number,
- double *value)
-{
- double *values;
- int i;
-
- 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;
-
- meta_input_device_x11_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,
- meta_input_device_x11_get_device_id (device),
- clutter_input_device_get_device_name (device),
- 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:
- case XI_TouchBegin:
- case XI_TouchUpdate:
- case XI_TouchEnd:
- {
- XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
-
- xwindow = xev->event;
- }
- break;
-
- case XI_Enter:
- case XI_Leave:
- case XI_FocusIn:
- case XI_FocusOut:
- {
- XIEnterEvent *xev = (XIEnterEvent *) xi_event;
-
- xwindow = xev->event;
- }
- break;
-
- case XI_HierarchyChanged:
- return CLUTTER_STAGE (meta_backend_get_stage (meta_get_backend ()));
-
- default:
- break;
- }
-
- if (xwindow == None)
- return NULL;
-
- return meta_x11_get_stage_from_window (xwindow);
-}
-
-/*
- * print_key_sym: Translate a symbol to its printable form if any
- * @symbol: the symbol to translate
- * @buffer: the buffer where to put the translated string
- * @len: size of the buffer
- *
- * Translates @symbol into a printable representation in @buffer, if possible.
- *
- * Return value: The number of bytes of the translated string, 0 if the
- * symbol can't be printed
- *
- * Note: The code is derived from libX11's src/KeyBind.c
- * Copyright 1985, 1987, 1998 The Open Group
- *
- * Note: This code works for Latin-1 symbols. clutter_keysym_to_unicode()
- * does the work for the other keysyms.
- */
-static int
-print_keysym (uint32_t symbol,
- char *buffer,
- int len)
-{
- unsigned long high_bytes;
- unsigned char c;
-
- high_bytes = symbol >> 8;
- if (!(len &&
- ((high_bytes == 0) ||
- ((high_bytes == 0xFF) &&
- (((symbol >= CLUTTER_KEY_BackSpace) &&
- (symbol <= CLUTTER_KEY_Clear)) ||
- (symbol == CLUTTER_KEY_Return) ||
- (symbol == CLUTTER_KEY_Escape) ||
- (symbol == CLUTTER_KEY_KP_Space) ||
- (symbol == CLUTTER_KEY_KP_Tab) ||
- (symbol == CLUTTER_KEY_KP_Enter) ||
- ((symbol >= CLUTTER_KEY_KP_Multiply) &&
- (symbol <= CLUTTER_KEY_KP_9)) ||
- (symbol == CLUTTER_KEY_KP_Equal) ||
- (symbol == CLUTTER_KEY_Delete))))))
- return 0;
-
- /* if X keysym, convert to ascii by grabbing low 7 bits */
- if (symbol == CLUTTER_KEY_KP_Space)
- c = CLUTTER_KEY_space & 0x7F; /* patch encoding botch */
- else if (high_bytes == 0xFF)
- c = symbol & 0x7F;
- else
- c = symbol & 0xFF;
-
- buffer[0] = c;
- return 1;
-}
-
-static double *
-translate_axes (ClutterInputDevice *device,
- double x,
- double y,
- XIValuatorState *valuators)
-{
- uint32_t i;
- double *retval;
- double *values;
-
- retval = g_new0 (double, CLUTTER_INPUT_AXIS_LAST);
- values = valuators->values;
-
- for (i = 0; i < valuators->mask_len * 8; i++)
- {
- ClutterInputAxis axis;
- double val;
-
- if (!XIMaskIsSet (valuators->mask, i))
- continue;
- if (!meta_input_device_x11_get_axis (device, i, &axis))
- continue;
-
- val = *values++;
-
- switch (axis)
- {
- case CLUTTER_INPUT_AXIS_X:
- retval[axis] = x;
- break;
-
- case CLUTTER_INPUT_AXIS_Y:
- retval[axis] = y;
- break;
-
- default:
- meta_input_device_x11_translate_axis (device, i, val, &retval[axis]);
- break;
- }
- }
-
- return retval;
-}
-
-static double
-scroll_valuators_changed (ClutterInputDevice *device,
- XIValuatorState *valuators,
- double *dx_p,
- double *dy_p)
-{
- gboolean retval = FALSE;
- uint32_t n_axes, n_val, i;
- double *values;
-
- n_axes = meta_input_device_x11_get_n_axes (device);
- values = valuators->values;
-
- *dx_p = *dy_p = 0.0;
-
- n_val = 0;
-
- for (i = 0; i < MIN (valuators->mask_len * 8, n_axes); i++)
- {
- ClutterScrollDirection direction;
- double delta;
-
- if (!XIMaskIsSet (valuators->mask, i))
- continue;
-
- if (meta_input_device_x11_get_scroll_delta (device, i,
- values[n_val],
- &direction,
- &delta))
- {
- retval = TRUE;
-
- if (direction == CLUTTER_SCROLL_UP ||
- direction == CLUTTER_SCROLL_DOWN)
- *dy_p = delta;
- else
- *dx_p = delta;
- }
-
- n_val += 1;
- }
-
- return retval;
-}
-
-static void
-translate_coords (MetaStageX11 *stage_x11,
- double event_x,
- double event_y,
- float *x_out,
- float *y_out)
-{
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_x11);
- ClutterActor *stage = CLUTTER_ACTOR (stage_impl->wrapper);
- float stage_width;
- float 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 void
-on_keymap_state_change (MetaKeymapX11 *keymap_x11,
- gpointer data)
-{
- ClutterSeat *seat = data;
- MetaInputSettings *input_settings;
- MetaKbdA11ySettings kbd_a11y_settings;
-
- /* On keymaps state change, just reapply the current settings, it'll
- * take care of enabling/disabling mousekeys based on NumLock state.
- */
- input_settings = meta_backend_get_input_settings (meta_get_backend ());
- meta_input_settings_get_kbd_a11y_settings (input_settings, &kbd_a11y_settings);
- meta_seat_x11_apply_kbd_a11y_settings (seat, &kbd_a11y_settings);
-}
-
-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)
- {
- 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);
- }
-}
-
-static void
-meta_seat_x11_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaSeatX11 *seat_x11 = META_SEAT_X11 (object);
-
- 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;
-
- 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_event_put (event);
- clutter_event_free (event);
- }
-}
-
-static void
-meta_seat_x11_constructed (GObject *object)
-{
- MetaSeatX11 *seat_x11 = META_SEAT_X11 (object);
- ClutterBackend *backend = clutter_get_default_backend ();
- XIDeviceInfo *info;
- XIEventMask event_mask;
- unsigned char mask[XIMaskLen(XI_LASTEVENT)] = { 0, };
- int n_devices, i;
- Display *xdisplay;
-
- xdisplay = meta_clutter_x11_get_default_display ();
-
- info = XIQueryDevice (xdisplay, XIAllDevices, &n_devices);
-
- for (i = 0; i < n_devices; i++)
- {
- XIDeviceInfo *xi_device = &info[i];
-
- if (!xi_device->enabled)
- continue;
-
- add_device (seat_x11, backend, xi_device);
- }
-
- XIFreeDeviceInfo (info);
-
- 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, meta_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, meta_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
-meta_seat_x11_finalize (GObject *object)
-{
- MetaSeatX11 *seat_x11 = META_SEAT_X11 (object);
-
- g_hash_table_unref (seat_x11->devices_by_id);
- g_hash_table_unref (seat_x11->tools_by_serial);
- g_hash_table_unref (seat_x11->touch_coords);
- g_list_free (seat_x11->devices);
-
- G_OBJECT_CLASS (meta_seat_x11_parent_class)->finalize (object);
-}
-
-static ClutterInputDevice *
-meta_seat_x11_get_pointer (ClutterSeat *seat)
-{
- MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat);
-
- 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 const GList *
-meta_seat_x11_peek_devices (ClutterSeat *seat)
-{
- MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat);
-
- return (const GList *) seat_x11->devices;
-}
-
-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 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);
-}
-
-static ClutterVirtualDeviceType
-meta_seat_x11_get_supported_virtual_device_types (ClutterSeat *seat)
-{
- return (CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD |
- CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER);
-}
-
-static void
-meta_seat_x11_warp_pointer (ClutterSeat *seat,
- int x,
- int y)
-{
- MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat);
-
- meta_clutter_x11_trap_x_errors ();
- XIWarpPointer (meta_clutter_x11_get_default_display (),
- seat_x11->pointer_id,
- None,
- meta_clutter_x11_get_root_window (),
- 0, 0, 0, 0,
- x, y);
- meta_clutter_x11_untrap_x_errors ();
-}
-
-static uint32_t
-translate_state (XIButtonState *button_state,
- XIModifierState *modifier_state,
- XIGroupState *group_state)
-{
- uint32_t state = 0;
- int i;
-
- if (modifier_state)
- state |= modifier_state->effective;
-
- if (button_state)
- {
- for (i = 1; i < button_state->mask_len * 8; i++)
- {
- if (!XIMaskIsSet (button_state->mask, i))
- continue;
-
- switch (i)
- {
- case 1:
- state |= CLUTTER_BUTTON1_MASK;
- break;
- case 2:
- state |= CLUTTER_BUTTON2_MASK;
- break;
- case 3:
- state |= CLUTTER_BUTTON3_MASK;
- break;
- case 8:
- state |= CLUTTER_BUTTON4_MASK;
- break;
- case 9:
- state |= CLUTTER_BUTTON5_MASK;
- break;
- default:
- break;
- }
- }
- }
-
- if (group_state)
- state |= XkbBuildCoreState (0, group_state->effective);
-
- return state;
-}
-
-static gboolean
-meta_seat_x11_query_state (ClutterSeat *seat,
- ClutterInputDevice *device,
- ClutterEventSequence *sequence,
- graphene_point_t *coords,
- ClutterModifierType *modifiers)
-{
- MetaBackendX11 *backend_x11 = META_BACKEND_X11 (meta_get_backend ());
- MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat);
- Window root_ret, child_ret;
- double root_x, root_y, win_x, win_y;
- XIButtonState button_state = { 0 };
- XIModifierState modifier_state;
- XIGroupState group_state;
-
- meta_clutter_x11_trap_x_errors ();
- XIQueryPointer (meta_clutter_x11_get_default_display (),
- seat_x11->pointer_id,
- meta_backend_x11_get_xwindow (backend_x11),
- &root_ret, &child_ret,
- &root_x, &root_y, &win_x, &win_y,
- &button_state, &modifier_state, &group_state);
- if (meta_clutter_x11_untrap_x_errors ())
- {
- g_free (button_state.mask);
- return FALSE;
- }
-
- if (sequence)
- {
- MetaTouchInfo *touch_info;
-
- touch_info = g_hash_table_lookup (seat_x11->touch_coords, sequence);
- if (!touch_info)
- {
- g_free (button_state.mask);
- return FALSE;
- }
-
- if (coords)
- {
- coords->x = touch_info->x;
- coords->y = touch_info->y;
- }
- }
- else
- {
- if (coords)
- {
- coords->x = win_x;
- coords->y = win_y;
- }
- }
-
- if (modifiers)
- *modifiers = translate_state (&button_state, &modifier_state, &group_state);
-
- g_free (button_state.mask);
- return TRUE;
-}
-
-static void
-meta_seat_x11_update_touchpoint (MetaSeatX11 *seat,
- ClutterEventSequence *sequence,
- double x,
- double y)
-{
- MetaTouchInfo *touch_info;
-
- touch_info = g_hash_table_lookup (seat->touch_coords, sequence);
- if (!touch_info)
- {
- touch_info = g_new0 (MetaTouchInfo, 1);
- touch_info->sequence = sequence;
- g_hash_table_insert (seat->touch_coords, sequence, touch_info);
- }
-
- touch_info->x = x;
- touch_info->y = y;
-}
-
-static void
-meta_seat_x11_remove_touchpoint (MetaSeatX11 *seat,
- ClutterEventSequence *sequence)
-{
- g_hash_table_remove (seat->touch_coords, sequence);
-}
-
-static void
-meta_touch_info_free (MetaTouchInfo *touch_info)
-{
- g_free (touch_info);
-}
-
-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->peek_devices = meta_seat_x11_peek_devices;
- seat_class->bell_notify = meta_seat_x11_bell_notify;
- seat_class->get_keymap = meta_seat_x11_get_keymap;
- 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_event_post = meta_seat_x11_handle_event_post;
- seat_class->query_state = meta_seat_x11_query_state;
-
- 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");
-}
-
-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);
- seat->touch_coords = g_hash_table_new_full (NULL, NULL, NULL,
- (GDestroyNotify) meta_touch_info_free);
-}
-
-MetaSeatX11 *
-meta_seat_x11_new (int opcode,
- int logical_pointer,
- int logical_keyboard)
-{
- return g_object_new (META_TYPE_SEAT_X11,
- "opcode", opcode,
- "pointer-id", logical_pointer,
- "keyboard-id", logical_keyboard,
- NULL);
-}
-
-static ClutterInputDevice *
-get_source_device_checked (MetaSeatX11 *seat,
- XIDeviceEvent *xev)
-{
- ClutterInputDevice *source_device;
-
- source_device = g_hash_table_lookup (seat->devices_by_id,
- GINT_TO_POINTER (xev->sourceid));
-
- 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 uint32_t
-evdev_button_code (uint32_t x_button)
-{
- uint32_t button;
-
- switch (x_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 = x_button + (BTN_LEFT - 1) + 4;
- break;
- }
-
- return button;
-}
-
-gboolean
-meta_seat_x11_translate_event (MetaSeatX11 *seat,
- XEvent *xevent,
- ClutterEvent *event)
-{
- 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;
-
- if (meta_keymap_x11_handle_event (seat->keymap, xevent))
- return FALSE;
-
- cookie = &xevent->xcookie;
-
- if (cookie->type != GenericEvent ||
- cookie->extension != seat->opcode)
- return FALSE;
-
- xi_event = (XIEvent *) cookie->data;
-
- if (!xi_event)
- 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_DeviceChanged ||
- xi_event->evtype == XI_PropertyEvent))
- {
- stage = get_event_stage (seat, xi_event);
- if (stage == NULL || CLUTTER_ACTOR_IN_DESTRUCTION (stage))
- return FALSE;
- else
- stage_x11 = META_STAGE_X11 (_clutter_stage_get_window (stage));
- }
-
- event->any.stage = stage;
-
- switch (xi_event->evtype)
- {
- case XI_HierarchyChanged:
- {
- XIHierarchyEvent *xev = (XIHierarchyEvent *) xi_event;
-
- retval = translate_hierarchy_event (backend, seat, xev, event);
- }
- break;
-
- case XI_DeviceChanged:
- {
- XIDeviceChangedEvent *xev = (XIDeviceChangedEvent *) xi_event;
-
- device = g_hash_table_lookup (seat->devices_by_id,
- GINT_TO_POINTER (xev->deviceid));
- source_device = g_hash_table_lookup (seat->devices_by_id,
- GINT_TO_POINTER (xev->sourceid));
- if (device)
- {
- meta_input_device_x11_reset_axes (device);
- translate_device_classes (meta_clutter_x11_get_default_display (),
- device,
- xev->classes,
- xev->num_classes);
- }
-
- if (source_device)
- meta_input_device_x11_reset_scroll_info (source_device);
- }
- retval = FALSE;
- break;
- case XI_KeyPress:
- case XI_KeyRelease:
- {
- XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
- MetaKeymapX11 *keymap_x11 = seat->keymap;
- 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;
- meta_input_device_x11_translate_state (event, &xev->mods, &xev->buttons, &xev->group);
- event->key.hardware_keycode = xev->detail;
-
- /* clutter-xkb-utils.c adds a fixed offset of 8 to go into XKB's
- * range, so we do the reverse here. */
- event->key.evdev_code = event->key.hardware_keycode - 8;
-
- /* keyval is the key ignoring all modifiers ('1' vs. '!') */
- event->key.keyval =
- meta_keymap_x11_translate_key_state (keymap_x11,
- event->key.hardware_keycode,
- &event->key.modifier_state,
- NULL);
-
- clutter_event_set_source_device (event, source_device);
-
- device = g_hash_table_lookup (seat->devices_by_id,
- GINT_TO_POINTER (xev->deviceid));
- clutter_event_set_device (event, device);
-
- /* XXX keep this in sync with the evdev device manager */
- n = print_keysym (event->key.keyval, buffer, sizeof (buffer));
- if (n == 0)
- {
- /* not printable */
- event->key.unicode_value = (gunichar) '\0';
- }
- else
- {
- event->key.unicode_value = g_utf8_get_char_validated (buffer, n);
- if (event->key.unicode_value == -1 ||
- event->key.unicode_value == -2)
- event->key.unicode_value = (gunichar) '\0';
- }
-
- 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)
- meta_stage_x11_set_user_time (stage_x11, event->key.time);
-
- retval = TRUE;
- }
- break;
-
- case XI_ButtonPress:
- case XI_ButtonRelease:
- {
- XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
-
- 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)
- {
- /* We got these events because of the passive button grab */
- XIAllowEvents (meta_clutter_x11_get_default_display (),
- xev->sourceid,
- XIAsyncDevice,
- xev->time);
-
- event->any.stage = stage;
-
- if (xev->detail >= 4 && xev->detail <= 7)
- {
- retval = FALSE;
-
- if (xi_event->evtype == XI_ButtonPress &&
- translate_pad_event (event, xev, source_device))
- retval = TRUE;
-
- break;
- }
-
- event->any.type =
- (xi_event->evtype == XI_ButtonPress) ? CLUTTER_PAD_BUTTON_PRESS
- : CLUTTER_PAD_BUTTON_RELEASE;
- event->any.time = xev->time;
-
- /* The 4-7 button range is taken as non-existent on pad devices,
- * let the buttons above that take over this range.
- */
- if (xev->detail > 7)
- xev->detail -= 4;
-
- /* Pad buttons are 0-indexed */
- event->pad_button.button = xev->detail - 1;
-#ifdef HAVE_LIBWACOM
- 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);
-
- 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,
- meta_input_device_x11_get_device_id (device),
- clutter_input_device_get_device_name (device),
- event->any.time,
- event->pad_button.button);
- retval = TRUE;
- break;
- }
-
- switch (xev->detail)
- {
- case 4:
- case 5:
- case 6:
- case 7:
- /* we only generate Scroll events on ButtonPress */
- if (xi_event->evtype == XI_ButtonRelease)
- return FALSE;
-
- event->scroll.type = event->type = CLUTTER_SCROLL;
-
- if (xev->detail == 4)
- event->scroll.direction = CLUTTER_SCROLL_UP;
- else if (xev->detail == 5)
- event->scroll.direction = CLUTTER_SCROLL_DOWN;
- else if (xev->detail == 6)
- event->scroll.direction = CLUTTER_SCROLL_LEFT;
- else
- event->scroll.direction = CLUTTER_SCROLL_RIGHT;
-
- 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);
- 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);
-
- event->scroll.axes = translate_axes (event->scroll.device,
- event->scroll.x,
- event->scroll.y,
- &xev->valuators);
- g_debug ("scroll: win:0x%x, device:%d '%s', time:%d "
- "(direction:%s, "
- "x:%.2f, y:%.2f, "
- "emulated:%s)",
- (unsigned int) stage_x11->xwin,
- meta_input_device_x11_get_device_id (device),
- clutter_input_device_get_device_name (device),
- 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:
- event->button.type = event->type =
- (xi_event->evtype == XI_ButtonPress) ? CLUTTER_BUTTON_PRESS
- : CLUTTER_BUTTON_RELEASE;
-
- event->button.stage = stage;
-
- 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;
- event->button.evdev_code = evdev_button_code (xev->detail);
- 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,
- 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);
- 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,
- meta_input_device_x11_get_device_id (device),
- clutter_input_device_get_device_name (device),
- 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 (xev->flags & XIPointerEmulated)
- _clutter_event_set_pointer_emulated (event, TRUE);
-
- if (xi_event->evtype == XI_ButtonPress)
- meta_stage_x11_set_user_time (stage_x11, event->button.time);
-
- retval = TRUE;
- }
- break;
-
- case XI_Motion:
- {
- XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
- double delta_x, delta_y;
-
- 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)
- {
- event->any.stage = stage;
-
- if (translate_pad_event (event, xev, source_device))
- retval = TRUE;
- break;
- }
-
- if (scroll_valuators_changed (source_device,
- &xev->valuators,
- &delta_x, &delta_y))
- {
- event->scroll.type = event->type = CLUTTER_SCROLL;
- event->scroll.direction = CLUTTER_SCROLL_SMOOTH;
-
- 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);
- 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);
-
- g_debug ("smooth scroll: win:0x%x device:%d '%s' (x:%.2f, y:%.2f, delta:%f, %f)",
- (unsigned int) stage_x11->xwin,
- meta_input_device_x11_get_device_id (event->scroll.device),
- clutter_input_device_get_device_name (event->scroll.device),
- event->scroll.x,
- event->scroll.y,
- delta_x, delta_y);
-
- retval = TRUE;
- break;
- }
-
- event->motion.type = event->type = CLUTTER_MOTION;
-
- event->motion.stage = stage;
-
- event->motion.time = xev->time;
- translate_coords (stage_x11, xev->event_x, xev->event_y, &event->motion.x, &event->motion.y);
- 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,
- 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 (xev->flags & XIPointerEmulated)
- _clutter_event_set_pointer_emulated (event, TRUE);
-
- g_debug ("motion: win:0x%x device:%d '%s' (x:%.2f, y:%.2f, axes:%s)",
- (unsigned int) stage_x11->xwin,
- meta_input_device_x11_get_device_id (event->motion.device),
- clutter_input_device_get_device_name (event->motion.device),
- event->motion.x,
- event->motion.y,
- event->motion.axes != NULL ? "yes" : "no");
-
- retval = TRUE;
- }
- break;
-
- case XI_TouchBegin:
- {
- XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
- device = g_hash_table_lookup (seat->devices_by_id,
- GINT_TO_POINTER (xev->deviceid));
- }
- /* Fall through */
- case XI_TouchEnd:
- {
- XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
-
- source_device = g_hash_table_lookup (seat->devices_by_id,
- GINT_TO_POINTER (xev->sourceid));
-
- if (xi_event->evtype == XI_TouchBegin)
- event->touch.type = event->type = CLUTTER_TOUCH_BEGIN;
- else
- event->touch.type = event->type = CLUTTER_TOUCH_END;
-
- 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);
- 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 (seat->devices_by_id,
- GINT_TO_POINTER (xev->deviceid));
- clutter_event_set_device (event, device);
-
- event->touch.axes = translate_axes (event->touch.device,
- event->motion.x,
- event->motion.y,
- &xev->valuators);
-
- if (xi_event->evtype == XI_TouchBegin)
- {
- event->touch.modifier_state |= CLUTTER_BUTTON1_MASK;
-
- meta_stage_x11_set_user_time (stage_x11, event->touch.time);
- meta_seat_x11_update_touchpoint (seat,
- GUINT_TO_POINTER (xev->detail),
- xev->root_x,
- xev->root_y);
- }
- else if (xi_event->evtype == XI_TouchEnd)
- {
- meta_seat_x11_remove_touchpoint (seat,
- GUINT_TO_POINTER (xev->detail));
- }
-
- /* "NULL" sequences are special cased in clutter */
- event->touch.sequence = GINT_TO_POINTER (MAX (1, xev->detail + 1));
-
- if (xev->flags & XITouchEmulatingPointer)
- _clutter_event_set_pointer_emulated (event, TRUE);
-
- 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,
- meta_input_device_x11_get_device_id (event->touch.device),
- clutter_input_device_get_device_name (event->touch.device),
- GPOINTER_TO_UINT (event->touch.sequence),
- event->touch.x,
- event->touch.y,
- event->touch.axes != NULL ? "yes" : "no");
-
- retval = TRUE;
- }
- break;
-
- case XI_TouchUpdate:
- {
- XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
-
- source_device = g_hash_table_lookup (seat->devices_by_id,
- GINT_TO_POINTER (xev->sourceid));
-
- event->touch.type = event->type = CLUTTER_TOUCH_UPDATE;
- event->touch.stage = stage;
- event->touch.time = xev->time;
- /* "NULL" sequences are special cased in clutter */
- event->touch.sequence = GINT_TO_POINTER (MAX (1, xev->detail + 1));
- translate_coords (stage_x11, xev->event_x, xev->event_y, &event->touch.x, &event->touch.y);
-
- clutter_event_set_source_device (event, source_device);
-
- device = g_hash_table_lookup (seat->devices_by_id,
- GINT_TO_POINTER (xev->deviceid));
- clutter_event_set_device (event, device);
-
- event->touch.axes = translate_axes (event->touch.device,
- event->motion.x,
- event->motion.y,
- &xev->valuators);
-
- 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);
-
- meta_seat_x11_update_touchpoint (seat,
- event->touch.sequence,
- xev->root_x,
- xev->root_y);
-
- g_debug ("touch update: win:0x%x device:%d '%s' (seq:%d, x:%.2f, y:%.2f, axes:%s)",
- (unsigned int) stage_x11->xwin,
- meta_input_device_x11_get_device_id (event->touch.device),
- clutter_input_device_get_device_name (event->touch.device),
- GPOINTER_TO_UINT (event->touch.sequence),
- event->touch.x,
- event->touch.y,
- event->touch.axes != NULL ? "yes" : "no");
-
- retval = TRUE;
- }
- break;
-
- case XI_Enter:
- case XI_Leave:
- {
- XIEnterEvent *xev = (XIEnterEvent *) xi_event;
-
- device = g_hash_table_lookup (seat->devices_by_id,
- GINT_TO_POINTER (xev->deviceid));
-
- source_device = g_hash_table_lookup (seat->devices_by_id,
- GINT_TO_POINTER (xev->sourceid));
-
- if (xi_event->evtype == XI_Enter)
- {
- event->crossing.type = event->type = CLUTTER_ENTER;
-
- event->crossing.stage = stage;
- event->crossing.source = CLUTTER_ACTOR (stage);
- event->crossing.related = NULL;
-
- event->crossing.time = xev->time;
- translate_coords (stage_x11, xev->event_x, xev->event_y, &event->crossing.x, &event->crossing.y);
-
- if (xev->deviceid == seat->pointer_id)
- seat->has_pointer_focus = TRUE;
- }
- else
- {
- event->crossing.type = event->type = CLUTTER_LEAVE;
-
- event->crossing.stage = stage;
- event->crossing.source = CLUTTER_ACTOR (stage);
- event->crossing.related = NULL;
-
- event->crossing.time = xev->time;
- translate_coords (stage_x11, xev->event_x, xev->event_y, &event->crossing.x, &event->crossing.y);
-
- if (xev->deviceid == seat->pointer_id)
- seat->has_pointer_focus = FALSE;
- }
-
- meta_input_device_x11_reset_scroll_info (source_device);
-
- clutter_event_set_device (event, device);
- clutter_event_set_source_device (event, source_device);
-
- retval = TRUE;
- }
- break;
-
- case XI_FocusIn:
- case XI_FocusOut:
- retval = FALSE;
- break;
- case XI_PropertyEvent:
- translate_property_event (seat, xi_event);
- retval = FALSE;
- break;
- }
-
- return retval;
-}
-
-ClutterInputDevice *
-meta_seat_x11_lookup_device_id (MetaSeatX11 *seat_x11,
- int device_id)
-{
- return g_hash_table_lookup (seat_x11->devices_by_id,
- GINT_TO_POINTER (device_id));
-}
-
-void
-meta_seat_x11_select_stage_events (MetaSeatX11 *seat,
- ClutterStage *stage)
-{
- MetaStageX11 *stage_x11;
- XIEventMask xi_event_mask;
- unsigned char *mask;
- int len;
-
- stage_x11 = META_STAGE_X11 (_clutter_stage_get_window (stage));
-
- len = XIMaskLen (XI_LASTEVENT);
- mask = g_new0 (unsigned char, len);
-
- 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);
-
- XISetMask (mask, XI_TouchBegin);
- XISetMask (mask, XI_TouchUpdate);
- XISetMask (mask, XI_TouchEnd);
-
- xi_event_mask.deviceid = XIAllMasterDevices;
- xi_event_mask.mask = mask;
- xi_event_mask.mask_len = len;
-
- XISelectEvents (meta_clutter_x11_get_default_display (),
- stage_x11->xwin, &xi_event_mask, 1);
-
- g_free (mask);
-}
diff --git a/src/backends/x11/meta-seat-x11.h b/src/backends/x11/meta-seat-x11.h
deleted file mode 100644
index 326db4a45..000000000
--- a/src/backends/x11/meta-seat-x11.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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 logical_pointer,
- int logical_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
deleted file mode 100644
index 87e7ffec6..000000000
--- a/src/backends/x11/meta-stage-x11.c
+++ /dev/null
@@ -1,853 +0,0 @@
-/*
- * 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/meta-stage-private.h"
-#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-clutter-backend-x11.h"
-#include "backends/x11/meta-seat-x11.h"
-#include "backends/x11/meta-stage-x11.h"
-#include "backends/x11/nested/meta-stage-x11-nested.h"
-#include "clutter/clutter-mutter.h"
-#include "cogl/cogl-mutter.h"
-#include "cogl/cogl.h"
-#include "core/display-private.h"
-#include "meta/meta-context.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 MetaStageImpl *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,
- META_TYPE_STAGE_IMPL,
- 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)
-{
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_x11);
-
- if (stage_x11->xwin != None)
- {
- Display *xdisplay = meta_clutter_x11_get_default_display ();
- uint32_t min_width, min_height;
- XSizeHints *size_hints;
-
- size_hints = XAllocSizeHints();
-
- clutter_stage_get_minimum_size (stage_impl->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)
-{
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_x11);
- MetaClutterBackendX11 *backend_x11 =
- META_CLUTTER_BACKEND_X11 (stage_impl->backend);
- Display *xdisplay = meta_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 = meta_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)
-{
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_x11);
- MetaClutterBackendX11 *backend_x11 =
- META_CLUTTER_BACKEND_X11 (stage_impl->backend);
- Display *xdisplay = meta_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)
-{
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_x11);
- MetaClutterBackendX11 *backend_x11 =
- META_CLUTTER_BACKEND_X11 (stage_impl->backend);
- Display *xdisplay = meta_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 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));
- }
-
- clutter_stage_window_parent_iface->unrealize (stage_window);
-
- g_clear_object (&stage_x11->onscreen);
-}
-
-static CoglOnscreen *
-create_onscreen (CoglContext *cogl_context,
- int width,
- int height)
-{
- CoglDisplay *cogl_display = cogl_context_get_display (cogl_context);
- CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_display);
-
- switch (cogl_renderer_get_winsys_id (cogl_renderer))
- {
- case COGL_WINSYS_ID_GLX:
-#ifdef COGL_HAS_GLX_SUPPORT
- return COGL_ONSCREEN (cogl_onscreen_glx_new (cogl_context,
- width, height));
-#else
- g_assert_not_reached ();
- break;
-#endif
- case COGL_WINSYS_ID_EGL_XLIB:
-#ifdef COGL_HAS_EGL_SUPPORT
- return COGL_ONSCREEN (cogl_onscreen_xlib_new (cogl_context,
- width, height));
-#else
- g_assert_not_reached ();
- break;
-#endif
- default:
- g_assert_not_reached ();
- return NULL;
- }
-}
-
-static gboolean
-meta_stage_x11_realize (ClutterStageWindow *stage_window)
-{
- MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window);
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_window);
- ClutterBackend *backend = CLUTTER_BACKEND (stage_impl->backend);
- MetaSeatX11 *seat_x11 = META_SEAT_X11 (clutter_backend_get_default_seat (backend));
- Display *xdisplay = meta_clutter_x11_get_default_display ();
- float width, height;
- GError *error = NULL;
-
- clutter_actor_get_size (CLUTTER_ACTOR (stage_impl->wrapper), &width, &height);
-
- stage_x11->onscreen = create_onscreen (backend->cogl_context, width, height);
-
- 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_init_screen_view (renderer_x11_cm,
- stage_x11->onscreen,
- stage_x11->xwin_width,
- stage_x11->xwin_height);
- }
-
- /* 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);
- g_object_unref (stage_x11->onscreen);
- abort();
- }
-
- if (!(clutter_stage_window_parent_iface->realize (stage_window)))
- return FALSE;
-
- stage_x11->xwin =
- cogl_x11_onscreen_get_x11_window (COGL_X11_ONSCREEN (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);
-
- /* we unconditionally select input events even with event retrieval
- * disabled because we need to guarantee that the Clutter internal
- * state is maintained when calling meta_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_impl->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_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 = meta_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 = True;
-
- XSetWMHints (xdisplay, stage_x11->xwin, &wm_hints);
-}
-
-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);
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_x11);
-
- if (stage_x11->xwin != None)
- {
- Display *xdisplay = meta_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_impl->wrapper));
-
- XMapWindow (xdisplay, stage_x11->xwin);
- }
-}
-
-static void
-meta_stage_x11_hide (ClutterStageWindow *stage_window)
-{
- MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window);
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_x11);
-
- if (stage_x11->xwin != None)
- {
- Display *xdisplay = meta_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_impl->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 void
-meta_stage_x11_redraw_view (ClutterStageWindow *stage_window,
- ClutterStageView *view,
- ClutterFrame *frame)
-{
- clutter_stage_window_parent_iface->redraw_view (stage_window, view, frame);
- clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
-}
-
-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)
-{
- stage->xwin = None;
- stage->xwin_width = 640;
- stage->xwin_height = 480;
-
- stage->wm_state = STAGE_X11_WITHDRAWN;
-
- stage->title = NULL;
-
- stage->backend = meta_get_backend ();
- g_assert (stage->backend);
-}
-
-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->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->redraw_view = meta_stage_x11_redraw_view;
-}
-
-static inline void
-set_user_time (MetaClutterBackendX11 *backend_x11,
- MetaStageX11 *stage_x11,
- long timestamp)
-{
- if (timestamp != CLUTTER_CURRENT_TIME)
- {
- Display *xdisplay = meta_clutter_x11_get_default_display ();
-
- XChangeProperty (xdisplay,
- stage_x11->xwin,
- backend_x11->atom_NET_WM_USER_TIME,
- XA_CARDINAL, 32,
- PropModeReplace,
- (unsigned char *) &timestamp, 1);
- }
-}
-
-static gboolean
-handle_wm_protocols_event (MetaClutterBackendX11 *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 = meta_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)
-{
- MetaStageImpl *stage_impl;
- gboolean res = FALSE;
- MetaClutterBackendX11 *clutter_backend_x11;
- ClutterStage *stage;
- MetaBackend *backend;
-
- stage_impl = meta_x11_get_stage_window_from_window (xevent->xany.window);
- if (stage_impl == NULL)
- return FALSE;
-
- stage = stage_impl->wrapper;
- backend = stage_x11->backend;
- clutter_backend_x11 = META_CLUTTER_BACKEND_X11 (stage_impl->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;
-
- if (META_IS_BACKEND_X11_CM (stage_x11->backend))
- {
- 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))
- {
- 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:
- meta_stage_set_active ((MetaStage *) stage_impl->wrapper, TRUE);
- break;
-
- case FocusOut:
- meta_stage_set_active ((MetaStage *) stage_impl->wrapper, FALSE);
- 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);
-
- g_return_val_if_fail (META_IS_STAGE_X11_NESTED (stage_x11),
- FALSE);
- meta_context_terminate (meta_backend_get_context (backend));
- res = FALSE;
- break;
-
- case ClientMessage:
- g_debug ("Client message for stage, win:0x%x",
- (unsigned int) xevent->xany.window);
-
- if (xevent->xclient.message_type == clutter_backend_x11->atom_WM_PROTOCOLS)
- {
- if (handle_wm_protocols_event (clutter_backend_x11,
- stage_x11,
- xevent))
- {
- g_return_val_if_fail (META_IS_STAGE_X11_NESTED (stage_x11),
- FALSE);
- meta_context_terminate (meta_backend_get_context (backend));
- res = FALSE;
- }
- }
-
- 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 MetaStageImpl *
-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)
-{
- MetaStageImpl *stage_impl;
-
- stage_impl = meta_x11_get_stage_window_from_window (win);
-
- if (stage_impl != NULL)
- return stage_impl->wrapper;
-
- return NULL;
-}
-
-void
-meta_stage_x11_set_user_time (MetaStageX11 *stage_x11,
- uint32_t user_time)
-{
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_x11);
- MetaClutterBackendX11 *backend_x11 =
- META_CLUTTER_BACKEND_X11 (stage_impl->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
deleted file mode 100644
index 041767167..000000000
--- a/src/backends/x11/meta-stage-x11.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* 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 "backends/x11/meta-clutter-backend-x11.h"
-#include "clutter/clutter-mutter.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
-{
- MetaStageImpl 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 viewport_initialized : 1;
-};
-
-struct _MetaStageX11Class
-{
- MetaStageImplClass 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
deleted file mode 100644
index 54bb43ad1..000000000
--- a/src/backends/x11/meta-virtual-input-device-x11.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * 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 "backends/x11/meta-clutter-backend-x11.h"
-#include "clutter/clutter.h"
-#include "meta-keymap-x11.h"
-#include "meta-virtual-input-device-x11.h"
-
-#define DISCRETE_SCROLL_STEP 10.0
-
-struct _MetaVirtualInputDeviceX11
-{
- ClutterVirtualInputDevice parent;
-
- double accum_scroll_dx;
- double accum_scroll_dy;
-};
-
-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 (meta_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 (meta_clutter_x11_get_default_display (),
- meta_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 (meta_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 = meta_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)
-{
- MetaVirtualInputDeviceX11 *virtual_device_x11;
- ClutterScrollDirection direction;
- int i, n_xscrolls, n_yscrolls;
-
- virtual_device_x11 = META_VIRTUAL_INPUT_DEVICE_X11 (virtual_device);
-
- virtual_device_x11->accum_scroll_dx += dx;
- virtual_device_x11->accum_scroll_dy += dy;
- n_xscrolls = floor ((fabs (virtual_device_x11->accum_scroll_dx) + DBL_EPSILON) /
- DISCRETE_SCROLL_STEP);
- n_yscrolls = floor ((fabs (virtual_device_x11->accum_scroll_dy) + DBL_EPSILON) /
- DISCRETE_SCROLL_STEP);
-
- direction = virtual_device_x11->accum_scroll_dx > 0 ? CLUTTER_SCROLL_RIGHT
- : CLUTTER_SCROLL_LEFT;
- for (i = 0; i < n_xscrolls; ++i)
- {
- meta_virtual_input_device_x11_notify_discrete_scroll (
- virtual_device, time_us, direction, CLUTTER_SCROLL_SOURCE_WHEEL);
- }
-
- direction = virtual_device_x11->accum_scroll_dy > 0 ? CLUTTER_SCROLL_DOWN
- : CLUTTER_SCROLL_UP;
- for (i = 0; i < n_yscrolls; ++i)
- {
- meta_virtual_input_device_x11_notify_discrete_scroll (
- virtual_device, time_us, direction, CLUTTER_SCROLL_SOURCE_WHEEL);
- }
-
- virtual_device_x11->accum_scroll_dx =
- fmod (virtual_device_x11->accum_scroll_dx, DISCRETE_SCROLL_STEP);
- virtual_device_x11->accum_scroll_dy =
- fmod (virtual_device_x11->accum_scroll_dy, DISCRETE_SCROLL_STEP);
-}
-
-static void
-meta_virtual_input_device_x11_notify_key (ClutterVirtualInputDevice *virtual_device,
- uint64_t time_us,
- uint32_t key,
- ClutterKeyState key_state)
-{
- XTestFakeKeyEvent (meta_clutter_x11_get_default_display (),
- key + 8, 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 (meta_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/src/backends/x11/meta-virtual-input-device-x11.h b/src/backends/x11/meta-virtual-input-device-x11.h
deleted file mode 100644
index 88c41ae8d..000000000
--- a/src/backends/x11/meta-virtual-input-device-x11.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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>
- */
-
-#ifndef META_VIRTUAL_INPUT_DEVICE_X11_H
-#define META_VIRTUAL_INPUT_DEVICE_X11_H
-
-#include "clutter/clutter.h"
-
-#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 /* META_VIRTUAL_INPUT_DEVICE_X11_H */
diff --git a/src/backends/x11/meta-xkb-a11y-x11.c b/src/backends/x11/meta-xkb-a11y-x11.c
deleted file mode 100644
index c73b9dc4f..000000000
--- a/src/backends/x11/meta-xkb-a11y-x11.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Copyright © 2001 Ximian, Inc.
- * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
- * 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 <X11/XKBlib.h>
-#include <X11/extensions/XKBstr.h>
-
-#include "backends/x11/meta-clutter-backend-x11.h"
-#include "backends/x11/meta-xkb-a11y-x11.h"
-#include "core/display-private.h"
-#include "meta/meta-x11-errors.h"
-
-#define DEFAULT_XKB_SET_CONTROLS_MASK XkbSlowKeysMask | \
- XkbBounceKeysMask | \
- XkbStickyKeysMask | \
- XkbMouseKeysMask | \
- XkbMouseKeysAccelMask | \
- XkbAccessXKeysMask | \
- XkbAccessXTimeoutMask | \
- XkbAccessXFeedbackMask | \
- XkbControlsEnabledMask
-
-static int _xkb_event_base;
-
-static XkbDescRec *
-get_xkb_desc_rec (Display *xdisplay)
-{
- XkbDescRec *desc;
- Status status = Success;
-
- meta_clutter_x11_trap_x_errors ();
- desc = XkbGetMap (xdisplay, XkbAllMapComponentsMask, XkbUseCoreKbd);
- if (desc != NULL)
- {
- desc->ctrls = NULL;
- status = XkbGetControls (xdisplay, XkbAllControlsMask, desc);
- }
- meta_clutter_x11_untrap_x_errors ();
-
- g_return_val_if_fail (desc != NULL, NULL);
- g_return_val_if_fail (desc->ctrls != NULL, NULL);
- g_return_val_if_fail (status == Success, NULL);
-
- return desc;
-}
-
-static void
-set_xkb_desc_rec (Display *xdisplay,
- XkbDescRec *desc)
-{
- meta_clutter_x11_trap_x_errors ();
- XkbSetControls (xdisplay, DEFAULT_XKB_SET_CONTROLS_MASK, desc);
- XSync (xdisplay, FALSE);
- meta_clutter_x11_untrap_x_errors ();
-}
-
-static void
-check_settings_changed (ClutterSeat *seat)
-{
- Display *xdisplay = meta_clutter_x11_get_default_display ();
- MetaKbdA11ySettings kbd_a11y_settings;
- MetaKeyboardA11yFlags what_changed = 0;
- MetaInputSettings *input_settings;
- XkbDescRec *desc;
-
- desc = get_xkb_desc_rec (xdisplay);
- if (!desc)
- return;
-
- input_settings = meta_backend_get_input_settings (meta_get_backend ());
- meta_input_settings_get_kbd_a11y_settings (input_settings,
- &kbd_a11y_settings);
-
- if (desc->ctrls->enabled_ctrls & XkbSlowKeysMask &&
- !(kbd_a11y_settings.controls & META_A11Y_SLOW_KEYS_ENABLED))
- {
- what_changed |= META_A11Y_SLOW_KEYS_ENABLED;
- kbd_a11y_settings.controls |= META_A11Y_SLOW_KEYS_ENABLED;
- }
- else if (!(desc->ctrls->enabled_ctrls & XkbSlowKeysMask) &&
- kbd_a11y_settings.controls & META_A11Y_SLOW_KEYS_ENABLED)
- {
- what_changed |= META_A11Y_SLOW_KEYS_ENABLED;
- kbd_a11y_settings.controls &= ~META_A11Y_SLOW_KEYS_ENABLED;
- }
-
- if (desc->ctrls->enabled_ctrls & XkbStickyKeysMask &&
- !(kbd_a11y_settings.controls & META_A11Y_STICKY_KEYS_ENABLED))
- {
- what_changed |= META_A11Y_STICKY_KEYS_ENABLED;
- kbd_a11y_settings.controls |= META_A11Y_STICKY_KEYS_ENABLED;
- }
- else if (!(desc->ctrls->enabled_ctrls & XkbStickyKeysMask) &&
- kbd_a11y_settings.controls & META_A11Y_STICKY_KEYS_ENABLED)
- {
- what_changed |= META_A11Y_STICKY_KEYS_ENABLED;
- kbd_a11y_settings.controls &= ~META_A11Y_STICKY_KEYS_ENABLED;
- }
-
- if (what_changed)
- {
- meta_input_settings_notify_kbd_a11y_change (input_settings,
- kbd_a11y_settings.controls,
- what_changed);
- g_signal_emit_by_name (seat,
- "kbd-a11y-flags-changed",
- kbd_a11y_settings.controls,
- what_changed);
- }
-
- XkbFreeKeyboard (desc, XkbAllComponentsMask, TRUE);
-}
-
-static MetaX11FilterReturn
-xkb_a11y_event_filter (XEvent *xevent,
- ClutterEvent *clutter_event,
- gpointer data)
-{
- ClutterSeat *seat = CLUTTER_SEAT (data);
- XkbEvent *xkbev = (XkbEvent *) xevent;
-
- /* 'event_type' is set to zero on notifying us of updates in
- * response to client requests (including our own) and non-zero
- * to notify us of key/mouse events causing changes (like
- * pressing shift 5 times to enable sticky keys).
- *
- * We only want to update out settings when it's in response to an
- * explicit user input event, so require a non-zero event_type.
- */
- if (xevent->xany.type == (_xkb_event_base + XkbEventCode) &&
- xkbev->any.xkb_type == XkbControlsNotify && xkbev->ctrls.event_type != 0)
- check_settings_changed (seat);
-
- return META_X11_FILTER_CONTINUE;
-}
-
-static gboolean
-is_xkb_available (Display *xdisplay)
-{
- int opcode, error_base, event_base, major, minor;
-
- if (_xkb_event_base)
- return TRUE;
-
- if (!XkbQueryExtension (xdisplay,
- &opcode,
- &event_base,
- &error_base,
- &major,
- &minor))
- return FALSE;
-
- if (!XkbUseExtension (xdisplay, &major, &minor))
- return FALSE;
-
- _xkb_event_base = event_base;
-
- return TRUE;
-}
-
-static unsigned long
-set_value_mask (gboolean flag,
- unsigned long value,
- unsigned long mask)
-{
- if (flag)
- return value | mask;
-
- return value & ~mask;
-}
-
-static gboolean
-set_xkb_ctrl (XkbDescRec *desc,
- MetaKeyboardA11yFlags settings,
- MetaKeyboardA11yFlags flag,
- unsigned long mask)
-{
- gboolean result = (settings & flag) == flag;
- desc->ctrls->enabled_ctrls = set_value_mask (result, desc->ctrls->enabled_ctrls, mask);
-
- return result;
-}
-
-void
-meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat,
- MetaKbdA11ySettings *kbd_a11y_settings)
-{
- Display *xdisplay = meta_clutter_x11_get_default_display ();
- XkbDescRec *desc;
- gboolean enable_accessX;
-
- desc = get_xkb_desc_rec (xdisplay);
- if (!desc)
- return;
-
- /* general */
- enable_accessX = kbd_a11y_settings->controls & META_A11Y_KEYBOARD_ENABLED;
-
- desc->ctrls->enabled_ctrls = set_value_mask (enable_accessX,
- desc->ctrls->enabled_ctrls,
- XkbAccessXKeysMask);
-
- if (set_xkb_ctrl (desc, kbd_a11y_settings->controls, META_A11Y_TIMEOUT_ENABLED,
- XkbAccessXTimeoutMask))
- {
- desc->ctrls->ax_timeout = kbd_a11y_settings->timeout_delay;
- /* disable only the master flag via the server we will disable
- * the rest on the rebound without affecting settings state
- * don't change the option flags at all.
- */
- desc->ctrls->axt_ctrls_mask = XkbAccessXKeysMask | XkbAccessXFeedbackMask;
- desc->ctrls->axt_ctrls_values = 0;
- desc->ctrls->axt_opts_mask = 0;
- }
-
- desc->ctrls->ax_options =
- set_value_mask (kbd_a11y_settings->controls & META_A11Y_FEATURE_STATE_CHANGE_BEEP,
- desc->ctrls->ax_options,
- XkbAccessXFeedbackMask | XkbAX_FeatureFBMask | XkbAX_SlowWarnFBMask);
-
- /* bounce keys */
- if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
- META_A11Y_BOUNCE_KEYS_ENABLED, XkbBounceKeysMask))
- {
- desc->ctrls->debounce_delay = kbd_a11y_settings->debounce_delay;
- desc->ctrls->ax_options =
- set_value_mask (kbd_a11y_settings->controls & META_A11Y_BOUNCE_KEYS_BEEP_REJECT,
- desc->ctrls->ax_options,
- XkbAccessXFeedbackMask | XkbAX_BKRejectFBMask);
- }
-
- /* mouse keys */
- if (clutter_keymap_get_num_lock_state (clutter_seat_get_keymap (seat)))
- {
- /* Disable mousekeys when NumLock is ON */
- desc->ctrls->enabled_ctrls &= ~(XkbMouseKeysMask | XkbMouseKeysAccelMask);
- }
- else if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
- META_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;
-
- /* We store pixels / sec, XKB wants pixels / event */
- mk_max_speed = kbd_a11y_settings->mousekeys_max_speed;
- desc->ctrls->mk_max_speed = mk_max_speed / (1000 / desc->ctrls->mk_interval);
- if (desc->ctrls->mk_max_speed <= 0)
- desc->ctrls->mk_max_speed = 1;
-
- mk_accel_time = kbd_a11y_settings->mousekeys_accel_time;
- desc->ctrls->mk_time_to_max = mk_accel_time / desc->ctrls->mk_interval;
-
- if (desc->ctrls->mk_time_to_max <= 0)
- desc->ctrls->mk_time_to_max = 1;
-
- desc->ctrls->mk_delay = kbd_a11y_settings->mousekeys_init_delay;
- }
-
- /* slow keys */
- if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
- META_A11Y_SLOW_KEYS_ENABLED, XkbSlowKeysMask))
- {
- desc->ctrls->ax_options =
- set_value_mask (kbd_a11y_settings->controls & META_A11Y_SLOW_KEYS_BEEP_PRESS,
- desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKPressFBMask);
- desc->ctrls->ax_options =
- set_value_mask (kbd_a11y_settings->controls & META_A11Y_SLOW_KEYS_BEEP_ACCEPT,
- desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKAcceptFBMask);
- desc->ctrls->ax_options =
- set_value_mask (kbd_a11y_settings->controls & META_A11Y_SLOW_KEYS_BEEP_REJECT,
- desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKRejectFBMask);
- desc->ctrls->slow_keys_delay = kbd_a11y_settings->slowkeys_delay;
- /* anything larger than 500 seems to loose all keyboard input */
- if (desc->ctrls->slow_keys_delay > 500)
- desc->ctrls->slow_keys_delay = 500;
- }
-
- /* sticky keys */
- if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
- META_A11Y_STICKY_KEYS_ENABLED, XkbStickyKeysMask))
- {
- desc->ctrls->ax_options |= XkbAX_LatchToLockMask;
- desc->ctrls->ax_options =
- set_value_mask (kbd_a11y_settings->controls & META_A11Y_STICKY_KEYS_TWO_KEY_OFF,
- desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_TwoKeysMask);
- desc->ctrls->ax_options =
- set_value_mask (kbd_a11y_settings->controls & META_A11Y_STICKY_KEYS_BEEP,
- desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_StickyKeysFBMask);
- }
-
- /* toggle keys */
- desc->ctrls->ax_options =
- set_value_mask (kbd_a11y_settings->controls & META_A11Y_TOGGLE_KEYS_ENABLED,
- desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_IndicatorFBMask);
-
- set_xkb_desc_rec (xdisplay, desc);
- XkbFreeKeyboard (desc, XkbAllComponentsMask, TRUE);
-}
-
-gboolean
-meta_seat_x11_a11y_init (ClutterSeat *seat)
-{
- Display *xdisplay = meta_clutter_x11_get_default_display ();
- guint event_mask;
-
- if (!is_xkb_available (xdisplay))
- return FALSE;
-
- event_mask = XkbControlsNotifyMask | XkbAccessXNotifyMask;
-
- XkbSelectEvents (xdisplay, XkbUseCoreKbd, event_mask, event_mask);
-
- meta_clutter_x11_add_filter (xkb_a11y_event_filter, seat);
-
- return TRUE;
-}
diff --git a/src/backends/x11/meta-xkb-a11y-x11.h b/src/backends/x11/meta-xkb-a11y-x11.h
deleted file mode 100644
index 58a4e1766..000000000
--- a/src/backends/x11/meta-xkb-a11y-x11.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *
- * Copyright © 2001 Ximian, Inc.
- * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
- * 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_XKB_A11Y_X11_H
-#define META_XKB_A11Y_X11_H
-
-#include <X11/Xlib.h>
-
-#include "backends/meta-input-settings-private.h"
-#include "clutter/clutter.h"
-
-void
-meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat,
- MetaKbdA11ySettings *kbd_a11y_settings);
-
-gboolean
-meta_seat_x11_a11y_init (ClutterSeat *seat);
-
-#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
deleted file mode 100644
index 041b42860..000000000
--- a/src/backends/x11/nested/meta-backend-x11-nested.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * 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-input-settings-dummy.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;
- MetaCursorRenderer *cursor_renderer;
- MetaInputSettings *input_settings;
-} 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_get_cursor_renderer (MetaBackend *backend,
- ClutterInputDevice *device)
-{
- MetaBackendX11Nested *backend_x11_nested = META_BACKEND_X11_NESTED (backend);
- MetaBackendX11NestedPrivate *priv =
- meta_backend_x11_nested_get_instance_private (backend_x11_nested);
-
- if (!priv->cursor_renderer)
- {
- priv->cursor_renderer =
- g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED,
- "backend", backend,
- "device", device,
- NULL);
- }
-
- return priv->cursor_renderer;
-}
-
-static MetaInputSettings *
-meta_backend_x11_nested_get_input_settings (MetaBackend *backend)
-{
- MetaBackendX11Nested *backend_x11_nested = META_BACKEND_X11_NESTED (backend);
- MetaBackendX11NestedPrivate *priv =
- meta_backend_x11_nested_get_instance_private (backend_x11_nested);
-
- if (!priv->input_settings)
- {
- priv->input_settings =
- g_object_new (META_TYPE_INPUT_SETTINGS_DUMMY, NULL);
- }
-
- return priv->input_settings;
-}
-
-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_clear_stage_views (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);
-}
-
-static gboolean
-meta_backend_x11_nested_initable_init (GInitable *initable,
- GCancellable *cancellable,
- GError **error)
-{
- 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_dispose (GObject *object)
-{
- MetaBackendX11Nested *backend_x11_nested = META_BACKEND_X11_NESTED (object);
- MetaBackendX11NestedPrivate *priv =
- meta_backend_x11_nested_get_instance_private (backend_x11_nested);
-
- g_clear_object (&priv->input_settings);
-
- G_OBJECT_CLASS (meta_backend_x11_nested_parent_class)->dispose (object);
-}
-
-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;
- object_class->dispose = meta_backend_x11_nested_dispose;
-
- 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->get_cursor_renderer = meta_backend_x11_nested_get_cursor_renderer;
- backend_class->get_input_settings = meta_backend_x11_nested_get_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
deleted file mode 100644
index 4f19ff54a..000000000
--- a/src/backends/x11/nested/meta-backend-x11-nested.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 0daae683c..000000000
--- a/src/backends/x11/nested/meta-cursor-renderer-x11-nested.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 32f816629..000000000
--- a/src/backends/x11/nested/meta-cursor-renderer-x11-nested.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 7c1a4facf..000000000
--- a/src/backends/x11/nested/meta-renderer-x11-nested.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/* -*- 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 "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 "backends/x11/meta-clutter-backend-x11.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,
- "name", "legacy nested",
- "stage", meta_backend_get_stage (backend),
- "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;
- const MetaCrtcConfig *crtc_config;
- int width, height;
- CoglOffscreen *fake_onscreen;
- CoglOffscreen *offscreen;
- MetaRectangle view_layout;
- const MetaCrtcModeInfo *mode_info;
- 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;
-
- crtc_config = meta_crtc_get_config (crtc);
- 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);
-
- mode_info = meta_crtc_mode_get_info (crtc_config->mode);
-
- view = g_object_new (META_TYPE_RENDERER_VIEW,
- "name", meta_output_get_name (output),
- "stage", meta_backend_get_stage (backend),
- "layout", &view_layout,
- "crtc", crtc,
- "refresh-rate", mode_info->refresh_rate,
- "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
deleted file mode 100644
index 9fc88e85b..000000000
--- a/src/backends/x11/nested/meta-renderer-x11-nested.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- 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
deleted file mode 100644
index dbf3b7bbf..000000000
--- a/src/backends/x11/nested/meta-stage-x11-nested.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/* -*- 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;
- MetaStageView *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;
- const MetaCrtcConfig *crtc_config;
- graphene_matrix_t projection_matrix;
- graphene_matrix_t 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 = meta_crtc_get_config (crtc);
-
- 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);
- graphene_matrix_init_scale (&projection_matrix, 2, -2, 0);
- graphene_matrix_translate (&projection_matrix,
- &GRAPHENE_POINT3D_INIT (-1, 1, 0));
- graphene_matrix_multiply (&transform, &projection_matrix, &projection_matrix);
- 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,
- ClutterStageView *stage_view,
- ClutterFrame *frame)
-{
- 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);
- CoglContext *context = cogl_framebuffer_get_context (onscreen);
- GList *l;
- CoglFrameInfo *frame_info;
-
- 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);
- }
-
- frame_info = cogl_frame_info_new (context, 0);
- cogl_onscreen_swap_buffers (stage_x11->onscreen, frame_info, frame);
-
- if (!clutter_frame_has_result (frame))
- clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_IDLE);
-}
-
-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
deleted file mode 100644
index 76678465b..000000000
--- a/src/backends/x11/nested/meta-stage-x11-nested.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 93edf8dc9..000000000
--- a/src/compositor/README
+++ /dev/null
@@ -1,70 +0,0 @@
-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
deleted file mode 100644
index 86d788562..000000000
--- a/src/compositor/clutter-utils.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Utilities for use with Cogl
- *
- * Copyright 2010 Red Hat, Inc.
- * Copyright 2010 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "compositor/clutter-utils.h"
-
-#include <math.h>
-
-/* This file uses pixel-aligned region computation to determine what
- * can be clipped out. This only really works if everything is aligned
- * to the pixel grid - not scaled or rotated and at integer offsets.
- *
- * (This could be relaxed - if we turned off filtering for unscaled
- * windows then windows would be, by definition aligned to the pixel
- * grid. And for rectangular windows without a shape, the outline that
- * we draw for an unrotated window is always a rectangle because we
- * don't use antialasing for the window boundary - with or without
- * filtering, with or without a scale. But figuring out exactly
- * what pixels will be drawn by the graphics system in these cases
- * gets tricky, so we just go for the easiest part - no scale,
- * and at integer offsets.)
- *
- * The way we check for pixel-aligned is by looking at the
- * transformation into screen space of the allocation box of an actor
- * and and checking if the corners are "close enough" to integral
- * pixel values.
- */
-
-/* The definition of "close enough" to integral pixel values is
- * equality when we convert to 24.8 fixed-point.
- */
-static inline int
-round_to_fixed (float x)
-{
- return roundf (x * 256);
-}
-
-/* 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))
-
-/* This helper function checks if (according to our fixed point precision)
- * the vertices @verts form a box of width @widthf and height @heightf
- * located at integral coordinates. These coordinates are returned
- * in @x_origin and @y_origin.
- */
-gboolean
-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);
-
- 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);
- v2x = round_to_fixed (verts[2].x); v2y = round_to_fixed (verts[2].y);
- v3x = round_to_fixed (verts[3].x); v3y = round_to_fixed (verts[3].y);
-
- /* Using shifting for converting fixed => int, gets things right for
- * negative values. / 256. wouldn't do the same
- */
- x = v0x >> 8;
- y = v0y >> 8;
-
- /* At integral coordinates? */
- if (x * 256 != v0x || y * 256 != v0y)
- return FALSE;
-
- /* Not scaled? */
- if (v1x - v0x != width || v2y - v0y != height)
- return FALSE;
-
- /* Not rotated/skewed? */
- if (v0x != v2x || v0y != v1y ||
- v3x != v1x || v3y != v2y)
- return FALSE;
-
- if (x_origin)
- *x_origin = x;
- if (y_origin)
- *y_origin = y;
-
- return TRUE;
-}
-
-/**
- * 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.
- * @y_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.
- *
- * Determines if the current painting transform is an integer translation.
- * This can differ from the result of meta_actor_is_untransformed() when
- * painting an actor if we're inside a inside a clone paint. @paint_width
- * and @paint_height are used to determine the vertices of the rectangle
- * we check to see if the painted area is "close enough" to the integer
- * transform.
- */
-gboolean
-meta_actor_painting_untransformed (CoglFramebuffer *fb,
- int paint_width,
- int paint_height,
- int sample_width,
- int sample_height,
- int *x_origin,
- int *y_origin)
-{
- graphene_matrix_t modelview, projection, modelview_projection;
- graphene_point3d_t vertices[4];
- float viewport[4];
- int i;
-
- cogl_framebuffer_get_modelview_matrix (fb, &modelview);
- cogl_framebuffer_get_projection_matrix (fb, &projection);
-
- graphene_matrix_multiply (&modelview,
- &projection,
- &modelview_projection);
-
- vertices[0].x = 0;
- vertices[0].y = 0;
- vertices[0].z = 0;
- vertices[1].x = paint_width;
- vertices[1].y = 0;
- vertices[1].z = 0;
- vertices[2].x = 0;
- vertices[2].y = paint_height;
- vertices[2].z = 0;
- vertices[3].x = paint_width;
- vertices[3].y = paint_height;
- vertices[3].z = 0;
-
- cogl_framebuffer_get_viewport4fv (fb, viewport);
-
- for (i = 0; i < 4; i++)
- {
- float w = 1;
- cogl_graphene_matrix_project_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,
- sample_width, sample_height,
- x_origin, y_origin);
-}
-
diff --git a/src/compositor/clutter-utils.h b/src/compositor/clutter-utils.h
deleted file mode 100644
index 8ed0e2a4d..000000000
--- a/src/compositor/clutter-utils.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Utilities for use with Clutter
- *
- * 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_CLUTTER_UTILS_H__
-#define __META_CLUTTER_UTILS_H__
-
-#include "clutter/clutter.h"
-
-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
deleted file mode 100644
index 0a39755a5..000000000
--- a/src/compositor/cogl-utils.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Utilities for use with Cogl
- *
- * Copyright 2010 Red Hat, Inc.
- * Copyright 2010 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.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_texture_pipeline:
- * @src_texture: (nullable): texture to use initially for the layer
- *
- * 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 #CoglPipeline
- */
-CoglPipeline *
-meta_create_texture_pipeline (CoglTexture *src_texture)
-{
- static CoglPipeline *texture_pipeline_template = NULL;
- CoglPipeline *pipeline;
-
- /* 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))
- {
- CoglContext *ctx =
- clutter_backend_get_cogl_context (clutter_get_default_backend ());
-
- texture_pipeline_template = cogl_pipeline_new (ctx);
- cogl_pipeline_set_layer_null_texture (texture_pipeline_template, 0);
- }
-
- pipeline = cogl_pipeline_copy (texture_pipeline_template);
-
- if (src_texture != NULL)
- cogl_pipeline_set_layer_texture (pipeline, 0, src_texture);
-
- return pipeline;
-}
-
-/**
- * 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.
- *
- * 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_create_texture (int width,
- int height,
- CoglTextureComponents components,
- MetaTextureFlags flags)
-{
- ClutterBackend *backend = clutter_get_default_backend ();
- CoglContext *ctx = clutter_backend_get_cogl_context (backend);
- CoglTexture *texture;
-
- texture = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height));
- cogl_texture_set_components (texture, components);
-
- 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
deleted file mode 100644
index ae7e85176..000000000
--- a/src/compositor/cogl-utils.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Utilities for use with Cogl
- *
- * 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_COGL_UTILS_H__
-#define __META_COGL_UTILS_H__
-
-#include "cogl/cogl.h"
-
-CoglPipeline * meta_create_texture_pipeline (CoglTexture *texture);
-
-typedef enum
-{
- META_TEXTURE_FLAGS_NONE = 0,
- META_TEXTURE_ALLOW_SLICING = 1 << 1
-} MetaTextureFlags;
-
-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
deleted file mode 100644
index 580618e48..000000000
--- a/src/compositor/compositor-private.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-#ifndef META_COMPOSITOR_PRIVATE_H
-#define META_COMPOSITOR_PRIVATE_H
-
-#include <X11/extensions/Xfixes.h>
-
-#include "clutter/clutter-mutter.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"
-
-/* Wait 2ms after vblank before starting to draw next frame */
-#define META_SYNC_DELAY 2
-
-typedef struct _MetaLaters MetaLaters;
-
-struct _MetaCompositorClass
-{
- GObjectClass parent_class;
-
- gboolean (* manage) (MetaCompositor *compositor,
- GError **error);
- void (* unmanage) (MetaCompositor *compositor);
- void (* before_paint) (MetaCompositor *compositor,
- ClutterStageView *stage_view);
- void (* after_paint) (MetaCompositor *compositor,
- ClutterStageView *stage_view);
- void (* remove_window) (MetaCompositor *compositor,
- MetaWindow *window);
- int64_t (* monotonic_to_high_res_xserver_time) (MetaCompositor *compositor,
- int64_t time_us);
- void (* grab_begin) (MetaCompositor *compositor);
- void (* grab_end) (MetaCompositor *compositor);
-};
-
-gboolean meta_compositor_do_manage (MetaCompositor *compositor,
- GError **error);
-
-void meta_compositor_remove_window_actor (MetaCompositor *compositor,
- MetaWindowActor *window_actor);
-
-void meta_switch_workspace_completed (MetaCompositor *compositor);
-
-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);
-
-MetaPluginManager * meta_compositor_get_plugin_manager (MetaCompositor *compositor);
-
-int64_t meta_compositor_monotonic_to_high_res_xserver_time (MetaCompositor *compositor,
- int64_t monotonic_time_us);
-
-void meta_compositor_flash_window (MetaCompositor *compositor,
- MetaWindow *window);
-
-MetaCloseDialog * meta_compositor_create_close_dialog (MetaCompositor *compositor,
- MetaWindow *window);
-
-MetaInhibitShortcutsDialog * meta_compositor_create_inhibit_shortcuts_dialog (MetaCompositor *compositor,
- MetaWindow *window);
-
-void meta_compositor_locate_pointer (MetaCompositor *compositor);
-
-void meta_compositor_redirect_x11_windows (MetaCompositor *compositor);
-
-gboolean meta_compositor_is_unredirect_inhibited (MetaCompositor *compositor);
-
-MetaDisplay * meta_compositor_get_display (MetaCompositor *compositor);
-
-MetaWindowActor * meta_compositor_get_top_window_actor (MetaCompositor *compositor);
-
-ClutterStage * meta_compositor_get_stage (MetaCompositor *compositor);
-
-gboolean meta_compositor_is_switching_workspace (MetaCompositor *compositor);
-
-MetaLaters * meta_compositor_get_laters (MetaCompositor *compositor);
-
-/*
- * 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;
-
- us = time_us % 1000;
- ms = time_us / 1000;
-
- return ms2us (ms & 0xffffffff) + us;
-}
-
-#endif /* META_COMPOSITOR_PRIVATE_H */
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
deleted file mode 100644
index 9cdd39c15..000000000
--- a/src/compositor/compositor.c
+++ /dev/null
@@ -1,1581 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * SECTION:compositor
- * @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.
- * meta_compositor_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
- *
- * meta_compositor_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 meta_compositor_show_window() and meta_compositor_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, meta_compositor_switch_workspace() is
- * called first, then meta_compositor_show_window() and
- * meta_compositor_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.
- *
- * # 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_display()
- * - top window group, accessible with meta_get_top_window_group_for_display()
- *
- * 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 <X11/extensions/Xcomposite.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-later-private.h"
-#include "compositor/meta-window-actor-x11.h"
-#include "compositor/meta-window-actor-private.h"
-#include "compositor/meta-window-group-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-context.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,
-
- PROP_DISPLAY,
- PROP_BACKEND,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS] = { NULL, };
-
-typedef struct _MetaCompositorPrivate
-{
- GObject parent;
-
- MetaDisplay *display;
- MetaBackend *backend;
-
- gulong stage_presented_id;
- gulong before_paint_handler_id;
- gulong after_paint_handler_id;
-
- int64_t server_time_query_time;
- int64_t server_time_offset;
-
- gboolean server_time_is_monotonic_time;
-
- ClutterActor *window_group;
- ClutterActor *top_window_group;
- ClutterActor *feedback_group;
-
- GList *windows;
-
- CoglContext *context;
-
- MetaWindowActor *top_window_actor;
- gulong top_window_actor_destroy_id;
-
- int disable_unredirect_count;
-
- int switch_workspace_in_progress;
-
- MetaPluginManager *plugin_mgr;
-
- MetaLaters *laters;
-} MetaCompositorPrivate;
-
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaCompositor, meta_compositor,
- G_TYPE_OBJECT)
-
-static void
-on_presented (ClutterStage *stage,
- ClutterStageView *stage_view,
- ClutterFrameInfo *frame_info,
- MetaCompositor *compositor);
-
-static void
-on_top_window_actor_destroyed (MetaWindowActor *window_actor,
- MetaCompositor *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
-meta_finish_workspace_switch (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- GList *l;
-
- /* Finish hiding and showing actors for the new workspace */
- for (l = priv->windows; l; l = l->next)
- meta_window_actor_sync_visibility (l->data);
-
- /* Fix up stacking order. */
- sync_actor_stacking (compositor);
-}
-
-void
-meta_switch_workspace_completed (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- /* FIXME -- must redo stacking order */
- priv->switch_workspace_in_progress--;
- if (priv->switch_workspace_in_progress < 0)
- {
- g_warning ("Error in workspace_switch accounting!");
- priv->switch_workspace_in_progress = 0;
- }
-
- if (!priv->switch_workspace_in_progress)
- meta_finish_workspace_switch (compositor);
-}
-
-void
-meta_compositor_destroy (MetaCompositor *compositor)
-{
- g_object_run_dispose (G_OBJECT (compositor));
- g_object_unref (compositor);
-}
-
-/* compat helper */
-static MetaCompositor *
-get_compositor_for_display (MetaDisplay *display)
-{
- return display->compositor;
-}
-
-/**
- * meta_get_stage_for_display:
- * @display: a #MetaDisplay
- *
- * Returns: (transfer none): The #ClutterStage for the display
- */
-ClutterActor *
-meta_get_stage_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 meta_backend_get_stage (priv->backend);
-}
-
-/**
- * meta_get_window_group_for_display:
- * @display: a #MetaDisplay
- *
- * Returns: (transfer none): The window group corresponding to @display
- */
-ClutterActor *
-meta_get_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->window_group;
-}
-
-/**
- * meta_get_top_window_group_for_display:
- * @display: a #MetaDisplay
- *
- * Returns: (transfer none): The top window group corresponding to @display
- */
-ClutterActor *
-meta_get_top_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->top_window_group;
-}
-
-/**
- * meta_get_feedback_group_for_display:
- * @display: a #MetaDisplay
- *
- * Returns: (transfer none): The feedback group corresponding to @display
- */
-ClutterActor *
-meta_get_feedback_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->feedback_group;
-}
-
-/**
- * meta_get_window_actors:
- * @display: a #MetaDisplay
- *
- * Returns: (transfer none) (element-type Clutter.Actor): The set of #MetaWindowActor on @display
- */
-GList *
-meta_get_window_actors (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->windows;
-}
-
-void
-meta_focus_stage_window (MetaDisplay *display,
- guint32 timestamp)
-{
- ClutterStage *stage;
- Window window;
-
- stage = CLUTTER_STAGE (meta_get_stage_for_display (display));
- if (!stage)
- return;
-
- window = meta_x11_get_stage_window (stage);
-
- if (window == None)
- return;
-
- meta_x11_display_set_input_focus_xwindow (display->x11_display,
- window,
- timestamp);
-}
-
-gboolean
-meta_stage_is_focused (MetaDisplay *display)
-{
- ClutterStage *stage;
- Window window;
-
- 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);
-}
-
-static gboolean
-grab_devices (MetaModalOptions options,
- guint32 timestamp)
-{
- MetaBackend *backend = META_BACKEND (meta_get_backend ());
- gboolean pointer_grabbed = FALSE;
- gboolean keyboard_grabbed = FALSE;
-
- 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)
- {
- if (!meta_backend_grab_device (backend, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp))
- goto fail;
-
- keyboard_grabbed = TRUE;
- }
-
- 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;
-}
-
-static void
-meta_compositor_grab_begin (MetaCompositor *compositor)
-{
- META_COMPOSITOR_GET_CLASS (compositor)->grab_begin (compositor);
-}
-
-static void
-meta_compositor_grab_end (MetaCompositor *compositor)
-{
- META_COMPOSITOR_GET_CLASS (compositor)->grab_end (compositor);
-}
-
-gboolean
-meta_begin_modal_for_plugin (MetaCompositor *compositor,
- MetaPlugin *plugin,
- MetaModalOptions options,
- guint32 timestamp)
-{
- /* To some extent this duplicates code in meta_display_begin_grab_op(), but there
- * 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;
-
-#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 (is_modal (display) || display->grab_op != META_GRAB_OP_NONE)
- return FALSE;
-
- if (display->x11_display)
- {
- /* XXX: why is this needed? */
- XIUngrabDevice (display->x11_display->xdisplay,
- META_VIRTUAL_CORE_POINTER_ID,
- timestamp);
- XSync (display->x11_display->xdisplay, False);
- }
-
- 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_have_pointer = TRUE;
- display->grab_have_keyboard = TRUE;
-
- g_signal_emit_by_name (display, "grab-op-begin",
- display->grab_window, display->grab_op);
-
- meta_compositor_grab_begin (compositor);
-
- return TRUE;
-}
-
-void
-meta_end_modal_for_plugin (MetaCompositor *compositor,
- MetaPlugin *plugin,
- guint32 timestamp)
-{
- 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;
-
- 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_have_pointer = FALSE;
- display->grab_have_keyboard = FALSE;
-
- meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp);
- meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
-
- meta_compositor_grab_end (compositor);
-
- g_signal_emit_by_name (display, "grab-op-end",
- grab_window, grab_op);
-}
-
-static void
-redirect_windows (MetaX11Display *x11_display)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaContext *context = meta_backend_get_context (backend);
- 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_context_is_replacing (context))
- max_retries = 5;
- else
- max_retries = 1;
-
- n_retries = 0;
-
- /* 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_x11_error_trap_push (x11_display);
- XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual);
- XSync (xdisplay, FALSE);
-
- 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, x11_display->name);
- }
-
- n_retries++;
- g_usleep (G_USEC_PER_SEC);
- }
-}
-
-void
-meta_compositor_redirect_x11_windows (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- MetaDisplay *display = priv->display;
-
- if (display->x11_display)
- redirect_windows (display->x11_display);
-}
-
-gboolean
-meta_compositor_do_manage (MetaCompositor *compositor,
- GError **error)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- MetaDisplay *display = priv->display;
- MetaBackend *backend = priv->backend;
- ClutterActor *stage = meta_backend_get_stage (backend);
-
- priv->stage_presented_id =
- g_signal_connect (stage, "presented",
- G_CALLBACK (on_presented),
- 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);
-
- clutter_actor_add_child (stage, priv->window_group);
- clutter_actor_add_child (stage, priv->top_window_group);
- clutter_actor_add_child (stage, priv->feedback_group);
-
- if (!META_COMPOSITOR_GET_CLASS (compositor)->manage (compositor, error))
- return FALSE;
-
- priv->plugin_mgr = meta_plugin_manager_new (compositor);
-
- return TRUE;
-}
-
-void
-meta_compositor_manage (MetaCompositor *compositor)
-{
- GError *error = NULL;
-
- if (!meta_compositor_do_manage (compositor, &error))
- g_error ("Compositor failed to manage display: %s", error->message);
-}
-
-void
-meta_compositor_unmanage (MetaCompositor *compositor)
-{
- META_COMPOSITOR_GET_CLASS (compositor)->unmanage (compositor);
-}
-
-void
-meta_compositor_add_window (MetaCompositor *compositor,
- MetaWindow *window)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- MetaWindowActor *window_actor;
- ClutterActor *window_group;
- GType window_actor_type = G_TYPE_INVALID;
-
- switch (window->client_type)
- {
- case META_WINDOW_CLIENT_TYPE_X11:
- window_actor_type = META_TYPE_WINDOW_ACTOR_X11;
- break;
-
-#ifdef HAVE_WAYLAND
- case META_WINDOW_CLIENT_TYPE_WAYLAND:
- window_actor_type = META_TYPE_WINDOW_ACTOR_WAYLAND;
- break;
-#endif
-
- default:
- g_return_if_reached ();
- }
-
- window_actor = g_object_new (window_actor_type,
- "meta-window", window,
- "show-on-set-parent", FALSE,
- NULL);
-
- if (window->layer == META_LAYER_OVERRIDE_REDIRECT)
- window_group = priv->top_window_group;
- else
- window_group = priv->window_group;
-
- 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);
-}
-
-static void
-meta_compositor_real_remove_window (MetaCompositor *compositor,
- MetaWindow *window)
-{
- MetaWindowActor *window_actor = meta_window_actor_from_window (window);
-
- meta_window_actor_queue_destroy (window_actor);
-}
-
-void
-meta_compositor_remove_window (MetaCompositor *compositor,
- MetaWindow *window)
-{
- META_COMPOSITOR_GET_CLASS (compositor)->remove_window (compositor, window);
-}
-
-void
-meta_compositor_remove_window_actor (MetaCompositor *compositor,
- MetaWindowActor *window_actor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- priv->windows = g_list_remove (priv->windows, window_actor);
-}
-
-void
-meta_compositor_sync_updates_frozen (MetaCompositor *compositor,
- MetaWindow *window)
-{
- MetaWindowActor *window_actor = meta_window_actor_from_window (window);
-
- meta_window_actor_sync_updates_frozen (window_actor);
-}
-
-void
-meta_compositor_queue_frame_drawn (MetaCompositor *compositor,
- MetaWindow *window,
- gboolean no_delay_frame)
-{
- MetaWindowActor *window_actor = meta_window_actor_from_window (window);
-
- meta_window_actor_queue_frame_drawn (window_actor, no_delay_frame);
-}
-
-void
-meta_compositor_window_shape_changed (MetaCompositor *compositor,
- MetaWindow *window)
-{
- MetaWindowActor *window_actor;
-
- window_actor = meta_window_actor_from_window (window);
- if (!window_actor)
- return;
-
- meta_window_actor_x11_update_shape (META_WINDOW_ACTOR_X11 (window_actor));
-}
-
-void
-meta_compositor_window_opacity_changed (MetaCompositor *compositor,
- MetaWindow *window)
-{
- MetaWindowActor *window_actor;
-
- window_actor = meta_window_actor_from_window (window);
- if (!window_actor)
- return;
-
- meta_window_actor_update_opacity (window_actor);
-}
-
-gboolean
-meta_compositor_filter_keybinding (MetaCompositor *compositor,
- MetaKeyBinding *binding)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return meta_plugin_manager_filter_keybinding (priv->plugin_mgr, binding);
-}
-
-void
-meta_compositor_show_window (MetaCompositor *compositor,
- MetaWindow *window,
- MetaCompEffect effect)
-{
- MetaWindowActor *window_actor = meta_window_actor_from_window (window);
-
- meta_window_actor_show (window_actor, effect);
-}
-
-void
-meta_compositor_hide_window (MetaCompositor *compositor,
- MetaWindow *window,
- MetaCompEffect effect)
-{
- 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_size_change_window (MetaCompositor *compositor,
- MetaWindow *window,
- MetaSizeChange which_change,
- MetaRectangle *old_frame_rect,
- MetaRectangle *old_buffer_rect)
-{
- MetaWindowActor *window_actor = meta_window_actor_from_window (window);
-
- meta_window_actor_size_change (window_actor, which_change, old_frame_rect, old_buffer_rect);
-}
-
-void
-meta_compositor_switch_workspace (MetaCompositor *compositor,
- 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);
-
- priv->switch_workspace_in_progress++;
-
- if (!meta_plugin_manager_switch_workspace (priv->plugin_mgr,
- from_indx,
- to_indx,
- direction))
- {
- priv->switch_workspace_in_progress--;
-
- /* We have to explicitly call this to fix up stacking order of the
- * actors; this is because the abs stacking position of actors does not
- * necessarily change during the window hiding/unhiding, only their
- * relative position toward the destkop window.
- */
- meta_finish_workspace_switch (compositor);
- }
-}
-
-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 */
-
- /* Restacking will trigger full screen redraws, so it's worth a
- * little effort to make sure we actually need to restack before
- * we go ahead and do it */
-
- children = clutter_actor_get_children (priv->window_group);
- has_windows = FALSE;
- reordered = FALSE;
-
- /* 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.)
- */
-
- /* 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)
- {
- ClutterActor *actor = old->data;
-
- if (META_IS_BACKGROUND_GROUP (actor) ||
- META_IS_BACKGROUND_ACTOR (actor))
- {
- backgrounds = g_list_prepend (backgrounds, actor);
-
- if (has_windows)
- reordered = TRUE;
- }
- else if (META_IS_WINDOW_ACTOR (actor) && !reordered)
- {
- has_windows = TRUE;
-
- if (expected_window_node != NULL && actor == expected_window_node->data)
- expected_window_node = expected_window_node->next;
- else
- reordered = TRUE;
- }
- }
-
- g_list_free (children);
-
- if (!reordered)
- {
- 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;
-
- parent = clutter_actor_get_parent (actor);
- clutter_actor_set_child_below_sibling (parent, actor, NULL);
- }
-
- /* 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, *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);
-
- meta_stack_tracker_queue_sync_stack (priv->display->stack_tracker);
-}
-
-void
-meta_compositor_sync_stack (MetaCompositor *compositor,
- GList *stack)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- MetaWindowActor *top_window_actor;
- GList *old_stack;
-
- /* 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
- * until the animation effect finishes.
- */
-
- /* Sources: first window is the highest */
- stack = g_list_copy (stack); /* The new stack of MetaWindow */
- old_stack = g_list_reverse (priv->windows); /* The old stack of MetaWindowActor */
- priv->windows = NULL;
-
- while (TRUE)
- {
- MetaWindowActor *old_actor = NULL, *stack_actor = NULL, *actor;
- MetaWindow *old_window = NULL, *stack_window = NULL, *window;
-
- /* Find the remaining top actor in our existing stack (ignoring
- * windows that have been hidden and are no longer animating) */
- while (old_stack)
- {
- old_actor = old_stack->data;
- old_window = meta_window_actor_get_meta_window (old_actor);
-
- if ((old_window->hidden || old_window->unmanaging) &&
- !meta_window_actor_effect_in_progress (old_actor))
- {
- old_stack = g_list_delete_link (old_stack, old_stack);
- old_actor = NULL;
- }
- else
- break;
- }
-
- /* And the remaining top actor in the new stack */
- while (stack)
- {
- stack_window = stack->data;
- stack_actor = meta_window_actor_from_window (stack_window);
- if (!stack_actor)
- {
- meta_verbose ("Failed to find corresponding MetaWindowActor "
- "for window %s", meta_window_get_description (stack_window));
- stack = g_list_delete_link (stack, stack);
- }
- else
- break;
- }
-
- if (!old_actor && !stack_actor) /* Nothing more to stack */
- break;
-
- /* We usually prefer the window in the new stack, but if if we
- * found a hidden window in the process of being animated out
- * of existence in the old stack we use that instead. We've
- * filtered out non-animating hidden windows above.
- */
- if (old_actor &&
- (!stack_actor || old_window->hidden || old_window->unmanaging))
- {
- actor = old_actor;
- window = old_window;
- }
- else
- {
- actor = stack_actor;
- window = stack_window;
- }
-
- /* OK, we know what actor we want next. Add it to our window
- * list, and remove it from both source lists. (It will
- * be at the front of at least one, hopefully it will be
- * near the front of the other.)
- */
- 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);
-
- top_window_actor = get_top_visible_window_actor (compositor);
-
- if (priv->top_window_actor == top_window_actor)
- return;
-
- 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_window_geometry (MetaCompositor *compositor,
- MetaWindow *window,
- gboolean did_placement)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- MetaWindowActor *window_actor = meta_window_actor_from_window (window);
- MetaWindowActorChanges changes;
-
- changes = meta_window_actor_sync_actor_geometry (window_actor, did_placement);
-
- if (changes & META_WINDOW_ACTOR_CHANGE_SIZE)
- meta_plugin_manager_event_size_changed (priv->plugin_mgr, window_actor);
-}
-
-static void
-on_presented (ClutterStage *stage,
- ClutterStageView *stage_view,
- ClutterFrameInfo *frame_info,
- MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- int64_t presentation_time = frame_info->presentation_time;
- GList *l;
-
- for (l = priv->windows; l; l = l->next)
- {
- ClutterActor *actor = l->data;
- GList *actor_stage_views;
-
- actor_stage_views = clutter_actor_peek_stage_views (actor);
- if (g_list_find (actor_stage_views, stage_view))
- {
- meta_window_actor_frame_complete (META_WINDOW_ACTOR (actor),
- frame_info,
- presentation_time);
- }
- }
-}
-
-static void
-meta_compositor_real_before_paint (MetaCompositor *compositor,
- ClutterStageView *stage_view)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- GList *l;
-
- for (l = priv->windows; l; l = l->next)
- meta_window_actor_before_paint (l->data, stage_view);
-}
-
-static void
-meta_compositor_before_paint (MetaCompositor *compositor,
- ClutterStageView *stage_view)
-{
- COGL_TRACE_BEGIN_SCOPED (MetaCompositorPrePaint,
- "Compositor (before-paint)");
- META_COMPOSITOR_GET_CLASS (compositor)->before_paint (compositor, stage_view);
-}
-
-static void
-meta_compositor_real_after_paint (MetaCompositor *compositor,
- ClutterStageView *stage_view)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- ClutterActor *stage_actor = meta_backend_get_stage (priv->backend);
- CoglGraphicsResetStatus status;
- GList *l;
-
- 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 (priv->display, "gl-video-memory-purged");
- g_signal_emit_by_name (stage_actor, "gl-video-memory-purged");
- clutter_actor_queue_redraw (stage_actor);
- break;
-
- default:
- /* The ARB_robustness spec says that, on error, the application
- should destroy the old context and create a new one. Since we
- don't have the necessary plumbing to do this we'll simply
- 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. */
- g_assert (!meta_is_wayland_compositor ());
- meta_restart (NULL);
- break;
- }
-
- for (l = priv->windows; l; l = l->next)
- {
- ClutterActor *actor = l->data;
- GList *actor_stage_views;
-
- actor_stage_views = clutter_actor_peek_stage_views (actor);
- if (g_list_find (actor_stage_views, stage_view))
- meta_window_actor_after_paint (META_WINDOW_ACTOR (actor), stage_view);
- }
-}
-
-static void
-meta_compositor_after_paint (MetaCompositor *compositor,
- ClutterStageView *stage_view)
-{
- COGL_TRACE_BEGIN_SCOPED (MetaCompositorPostPaint,
- "Compositor (after-paint)");
- META_COMPOSITOR_GET_CLASS (compositor)->after_paint (compositor, stage_view);
-}
-
-static void
-on_before_paint (ClutterStage *stage,
- ClutterStageView *stage_view,
- MetaCompositor *compositor)
-{
- meta_compositor_before_paint (compositor, stage_view);
-}
-
-static void
-on_after_paint (ClutterStage *stage,
- ClutterStageView *stage_view,
- MetaCompositor *compositor)
-{
- meta_compositor_after_paint (compositor, stage_view);
-}
-
-static void
-meta_compositor_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaCompositor *compositor = META_COMPOSITOR (object);
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- switch (prop_id)
- {
- case PROP_DISPLAY:
- priv->display = g_value_get_object (value);
- break;
- 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_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);
-
- switch (prop_id)
- {
- case PROP_DISPLAY:
- g_value_set_object (value, priv->display);
- break;
- 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_compositor_init (MetaCompositor *compositor)
-{
-}
-
-static void
-meta_compositor_constructed (GObject *object)
-{
- MetaCompositor *compositor = META_COMPOSITOR (object);
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- ClutterBackend *clutter_backend =
- meta_backend_get_clutter_backend (priv->backend);
- ClutterActor *stage = meta_backend_get_stage (priv->backend);
-
- priv->context = clutter_backend->cogl_context;
-
- priv->before_paint_handler_id =
- g_signal_connect (stage,
- "before-paint",
- G_CALLBACK (on_before_paint),
- compositor);
- priv->after_paint_handler_id =
- g_signal_connect_after (stage,
- "after-paint",
- G_CALLBACK (on_after_paint),
- compositor);
-
- priv->laters = meta_laters_new (compositor);
-
- G_OBJECT_CLASS (meta_compositor_parent_class)->constructed (object);
-}
-
-static void
-meta_compositor_dispose (GObject *object)
-{
- MetaCompositor *compositor = META_COMPOSITOR (object);
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
- ClutterActor *stage = meta_backend_get_stage (priv->backend);
-
- g_clear_pointer (&priv->laters, meta_laters_free);
-
- g_clear_signal_handler (&priv->stage_presented_id, stage);
- g_clear_signal_handler (&priv->before_paint_handler_id, stage);
- g_clear_signal_handler (&priv->after_paint_handler_id, stage);
-
- g_clear_signal_handler (&priv->top_window_actor_destroy_id,
- priv->top_window_actor);
-
- 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);
-
- G_OBJECT_CLASS (meta_compositor_parent_class)->dispose (object);
-}
-
-static void
-meta_compositor_class_init (MetaCompositorClass *klass)
-{
- 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->constructed = meta_compositor_constructed;
- object_class->dispose = meta_compositor_dispose;
-
- klass->remove_window = meta_compositor_real_remove_window;
- klass->before_paint = meta_compositor_real_before_paint;
- klass->after_paint = meta_compositor_real_after_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);
- 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);
-}
-
-/**
- * meta_disable_unredirect_for_display:
- * @display: a #MetaDisplay
- *
- * Disables unredirection, can be useful in situations where having
- * unredirected windows is undesirable like when recording a video.
- *
- */
-void
-meta_disable_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);
-
- priv->disable_unredirect_count++;
-}
-
-/**
- * meta_enable_unredirect_for_display:
- * @display: a #MetaDisplay
- *
- * Enables unredirection which reduces the overhead for apps like games.
- *
- */
-void
-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)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return priv->disable_unredirect_count > 0;
-}
-
-#define FLASH_TIME_MS 50
-
-static void
-flash_out_completed (ClutterTimeline *timeline,
- gboolean is_finished,
- gpointer user_data)
-{
- ClutterActor *flash = CLUTTER_ACTOR (user_data);
- clutter_actor_destroy (flash);
-}
-
-void
-meta_compositor_flash_display (MetaCompositor *compositor,
- MetaDisplay *display)
-{
- ClutterActor *stage;
- ClutterActor *flash;
- ClutterTransition *transition;
- gfloat width, height;
-
- stage = meta_get_stage_for_display (display);
- clutter_actor_get_size (stage, &width, &height);
-
- flash = clutter_actor_new ();
- clutter_actor_set_background_color (flash, CLUTTER_COLOR_Black);
- clutter_actor_set_size (flash, width, height);
- clutter_actor_set_opacity (flash, 0);
- clutter_actor_add_child (stage, flash);
-
- 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 (flash_out_completed), flash);
-
- clutter_actor_restore_easing_state (flash);
-}
-
-static void
-window_flash_out_completed (ClutterTimeline *timeline,
- gboolean is_finished,
- gpointer user_data)
-{
- ClutterActor *flash = CLUTTER_ACTOR (user_data);
- clutter_actor_destroy (flash);
-}
-
-void
-meta_compositor_flash_window (MetaCompositor *compositor,
- MetaWindow *window)
-{
- ClutterActor *window_actor =
- CLUTTER_ACTOR (meta_window_actor_from_window (window));
- ClutterActor *flash;
- ClutterTransition *transition;
-
- 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);
-
- 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_to_high_res_xserver_time:
- * @display: a #MetaDisplay
- * @monotonic_time: time in the units of g_get_monotonic_time()
- *
- * _NET_WM_FRAME_DRAWN and _NET_WM_FRAME_TIMINGS messages represent time
- * as a "high resolution server time" - this is the server time interpolated
- * to microsecond resolution. The advantage of this time representation
- * is that if X server is running on the same computer as a client, and
- * the Xserver uses 'clock_gettime(CLOCK_MONOTONIC, ...)' for the server
- * time, the client can detect this, and all such clients will share a
- * a time representation with high accuracy. If there is not a common
- * time source, then the time synchronization will be less accurate.
- */
-int64_t
-meta_compositor_monotonic_to_high_res_xserver_time (MetaCompositor *compositor,
- int64_t monotonic_time_us)
-{
- MetaCompositorClass *klass = META_COMPOSITOR_GET_CLASS (compositor);
-
- return klass->monotonic_to_high_res_xserver_time (compositor, monotonic_time_us);
-}
-
-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);
-
- 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_show_window_menu (MetaCompositor *compositor,
- MetaWindow *window,
- MetaWindowMenuType menu,
- int x,
- int y)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- meta_plugin_manager_show_window_menu (priv->plugin_mgr, window, menu, x, y);
-}
-
-void
-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)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return meta_plugin_manager_create_close_dialog (priv->plugin_mgr,
- window);
-}
-
-MetaInhibitShortcutsDialog *
-meta_compositor_create_inhibit_shortcuts_dialog (MetaCompositor *compositor,
- MetaWindow *window)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return meta_plugin_manager_create_inhibit_shortcuts_dialog (priv->plugin_mgr,
- window);
-}
-
-void
-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 (meta_backend_get_stage (priv->backend));
-}
-
-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)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return priv->switch_workspace_in_progress > 0;
-}
-
-MetaLaters *
-meta_compositor_get_laters (MetaCompositor *compositor)
-{
- MetaCompositorPrivate *priv =
- meta_compositor_get_instance_private (compositor);
-
- return priv->laters;
-}
diff --git a/src/compositor/meta-background-actor-private.h b/src/compositor/meta-background-actor-private.h
deleted file mode 100644
index bdf8c4744..000000000
--- a/src/compositor/meta-background-actor-private.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-#ifndef META_BACKGROUND_ACTOR_PRIVATE_H
-#define META_BACKGROUND_ACTOR_PRIVATE_H
-
-#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
deleted file mode 100644
index 105f94259..000000000
--- a/src/compositor/meta-background-actor.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Copyright 2009 Sander Dijkhuis
- * 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/>.
- *
- * Portions adapted from gnome-shell/src/shell-global.c
- */
-
-#include "config.h"
-
-#include "compositor/meta-background-actor-private.h"
-#include "compositor/meta-background-content-private.h"
-
-#include "compositor/meta-cullable.h"
-
-enum
-{
- PROP_META_DISPLAY = 1,
- PROP_MONITOR,
-};
-
-struct _MetaBackgroundActor
-{
- ClutterActor parent;
-
- MetaDisplay *display;
- int monitor;
-
- MetaBackgroundContent *content;
-};
-
-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
-maybe_create_content (MetaBackgroundActor *self)
-{
- g_autoptr (ClutterContent) content = NULL;
-
- if (self->content || !self->display || self->monitor == -1)
- return;
-
- content = meta_background_content_new (self->display, self->monitor);
- self->content = META_BACKGROUND_CONTENT (content);
- clutter_actor_set_content (CLUTTER_ACTOR (self), content);
-}
-
-static void
-meta_background_actor_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
-
- switch (prop_id)
- {
- case PROP_META_DISPLAY:
- self->display = g_value_get_object (value);
- maybe_create_content (self);
- break;
- case PROP_MONITOR:
- self->monitor = g_value_get_int (value);
- maybe_create_content (self);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-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_META_DISPLAY:
- g_value_set_object (value, self->display);
- break;
- case PROP_MONITOR:
- g_value_set_int (value, self->monitor);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_background_actor_class_init (MetaBackgroundActorClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GParamSpec *param_spec;
-
- object_class->set_property = meta_background_actor_set_property;
- object_class->get_property = meta_background_actor_get_property;
-
- 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);
-}
-
-static void
-meta_background_actor_init (MetaBackgroundActor *self)
-{
- self->monitor = -1;
-
- clutter_actor_set_request_mode (CLUTTER_ACTOR (self),
- CLUTTER_REQUEST_CONTENT_SIZE);
-}
-
-/**
- * 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 monitor.
- *
- * Return value: the newly created background actor
- */
-ClutterActor *
-meta_background_actor_new (MetaDisplay *display,
- int monitor)
-{
- MetaBackgroundActor *self;
-
- self = g_object_new (META_TYPE_BACKGROUND_ACTOR,
- "meta-display", display,
- "monitor", monitor,
- NULL);
-
- return CLUTTER_ACTOR (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);
-
- if (!self->content)
- return;
-
- meta_background_content_cull_out (self->content,
- unobscured_region,
- clip_region);
-}
-
-static void
-meta_background_actor_reset_culling (MetaCullable *cullable)
-{
- MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable);
-
- if (!self->content)
- return;
-
- meta_background_content_reset_culling (self->content);
-}
-
-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_get_clip_region:
- * @self: a #MetaBackgroundActor
- *
- * Return value (transfer none): a #cairo_region_t that represents the part of
- * the background not obscured by other #MetaBackgroundActor or
- * #MetaWindowActor objects.
- */
-cairo_region_t *
-meta_background_actor_get_clip_region (MetaBackgroundActor *self)
-{
- if (!self->content)
- return NULL;
-
- return meta_background_content_get_clip_region (self->content);
-}
diff --git a/src/compositor/meta-background-content-private.h b/src/compositor/meta-background-content-private.h
deleted file mode 100644
index 284cddb3a..000000000
--- a/src/compositor/meta-background-content-private.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-#ifndef META_BACKGROUND_CONTENT_PRIVATE_H
-#define META_BACKGROUND_CONTENT_PRIVATE_H
-
-#include "meta/meta-background-content.h"
-
-cairo_region_t *meta_background_content_get_clip_region (MetaBackgroundContent *self);
-
-void meta_background_content_cull_out (MetaBackgroundContent *self,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region);
-
-void meta_background_content_reset_culling (MetaBackgroundContent *self);
-
-#endif /* META_BACKGROUND_CONTENT_PRIVATE_H */
diff --git a/src/compositor/meta-background-content.c b/src/compositor/meta-background-content.c
deleted file mode 100644
index 86f777752..000000000
--- a/src/compositor/meta-background-content.c
+++ /dev/null
@@ -1,1312 +0,0 @@
-/*
- * Copyright 2009 Sander Dijkhuis
- * Copyright 2014 Red Hat, Inc.
- * Copyright 2020 Endless Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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 adapted from gnome-shell/src/shell-global.c
- */
-
-
-/**
- * SECTION:meta-background-content
- * @title: MetaBackgroundContent
- * @short_description: ClutterContent for painting the root window background
- *
- */
-
-/*
- * The overall model drawing model of this content 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 "config.h"
-
-#include "compositor/meta-background-content-private.h"
-
-#include "backends/meta-backend-private.h"
-#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"
-
-typedef enum
-{
- CHANGED_BACKGROUND = 1 << 0,
- CHANGED_EFFECTS = 1 << 2,
- CHANGED_VIGNETTE_PARAMETERS = 1 << 3,
- CHANGED_GRADIENT_PARAMETERS = 1 << 4,
- CHANGED_ROUNDED_CLIP_PARAMETERS = 1 << 5,
- 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" \
-
-/* The ellipsis_dist(), ellipsis_coverage() and rounded_rect_coverage() are
- * copied from GSK, see gsk_ellipsis_dist(), gsk_ellipsis_coverage(), and
- * gsk_rounded_rect_coverage() here:
- * https://gitlab.gnome.org/GNOME/gtk/-/blob/4.3.1/gsk/gl/resources/preamble.fs.glsl
- */
-#define ROUNDED_CLIP_FRAGMENT_SHADER_DECLARATIONS \
-"uniform vec4 bounds; // x, y: top left; w, v: bottom right \n"\
-"uniform vec4 corner_centers_1; // x, y: top left; w, v: top right \n"\
-"uniform vec4 corner_centers_2; // x, y: bottom right; w, v: bottom left \n"\
-"uniform vec2 pixel_step; \n"\
-" \n"\
-"float \n"\
-"ellipsis_dist (vec2 p, vec2 radius) \n"\
-"{ \n"\
-" if (radius == vec2(0, 0)) \n"\
-" return 0.0; \n"\
-" \n"\
-" vec2 p0 = p / radius; \n"\
-" vec2 p1 = (2.0 * p0) / radius; \n"\
-" \n"\
-" return (dot(p0, p0) - 1.0) / length (p1); \n"\
-"} \n"\
-" \n"\
-"float \n"\
-"ellipsis_coverage (vec2 point, vec2 center, vec2 radius) \n"\
-"{ \n"\
-" float d = ellipsis_dist ((point - center), radius); \n"\
-" return clamp (0.5 - d, 0.0, 1.0); \n"\
-"} \n"\
-" \n"\
-"float \n"\
-"rounded_rect_coverage (vec4 bounds, \n"\
-" vec4 corner_centers_1, \n"\
-" vec4 corner_centers_2, \n"\
-" vec2 p) \n"\
-"{ \n"\
-" if (p.x < bounds.x || p.y < bounds.y || \n"\
-" p.x >= bounds.z || p.y >= bounds.w) \n"\
-" return 0.0; \n"\
-" \n"\
-" vec2 ref_tl = corner_centers_1.xy; \n"\
-" vec2 ref_tr = corner_centers_1.zw; \n"\
-" vec2 ref_br = corner_centers_2.xy; \n"\
-" vec2 ref_bl = corner_centers_2.zw; \n"\
-" \n"\
-" if (p.x >= ref_tl.x && p.x >= ref_bl.x && \n"\
-" p.x <= ref_tr.x && p.x <= ref_br.x) \n"\
-" return 1.0; \n"\
-" \n"\
-" if (p.y >= ref_tl.y && p.y >= ref_tr.y && \n"\
-" p.y <= ref_bl.y && p.y <= ref_br.y) \n"\
-" return 1.0; \n"\
-" \n"\
-" vec2 rad_tl = corner_centers_1.xy - bounds.xy; \n"\
-" vec2 rad_tr = corner_centers_1.zw - bounds.zy; \n"\
-" vec2 rad_br = corner_centers_2.xy - bounds.zw; \n"\
-" vec2 rad_bl = corner_centers_2.zw - bounds.xw; \n"\
-" \n"\
-" float d_tl = ellipsis_coverage(p, ref_tl, rad_tl); \n"\
-" float d_tr = ellipsis_coverage(p, ref_tr, rad_tr); \n"\
-" float d_br = ellipsis_coverage(p, ref_br, rad_br); \n"\
-" float d_bl = ellipsis_coverage(p, ref_bl, rad_bl); \n"\
-" \n"\
-" vec4 corner_coverages = 1.0 - vec4(d_tl, d_tr, d_br, d_bl); \n"\
-" \n"\
-" bvec4 is_out = bvec4(p.x < ref_tl.x && p.y < ref_tl.y, \n"\
-" p.x > ref_tr.x && p.y < ref_tr.y, \n"\
-" p.x > ref_br.x && p.y > ref_br.y, \n"\
-" p.x < ref_bl.x && p.y > ref_bl.y); \n"\
-" \n"\
-" return 1.0 - dot(vec4(is_out), corner_coverages); \n"\
-"} \n"
-
-#define ROUNDED_CLIP_FRAGMENT_SHADER_CODE \
-"vec2 texture_coord; \n"\
-" \n"\
-"texture_coord = cogl_tex_coord0_in.xy / pixel_step; \n"\
-" \n"\
-"cogl_color_out *= rounded_rect_coverage (bounds, \n"\
-" corner_centers_1, \n"\
-" corner_centers_2, \n"\
-" texture_coord); \n"
-
-typedef struct _MetaBackgroundLayer MetaBackgroundLayer;
-
-typedef enum
-{
- PIPELINE_VIGNETTE = (1 << 0),
- PIPELINE_BLEND = (1 << 1),
- PIPELINE_GRADIENT = (1 << 2),
- PIPELINE_ROUNDED_CLIP = (1 << 3),
-
- PIPELINE_ALL = (PIPELINE_VIGNETTE |
- PIPELINE_BLEND |
- PIPELINE_GRADIENT |
- PIPELINE_ROUNDED_CLIP)
-} PipelineFlags;
-
-struct _MetaBackgroundContent
-{
- GObject parent;
-
- MetaDisplay *display;
- int monitor;
-
- MetaBackground *background;
-
- gboolean gradient;
- double gradient_max_darkness;
- int gradient_height;
-
- gboolean vignette;
- double vignette_brightness;
- double vignette_sharpness;
-
- gboolean has_rounded_clip;
- float rounded_clip_radius;
- gboolean rounded_clip_bounds_set;
- graphene_rect_t rounded_clip_bounds;
-
- ChangedFlags changed;
- CoglPipeline *pipeline;
- PipelineFlags pipeline_flags;
- cairo_rectangle_int_t texture_area;
- int texture_width, texture_height;
-
- cairo_region_t *clip_region;
- cairo_region_t *unobscured_region;
-};
-
-static void clutter_content_iface_init (ClutterContentInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaBackgroundContent,
- meta_background_content,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT,
- clutter_content_iface_init));
-
-enum
-{
- PROP_0,
- PROP_META_DISPLAY,
- PROP_MONITOR,
- PROP_BACKGROUND,
- PROP_GRADIENT,
- PROP_GRADIENT_HEIGHT,
- PROP_GRADIENT_MAX_DARKNESS,
- PROP_VIGNETTE,
- PROP_VIGNETTE_SHARPNESS,
- PROP_VIGNETTE_BRIGHTNESS,
- PROP_ROUNDED_CLIP_RADIUS,
- N_PROPS,
-};
-
-static GParamSpec *properties[N_PROPS] = { NULL, };
-
-static void
-set_clip_region (MetaBackgroundContent *self,
- cairo_region_t *clip_region)
-{
- 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
-set_unobscured_region (MetaBackgroundContent *self,
- cairo_region_t *unobscured_region)
-{
- g_clear_pointer (&self->unobscured_region, cairo_region_destroy);
- if (unobscured_region)
- {
- 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 void
-invalidate_pipeline (MetaBackgroundContent *self,
- ChangedFlags changed)
-{
- self->changed |= changed;
-}
-
-static void
-on_background_changed (MetaBackground *background,
- MetaBackgroundContent *self)
-{
- invalidate_pipeline (self, CHANGED_BACKGROUND);
- clutter_content_invalidate (CLUTTER_CONTENT (self));
-}
-
-static CoglPipeline *
-make_pipeline (PipelineFlags pipeline_flags)
-{
- static CoglPipeline *templates[PIPELINE_ALL + 1];
- CoglPipeline **templatep;
-
- g_assert (pipeline_flags < G_N_ELEMENTS (templates));
-
- 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));
-
- if ((pipeline_flags & PIPELINE_VIGNETTE) != 0)
- {
- static CoglSnippet *vignette_vertex_snippet;
- static CoglSnippet *vignette_fragment_snippet;
-
- if (!vignette_vertex_snippet)
- vignette_vertex_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
- VIGNETTE_VERTEX_SHADER_DECLARATIONS,
- VIGNETTE_VERTEX_SHADER_CODE);
-
- cogl_pipeline_add_snippet (*templatep, vignette_vertex_snippet);
-
- if (!vignette_fragment_snippet)
- vignette_fragment_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
- VIGNETTE_FRAGMENT_SHADER_DECLARATIONS,
- VIGNETTE_FRAGMENT_SHADER_CODE);
-
- cogl_pipeline_add_snippet (*templatep, vignette_fragment_snippet);
- }
-
- if ((pipeline_flags & PIPELINE_GRADIENT) != 0)
- {
- static CoglSnippet *gradient_vertex_snippet;
- static CoglSnippet *gradient_fragment_snippet;
-
- if (!gradient_vertex_snippet)
- gradient_vertex_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
- GRADIENT_VERTEX_SHADER_DECLARATIONS,
- GRADIENT_VERTEX_SHADER_CODE);
-
- cogl_pipeline_add_snippet (*templatep, gradient_vertex_snippet);
-
- if (!gradient_fragment_snippet)
- gradient_fragment_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
- GRADIENT_FRAGMENT_SHADER_DECLARATIONS,
- GRADIENT_FRAGMENT_SHADER_CODE);
-
- cogl_pipeline_add_snippet (*templatep, gradient_fragment_snippet);
- }
-
- if ((pipeline_flags & PIPELINE_ROUNDED_CLIP) != 0)
- {
- static CoglSnippet *rounded_clip_fragment_snippet;
-
- if (!rounded_clip_fragment_snippet)
- {
- rounded_clip_fragment_snippet =
- cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
- ROUNDED_CLIP_FRAGMENT_SHADER_DECLARATIONS,
- ROUNDED_CLIP_FRAGMENT_SHADER_CODE);
- }
-
- cogl_pipeline_add_snippet (*templatep, rounded_clip_fragment_snippet);
- }
-
-
- if ((pipeline_flags & PIPELINE_BLEND) == 0)
- cogl_pipeline_set_blend (*templatep, "RGBA = ADD (SRC_COLOR, 0)", NULL);
- }
-
- return cogl_pipeline_copy (*templatep);
-}
-
-static void
-setup_pipeline (MetaBackgroundContent *self,
- ClutterActor *actor,
- ClutterPaintContext *paint_context,
- cairo_rectangle_int_t *actor_pixel_rect)
-{
- PipelineFlags pipeline_flags = 0;
- guint8 opacity;
- float color_component;
- CoglFramebuffer *fb;
- CoglPipelineFilter min_filter, mag_filter;
-
- opacity = clutter_actor_get_paint_opacity (actor);
- 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->has_rounded_clip && clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
- pipeline_flags |= PIPELINE_ROUNDED_CLIP | PIPELINE_BLEND;
-
- if (pipeline_flags != self->pipeline_flags)
- g_clear_pointer (&self->pipeline, cogl_object_unref);
-
- if (self->pipeline == NULL)
- {
- self->pipeline_flags = pipeline_flags;
- self->pipeline = make_pipeline (pipeline_flags);
- self->changed = CHANGED_ALL;
- }
-
- if (self->changed & CHANGED_BACKGROUND)
- {
- CoglPipelineWrapMode wrap_mode;
- CoglTexture *texture = meta_background_get_texture (self->background,
- self->monitor,
- &self->texture_area,
- &wrap_mode);
-
- if (texture)
- {
- self->texture_width = cogl_texture_get_width (texture);
- self->texture_height = cogl_texture_get_height (texture);
- }
- else
- {
- self->texture_width = 0;
- self->texture_height = 0;
- }
-
- cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
- cogl_pipeline_set_layer_wrap_mode (self->pipeline, 0, wrap_mode);
-
- self->changed &= ~CHANGED_BACKGROUND;
- }
-
- if (self->changed & CHANGED_VIGNETTE_PARAMETERS)
- {
- cogl_pipeline_set_uniform_1f (self->pipeline,
- cogl_pipeline_get_uniform_location (self->pipeline,
- "vignette_sharpness"),
- self->vignette_sharpness);
-
- self->changed &= ~CHANGED_VIGNETTE_PARAMETERS;
- }
-
- if (self->changed & CHANGED_GRADIENT_PARAMETERS)
- {
- 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 (self->changed & CHANGED_ROUNDED_CLIP_PARAMETERS)
- {
- float monitor_scale;
- float bounds_x1, bounds_x2, bounds_y1, bounds_y2;
- float clip_radius;
-
- monitor_scale = meta_is_stage_views_scaled ()
- ? meta_display_get_monitor_scale (self->display, self->monitor)
- : 1.0;
-
- if (self->rounded_clip_bounds_set)
- {
- bounds_x1 = self->rounded_clip_bounds.origin.x;
- bounds_x2 = self->rounded_clip_bounds.origin.x + self->rounded_clip_bounds.size.width;
- bounds_y1 = self->rounded_clip_bounds.origin.y;
- bounds_y2 = self->rounded_clip_bounds.origin.y + self->rounded_clip_bounds.size.height;
-
- bounds_x1 *= monitor_scale;
- bounds_x2 *= monitor_scale;
- bounds_y1 *= monitor_scale;
- bounds_y2 *= monitor_scale;
- }
- else
- {
- bounds_x1 = 0.0;
- bounds_x2 = self->texture_width;
- bounds_y1 = 0.0;
- bounds_y2 = self->texture_height;
- }
-
- clip_radius = self->rounded_clip_radius * monitor_scale;
-
- float bounds[] = {
- bounds_x1,
- bounds_y1,
- bounds_x2,
- bounds_y2,
- };
-
- float corner_centers_1[] = {
- bounds_x1 + clip_radius,
- bounds_y1 + clip_radius,
- bounds_x2 - clip_radius,
- bounds_y1 + clip_radius,
- };
-
- float corner_centers_2[] = {
- bounds_x2 - clip_radius,
- bounds_y2 - clip_radius,
- bounds_x1 + clip_radius,
- bounds_y2 - clip_radius,
- };
-
- int bounds_uniform_location;
- int corner_centers_1_uniform_location;
- int corner_centers_2_uniform_location;
-
- bounds_uniform_location =
- cogl_pipeline_get_uniform_location (self->pipeline, "bounds");
- corner_centers_1_uniform_location =
- cogl_pipeline_get_uniform_location (self->pipeline, "corner_centers_1");
- corner_centers_2_uniform_location =
- cogl_pipeline_get_uniform_location (self->pipeline, "corner_centers_2");
-
- cogl_pipeline_set_uniform_float (self->pipeline,
- bounds_uniform_location,
- 4, 1,
- bounds);
-
- cogl_pipeline_set_uniform_float (self->pipeline,
- corner_centers_1_uniform_location,
- 4, 1,
- corner_centers_1);
-
- cogl_pipeline_set_uniform_float (self->pipeline,
- corner_centers_2_uniform_location,
- 4, 1,
- corner_centers_2);
-
- self->changed &= ~CHANGED_ROUNDED_CLIP_PARAMETERS;
- }
-
- if (self->vignette)
- {
- color_component = self->vignette_brightness * opacity / 255.;
-
- 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 (meta_actor_painting_untransformed (fb,
- actor_pixel_rect->width,
- actor_pixel_rect->height,
- self->texture_width,
- self->texture_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;
- }
-
- cogl_pipeline_set_layer_filters (self->pipeline, 0, min_filter, mag_filter);
-}
-
-static void
-set_glsl_parameters (MetaBackgroundContent *self,
- cairo_rectangle_int_t *actor_pixel_rect)
-{
- float monitor_scale;
- float scale[2];
- float offset[2];
- int pixel_step_uniform_location;
-
- monitor_scale = meta_is_stage_views_scaled ()
- ? meta_display_get_monitor_scale (self->display, self->monitor)
- : 1.0;
-
- float pixel_step[] = {
- 1.f / (self->texture_area.width * monitor_scale),
- 1.f / (self->texture_area.height * monitor_scale),
- };
-
- pixel_step_uniform_location =
- cogl_pipeline_get_uniform_location (self->pipeline,
- "pixel_step");
-
- /* 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);
-
- cogl_pipeline_set_uniform_float (self->pipeline,
- pixel_step_uniform_location,
- 2, 1,
- pixel_step);
-}
-
-static void
-paint_clipped_rectangle (MetaBackgroundContent *self,
- ClutterPaintNode *node,
- ClutterActorBox *actor_box,
- cairo_rectangle_int_t *rect)
-{
- g_autoptr (ClutterPaintNode) pipeline_node = NULL;
- float h_scale, v_scale;
- float x1, y1, x2, y2;
- float tx1, ty1, tx2, ty2;
-
- h_scale = self->texture_area.width / clutter_actor_box_get_width (actor_box);
- v_scale = self->texture_area.height / clutter_actor_box_get_height (actor_box);
-
- x1 = rect->x;
- y1 = rect->y;
- x2 = rect->x + rect->width;
- y2 = rect->y + rect->height;
-
- tx1 = (x1 * h_scale - self->texture_area.x) / (float)self->texture_area.width;
- ty1 = (y1 * v_scale - self->texture_area.y) / (float)self->texture_area.height;
- tx2 = (x2 * h_scale - self->texture_area.x) / (float)self->texture_area.width;
- ty2 = (y2 * v_scale - self->texture_area.y) / (float)self->texture_area.height;
-
- pipeline_node = clutter_pipeline_node_new (self->pipeline);
- clutter_paint_node_set_name (pipeline_node, "MetaBackgroundContent (Slice)");
- clutter_paint_node_add_texture_rectangle (pipeline_node,
- &(ClutterActorBox) {
- .x1 = x1,
- .y1 = y1,
- .x2 = x2,
- .y2 = y2,
- },
- tx1, ty1,
- tx2, ty2);
-
- clutter_paint_node_add_child (node, pipeline_node);
-}
-
-static void
-meta_background_content_paint_content (ClutterContent *content,
- ClutterActor *actor,
- ClutterPaintNode *node,
- ClutterPaintContext *paint_context)
-{
- MetaBackgroundContent *self = META_BACKGROUND_CONTENT (content);
- ClutterActorBox actor_box;
- cairo_rectangle_int_t rect_within_actor;
- cairo_rectangle_int_t rect_within_stage;
- cairo_region_t *region;
- int i, n_rects;
- float transformed_x, transformed_y, transformed_width, transformed_height;
- gboolean untransformed;
-
- if ((self->clip_region && cairo_region_is_empty (self->clip_region)))
- return;
-
- clutter_actor_get_content_box (actor, &actor_box);
- rect_within_actor.x = actor_box.x1;
- rect_within_actor.y = actor_box.y1;
- rect_within_actor.width = actor_box.x2 - actor_box.x1;
- rect_within_actor.height = actor_box.y2 - actor_box.y1;
-
- if (clutter_actor_is_in_clone_paint (actor))
- {
- untransformed = FALSE;
- }
- else
- {
- clutter_actor_get_transformed_position (actor,
- &transformed_x,
- &transformed_y);
- rect_within_stage.x = floorf (transformed_x);
- rect_within_stage.y = floorf (transformed_y);
-
- clutter_actor_get_transformed_size (actor,
- &transformed_width,
- &transformed_height);
- rect_within_stage.width = ceilf (transformed_width);
- rect_within_stage.height = ceilf (transformed_height);
-
- untransformed =
- rect_within_actor.x == rect_within_stage.x &&
- rect_within_actor.y == rect_within_stage.y &&
- rect_within_actor.width == rect_within_stage.width &&
- rect_within_actor.height == rect_within_stage.height;
- }
-
- if (untransformed) /* actor and stage space are the same */
- {
- if (self->clip_region)
- {
- region = cairo_region_copy (self->clip_region);
- cairo_region_intersect_rectangle (region, &rect_within_stage);
- }
- else
- {
- const cairo_region_t *redraw_clip;
-
- redraw_clip = clutter_paint_context_get_redraw_clip (paint_context);
- if (redraw_clip)
- {
- region = cairo_region_copy (redraw_clip);
- cairo_region_intersect_rectangle (region, &rect_within_stage);
- }
- else
- {
- region = cairo_region_create_rectangle (&rect_within_stage);
- }
- }
- }
- else /* actor and stage space are different but we need actor space */
- {
- if (self->clip_region)
- {
- region = cairo_region_copy (self->clip_region);
- cairo_region_intersect_rectangle (region, &rect_within_actor);
- }
- else
- {
- region = cairo_region_create_rectangle (&rect_within_actor);
- }
- }
-
- if (self->unobscured_region)
- cairo_region_intersect (region, self->unobscured_region);
-
- /* region is now in actor space */
- if (cairo_region_is_empty (region))
- {
- cairo_region_destroy (region);
- return;
- }
-
- setup_pipeline (self, actor, paint_context, &rect_within_actor);
- set_glsl_parameters (self, &rect_within_actor);
-
- /* Limit to how many separate rectangles we'll draw; beyond this just
- * fall back and draw the whole thing */
-#define MAX_RECTS 64
-
- 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 (self, node, &actor_box, &rect);
- }
- }
- else
- {
- cairo_rectangle_int_t rect;
- cairo_region_get_extents (region, &rect);
- paint_clipped_rectangle (self, node, &actor_box, &rect);
- }
-
- cairo_region_destroy (region);
-}
-
-static gboolean
-meta_background_content_get_preferred_size (ClutterContent *content,
- float *width,
- float *height)
-
-{
- MetaBackgroundContent *background_content = META_BACKGROUND_CONTENT (content);
- MetaRectangle monitor_geometry;
-
- meta_display_get_monitor_geometry (background_content->display,
- background_content->monitor,
- &monitor_geometry);
-
- if (width)
- *width = monitor_geometry.width;
-
- if (height)
- *height = monitor_geometry.height;
-
- return TRUE;
-}
-
-static void
-clutter_content_iface_init (ClutterContentInterface *iface)
-{
- iface->paint_content = meta_background_content_paint_content;
- iface->get_preferred_size = meta_background_content_get_preferred_size;
-}
-
-static void
-set_monitor (MetaBackgroundContent *self,
- int monitor)
-{
- MetaRectangle old_monitor_geometry;
- MetaRectangle new_monitor_geometry;
- MetaDisplay *display = self->display;
-
- if(self->monitor == monitor)
- return;
-
- 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);
-
- self->monitor = monitor;
-}
-
-static void
-meta_background_content_dispose (GObject *object)
-{
- MetaBackgroundContent *self = META_BACKGROUND_CONTENT (object);
-
- set_clip_region (self, NULL);
- set_unobscured_region (self, NULL);
- meta_background_content_set_background (self, NULL);
-
- g_clear_pointer (&self->pipeline, cogl_object_unref);
-
- G_OBJECT_CLASS (meta_background_content_parent_class)->dispose (object);
-}
-
-static void
-meta_background_content_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaBackgroundContent *self = META_BACKGROUND_CONTENT (object);
-
- switch (prop_id)
- {
- case PROP_META_DISPLAY:
- self->display = g_value_get_object (value);
- break;
- case PROP_MONITOR:
- set_monitor (self, g_value_get_int (value));
- break;
- case PROP_BACKGROUND:
- meta_background_content_set_background (self, g_value_get_object (value));
- break;
- case PROP_GRADIENT:
- meta_background_content_set_gradient (self,
- g_value_get_boolean (value),
- self->gradient_height,
- self->gradient_max_darkness);
- break;
- case PROP_GRADIENT_HEIGHT:
- meta_background_content_set_gradient (self,
- self->gradient,
- g_value_get_int (value),
- self->gradient_max_darkness);
- break;
- case PROP_GRADIENT_MAX_DARKNESS:
- meta_background_content_set_gradient (self,
- self->gradient,
- self->gradient_height,
- g_value_get_double (value));
- break;
- case PROP_VIGNETTE:
- meta_background_content_set_vignette (self,
- g_value_get_boolean (value),
- self->vignette_brightness,
- self->vignette_sharpness);
- break;
- case PROP_VIGNETTE_SHARPNESS:
- meta_background_content_set_vignette (self,
- self->vignette,
- self->vignette_brightness,
- g_value_get_double (value));
- break;
- case PROP_VIGNETTE_BRIGHTNESS:
- meta_background_content_set_vignette (self,
- self->vignette,
- g_value_get_double (value),
- self->vignette_sharpness);
- break;
- case PROP_ROUNDED_CLIP_RADIUS:
- meta_background_content_set_rounded_clip_radius (self,
- g_value_get_float (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_background_content_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaBackgroundContent *self = META_BACKGROUND_CONTENT (object);
-
- switch (prop_id)
- {
- 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;
- case PROP_ROUNDED_CLIP_RADIUS:
- g_value_set_float (value, self->rounded_clip_radius);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_background_content_class_init (MetaBackgroundContentClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->dispose = meta_background_content_dispose;
- object_class->set_property = meta_background_content_set_property;
- object_class->get_property = meta_background_content_get_property;
-
- properties[PROP_META_DISPLAY] =
- g_param_spec_object ("meta-display",
- "MetaDisplay",
- "MetaDisplay",
- META_TYPE_DISPLAY,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
- properties[PROP_MONITOR] =
- g_param_spec_int ("monitor",
- "monitor",
- "monitor",
- 0, G_MAXINT, 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
- properties[PROP_BACKGROUND] =
- g_param_spec_object ("background",
- "Background",
- "MetaBackground object holding background parameters",
- META_TYPE_BACKGROUND,
- G_PARAM_READWRITE);
-
- properties[PROP_GRADIENT] =
- g_param_spec_boolean ("gradient",
- "Gradient",
- "Whether gradient effect is enabled",
- FALSE,
- G_PARAM_READWRITE);
-
- properties[PROP_GRADIENT_HEIGHT] =
- g_param_spec_int ("gradient-height",
- "Gradient Height",
- "Height of gradient effect",
- 0, G_MAXINT, 0,
- G_PARAM_READWRITE);
-
- properties[PROP_GRADIENT_MAX_DARKNESS] =
- 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);
-
- properties[PROP_VIGNETTE] =
- g_param_spec_boolean ("vignette",
- "Vignette",
- "Whether vignette effect is enabled",
- FALSE,
- G_PARAM_READWRITE);
-
- properties[PROP_VIGNETTE_BRIGHTNESS] =
- g_param_spec_double ("brightness",
- "Vignette Brightness",
- "Brightness of vignette effect",
- 0.0, 1.0, 1.0,
- G_PARAM_READWRITE);
-
- properties[PROP_VIGNETTE_SHARPNESS] =
- g_param_spec_double ("vignette-sharpness",
- "Vignette Sharpness",
- "Sharpness of vignette effect",
- 0.0, G_MAXDOUBLE, 0.0,
- G_PARAM_READWRITE);
-
- properties[PROP_ROUNDED_CLIP_RADIUS] =
- g_param_spec_float ("rounded-clip-radius",
- "Rounded clip radius",
- "Rounded clip radius",
- 0.0, G_MAXFLOAT, 0.0,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS |
- G_PARAM_EXPLICIT_NOTIFY);
-
- g_object_class_install_properties (object_class, N_PROPS, properties);
-}
-
-static void
-meta_background_content_init (MetaBackgroundContent *self)
-{
- self->gradient = FALSE;
- self->gradient_height = 0;
- self->gradient_max_darkness = 0.0;
-
- self->vignette = FALSE;
- self->vignette_brightness = 1.0;
- self->vignette_sharpness = 0.0;
-
- self->has_rounded_clip = FALSE;
- self->rounded_clip_radius = 0.0;
-}
-
-/**
- * meta_background_content_new:
- * @monitor: Index of the monitor for which to draw the background
- *
- * Creates a new actor to draw the background for the given monitor.
- *
- * Return value: (transfer full): the newly created background actor
- */
-ClutterContent *
-meta_background_content_new (MetaDisplay *display,
- int monitor)
-{
- return g_object_new (META_TYPE_BACKGROUND_CONTENT,
- "meta-display", display,
- "monitor", monitor,
- NULL);
-}
-
-void
-meta_background_content_set_background (MetaBackgroundContent *self,
- MetaBackground *background)
-{
- g_return_if_fail (META_IS_BACKGROUND_CONTENT (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_clear_object (&self->background);
- }
-
- if (background)
- {
- self->background = g_object_ref (background);
- g_signal_connect (self->background, "changed",
- G_CALLBACK (on_background_changed), self);
- }
-
- invalidate_pipeline (self, CHANGED_BACKGROUND);
- clutter_content_invalidate (CLUTTER_CONTENT (self));
-}
-
-void
-meta_background_content_set_gradient (MetaBackgroundContent *self,
- gboolean enabled,
- int height,
- double max_darkness)
-{
- gboolean changed = FALSE;
-
- g_return_if_fail (META_IS_BACKGROUND_CONTENT (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;
- }
-
- 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_content_invalidate (CLUTTER_CONTENT (self));
-}
-
-void
-meta_background_content_set_vignette (MetaBackgroundContent *self,
- gboolean enabled,
- double brightness,
- double sharpness)
-{
- gboolean changed = FALSE;
-
- g_return_if_fail (META_IS_BACKGROUND_CONTENT (self));
- g_return_if_fail (brightness >= 0. && brightness <= 1.);
- g_return_if_fail (sharpness >= 0.);
-
- enabled = enabled != FALSE;
-
- 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_content_invalidate (CLUTTER_CONTENT (self));
-}
-
-void
-meta_background_content_set_rounded_clip_radius (MetaBackgroundContent *self,
- float radius)
-{
- gboolean enabled;
- gboolean changed = FALSE;
-
- g_return_if_fail (META_IS_BACKGROUND_CONTENT (self));
- g_return_if_fail (radius >= 0.0);
-
- enabled = radius > 0.0;
-
- if (enabled != self->has_rounded_clip)
- {
- self->has_rounded_clip = enabled;
- invalidate_pipeline (self, CHANGED_EFFECTS);
- changed = TRUE;
- }
-
- if (!G_APPROX_VALUE (radius, self->rounded_clip_radius, FLT_EPSILON))
- {
- self->rounded_clip_radius = radius;
- invalidate_pipeline (self, CHANGED_ROUNDED_CLIP_PARAMETERS);
- changed = TRUE;
- }
-
- if (changed)
- {
- clutter_content_invalidate (CLUTTER_CONTENT (self));
- g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ROUNDED_CLIP_RADIUS]);
- }
-}
-
-/**
- * meta_background_content_set_rounded_clip_bounds:
- * @self: The #MetaBackgroundContent
- * @bounds: (allow-none): The new bounding clip rectangle, or %NULL
- *
- * Sets the bounding clip rectangle of the #MetaBackgroundContent that's used
- * when a rounded clip set via meta_background_content_set_rounded_clip_radius()
- * is in effect, set it to %NULL to use no bounding clip, rounding the edges
- * of the full texture.
- */
-void
-meta_background_content_set_rounded_clip_bounds (MetaBackgroundContent *self,
- const graphene_rect_t *bounds)
-{
- g_return_if_fail (META_IS_BACKGROUND_CONTENT (self));
-
- if (bounds == NULL)
- {
- if (!self->rounded_clip_bounds_set)
- return;
-
- self->rounded_clip_bounds_set = FALSE;
- }
- else
- {
- if (self->rounded_clip_bounds_set &&
- graphene_rect_equal (&self->rounded_clip_bounds, bounds))
- return;
-
- self->rounded_clip_bounds_set = TRUE;
- graphene_rect_init_from_rect (&self->rounded_clip_bounds, bounds);
- }
-
- invalidate_pipeline (self, CHANGED_ROUNDED_CLIP_PARAMETERS);
- clutter_content_invalidate (CLUTTER_CONTENT (self));
-}
-
-cairo_region_t *
-meta_background_content_get_clip_region (MetaBackgroundContent *self)
-{
- return self->clip_region;
-}
-
-void
-meta_background_content_cull_out (MetaBackgroundContent *self,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region)
-{
- set_unobscured_region (self, unobscured_region);
- set_clip_region (self, clip_region);
-}
-
-void
-meta_background_content_reset_culling (MetaBackgroundContent *self)
-{
- set_unobscured_region (self, NULL);
- set_clip_region (self, NULL);
-}
diff --git a/src/compositor/meta-background-group.c b/src/compositor/meta-background-group.c
deleted file mode 100644
index e30b8af4c..000000000
--- a/src/compositor/meta-background-group.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- 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
deleted file mode 100644
index ed9425bb3..000000000
--- a/src/compositor/meta-background-image.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/* -*- 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 dereferenced
- * 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
deleted file mode 100644
index 871487da4..000000000
--- a/src/compositor/meta-background-private.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* -*- 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
deleted file mode 100644
index c0d8d335d..000000000
--- a/src/compositor/meta-background.c
+++ /dev/null
@@ -1,1018 +0,0 @@
-/* -*- 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/>.
- */
-
-#include "config.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"
-
-enum
-{
- CHANGED,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-typedef struct _MetaBackgroundMonitor MetaBackgroundMonitor;
-
-struct _MetaBackgroundMonitor
-{
- gboolean dirty;
- CoglTexture *texture;
- CoglFramebuffer *fbo;
-};
-
-struct _MetaBackground
-{
- GObject parent;
-
- MetaDisplay *display;
- MetaBackgroundMonitor *monitors;
- int n_monitors;
-
- GDesktopBackgroundStyle style;
- GDesktopBackgroundShading 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;
-};
-
-enum
-{
- PROP_META_DISPLAY = 1,
- PROP_MONITOR,
-};
-
-G_DEFINE_TYPE (MetaBackground, meta_background, G_TYPE_OBJECT)
-
-static gboolean texture_has_alpha (CoglTexture *texture);
-
-static GSList *all_backgrounds = NULL;
-
-static void
-free_fbos (MetaBackground *self)
-{
- int i;
-
- for (i = 0; i < self->n_monitors; i++)
- {
- MetaBackgroundMonitor *monitor = &self->monitors[i];
-
- g_clear_object (&monitor->fbo);
- cogl_clear_object (&monitor->texture);
- }
-}
-
-static void
-free_color_texture (MetaBackground *self)
-{
- cogl_clear_object (&self->color_texture);
-}
-
-static void
-free_wallpaper_texture (MetaBackground *self)
-{
- cogl_clear_object (&self->wallpaper_texture);
-
- self->wallpaper_allocation_failed = FALSE;
-}
-
-static void
-invalidate_monitor_backgrounds (MetaBackground *self)
-{
- free_fbos (self);
- g_clear_pointer (&self->monitors, g_free);
- self->n_monitors = 0;
-
- if (self->display)
- {
- int i;
-
- self->n_monitors = meta_display_get_n_monitors (self->display);
- self->monitors = g_new0 (MetaBackgroundMonitor, self->n_monitors);
-
- for (i = 0; i < self->n_monitors; i++)
- self->monitors[i].dirty = TRUE;
- }
-}
-
-static void
-on_monitors_changed (MetaBackground *self)
-{
- invalidate_monitor_backgrounds (self);
-}
-
-static void
-set_display (MetaBackground *self,
- MetaDisplay *display)
-{
- g_set_object (&self->display, display);
-
- invalidate_monitor_backgrounds (self);
-}
-
-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_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaBackground *self = META_BACKGROUND (object);
-
- 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;
- }
-}
-
-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 == G_DESKTOP_BACKGROUND_STYLE_WALLPAPER)
- return FALSE;
-
- return TRUE;
-}
-
-static void
-mark_changed (MetaBackground *self)
-{
- int i;
-
- if (!need_prerender (self))
- free_fbos (self);
-
- 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;
-
- if ((file1 == NULL) || (file2 == NULL))
- return FALSE;
-
- 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))
- {
- if (*imagep)
- {
- g_signal_handlers_disconnect_by_func (*imagep,
- (gpointer)on_background_loaded,
- self);
- g_clear_object (imagep);
- }
-
- g_set_object (filep, file);
-
- if (file)
- {
- MetaBackgroundImageCache *cache = meta_background_image_cache_get_default ();
-
- *imagep = meta_background_image_cache_load (cache, file);
- g_signal_connect (*imagep, "loaded",
- G_CALLBACK (on_background_loaded), self);
- }
- }
-}
-
-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)
- {
- 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 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)
-{
- 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);
- 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);
-
-}
-
-static void
-meta_background_init (MetaBackground *self)
-{
- 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;
-}
-
-static void
-get_texture_area (MetaBackground *self,
- cairo_rectangle_int_t *monitor_rect,
- float monitor_scale,
- CoglTexture *texture,
- cairo_rectangle_int_t *texture_area)
-{
- cairo_rectangle_int_t image_area;
- int screen_width, screen_height;
- float texture_width, texture_height;
- float monitor_x_scale, monitor_y_scale;
-
- texture_width = cogl_texture_get_width (texture);
- texture_height = cogl_texture_get_height (texture);
-
- switch (self->style)
- {
- case G_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 G_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 G_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 G_DESKTOP_BACKGROUND_STYLE_SCALED:
- case G_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 == G_DESKTOP_BACKGROUND_STYLE_SCALED &&
- (monitor_x_scale < monitor_y_scale)) ||
- (self->style == G_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;
-
- /* 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 G_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;
- }
- }
-}
-
-static gboolean
-draw_texture (MetaBackground *self,
- CoglFramebuffer *framebuffer,
- CoglPipeline *pipeline,
- CoglTexture *texture,
- cairo_rectangle_int_t *monitor_area,
- float monitor_scale)
-{
- cairo_rectangle_int_t texture_area;
- gboolean bare_region_visible;
-
- get_texture_area (self, monitor_area, monitor_scale, texture, &texture_area);
-
- switch (self->style)
- {
- case G_DESKTOP_BACKGROUND_STYLE_STRETCHED:
- case G_DESKTOP_BACKGROUND_STYLE_WALLPAPER:
- case G_DESKTOP_BACKGROUND_STYLE_ZOOM:
- case G_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);
-
- bare_region_visible = texture_has_alpha (texture);
-
- /* Draw just the texture */
- break;
- case G_DESKTOP_BACKGROUND_STYLE_CENTERED:
- case G_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 G_DESKTOP_BACKGROUND_STYLE_NONE:
- bare_region_visible = TRUE;
- break;
- default:
- g_return_val_if_reached(FALSE);
- }
-
- return bare_region_visible;
-}
-
-static void
-ensure_color_texture (MetaBackground *self)
-{
- 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 == G_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 G_DESKTOP_BACKGROUND_SHADING_VERTICAL:
- width = 1;
- height = 2;
- break;
- case G_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;
- }
-
- 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", error->message);
- g_error_free (error);
- }
- }
-}
-
-typedef enum
-{
- PIPELINE_REPLACE,
- PIPELINE_ADD,
- PIPELINE_OVER_REVERSE,
-} PipelineType;
-
-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];
-
- if (templates[type] == NULL)
- {
- templates[type] = meta_create_texture_pipeline (NULL);
- cogl_pipeline_set_blend (templates[type], blend_strings[type], NULL);
- }
-
- 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))
- {
- 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;
- }
-}
-
-static gboolean
-ensure_wallpaper_texture (MetaBackground *self,
- CoglTexture *texture)
-{
- if (self->wallpaper_texture == NULL && !self->wallpaper_allocation_failed)
- {
- int width = cogl_texture_get_width (texture);
- int height = cogl_texture_get_height (texture);
- CoglOffscreen *offscreen;
- CoglFramebuffer *fbo;
- GError *catch_error = NULL;
- CoglPipeline *pipeline;
-
- 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_clear_object (&self->wallpaper_texture);
- g_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);
- }
-
- g_object_unref (fbo);
- }
-
- return self->wallpaper_texture != NULL;
-}
-
-static CoglPipelineWrapMode
-get_wrap_mode (GDesktopBackgroundStyle style)
-{
- switch (style)
- {
- case G_DESKTOP_BACKGROUND_STYLE_WALLPAPER:
- return COGL_PIPELINE_WRAP_MODE_REPEAT;
- case G_DESKTOP_BACKGROUND_STYLE_NONE:
- case G_DESKTOP_BACKGROUND_STYLE_STRETCHED:
- case G_DESKTOP_BACKGROUND_STYLE_CENTERED:
- case G_DESKTOP_BACKGROUND_STYLE_SCALED:
- case G_DESKTOP_BACKGROUND_STYLE_ZOOM:
- case G_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 == G_DESKTOP_BACKGROUND_STYLE_WALLPAPER &&
- self->shading_direction == G_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_RGB,
- META_TEXTURE_FLAGS_NONE);
- offscreen = cogl_offscreen_new_with_texture (monitor->texture);
- monitor->fbo = COGL_FRAMEBUFFER (offscreen);
- }
-
- if (self->style != G_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_clear_object (&monitor->texture);
- g_clear_object (&monitor->fbo);
-
- 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;
- }
-
- 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,
- G_DESKTOP_BACKGROUND_SHADING_SOLID,
- color, &dummy);
-}
-
-void
-meta_background_set_gradient (MetaBackground *self,
- GDesktopBackgroundShading 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,
- GDesktopBackgroundStyle 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,
- GDesktopBackgroundStyle 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-compositor-native.c b/src/compositor/meta-compositor-native.c
deleted file mode 100644
index 00f66b70d..000000000
--- a/src/compositor/meta-compositor-native.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * 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-native.h"
-
-#include "backends/meta-logical-monitor.h"
-#include "compositor/meta-surface-actor-wayland.h"
-
-struct _MetaCompositorNative
-{
- MetaCompositorServer parent;
-};
-
-G_DEFINE_TYPE (MetaCompositorNative, meta_compositor_native,
- META_TYPE_COMPOSITOR_SERVER)
-
-static MetaRendererView *
-get_window_view (MetaRenderer *renderer,
- MetaWindow *window)
-{
- GList *l;
- MetaRendererView *view_found = NULL;
-
- for (l = meta_renderer_get_views (renderer); l; l = l->next)
- {
- ClutterStageView *stage_view = l->data;
- MetaRectangle view_layout;
-
- clutter_stage_view_get_layout (stage_view, &view_layout);
-
- if (meta_rectangle_equal (&window->buffer_rect,
- &view_layout))
- {
- if (view_found)
- return NULL;
- view_found = META_RENDERER_VIEW (stage_view);
- }
- }
-
- return view_found;
-}
-
-static void
-maybe_assign_primary_plane (MetaCompositor *compositor)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
- MetaWindowActor *window_actor;
- MetaWindow *window;
- MetaRendererView *view;
- CoglFramebuffer *framebuffer;
- CoglOnscreen *onscreen;
- MetaSurfaceActor *surface_actor;
- MetaSurfaceActorWayland *surface_actor_wayland;
- g_autoptr (CoglScanout) scanout = NULL;
-
- if (meta_compositor_is_unredirect_inhibited (compositor))
- return;
-
- window_actor = meta_compositor_get_top_window_actor (compositor);
- if (!window_actor)
- return;
-
- if (meta_window_actor_effect_in_progress (window_actor))
- return;
-
- if (clutter_actor_has_transitions (CLUTTER_ACTOR (window_actor)))
- return;
-
- if (clutter_actor_get_n_children (CLUTTER_ACTOR (window_actor)) != 1)
- return;
-
- window = meta_window_actor_get_meta_window (window_actor);
- if (!window)
- return;
-
- view = get_window_view (renderer, window);
- if (!view)
- return;
-
- framebuffer = clutter_stage_view_get_framebuffer (CLUTTER_STAGE_VIEW (view));
- if (!COGL_IS_ONSCREEN (framebuffer))
- return;
-
- surface_actor = meta_window_actor_get_surface (window_actor);
- if (!META_IS_SURFACE_ACTOR_WAYLAND (surface_actor))
- return;
-
- surface_actor_wayland = META_SURFACE_ACTOR_WAYLAND (surface_actor);
- onscreen = COGL_ONSCREEN (framebuffer);
- scanout = meta_surface_actor_wayland_try_acquire_scanout (surface_actor_wayland,
- onscreen);
- if (!scanout)
- return;
-
- clutter_stage_view_assign_next_scanout (CLUTTER_STAGE_VIEW (view), scanout);
-}
-
-static void
-meta_compositor_native_before_paint (MetaCompositor *compositor,
- ClutterStageView *stage_view)
-{
- MetaCompositorClass *parent_class;
-
- maybe_assign_primary_plane (compositor);
-
- parent_class = META_COMPOSITOR_CLASS (meta_compositor_native_parent_class);
- parent_class->before_paint (compositor, stage_view);
-}
-
-MetaCompositorNative *
-meta_compositor_native_new (MetaDisplay *display,
- MetaBackend *backend)
-{
- return g_object_new (META_TYPE_COMPOSITOR_NATIVE,
- "display", display,
- "backend", backend,
- NULL);
-}
-
-static void
-meta_compositor_native_init (MetaCompositorNative *compositor_native)
-{
-}
-
-static void
-meta_compositor_native_class_init (MetaCompositorNativeClass *klass)
-{
- MetaCompositorClass *compositor_class = META_COMPOSITOR_CLASS (klass);
-
- compositor_class->before_paint = meta_compositor_native_before_paint;
-}
diff --git a/src/compositor/meta-compositor-native.h b/src/compositor/meta-compositor-native.h
deleted file mode 100644
index 2b1c65208..000000000
--- a/src/compositor/meta-compositor-native.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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_NATIVE_H
-#define META_COMPOSITOR_NATIVE_H
-
-#include "compositor/meta-compositor-server.h"
-
-#define META_TYPE_COMPOSITOR_NATIVE (meta_compositor_native_get_type ())
-G_DECLARE_FINAL_TYPE (MetaCompositorNative, meta_compositor_native,
- META, COMPOSITOR_NATIVE, MetaCompositor)
-
-MetaCompositorNative * meta_compositor_native_new (MetaDisplay *display,
- MetaBackend *backend);
-
-#endif /* META_COMPOSITOR_NATIVE_H */
diff --git a/src/compositor/meta-compositor-server.c b/src/compositor/meta-compositor-server.c
deleted file mode 100644
index 179dc83ef..000000000
--- a/src/compositor/meta-compositor-server.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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 "backends/meta-dnd-private.h"
-#include "compositor/meta-compositor-server.h"
-#include "core/display-private.h"
-
-G_DEFINE_TYPE (MetaCompositorServer, meta_compositor_server, META_TYPE_COMPOSITOR)
-
-static gboolean
-meta_compositor_server_manage (MetaCompositor *compositor,
- GError **error)
-{
- return TRUE;
-}
-
-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);
-}
-
-static void
-meta_compositor_server_grab_begin (MetaCompositor *compositor)
-{
- MetaDisplay *display;
-
- display = meta_compositor_get_display (compositor);
- meta_display_sync_wayland_input_focus (display);
- meta_display_cancel_touch (display);
-
-#ifdef HAVE_WAYLAND
- meta_dnd_wayland_handle_begin_modal (compositor);
-#endif
-}
-
-static void
-meta_compositor_server_grab_end (MetaCompositor *compositor)
-{
- MetaDisplay *display;
-
- display = meta_compositor_get_display (compositor);
-#ifdef HAVE_WAYLAND
- meta_dnd_wayland_handle_end_modal (compositor);
-#endif
- meta_display_sync_wayland_input_focus (display);
-}
-
-MetaCompositorServer *
-meta_compositor_server_new (MetaDisplay *display,
- MetaBackend *backend)
-{
- return g_object_new (META_TYPE_COMPOSITOR_SERVER,
- "display", display,
- "backend", backend,
- 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;
- compositor_class->grab_begin = meta_compositor_server_grab_begin;
- compositor_class->grab_end = meta_compositor_server_grab_end;
-}
diff --git a/src/compositor/meta-compositor-server.h b/src/compositor/meta-compositor-server.h
deleted file mode 100644
index 2bf8d5ec3..000000000
--- a/src/compositor/meta-compositor-server.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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_DERIVABLE_TYPE (MetaCompositorServer, meta_compositor_server,
- META, COMPOSITOR_SERVER, MetaCompositor)
-
-struct _MetaCompositorServerClass
-{
- MetaCompositorClass parent_class;
-};
-
-MetaCompositorServer * meta_compositor_server_new (MetaDisplay *display,
- MetaBackend *backend);
-
-#endif /* META_COMPOSITOR_SERVER_H */
diff --git a/src/compositor/meta-compositor-x11.c b/src/compositor/meta-compositor-x11.c
deleted file mode 100644
index a16604640..000000000
--- a/src/compositor/meta-compositor-x11.c
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * 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-clutter-backend-x11.h"
-#include "backends/x11/meta-event-x11.h"
-#include "compositor/meta-sync-ring.h"
-#include "compositor/meta-window-actor-x11.h"
-#include "core/display-private.h"
-#include "x11/meta-x11-display-private.h"
-
-struct _MetaCompositorX11
-{
- MetaCompositor parent;
-
- Window output;
-
- gulong before_update_handler_id;
- gulong after_update_handler_id;
-
- 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;
-};
-
-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 gboolean
-meta_compositor_x11_manage (MetaCompositor *compositor,
- GError **error)
-{
- MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
- MetaDisplay *display = meta_compositor_get_display (compositor);
- MetaX11Display *x11_display = display->x11_display;
- Display *xdisplay = meta_x11_display_get_xdisplay (x11_display);
- int composite_version;
- MetaBackend *backend = meta_get_backend ();
- Window xwindow;
-
- if (!META_X11_DISPLAY_HAS_COMPOSITE (x11_display) ||
- !META_X11_DISPLAY_HAS_DAMAGE (x11_display))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Missing required extension %s",
- !META_X11_DISPLAY_HAS_COMPOSITE (x11_display) ?
- "composite" : "damage");
- return FALSE;
- }
-
- composite_version = ((x11_display->composite_major_version * 10) +
- x11_display->composite_minor_version);
- if (composite_version < 3)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "COMPOSITE extension 3.0 required (found %d.%d)",
- x11_display->composite_major_version,
- x11_display->composite_minor_version);
- return FALSE;
- }
-
- 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));
-
- return TRUE;
-}
-
-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
-set_unredirected_window (MetaCompositorX11 *compositor_x11,
- MetaWindow *window)
-{
- MetaWindow *prev_unredirected_window = compositor_x11->unredirected_window;
-
- if (prev_unredirected_window == window)
- return;
-
- if (prev_unredirected_window)
- {
- MetaWindowActor *window_actor;
- MetaWindowActorX11 *window_actor_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;
-
- 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;
- MetaWindowActor *window_actor;
- MetaWindowActorX11 *window_actor_x11;
-
- if (meta_compositor_is_unredirect_inhibited (compositor))
- goto out;
-
- window_actor = meta_compositor_get_top_window_actor (compositor);
- if (!window_actor)
- goto out;
-
- window_actor_x11 = META_WINDOW_ACTOR_X11 (window_actor);
- if (!meta_window_actor_x11_should_unredirect (window_actor_x11))
- goto out;
-
- window_to_unredirect = meta_window_actor_get_meta_window (window_actor);
-
-out:
- set_unredirected_window (compositor_x11, window_to_unredirect);
-}
-
-static void
-on_before_update (ClutterStage *stage,
- ClutterStageView *stage_view,
- MetaCompositor *compositor)
-{
- MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (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
-on_after_update (ClutterStage *stage,
- ClutterStageView *stage_view,
- MetaCompositor *compositor)
-{
- MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
-
- 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;
- }
-}
-
-static void
-meta_compositor_x11_before_paint (MetaCompositor *compositor,
- ClutterStageView *stage_view)
-{
- 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->before_paint (compositor, stage_view);
-}
-
-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;
-}
-
-static void
-meta_compositor_x11_grab_begin (MetaCompositor *compositor)
-{
- MetaBackendX11 *backend_x11 = META_BACKEND_X11 (meta_get_backend ());
-
- meta_backend_x11_sync_pointer (backend_x11);
-}
-
-static void
-meta_compositor_x11_grab_end (MetaCompositor *compositor)
-{
- MetaBackendX11 *backend_x11 = META_BACKEND_X11 (meta_get_backend ());
-
- meta_backend_x11_sync_pointer (backend_x11);
-}
-
-Window
-meta_compositor_x11_get_output_xwindow (MetaCompositorX11 *compositor_x11)
-{
- return compositor_x11->output;
-}
-
-MetaCompositorX11 *
-meta_compositor_x11_new (MetaDisplay *display,
- MetaBackend *backend)
-{
- return g_object_new (META_TYPE_COMPOSITOR_X11,
- "display", display,
- "backend", backend,
- NULL);
-}
-
-static void
-meta_compositor_x11_constructed (GObject *object)
-{
- MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (object);
- MetaCompositor *compositor = META_COMPOSITOR (compositor_x11);
- 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);
-
- G_OBJECT_CLASS (meta_compositor_x11_parent_class)->constructed (object);
-}
-
-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)
- {
- meta_sync_ring_destroy ();
- 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);
-}
-
-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->constructed = meta_compositor_x11_constructed;
- object_class->dispose = meta_compositor_x11_dispose;
-
- compositor_class->manage = meta_compositor_x11_manage;
- compositor_class->unmanage = meta_compositor_x11_unmanage;
- compositor_class->before_paint = meta_compositor_x11_before_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;
- compositor_class->grab_begin = meta_compositor_x11_grab_begin;
- compositor_class->grab_end = meta_compositor_x11_grab_end;
-}
diff --git a/src/compositor/meta-compositor-x11.h b/src/compositor/meta-compositor-x11.h
deleted file mode 100644
index 42554feb3..000000000
--- a/src/compositor/meta-compositor-x11.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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,
- MetaBackend *backend);
-
-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
deleted file mode 100644
index 6f38c5e47..000000000
--- a/src/compositor/meta-cullable.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 471681da3..000000000
--- a/src/compositor/meta-cullable.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 20be369eb..000000000
--- a/src/compositor/meta-dnd-actor-private.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 80bffdeb7..000000000
--- a/src/compositor/meta-dnd-actor.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 8461690a2..000000000
--- a/src/compositor/meta-dnd.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/* -*- 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 "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-clutter-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
deleted file mode 100644
index 86cacb360..000000000
--- a/src/compositor/meta-feedback-actor-private.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 4b4bed78a..000000000
--- a/src/compositor/meta-feedback-actor.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/* -*- 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);
- graphene_matrix_t child_transform;
-
- if (priv->geometry_scale == geometry_scale)
- return;
-
- priv->geometry_scale = geometry_scale;
-
- graphene_matrix_init_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-later-private.h b/src/compositor/meta-later-private.h
deleted file mode 100644
index c8d0f80a8..000000000
--- a/src/compositor/meta-later-private.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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/>.
- */
-
-#ifndef META_LATER_PRIVATE_H
-#define META_LATER_PRIVATE_H
-
-typedef struct _MetaLaters MetaLaters;
-typedef struct _MetaCompositor MetaCompositor;
-
-MetaLaters * meta_laters_new (MetaCompositor *compositor);
-
-void meta_laters_free (MetaLaters *laters);
-
-#endif /* META_LATER_PRIVATE_H */
diff --git a/src/compositor/meta-later.c b/src/compositor/meta-later.c
deleted file mode 100644
index 43da6d8e6..000000000
--- a/src/compositor/meta-later.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2005 Elijah Newren
- * 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 "compositor/meta-later-private.h"
-
-#include "cogl/cogl.h"
-#include "compositor/compositor-private.h"
-#include "core/display-private.h"
-#include "meta/meta-later.h"
-
-typedef struct _MetaLater
-{
- unsigned int id;
- unsigned int ref_count;
- MetaLaterType when;
-
- GSourceFunc func;
- gpointer user_data;
- GDestroyNotify destroy_notify;
-
- guint source_id;
- gboolean run_once;
-} MetaLater;
-
-#define META_LATER_N_TYPES (META_LATER_IDLE + 1)
-
-struct _MetaLaters
-{
- MetaCompositor *compositor;
-
- unsigned int last_later_id;
-
- GSList *laters[META_LATER_N_TYPES];
-
- gulong before_update_handler_id;
-};
-
-static MetaLater *
-meta_later_ref (MetaLater *later)
-{
- later->ref_count++;
- return later;
-}
-
-static void
-meta_later_unref (MetaLater *later)
-{
- if (--later->ref_count == 0)
- {
- if (later->destroy_notify)
- {
- later->destroy_notify (later->user_data);
- later->destroy_notify = NULL;
- }
-
- g_free (later);
- }
-}
-
-static void
-meta_later_destroy (MetaLater *later)
-{
- g_clear_handle_id (&later->source_id, g_source_remove);
- later->func = NULL;
- meta_later_unref (later);
-}
-
-#ifdef COGL_HAS_TRACING
-static const char *
-later_type_to_string (MetaLaterType 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
-meta_later_invoke (MetaLater *later)
-{
- COGL_TRACE_BEGIN_SCOPED (later, later_type_to_string (later->when));
- return later->func (later->user_data);
-}
-
-static gboolean
-remove_later_from_list (unsigned int later_id,
- GSList **laters_list)
-{
- GSList *l;
-
- for (l = *laters_list; l; l = l->next)
- {
- MetaLater *later = l->data;
-
- if (later->id == later_id)
- {
- *laters_list = g_slist_delete_link (*laters_list, l);
- meta_later_destroy (later);
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static void
-run_repaint_laters (GSList **laters_list)
-{
- g_autoptr (GSList) laters_copy = NULL;
- GSList *l;
-
- for (l = *laters_list; l; l = l->next)
- {
- MetaLater *later = l->data;
-
- if (!later->source_id ||
- (later->when <= META_LATER_BEFORE_REDRAW && !later->run_once))
- laters_copy = g_slist_prepend (laters_copy, meta_later_ref (later));
- }
- laters_copy = g_slist_reverse (laters_copy);
-
- for (l = laters_copy; l; l = l->next)
- {
- MetaLater *later = l->data;
-
- if (!later->func)
- remove_later_from_list (later->id, laters_list);
- else if (!meta_later_invoke (later))
- remove_later_from_list (later->id, laters_list);
-
- meta_later_unref (later);
- }
-}
-
-static void
-on_before_update (ClutterStage *stage,
- ClutterStageView *stage_view,
- MetaLaters *laters)
-{
- unsigned int i;
- GSList *l;
- gboolean needs_schedule_update = FALSE;
-
- for (i = 0; i < G_N_ELEMENTS (laters->laters); i++)
- run_repaint_laters (&laters->laters[i]);
-
- for (i = 0; i < G_N_ELEMENTS (laters->laters); i++)
- {
- for (l = laters->laters[i]; l; l = l->next)
- {
- MetaLater *later = l->data;
-
- if (!later->source_id)
- needs_schedule_update = TRUE;
- }
- }
-
- if (needs_schedule_update)
- clutter_stage_schedule_update (stage);
-}
-
-static gboolean
-invoke_later_idle (gpointer data)
-{
- MetaLater *later = data;
-
- if (!later->func (later->user_data))
- {
- meta_later_remove (later->id);
- return FALSE;
- }
- else
- {
- later->run_once = TRUE;
- return TRUE;
- }
-}
-
-static unsigned int
-meta_laters_add (MetaLaters *laters,
- MetaLaterType when,
- GSourceFunc func,
- gpointer user_data,
- GDestroyNotify notify)
-{
- ClutterStage *stage = meta_compositor_get_stage (laters->compositor);
- MetaLater *later = g_new0 (MetaLater, 1);
-
- later->id = ++laters->last_later_id;
- later->ref_count = 1;
- later->when = when;
- later->func = func;
- later->user_data = user_data;
- later->destroy_notify = notify;
-
- laters->laters[when] = g_slist_prepend (laters->laters[when], later);
-
- switch (when)
- {
- case META_LATER_RESIZE:
- later->source_id = g_idle_add_full (META_PRIORITY_RESIZE,
- invoke_later_idle,
- later, NULL);
- g_source_set_name_by_id (later->source_id, "[mutter] invoke_later_idle");
- clutter_stage_schedule_update (stage);
- break;
- case META_LATER_CALC_SHOWING:
- case META_LATER_CHECK_FULLSCREEN:
- case META_LATER_SYNC_STACK:
- case META_LATER_BEFORE_REDRAW:
- clutter_stage_schedule_update (stage);
- break;
- case META_LATER_IDLE:
- later->source_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
- invoke_later_idle,
- later, NULL);
- g_source_set_name_by_id (later->source_id, "[mutter] invoke_later_idle");
- break;
- }
-
- return later->id;
-}
-
-/**
- * meta_later_add:
- * @when: enumeration value determining the phase at which to run the callback
- * @func: callback to run later
- * @data: data to pass to the callback
- * @notify: function to call to destroy @data when it is no longer in use, or %NULL
- *
- * Sets up a callback to be called at some later time. @when determines the
- * particular later occasion at which it is called. This is much like g_idle_add(),
- * except that the functions interact properly with clutter event handling.
- * If a "later" function is added from a clutter event handler, and is supposed
- * to be run before the stage is redrawn, it will be run before that redraw
- * of the stage, not the next one.
- *
- * Return value: an integer ID (guaranteed to be non-zero) that can be used
- * to cancel the callback and prevent it from being run.
- */
-unsigned int
-meta_later_add (MetaLaterType when,
- GSourceFunc func,
- gpointer data,
- GDestroyNotify notify)
-{
- MetaDisplay *display = meta_get_display ();
- MetaCompositor *compositor;
-
- g_return_val_if_fail (display, 0);
- g_return_val_if_fail (display->compositor, 0);
-
- compositor = display->compositor;
- return meta_laters_add (meta_compositor_get_laters (compositor),
- when, func, data, notify);
-}
-
-static void
-meta_laters_remove (MetaLaters *laters,
- unsigned int later_id)
-{
- unsigned int i;
-
- for (i = 0; i < G_N_ELEMENTS (laters->laters); i++)
- {
- if (remove_later_from_list (later_id, &laters->laters[i]))
- return;
- }
-}
-
-/**
- * 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 (unsigned int later_id)
-{
- MetaDisplay *display = meta_get_display ();
- MetaCompositor *compositor;
-
- g_return_if_fail (display);
-
- compositor = display->compositor;
- if (!compositor)
- return;
-
- meta_laters_remove (meta_compositor_get_laters (compositor), later_id);
-}
-
-MetaLaters *
-meta_laters_new (MetaCompositor *compositor)
-{
- ClutterStage *stage = meta_compositor_get_stage (compositor);
- MetaLaters *laters;
-
- laters = g_new0 (MetaLaters, 1);
- laters->compositor = compositor;
-
- laters->before_update_handler_id =
- g_signal_connect (stage, "before-update",
- G_CALLBACK (on_before_update),
- laters);
-
- return laters;
-}
-
-void
-meta_laters_free (MetaLaters *laters)
-{
- ClutterStage *stage = meta_compositor_get_stage (laters->compositor);
- unsigned int i;
-
- for (i = 0; i < G_N_ELEMENTS (laters->laters); i++)
- g_slist_free_full (laters->laters[i], (GDestroyNotify) meta_later_unref);
-
- g_clear_signal_handler (&laters->before_update_handler_id, stage);
- g_free (laters);
-}
diff --git a/src/compositor/meta-module.c b/src/compositor/meta-module.c
deleted file mode 100644
index a8ed15bae..000000000
--- a/src/compositor/meta-module.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (c) 2008 Intel Corp.
- *
- * Author: Tomas Frydrych <tf@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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/meta-module.h"
-
-#include <gmodule.h>
-
-#include "meta/meta-plugin.h"
-
-enum
-{
- PROP_0,
- PROP_PATH,
-};
-
-struct _MetaModulePrivate
-{
- GModule *lib;
- gchar *path;
- GType plugin_type;
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE (MetaModule, meta_module, G_TYPE_TYPE_MODULE);
-
-static gboolean
-meta_module_load (GTypeModule *gmodule)
-{
- MetaModulePrivate *priv = META_MODULE (gmodule)->priv;
- GType (*register_type) (GTypeModule *) = NULL;
-
- if (priv->lib && priv->plugin_type)
- return TRUE;
-
- g_assert (priv->path);
-
- if (!priv->lib &&
- !(priv->lib = g_module_open (priv->path, 0)))
- {
- g_warning ("Could not load library [%s (%s)]",
- priv->path, g_module_error ());
- return FALSE;
- }
-
- if (g_module_symbol (priv->lib, "meta_plugin_register_type",
- (gpointer *)(void *)&register_type) &&
- register_type)
- {
- GType plugin_type;
-
- if (!(plugin_type = register_type (gmodule)))
- {
- g_warning ("Could not register type for plugin %s",
- priv->path);
- return FALSE;
- }
- else
- {
- priv->plugin_type = plugin_type;
- }
-
- return TRUE;
- }
- else
- g_warning ("Broken plugin module [%s]", priv->path);
-
- return FALSE;
-}
-
-static void
-meta_module_unload (GTypeModule *gmodule)
-{
- MetaModulePrivate *priv = META_MODULE (gmodule)->priv;
-
- g_module_close (priv->lib);
-
- priv->lib = NULL;
- priv->plugin_type = 0;
-}
-
-static void
-meta_module_dispose (GObject *object)
-{
- G_OBJECT_CLASS (meta_module_parent_class)->dispose (object);
-}
-
-static void
-meta_module_finalize (GObject *object)
-{
- MetaModulePrivate *priv = META_MODULE (object)->priv;
-
- g_free (priv->path);
- priv->path = NULL;
-
- G_OBJECT_CLASS (meta_module_parent_class)->finalize (object);
-}
-
-static void
-meta_module_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaModulePrivate *priv = META_MODULE (object)->priv;
-
- switch (prop_id)
- {
- case PROP_PATH:
- g_free (priv->path);
- priv->path = g_value_dup_string (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_module_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaModulePrivate *priv = META_MODULE (object)->priv;
-
- switch (prop_id)
- {
- case PROP_PATH:
- g_value_set_string (value, priv->path);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_module_class_init (MetaModuleClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GTypeModuleClass *gmodule_class = G_TYPE_MODULE_CLASS (klass);
-
- gobject_class->finalize = meta_module_finalize;
- gobject_class->dispose = meta_module_dispose;
- gobject_class->set_property = meta_module_set_property;
- gobject_class->get_property = meta_module_get_property;
-
- gmodule_class->load = meta_module_load;
- gmodule_class->unload = meta_module_unload;
-
- g_object_class_install_property (gobject_class,
- PROP_PATH,
- g_param_spec_string ("path",
- "Path",
- "Load path",
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
-}
-
-static void
-meta_module_init (MetaModule *self)
-{
- self->priv = meta_module_get_instance_private (self);
-}
-
-GType
-meta_module_get_plugin_type (MetaModule *module)
-{
- MetaModulePrivate *priv = META_MODULE (module)->priv;
-
- return priv->plugin_type;
-}
-
diff --git a/src/compositor/meta-module.h b/src/compositor/meta-module.h
deleted file mode 100644
index dd6d5a685..000000000
--- a/src/compositor/meta-module.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (c) 2008 Intel Corp.
- *
- * Author: Tomas Frydrych <tf@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_MODULE_H_
-#define META_MODULE_H_
-
-#include <glib-object.h>
-
-#define META_TYPE_MODULE (meta_module_get_type ())
-#define META_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MODULE, MetaModule))
-#define META_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_MODULE, MetaModuleClass))
-#define META_IS_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_MODULE_TYPE))
-#define META_IS_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_MODULE))
-#define META_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_MODULE, MetaModuleClass))
-
-typedef struct _MetaModule MetaModule;
-typedef struct _MetaModuleClass MetaModuleClass;
-typedef struct _MetaModulePrivate MetaModulePrivate;
-
-struct _MetaModule
-{
- GTypeModule parent;
-
- MetaModulePrivate *priv;
-};
-
-struct _MetaModuleClass
-{
- GTypeModuleClass parent_class;
-};
-
-
-GType meta_module_get_type (void);
-
-GType meta_module_get_plugin_type (MetaModule *module);
-
-#endif
diff --git a/src/compositor/meta-plugin-manager.c b/src/compositor/meta-plugin-manager.c
deleted file mode 100644
index ab7fce663..000000000
--- a/src/compositor/meta-plugin-manager.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (c) 2008 Intel Corp.
- *
- * Author: Tomas Frydrych <tf@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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/meta-plugin-manager.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "backends/x11/meta-clutter-backend-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
-{
- MetaCompositor *compositor;
- MetaPlugin *plugin;
-};
-
-void
-meta_plugin_manager_set_plugin_type (GType gtype)
-{
- if (plugin_type != G_TYPE_NONE)
- meta_fatal ("Mutter plugin already set: %s", g_type_name (plugin_type));
-
- plugin_type = gtype;
-}
-
-/*
- * Loads the given plugin.
- */
-void
-meta_plugin_manager_load (const gchar *plugin_name)
-{
- const gchar *dpath = MUTTER_PLUGIN_DIR "/";
- gchar *path;
- MetaModule *module;
-
- if (g_path_is_absolute (plugin_name))
- path = g_strdup (plugin_name);
- else
- path = g_strconcat (dpath, plugin_name, ".so", NULL);
-
- module = g_object_new (META_TYPE_MODULE, "path", path, NULL);
- if (!module || !g_type_module_use (G_TYPE_MODULE (module)))
- {
- /* This is fatal under the assumption that a monitoring
- * process like gnome-session will take over and handle
- * our untimely exit.
- */
- g_printerr ("Unable to load plugin module [%s]: %s",
- path, g_module_error());
- exit (1);
- }
-
- meta_plugin_manager_set_plugin_type (meta_module_get_plugin_type (module));
-
- g_type_module_unuse (G_TYPE_MODULE (module));
- 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 (MetaCompositor *compositor)
-{
- MetaPluginManager *plugin_mgr;
- MetaPluginClass *klass;
- MetaPlugin *plugin;
- MetaMonitorManager *monitors;
-
- plugin_mgr = g_new0 (MetaPluginManager, 1);
- 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);
-
- monitors = meta_monitor_manager_get ();
- g_signal_connect (monitors, "confirm-display-change",
- G_CALLBACK (on_confirm_display_change), plugin_mgr);
-
- return plugin_mgr;
-}
-
-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);
-
- 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_switch_workspace)
- klass->kill_switch_workspace (plugin);
-}
-
-/*
- * Public method that the compositor hooks into for events that require
- * no additional parameters.
- *
- * 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
-meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
- MetaWindowActor *actor,
- MetaPluginEffect event)
-{
- 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;
-
- switch (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;
-}
-
-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_compositor_get_display (plugin_mgr->compositor);
-
- if (display->display_opening)
- return FALSE;
-
- if (!klass->size_change)
- return FALSE;
-
- meta_plugin_manager_kill_window_effects (plugin_mgr, actor);
- klass->size_change (plugin, actor, which_change, old_frame_rect, old_buffer_rect);
- return TRUE;
-}
-
-/*
- * 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.
- */
-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_compositor_get_display (plugin_mgr->compositor);
- gboolean retval = FALSE;
-
- if (display->display_opening)
- return FALSE;
-
- if (klass->switch_workspace)
- {
- retval = TRUE;
- meta_plugin_manager_kill_switch_workspace (plugin_mgr);
- klass->switch_workspace (plugin, from, to, direction);
- }
-
- return retval;
-}
-
-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;
-
- 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);
-
- 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)
-{
- 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 (klass->show_tile_preview)
- {
- klass->show_tile_preview (plugin, window, tile_rect, tile_monitor_number);
- return TRUE;
- }
-
- 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_compositor_get_display (plugin_mgr->compositor);
-
- if (display->display_opening)
- return FALSE;
-
- if (klass->hide_tile_preview)
- {
- klass->hide_tile_preview (plugin);
- return TRUE;
- }
-
- return FALSE;
-}
-
-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_compositor_get_display (plugin_mgr->compositor);
-
- if (display->display_opening)
- return;
-
- if (klass->show_window_menu)
- klass->show_window_menu (plugin, window, menu, x, y);
-}
-
-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);
-}
-
-MetaCloseDialog *
-meta_plugin_manager_create_close_dialog (MetaPluginManager *plugin_mgr,
- MetaWindow *window)
-{
- MetaPlugin *plugin = plugin_mgr->plugin;
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
-
- if (klass->create_close_dialog)
- return klass->create_close_dialog (plugin, window);
-
- return meta_close_dialog_default_new (window);
-}
-
-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
deleted file mode 100644
index d1c007fa1..000000000
--- a/src/compositor/meta-plugin-manager.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (c) 2008 Intel Corp.
- *
- * Author: Tomas Frydrych <tf@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_PLUGIN_MANAGER_H_
-#define META_PLUGIN_MANAGER_H_
-
-#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)
- *
- */
-typedef struct MetaPluginManager MetaPluginManager;
-
-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,
- MetaPluginEffect event);
-
-void meta_plugin_manager_event_size_changed (MetaPluginManager *mgr,
- MetaWindowActor *actor);
-
-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);
-
-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);
-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);
-
-MetaCloseDialog * meta_plugin_manager_create_close_dialog (MetaPluginManager *plugin_mgr,
- MetaWindow *window);
-
-MetaInhibitShortcutsDialog *
- meta_plugin_manager_create_inhibit_shortcuts_dialog (MetaPluginManager *plugin_mgr,
- MetaWindow *window);
-
-void meta_plugin_manager_locate_pointer (MetaPluginManager *mgr);
-
-#endif
diff --git a/src/compositor/meta-plugin.c b/src/compositor/meta-plugin.c
deleted file mode 100644
index 188675a4d..000000000
--- a/src/compositor/meta-plugin.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (c) 2008 Intel Corp.
- *
- * Author: Tomas Frydrych <tf@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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-plugin
- * @title: MetaPlugin
- * @short_description: Entry point for plugins
- *
- */
-
-#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 "backends/meta-monitor-manager-private.h"
-#include "backends/x11/meta-clutter-backend-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"
-
-
-typedef struct _MetaPluginPrivate
-{
- MetaCompositor *compositor;
-} MetaPluginPrivate;
-
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaPlugin, meta_plugin, G_TYPE_OBJECT);
-
-static void
-meta_plugin_class_init (MetaPluginClass *klass)
-{
-}
-
-static void
-meta_plugin_init (MetaPlugin *self)
-{
-}
-
-const MetaPluginInfo *
-meta_plugin_get_info (MetaPlugin *plugin)
-{
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
-
- if (klass && klass->plugin_info)
- return klass->plugin_info (plugin);
-
- return NULL;
-}
-
-gboolean
-_meta_plugin_xevent_filter (MetaPlugin *plugin,
- XEvent *xev)
-{
- MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
-
- 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_get_instance_private (plugin);
-
- meta_switch_workspace_completed (priv->compositor);
-}
-
-static void
-meta_plugin_window_effect_completed (MetaPlugin *plugin,
- MetaWindowActor *actor,
- unsigned long event)
-{
- meta_window_actor_effect_completed (actor, event);
-}
-
-void
-meta_plugin_minimize_completed (MetaPlugin *plugin,
- MetaWindowActor *actor)
-{
- meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_MINIMIZE);
-}
-
-void
-meta_plugin_unminimize_completed (MetaPlugin *plugin,
- MetaWindowActor *actor)
-{
- meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_UNMINIMIZE);
-}
-
-void
-meta_plugin_size_change_completed (MetaPlugin *plugin,
- MetaWindowActor *actor)
-{
- meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_SIZE_CHANGE);
-}
-
-void
-meta_plugin_map_completed (MetaPlugin *plugin,
- MetaWindowActor *actor)
-{
- meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_MAP);
-}
-
-void
-meta_plugin_destroy_completed (MetaPlugin *plugin,
- MetaWindowActor *actor)
-{
- meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_DESTROY);
-}
-
-/**
- * meta_plugin_begin_modal:
- * @plugin: a #MetaPlugin
- * @options: flags that modify the behavior of the modal grab
- * @timestamp: the timestamp used for establishing grabs
- *
- * This function is used to grab the keyboard and mouse for the exclusive
- * use of the plugin. Correct operation requires that both the keyboard
- * and mouse are grabbed, or thing will break. (In particular, other
- * passive X grabs in Meta can trigger but not be handled by the normal
- * keybinding handling code.) However, the plugin can establish the keyboard
- * and/or mouse grabs ahead of time and pass in the
- * %META_MODAL_POINTER_ALREADY_GRABBED and/or %META_MODAL_KEYBOARD_ALREADY_GRABBED
- * options. This facility is provided for two reasons: first to allow using
- * this function to establish modality after a passive grab, and second to
- * allow using obscure features of XGrabPointer() and XGrabKeyboard() without
- * having to add them to this API.
- *
- * Return value: whether we successfully grabbed the keyboard and
- * mouse and made the plugin modal.
- */
-gboolean
-meta_plugin_begin_modal (MetaPlugin *plugin,
- MetaModalOptions options,
- guint32 timestamp)
-{
- MetaPluginPrivate *priv = meta_plugin_get_instance_private (plugin);
-
- return meta_begin_modal_for_plugin (priv->compositor, plugin,
- options, timestamp);
-}
-
-/**
- * meta_plugin_end_modal:
- * @plugin: a #MetaPlugin
- * @timestamp: the time used for releasing grabs
- *
- * Ends the modal operation begun with meta_plugin_begin_modal(). This
- * ungrabs both the mouse and keyboard even when
- * %META_MODAL_POINTER_ALREADY_GRABBED or
- * %META_MODAL_KEYBOARD_ALREADY_GRABBED were provided as options
- * when beginnning the modal operation.
- */
-void
-meta_plugin_end_modal (MetaPlugin *plugin,
- guint32 timestamp)
-{
- MetaPluginPrivate *priv = meta_plugin_get_instance_private (plugin);
-
- meta_end_modal_for_plugin (priv->compositor, plugin, timestamp);
-}
-
-/**
- * meta_plugin_get_display:
- * @plugin: a #MetaPlugin
- *
- * Gets the #MetaDisplay corresponding to a plugin.
- *
- * Return value: (transfer none): the #MetaDisplay for the 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)
-{
- MetaMonitorManager *manager;
-
- manager = meta_monitor_manager_get ();
- meta_monitor_manager_confirm_configuration (manager, ok);
-}
diff --git a/src/compositor/meta-shadow-factory.c b/src/compositor/meta-shadow-factory.c
deleted file mode 100644
index d6424d3be..000000000
--- a/src/compositor/meta-shadow-factory.c
+++ /dev/null
@@ -1,1066 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * 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/>.
- */
-
-/**
- * SECTION:meta-shadow-factory
- * @title: MetaShadowFactory
- * @short_description: Create and cache shadow textures for arbitrary window shapes
- */
-
-#include "config.h"
-
-#include <math.h>
-#include <string.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
- * of the optimizations we use:
- *
- * - If the window shape is along the lines of a rounded rectangle -
- * a rectangular center portion with stuff at the corners - then
- * the blur of this - the shadow - can also be represented as a
- * 9-sliced texture and the same texture can be used for different
- * size.
- *
- * - We use the fact that a Gaussian blur is separable to do a
- * 2D blur as 1D blur of the rows followed by a 1D blur of the
- * columns.
- *
- * - For better cache efficiency, we blur rows, transpose the image
- * in blocks, blur rows again, and then transpose back.
- *
- * - We approximate the 1D gaussian blur as 3 successive box filters.
- */
-
-typedef struct _MetaShadowCacheKey MetaShadowCacheKey;
-typedef struct _MetaShadowClassInfo MetaShadowClassInfo;
-
-struct _MetaShadowCacheKey
-{
- MetaWindowShape *shape;
- int radius;
- int top_fade;
-};
-
-struct _MetaShadow
-{
- int ref_count;
-
- MetaShadowFactory *factory;
- MetaShadowCacheKey key;
- CoglTexture *texture;
- CoglPipeline *pipeline;
-
- /* The outer order is the distance the shadow extends outside the window
- * shape; the inner border is the unscaled portion inside the window
- * shape */
- int outer_border_top;
- int inner_border_top;
- int outer_border_right;
- int inner_border_right;
- int outer_border_bottom;
- int inner_border_bottom;
- int outer_border_left;
- int inner_border_left;
-
- guint scale_width : 1;
- guint scale_height : 1;
-};
-
-struct _MetaShadowClassInfo
-{
- const char *name; /* const so we can reuse for static definitions */
- MetaShadowParams focused;
- MetaShadowParams unfocused;
-};
-
-struct _MetaShadowFactory
-{
- GObject parent_instance;
-
- /* MetaShadowCacheKey => MetaShadow; the shadows are not referenced
- * by the factory, they are simply removed from the table when freed */
- GHashTable *shadows;
-
- /* class name => MetaShadowClassInfo */
- GHashTable *shadow_classes;
-};
-
-enum
-{
- CHANGED,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-/* The first element in this array also defines the default parameters
- * for newly created 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 } },
- { "utility", { 10, -1, 0, 3, 128 }, { 8, -1, 0, 2, 64 } },
- { "border", { 10, -1, 0, 3, 128 }, { 8, -1, 0, 2, 64 } },
- { "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 } }
-};
-
-G_DEFINE_TYPE (MetaShadowFactory, meta_shadow_factory, G_TYPE_OBJECT);
-
-static guint
-meta_shadow_cache_key_hash (gconstpointer val)
-{
- const MetaShadowCacheKey *key = val;
-
- return 59 * key->radius + 67 * key->top_fade + 73 * meta_window_shape_hash (key->shape);
-}
-
-static gboolean
-meta_shadow_cache_key_equal (gconstpointer a,
- gconstpointer b)
-{
- const MetaShadowCacheKey *key_a = a;
- const MetaShadowCacheKey *key_b = b;
-
- return (key_a->radius == key_b->radius && key_a->top_fade == key_b->top_fade &&
- meta_window_shape_equal (key_a->shape, key_b->shape));
-}
-
-MetaShadow *
-meta_shadow_ref (MetaShadow *shadow)
-{
- shadow->ref_count++;
-
- return shadow;
-}
-
-void
-meta_shadow_unref (MetaShadow *shadow)
-{
- shadow->ref_count--;
- if (shadow->ref_count == 0)
- {
- if (shadow->factory)
- {
- g_hash_table_remove (shadow->factory->shadows,
- &shadow->key);
- }
-
- meta_window_shape_unref (shadow->key.shape);
- cogl_object_unref (shadow->texture);
- cogl_object_unref (shadow->pipeline);
-
- g_free (shadow);
- }
-}
-
-/**
- * meta_shadow_paint:
- * @window_x: x position of the region to paint a shadow for
- * @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: (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
- * drawing.
- *
- * Paints the shadow at the given position, for the specified actual
- * size of the region. (Since a #MetaShadow can be shared between
- * different sizes with the same extracted #MetaWindowShape the
- * size needs to be passed in here.)
- */
-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)
-{
- float texture_width = cogl_texture_get_width (shadow->texture);
- float texture_height = cogl_texture_get_height (shadow->texture);
- int i, j;
- float src_x[4];
- float src_y[4];
- int dest_x[4];
- int dest_y[4];
- int n_x, n_y;
-
- if (clip && cairo_region_is_empty (clip))
- return;
-
- cogl_pipeline_set_color4ub (shadow->pipeline,
- opacity, opacity, opacity, opacity);
-
- if (shadow->scale_width)
- {
- n_x = 3;
-
- src_x[0] = 0.0;
- src_x[1] = (shadow->inner_border_left + shadow->outer_border_left) / texture_width;
- src_x[2] = (texture_width - (shadow->inner_border_right + shadow->outer_border_right)) / texture_width;
- src_x[3] = 1.0;
-
- dest_x[0] = window_x - shadow->outer_border_left;
- dest_x[1] = window_x + shadow->inner_border_left;
- dest_x[2] = window_x + window_width - shadow->inner_border_right;
- dest_x[3] = window_x + window_width + shadow->outer_border_right;
- }
- else
- {
- n_x = 1;
-
- src_x[0] = 0.0;
- src_x[1] = 1.0;
-
- dest_x[0] = window_x - shadow->outer_border_left;
- dest_x[1] = window_x + window_width + shadow->outer_border_right;
- }
-
- if (shadow->scale_height)
- {
- n_y = 3;
-
- src_y[0] = 0.0;
- src_y[1] = (shadow->inner_border_top + shadow->outer_border_top) / texture_height;
- src_y[2] = (texture_height - (shadow->inner_border_bottom + shadow->outer_border_bottom)) / texture_height;
- src_y[3] = 1.0;
-
- dest_y[0] = window_y - shadow->outer_border_top;
- dest_y[1] = window_y + shadow->inner_border_top;
- dest_y[2] = window_y + window_height - shadow->inner_border_bottom;
- dest_y[3] = window_y + window_height + shadow->outer_border_bottom;
- }
- else
- {
- n_y = 1;
-
- src_y[0] = 0.0;
- src_y[1] = 1.0;
-
- dest_y[0] = window_y - shadow->outer_border_top;
- dest_y[1] = window_y + window_height + shadow->outer_border_bottom;
- }
-
- for (j = 0; j < n_y; j++)
- {
- cairo_rectangle_int_t dest_rect;
- dest_rect.y = dest_y[j];
- dest_rect.height = dest_y[j + 1] - dest_y[j];
-
- if (dest_rect.height == 0)
- continue;
-
- for (i = 0; i < n_x; i++)
- {
- cairo_region_overlap_t overlap;
-
- dest_rect.x = dest_x[i];
- dest_rect.width = dest_x[i + 1] - dest_x[i];
-
- if (dest_rect.width == 0)
- continue;
-
- if (clip)
- overlap = cairo_region_contains_rectangle (clip, &dest_rect);
- else
- overlap = CAIRO_REGION_OVERLAP_IN;
-
- if (overlap == CAIRO_REGION_OVERLAP_OUT)
- continue;
-
- /* 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
- * unless we have to clip strictly it will be cheaper to
- * just draw the entire rectangle.
- */
- if (overlap == CAIRO_REGION_OVERLAP_IN ||
- (overlap == CAIRO_REGION_OVERLAP_PART && !clip_strictly))
- {
- cogl_framebuffer_draw_textured_rectangle (framebuffer,
- shadow->pipeline,
- dest_x[i], dest_y[j],
- dest_x[i + 1], dest_y[j + 1],
- src_x[i], src_y[j],
- src_x[i + 1], src_y[j + 1]);
- }
- else if (overlap == CAIRO_REGION_OVERLAP_PART)
- {
- cairo_region_t *intersection;
- int n_rectangles, k;
-
- intersection = cairo_region_create_rectangle (&dest_rect);
- cairo_region_intersect (intersection, clip);
-
- n_rectangles = cairo_region_num_rectangles (intersection);
- for (k = 0; k < n_rectangles; k++)
- {
- cairo_rectangle_int_t rect;
- float src_x1, src_x2, src_y1, src_y2;
-
- cairo_region_get_rectangle (intersection, k, &rect);
-
- /* Separately linear interpolate X and Y coordinates in the source
- * based on the destination X and Y coordinates */
-
- src_x1 = (src_x[i] * (dest_rect.x + dest_rect.width - rect.x) +
- src_x[i + 1] * (rect.x - dest_rect.x)) / dest_rect.width;
- src_x2 = (src_x[i] * (dest_rect.x + dest_rect.width - (rect.x + rect.width)) +
- src_x[i + 1] * (rect.x + rect.width - dest_rect.x)) / dest_rect.width;
-
- src_y1 = (src_y[j] * (dest_rect.y + dest_rect.height - rect.y) +
- src_y[j + 1] * (rect.y - dest_rect.y)) / dest_rect.height;
- 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;
-
- 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);
- }
-
- cairo_region_destroy (intersection);
- }
- }
- }
-}
-
-/**
- * meta_shadow_get_bounds:
- * @shadow: a #MetaShadow
- * @window_x: x position of the region to paint a shadow for
- * @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
- *
- * Computes the bounds of the pixels that will be affected by
- * meta_shadow_paint()
- */
-void
-meta_shadow_get_bounds (MetaShadow *shadow,
- int window_x,
- int window_y,
- int window_width,
- int window_height,
- cairo_rectangle_int_t *bounds)
-{
- bounds->x = window_x - shadow->outer_border_left;
- bounds->y = window_y - shadow->outer_border_top;
- bounds->width = window_width + shadow->outer_border_left + shadow->outer_border_right;
- bounds->height = window_height + shadow->outer_border_top + shadow->outer_border_bottom;
-}
-
-static void
-meta_shadow_class_info_free (MetaShadowClassInfo *class_info)
-{
- g_free ((char *)class_info->name);
- g_free (class_info);
-}
-
-static void
-meta_shadow_factory_init (MetaShadowFactory *factory)
-{
- guint i;
-
- factory->shadows = g_hash_table_new (meta_shadow_cache_key_hash,
- meta_shadow_cache_key_equal);
-
- factory->shadow_classes = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- NULL,
- (GDestroyNotify)meta_shadow_class_info_free);
-
- for (i = 0; i < G_N_ELEMENTS (default_shadow_classes); i++)
- {
- MetaShadowClassInfo *class_info = g_new0 (MetaShadowClassInfo, 1);
-
- *class_info = default_shadow_classes[i];
- class_info->name = g_strdup (class_info->name);
-
- g_hash_table_insert (factory->shadow_classes,
- (char *)class_info->name, class_info);
- }
-}
-
-static void
-meta_shadow_factory_finalize (GObject *object)
-{
- MetaShadowFactory *factory = META_SHADOW_FACTORY (object);
- GHashTableIter iter;
- gpointer key, value;
-
- /* Detach from the shadows in the table so we won't try to
- * remove them when they're freed. */
- g_hash_table_iter_init (&iter, factory->shadows);
- while (g_hash_table_iter_next (&iter, &key, &value))
- {
- MetaShadow *shadow = key;
- shadow->factory = NULL;
- }
-
- g_hash_table_destroy (factory->shadows);
- g_hash_table_destroy (factory->shadow_classes);
-
- G_OBJECT_CLASS (meta_shadow_factory_parent_class)->finalize (object);
-}
-
-static void
-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);
-}
-
-MetaShadowFactory *
-meta_shadow_factory_new (void)
-{
- return g_object_new (META_TYPE_SHADOW_FACTORY, NULL);
-}
-
-/**
- * meta_shadow_factory_get_default:
- *
- * Return value: (transfer none): the global singleton shadow factory
- */
-MetaShadowFactory *
-meta_shadow_factory_get_default (void)
-{
- static MetaShadowFactory *factory;
-
- if (factory == NULL)
- factory = meta_shadow_factory_new ();
-
- return factory;
-}
-
-/* We emulate a 1D Gaussian blur by using 3 consecutive box blurs;
- * this produces a result that's within 3% of the original and can be
- * implemented much faster for large filter sizes because of the
- * efficiency of implementation of a box blur. Idea and formula
- * for choosing the box blur size come from:
- *
- * http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement
- *
- * The 2D blur is then done by blurring the rows, flipping the
- * image and blurring the columns. (This is possible because the
- * Gaussian kernel is separable - it's the product of a horizontal
- * blur and a vertical blur.)
- */
-static int
-get_box_filter_size (int radius)
-{
- return (int)(0.5 + radius * (0.75 * sqrt(2*M_PI)));
-}
-
-/* The "spread" of the filter is the number of pixels from an original
- * pixel that it's blurred image extends. (A no-op blur that doesn't
- * blur would have a spread of 0.) See comment in blur_rows() for why the
- * odd and even cases are different
- */
-static int
-get_shadow_spread (int radius)
-{
- int d;
-
- if (radius == 0)
- return 0;
-
- d = get_box_filter_size (radius);
-
- if (d % 2 == 1)
- return 3 * (d / 2);
- else
- return 3 * (d / 2) - 1;
-}
-
-/* This applies a single box blur pass to a horizontal range of pixels;
- * since the box blur has the same weight for all pixels, we can
- * implement an efficient sliding window algorithm where we add
- * in pixels coming into the window from the right and remove
- * them when they leave the windw to the left.
- *
- * d is the filter width; for even d shift indicates how the blurred
- * result is aligned with the original - does ' x ' go to ' yy' (shift=1)
- * or 'yy ' (shift=-1)
- */
-static void
-blur_xspan (guchar *row,
- guchar *tmp_buffer,
- int row_width,
- int x0,
- int x1,
- int d,
- int shift)
-{
- int offset;
- int sum = 0;
- int i;
-
- if (d % 2 == 1)
- offset = d / 2;
- else
- offset = (d - shift) / 2;
-
- /* All the conditionals in here look slow, but the branches will
- * 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 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.)
- */
- for (i = x0 - d + offset; i < x1 + offset; i++)
- {
- if (i >= 0 && i < row_width)
- sum += row[i];
-
- if (i >= x0 + offset)
- {
- if (i >= d)
- sum -= row[i - d];
-
- tmp_buffer[i - offset] = (sum + d / 2) / d;
- }
- }
-
- 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,
- int d)
-{
- int i, j;
- int n_rectangles;
- guchar *tmp_buffer;
-
- tmp_buffer = g_malloc (buffer_width);
-
- n_rectangles = cairo_region_num_rectangles (convolve_region);
- for (i = 0; i < n_rectangles; i++)
- {
- cairo_rectangle_int_t rect;
-
- 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;
-
- /* 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.
- * (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);
- }
- }
- }
-
- g_free (tmp_buffer);
-}
-
-static void
-fade_bytes (guchar *bytes,
- int width,
- int distance,
- int total)
-{
- guint32 multiplier = (distance * 0x10000 + 0x8000) / total;
- int i;
-
- for (i = 0; i < width; i++)
- bytes[i] = (bytes[i] * multiplier) >> 16;
-}
-
-/* Swaps width and height. Either swaps in-place and returns the original
- * buffer or allocates a new buffer, frees the original buffer and returns
- * the new buffer.
- */
-static guchar *
-flip_buffer (guchar *buffer,
- int width,
- int height)
-{
- /* Working in blocks increases cache efficiency, compared to reading
- * or writing an entire column at once */
-#define BLOCK_SIZE 16
-
- if (width == height)
- {
- 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;
- }
- }
- }
-
- return buffer;
- }
- else
- {
- 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;
-
- for (i = i0; i < max_i; i++)
- for (j = j0; j < max_j; j++)
- new_buffer[i * height + j] = buffer[j * width + i];
- }
-
- g_free (buffer);
-
- return new_buffer;
- }
-#undef BLOCK_SIZE
-}
-
-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;
- cairo_region_t *row_convolve_region;
- cairo_region_t *column_convolve_region;
- guchar *buffer;
- int buffer_width;
- int buffer_height;
- int x_offset;
- int y_offset;
- int n_rectangles, j, k;
-
- cairo_region_get_extents (region, &extents);
-
- /* In the case where top_fade >= 0 and the portion above the top
- * edge of the shape will be cropped, it seems like we could create
- * a smaller buffer and omit the top portion, but actually, in our
- * multi-pass blur algorithm, the blur into the area above the window
- * in the first pass will contribute back to the final pixel values
- * for the top pixels, so we create a buffer as if we weren't cropping
- * and only crop when creating the CoglTexture.
- */
-
- buffer_width = extents.width + 2 * spread;
- buffer_height = extents.height + 2 * spread;
-
- /* Round up so we have aligned rows/columns */
- buffer_width = (buffer_width + 3) & ~3;
- buffer_height = (buffer_height + 3) & ~3;
-
- /* Square buffer allows in-place swaps, which are roughly 70% faster, but we
- * don't want to over-allocate too much memory.
- */
- if (buffer_height < buffer_width && buffer_height > (3 * buffer_width) / 4)
- buffer_height = buffer_width;
- if (buffer_width < buffer_height && buffer_width > (3 * buffer_height) / 4)
- 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
- * to the region that actually needs to be blurred.
- */
- row_convolve_region = meta_make_border_region (region, spread, spread, FALSE);
- column_convolve_region = meta_make_border_region (region, 0, spread, TRUE);
-
- /* Offsets between coordinates of the regions and coordinates in the buffer */
- x_offset = spread;
- y_offset = spread;
-
- /* Step 1: unblurred image */
- n_rectangles = cairo_region_num_rectangles (region);
- for (k = 0; k < n_rectangles; k++)
- {
- cairo_rectangle_int_t rect;
-
- 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);
- }
-
- /* Step 2: swap rows and columns */
- buffer = flip_buffer (buffer, buffer_width, buffer_height);
-
- /* Step 3: blur rows (really columns) */
- blur_rows (column_convolve_region, y_offset, x_offset,
- buffer, buffer_height, buffer_width,
- d);
-
- /* Step 4: swap rows and columns */
- buffer = flip_buffer (buffer, buffer_height, buffer_width);
-
- /* Step 5: blur rows */
- blur_rows (row_convolve_region, x_offset, y_offset,
- buffer, buffer_width, buffer_height,
- d);
-
- /* Step 6: fade out the top, if applicable */
- if (shadow->key.top_fade >= 0)
- {
- for (j = y_offset; j < y_offset + MIN (shadow->key.top_fade, extents.height + shadow->outer_border_bottom); j++)
- fade_bytes(buffer + j * buffer_width, buffer_width, j - y_offset, shadow->key.top_fade);
- }
-
- /* We offset the passed in pixels to crop off the extra area we allocated at the top
- * 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 = 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", error->message);
- g_error_free (error);
- }
-
- cairo_region_destroy (row_convolve_region);
- cairo_region_destroy (column_convolve_region);
- g_free (buffer);
-
- shadow->pipeline = meta_create_texture_pipeline (shadow->texture);
-}
-
-static MetaShadowParams *
-get_shadow_params (MetaShadowFactory *factory,
- const char *class_name,
- gboolean focused,
- gboolean create)
-{
- MetaShadowClassInfo *class_info = g_hash_table_lookup (factory->shadow_classes,
- class_name);
- if (class_info == NULL)
- {
- if (create)
- {
- class_info = g_new0 (MetaShadowClassInfo, 1);
- *class_info = default_shadow_classes[0];
- class_info->name = g_strdup (class_info->name);
-
- g_hash_table_insert (factory->shadow_classes,
- (char *)class_info->name, class_info);
- }
- else
- {
- class_info = &default_shadow_classes[0];
- }
- }
-
- if (focused)
- return &class_info->focused;
- else
- return &class_info->unfocused;
-}
-
-/**
- * meta_shadow_factory_get_shadow:
- * @factory: a #MetaShadowFactory
- * @shape: the size-invariant shape of the window's region
- * @width: the actual width of the window's region
- * @height: the actual height of the window's region
- * @class_name: name of the class of window shadows
- * @focused: whether the shadow is for a focused window
- *
- * Gets the appropriate shadow object for drawing shadows for the
- * specified window shape. The region that we are shadowing is specified
- * as a combination of a size-invariant extracted shape and the size.
- * In some cases, the same shadow object can be shared between sizes;
- * in other cases a different shadow object is used for each size.
- *
- * Return value: (transfer full): a newly referenced #MetaShadow; unref with
- * meta_shadow_unref()
- */
-MetaShadow *
-meta_shadow_factory_get_shadow (MetaShadowFactory *factory,
- MetaWindowShape *shape,
- int width,
- int height,
- const char *class_name,
- gboolean focused)
-{
- MetaShadowParams *params;
- MetaShadowCacheKey key;
- MetaShadow *shadow;
- cairo_region_t *region;
- int spread;
- int shape_border_top, shape_border_right, shape_border_bottom, shape_border_left;
- int inner_border_top, inner_border_right, inner_border_bottom, inner_border_left;
- int outer_border_top, outer_border_right, outer_border_bottom, outer_border_left;
- gboolean scale_width, scale_height;
- gboolean cacheable;
- int center_width, center_height;
-
- g_return_val_if_fail (META_IS_SHADOW_FACTORY (factory), NULL);
- g_return_val_if_fail (shape != NULL, NULL);
-
- /* Using a single shadow texture for different window sizes only works
- * when there is a central scaled area that is greater than twice
- * the spread of the gaussian blur we are applying to get to the
- * shadow image.
- * ********* ***********
- * /----------\ *###########* *#############*
- * | | => **#*********#** => **#***********#**
- * | | **#** **#** **#** **#**
- * | | **#*********#** **#***********#**
- * \----------/ *###########* *#############*
- * ********** ************
- * Original Blur Stretched Blur
- *
- * For smaller sizes, we create a separate shadow image for each size;
- * since we assume that there will be little reuse, we don't try to
- * cache such images but just recreate them. (Since the current cache
- * policy is to only keep around referenced shadows, there wouldn't
- * be any harm in caching them, it would just make the book-keeping
- * a bit tricker.)
- *
- * In the case where we are fading a the top, that also has to fit
- * within the top unscaled border.
- */
-
- params = get_shadow_params (factory, class_name, focused, FALSE);
-
- spread = get_shadow_spread (params->radius);
- meta_window_shape_get_borders (shape,
- &shape_border_top,
- &shape_border_right,
- &shape_border_bottom,
- &shape_border_left);
-
- inner_border_top = MAX (shape_border_top + spread, params->top_fade);
- outer_border_top = params->top_fade >= 0 ? 0 : spread;
- inner_border_right = shape_border_right + spread;
- outer_border_right = spread;
- inner_border_bottom = shape_border_bottom + spread;
- outer_border_bottom = spread;
- inner_border_left = shape_border_left + spread;
- outer_border_left = spread;
-
- scale_width = inner_border_left + inner_border_right <= width;
- scale_height = inner_border_top + inner_border_bottom <= height;
- cacheable = scale_width && scale_height;
-
- if (cacheable)
- {
- key.shape = shape;
- key.radius = params->radius;
- key.top_fade = params->top_fade;
-
- shadow = g_hash_table_lookup (factory->shadows, &key);
- if (shadow)
- return meta_shadow_ref (shadow);
- }
-
- shadow = g_new0 (MetaShadow, 1);
-
- shadow->ref_count = 1;
- shadow->factory = factory;
- shadow->key.shape = meta_window_shape_ref (shape);
- shadow->key.radius = params->radius;
- shadow->key.top_fade = params->top_fade;
-
- shadow->outer_border_top = outer_border_top;
- shadow->inner_border_top = inner_border_top;
- shadow->outer_border_right = outer_border_right;
- shadow->inner_border_right = inner_border_right;
- shadow->outer_border_bottom = outer_border_bottom;
- shadow->inner_border_bottom = inner_border_bottom;
- shadow->outer_border_left = outer_border_left;
- shadow->inner_border_left = inner_border_left;
-
- shadow->scale_width = scale_width;
- if (scale_width)
- center_width = inner_border_left + inner_border_right - (shape_border_left + shape_border_right);
- else
- center_width = width - (shape_border_left + shape_border_right);
-
- shadow->scale_height = scale_height;
- if (scale_height)
- center_height = inner_border_top + inner_border_bottom - (shape_border_top + shape_border_bottom);
- else
- center_height = height - (shape_border_top + shape_border_bottom);
-
- g_assert (center_width >= 0 && center_height >= 0);
-
- region = meta_window_shape_to_region (shape, center_width, center_height);
- make_shadow (shadow, region);
-
- cairo_region_destroy (region);
-
- if (cacheable)
- g_hash_table_insert (factory->shadows, &shadow->key, shadow);
-
- return shadow;
-}
-
-/**
- * meta_shadow_factory_set_params:
- * @factory: a #MetaShadowFactory
- * @class_name: name of the class of shadow to set the params for.
- * the default shadow classes are the names of the different
- * theme frame types (normal, dialog, modal_dialog, utility,
- * border, menu, attached) and in addition, popup-menu
- * and dropdown-menu.
- * @focused: whether the shadow is for a focused window
- * @params: new parameter values
- *
- * Updates the shadow parameters for a particular class of shadows
- * for either the focused or unfocused state. If the class name
- * does not name an existing class, a new class will be created
- * (the other focus state for that class will have default values
- * assigned to it.)
- */
-void
-meta_shadow_factory_set_params (MetaShadowFactory *factory,
- const char *class_name,
- gboolean focused,
- MetaShadowParams *params)
-{
- MetaShadowParams *stored_params;
-
- g_return_if_fail (META_IS_SHADOW_FACTORY (factory));
- g_return_if_fail (class_name != NULL);
- g_return_if_fail (params != NULL);
- g_return_if_fail (params->radius >= 0);
-
- stored_params = get_shadow_params (factory, class_name, focused, TRUE);
-
- *stored_params = *params;
-
- g_signal_emit (factory, signals[CHANGED], 0);
-}
-
-/**
- * meta_shadow_factory_get_params:
- * @factory: a #MetaShadowFactory
- * @class_name: name of the class of shadow to get the params for
- * @focused: whether the shadow is for a focused window
- * @params: (out caller-allocates): location to store the current parameter values
- *
- * Gets the shadow parameters for a particular class of shadows
- * for either the focused or unfocused state. If the class name
- * does not name an existing class, default values will be returned
- * without printing an error.
- */
-void
-meta_shadow_factory_get_params (MetaShadowFactory *factory,
- const char *class_name,
- gboolean focused,
- MetaShadowParams *params)
-{
- MetaShadowParams *stored_params;
-
- g_return_if_fail (META_IS_SHADOW_FACTORY (factory));
- g_return_if_fail (class_name != NULL);
-
- stored_params = get_shadow_params (factory, class_name, focused, FALSE);
-
- 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
deleted file mode 100644
index 2fe1b8ea4..000000000
--- a/src/compositor/meta-shaped-texture-private.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * shaped texture
- *
- * An actor to draw a texture clipped to a list of rectangles
- *
- * Authored By Neil Roberts <neil@linux.intel.com>
- *
- * Copyright (C) 2008 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_SHAPED_TEXTURE_PRIVATE_H__
-#define __META_SHAPED_TEXTURE_PRIVATE_H__
-
-#include "backends/meta-monitor-manager-private.h"
-#include "meta/meta-shaped-texture.h"
-
-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);
-void meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex,
- cairo_region_t *opaque_region);
-
-void meta_shaped_texture_ensure_size_valid (MetaShapedTexture *stex);
-
-#endif
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
deleted file mode 100644
index 6a8af828f..000000000
--- a/src/compositor/meta-shaped-texture.c
+++ /dev/null
@@ -1,1676 +0,0 @@
-/*
- * 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
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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-shaped-texture
- * @title: MetaShapedTexture
- * @short_description: A ClutterContent which draws a shaped texture
- *
- * A MetaShapedTexture draws a #CoglTexture (often provided from a client
- * surface) in such a way that it matches any required transformations that
- * give its final shape, such as a #MetaMonitorTransform, y-invertedness, or a
- * crop-and-scale operation.
- */
-
-#include "config.h"
-
-#include "backends/meta-monitor-transform.h"
-#include "compositor/meta-shaped-texture-private.h"
-#include "core/boxes-private.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
- * windows like top or a blinking cursor, so that such windows do get
- * mipmapped.
- */
-#define MAX_MIPMAPPING_FPS 5
-#define MIN_MIPMAP_AGE_USEC (G_USEC_PER_SEC / MAX_MIPMAPPING_FPS)
-
-/* MIN_FAST_UPDATES_BEFORE_UNMIPMAP allows windows to update themselves
- * occasionally without causing mipmapping to be disabled, so long as such
- * an update takes fewer update_area calls than:
- */
-#define MIN_FAST_UPDATES_BEFORE_UNMIPMAP 20
-
-static void meta_shaped_texture_dispose (GObject *object);
-
-static void clutter_content_iface_init (ClutterContentInterface *iface);
-
-enum
-{
- SIZE_CHANGED,
-
- LAST_SIGNAL,
-};
-
-static guint signals[LAST_SIGNAL];
-
-static CoglPipelineKey opaque_overlay_pipeline_key =
- "meta-shaped-texture-opaque-pipeline-key";
-static CoglPipelineKey blended_overlay_pipeline_key =
- "meta-shaped-texture-blended-pipeline-key";
-
-struct _MetaShapedTexture
-{
- GObject parent;
-
- MetaTextureTower *paint_tower;
-
- CoglTexture *texture;
- CoglTexture *mask_texture;
- CoglSnippet *snippet;
-
- 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;
-
- /* 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;
-
- 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;
-};
-
-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;
-
- gobject_class->dispose = meta_shaped_texture_dispose;
-
- 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);
-}
-
-static void
-invalidate_size (MetaShapedTexture *stex)
-{
- stex->size_invalid = 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
-update_size (MetaShapedTexture *stex)
-{
- int buffer_scale = stex->buffer_scale;
- int dst_width;
- int dst_height;
-
- if (stex->has_viewport_dst_size)
- {
- 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;
- }
- }
- }
-
- stex->size_invalid = FALSE;
-
- if (stex->dst_width != dst_width ||
- stex->dst_height != dst_height)
- {
- 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);
- }
-}
-
-void
-meta_shaped_texture_ensure_size_valid (MetaShapedTexture *stex)
-{
- if (stex->size_invalid)
- update_size (stex);
-}
-
-void
-meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
- cairo_region_t *clip_region)
-{
- g_clear_pointer (&stex->clip_region, cairo_region_destroy);
- if (clip_region)
- stex->clip_region = cairo_region_reference (clip_region);
-}
-
-static void
-meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
-{
- 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
-meta_shaped_texture_dispose (GObject *object)
-{
- MetaShapedTexture *stex = (MetaShapedTexture *) object;
-
- g_clear_handle_id (&stex->remipmap_timeout_id, g_source_remove);
-
- if (stex->paint_tower)
- meta_texture_tower_free (stex->paint_tower);
- stex->paint_tower = NULL;
-
- g_clear_pointer (&stex->texture, cogl_object_unref);
-
- 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);
-
- g_clear_pointer (&stex->snippet, cogl_object_unref);
-
- G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
-}
-
-static CoglPipeline *
-get_base_pipeline (MetaShapedTexture *stex,
- CoglContext *ctx)
-{
- CoglPipeline *pipeline;
- graphene_matrix_t matrix;
-
- if (stex->base_pipeline)
- return stex->base_pipeline;
-
- 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);
-
- graphene_matrix_init_identity (&matrix);
-
- if (stex->has_viewport_src_rect)
- {
- float scaled_tex_width = stex->tex_width / (float) stex->buffer_scale;
- float scaled_tex_height = stex->tex_height / (float) stex->buffer_scale;
- graphene_point3d_t p;
-
- graphene_point3d_init (&p,
- 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);
- graphene_matrix_translate (&matrix, &p);
-
- if (meta_monitor_transform_is_rotated (stex->transform))
- {
- graphene_matrix_scale (&matrix,
- stex->viewport_src_rect.size.width /
- scaled_tex_height,
- stex->viewport_src_rect.size.height /
- scaled_tex_width,
- 1);
- }
- else
- {
- graphene_matrix_scale (&matrix,
- stex->viewport_src_rect.size.width /
- scaled_tex_width,
- stex->viewport_src_rect.size.height /
- scaled_tex_height,
- 1);
- }
- }
-
- if (stex->transform != META_MONITOR_TRANSFORM_NORMAL)
- {
- graphene_euler_t euler;
-
- graphene_matrix_translate (&matrix,
- &GRAPHENE_POINT3D_INIT (-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 ();
- }
- graphene_matrix_rotate_euler (&matrix, &euler);
- graphene_matrix_translate (&matrix,
- &GRAPHENE_POINT3D_INIT (0.5, 0.5, 0.0));
- }
-
- if (!stex->is_y_inverted)
- {
- graphene_matrix_translate (&matrix, &GRAPHENE_POINT3D_INIT (0, -1, 0));
- graphene_matrix_scale (&matrix, 1, -1, 1);
- cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
- }
-
- cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
- cogl_pipeline_set_layer_matrix (pipeline, 1, &matrix);
-
- if (stex->snippet)
- cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
-
- stex->base_pipeline = pipeline;
-
- return stex->base_pipeline;
-}
-
-static CoglPipeline *
-get_unmasked_pipeline (MetaShapedTexture *stex,
- CoglContext *ctx)
-{
- return get_base_pipeline (stex, ctx);
-}
-
-static CoglPipeline *
-get_masked_pipeline (MetaShapedTexture *stex,
- CoglContext *ctx)
-{
- CoglPipeline *pipeline;
-
- if (stex->masked_pipeline)
- return stex->masked_pipeline;
-
- pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
- cogl_pipeline_set_layer_combine (pipeline, 1,
- "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
- NULL);
-
- stex->masked_pipeline = pipeline;
-
- return pipeline;
-}
-
-static CoglPipeline *
-get_unblended_pipeline (MetaShapedTexture *stex,
- CoglContext *ctx)
-{
- CoglPipeline *pipeline;
-
- if (stex->unblended_pipeline)
- return stex->unblended_pipeline;
-
- pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
- cogl_pipeline_set_layer_combine (pipeline, 0,
- "RGBA = REPLACE (TEXTURE)",
- NULL);
-
- stex->unblended_pipeline = pipeline;
-
- return pipeline;
-}
-
-static CoglPipeline *
-get_opaque_overlay_pipeline (CoglContext *ctx)
-{
- CoglPipeline *pipeline;
-
- pipeline = cogl_context_get_named_pipeline (ctx,
- &opaque_overlay_pipeline_key);
- if (!pipeline)
- {
- pipeline = cogl_pipeline_new (ctx);
- cogl_pipeline_set_color4ub (pipeline, 0x00, 0x33, 0x00, 0x33);
-
- cogl_context_set_named_pipeline (ctx,
- &opaque_overlay_pipeline_key,
- pipeline);
- }
-
- return pipeline;
-}
-
-static CoglPipeline *
-get_blended_overlay_pipeline (CoglContext *ctx)
-{
- CoglPipeline *pipeline;
-
- pipeline = cogl_context_get_named_pipeline (ctx,
- &blended_overlay_pipeline_key);
- if (!pipeline)
- {
- pipeline = cogl_pipeline_new (ctx);
- cogl_pipeline_set_color4ub (pipeline, 0x33, 0x00, 0x33, 0x33);
-
- cogl_context_set_named_pipeline (ctx,
- &blended_overlay_pipeline_key,
- pipeline);
- }
-
- return pipeline;
-}
-
-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;
-
- ratio_h = clutter_actor_box_get_width (alloc) / (float) stex->dst_width;
- ratio_v = clutter_actor_box_get_height (alloc) / (float) stex->dst_height;
-
- 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;
-
- 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);
-
- if ((g_get_monotonic_time () - stex->earliest_remipmap) < 0)
- return G_SOURCE_CONTINUE;
-
- 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
-do_paint_content (MetaShapedTexture *stex,
- ClutterPaintNode *root_node,
- ClutterPaintContext *paint_context,
- CoglTexture *paint_tex,
- ClutterActorBox *alloc,
- uint8_t opacity)
-{
- int dst_width, dst_height;
- cairo_rectangle_int_t content_rect;
- gboolean use_opaque_region;
- cairo_region_t *blended_tex_region;
- CoglContext *ctx;
- CoglPipelineFilter filter;
- CoglFramebuffer *framebuffer;
- int sample_width, sample_height;
- gboolean debug_paint_opaque_region;
-
- meta_shaped_texture_ensure_size_valid (stex);
-
- dst_width = stex->dst_width;
- dst_height = stex->dst_height;
-
- if (dst_width == 0 || dst_height == 0) /* no contents yet */
- return;
-
- content_rect = (cairo_rectangle_int_t) {
- .x = 0,
- .y = 0,
- .width = dst_width,
- .height = dst_height,
- };
-
- debug_paint_opaque_region =
- meta_get_debug_paint_flags() & META_DEBUG_PAINT_OPAQUE_REGION;
-
- /* Use nearest-pixel interpolation if the texture is unscaled. This
- * improves performance, especially with software rendering.
- */
-
- 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 (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 ());
-
- use_opaque_region = stex->opaque_region && opacity == 255;
-
- if (use_opaque_region)
- {
- if (stex->clip_region)
- blended_tex_region = cairo_region_copy (stex->clip_region);
- else
- blended_tex_region = cairo_region_create_rectangle (&content_rect);
-
- cairo_region_subtract (blended_tex_region, stex->opaque_region);
- }
- else
- {
- if (stex->clip_region)
- blended_tex_region = cairo_region_reference (stex->clip_region);
- else
- 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_tex_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;
-
- g_clear_pointer (&blended_tex_region, cairo_region_destroy);
- }
- }
-
- /* First, paint the unblended parts, which are part of the opaque region. */
- if (use_opaque_region)
- {
- cairo_region_t *region;
- int n_rects;
- int i;
-
- if (stex->clip_region)
- {
- region = cairo_region_copy (stex->clip_region);
- cairo_region_intersect (region, stex->opaque_region);
- }
- else
- {
- region = cairo_region_reference (stex->opaque_region);
- }
-
- if (!cairo_region_is_empty (region))
- {
- 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);
-
- n_rects = cairo_region_num_rectangles (region);
- for (i = 0; i < n_rects; i++)
- {
- cairo_rectangle_int_t rect;
- cairo_region_get_rectangle (region, i, &rect);
- paint_clipped_rectangle_node (stex, root_node,
- opaque_pipeline,
- &rect, alloc);
-
- if (G_UNLIKELY (debug_paint_opaque_region))
- {
- CoglPipeline *opaque_overlay_pipeline;
-
- opaque_overlay_pipeline = get_opaque_overlay_pipeline (ctx);
- paint_clipped_rectangle_node (stex, root_node,
- opaque_overlay_pipeline,
- &rect, alloc);
- }
- }
- }
-
- cairo_region_destroy (region);
- }
-
- /* Now, go ahead and paint the blended parts. */
-
- /* We have three cases:
- * 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_tex_region || !cairo_region_is_empty (blended_tex_region))
- {
- CoglPipeline *blended_pipeline;
-
- if (stex->mask_texture == NULL)
- {
- blended_pipeline = get_unmasked_pipeline (stex, ctx);
- }
- else
- {
- 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);
- }
-
- cogl_pipeline_set_layer_texture (blended_pipeline, 0, paint_tex);
- cogl_pipeline_set_layer_filters (blended_pipeline, 0, filter, filter);
-
- CoglColor color;
- cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
- cogl_pipeline_set_color (blended_pipeline, &color);
-
- if (blended_tex_region)
- {
- /* 1) blended_tex_region is not empty. Paint the rectangles. */
- int i;
- 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_tex_region, i, &rect);
-
- if (!gdk_rectangle_intersect (&content_rect, &rect, &rect))
- continue;
-
- paint_clipped_rectangle_node (stex, root_node,
- blended_pipeline,
- &rect, alloc);
-
- if (G_UNLIKELY (debug_paint_opaque_region))
- {
- CoglPipeline *blended_overlay_pipeline;
-
- blended_overlay_pipeline = get_blended_overlay_pipeline (ctx);
- paint_clipped_rectangle_node (stex, root_node,
- blended_overlay_pipeline,
- &rect, alloc);
- }
- }
- }
- else
- {
- 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 (G_UNLIKELY (debug_paint_opaque_region))
- {
- CoglPipeline *blended_overlay_pipeline;
- g_autoptr (ClutterPaintNode) node_overlay = NULL;
-
- blended_overlay_pipeline = get_blended_overlay_pipeline (ctx);
-
- node_overlay = clutter_pipeline_node_new (blended_overlay_pipeline);
- clutter_paint_node_set_static_name (node_overlay,
- "MetaShapedTexture (unclipped overlay)");
- clutter_paint_node_add_child (root_node, node_overlay);
- clutter_paint_node_add_rectangle (node_overlay, alloc);
- }
- }
- }
-
- g_clear_pointer (&blended_tex_region, cairo_region_destroy);
-}
-
-static CoglTexture *
-select_texture_for_paint (MetaShapedTexture *stex,
- ClutterPaintContext *paint_context)
-{
- CoglTexture *texture = NULL;
- int64_t now;
-
- 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 (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_paint_content (ClutterContent *content,
- ClutterActor *actor,
- ClutterPaintNode *root_node,
- ClutterPaintContext *paint_context)
-{
- 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;
-
- opacity = clutter_actor_get_paint_opacity (actor);
- clutter_actor_get_content_box (actor, &alloc);
-
- do_paint_content (stex, root_node, paint_context, paint_tex, &alloc, opacity);
-}
-
-static gboolean
-meta_shaped_texture_get_preferred_size (ClutterContent *content,
- float *width,
- float *height)
-{
- MetaShapedTexture *stex = META_SHAPED_TEXTURE (content);
-
- meta_shaped_texture_ensure_size_valid (stex);
-
- if (width)
- *width = stex->dst_width;
-
- if (height)
- *height = stex->dst_height;
-
- return TRUE;
-}
-
-static void
-clutter_content_iface_init (ClutterContentInterface *iface)
-{
- 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)
-{
- g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
-
- create_mipmaps = create_mipmaps != FALSE;
-
- if (create_mipmaps != stex->create_mipmaps)
- {
- CoglTexture *base_texture;
- stex->create_mipmaps = create_mipmaps;
- base_texture = create_mipmaps ? stex->texture : NULL;
- meta_texture_tower_set_base_texture (stex->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));
-}
-
-/**
- * meta_shaped_texture_update_area:
- * @stex: #MetaShapedTexture
- * @x: the x coordinate of the damaged area
- * @y: the y coordinate of the damaged area
- * @width: the width of the damaged area
- * @height: the height of the damaged area
- * @clip: (out): the resulting clip region
- *
- * Repairs the damaged area indicated by @x, @y, @width and @height
- * 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_rectangle_int_t *clip)
-{
- MetaMonitorTransform inverted_transform;
- int scaled_and_transformed_width;
- int scaled_and_transformed_height;
-
- if (stex->texture == NULL)
- return FALSE;
-
- *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_GROW,
- clip);
-
- if (meta_monitor_transform_is_rotated (stex->transform))
- {
- scaled_and_transformed_width = stex->tex_height / stex->buffer_scale;
- scaled_and_transformed_height = stex->tex_width / stex->buffer_scale;
- }
- else
- {
- scaled_and_transformed_width = stex->tex_width / stex->buffer_scale;
- scaled_and_transformed_height = stex->tex_height / stex->buffer_scale;
- }
- inverted_transform = meta_monitor_transform_invert (stex->transform);
- meta_rectangle_transform (clip,
- inverted_transform,
- scaled_and_transformed_width,
- scaled_and_transformed_height,
- clip);
-
- if (stex->has_viewport_src_rect || stex->has_viewport_dst_size)
- {
- 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 = scaled_and_transformed_width,
- .size.height = scaled_and_transformed_height,
- };
- }
-
- if (stex->has_viewport_dst_size)
- {
- dst_width = (float) stex->viewport_dst_width;
- dst_height = (float) stex->viewport_dst_height;
- }
- else
- {
- dst_width = (float) viewport.size.width;
- dst_height = (float) viewport.size.height;
- }
-
- 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);
- }
-
- meta_texture_tower_update_area (stex->paint_tower,
- x,
- y,
- width,
- height);
-
- stex->prev_invalidation = stex->last_invalidation;
- stex->last_invalidation = g_get_monotonic_time ();
-
- if (stex->prev_invalidation)
- {
- gint64 interval = stex->last_invalidation - stex->prev_invalidation;
- gboolean fast_update = interval < MIN_MIPMAP_AGE_USEC;
-
- if (!fast_update)
- stex->fast_updates = 0;
- else if (stex->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP)
- stex->fast_updates++;
- }
-
- return TRUE;
-}
-
-/**
- * meta_shaped_texture_set_texture:
- * @stex: The #MetaShapedTexture
- * @pixmap: The #CoglTexture to display
- */
-void
-meta_shaped_texture_set_texture (MetaShapedTexture *stex,
- CoglTexture *texture)
-{
- 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
- *
- * Returns: (transfer none): the unshaped texture
- */
-CoglTexture *
-meta_shaped_texture_get_texture (MetaShapedTexture *stex)
-{
- g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
- return COGL_TEXTURE (stex->texture);
-}
-
-/**
- * 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)
-{
- g_clear_pointer (&stex->opaque_region, cairo_region_destroy);
- if (opaque_region)
- stex->opaque_region = cairo_region_reference (opaque_region);
-}
-
-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;
-
- switch (cogl_texture_get_components (texture))
- {
- 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;
- }
-
- 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);
-
- meta_shaped_texture_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);
-}
-
-/**
- * meta_shaped_texture_set_viewport_src_rect:
- * @stex: A #MetaShapedTexture
- * @src_rect: The viewport source rectangle
- *
- * Sets the viewport area that can be used to crop the original texture. The
- * cropped result can then be optionally scaled afterwards using
- * meta_shaped_texture_set_viewport_dst_size() as part of a crop-and-scale
- * operation.
- *
- * Note that the viewport's geometry should be provided in the coordinate space
- * of the texture received by the client, which might've been scaled as noted by
- * meta_shaped_texture_set_buffer_scale().
- *
- * %NULL is an invalid value for @src_rect. Use
- * meta_shaped_texture_reset_viewport_src_rect() if you want to remove the
- * cropping source rectangle.
- */
-void
-meta_shaped_texture_set_viewport_src_rect (MetaShapedTexture *stex,
- graphene_rect_t *src_rect)
-{
- if (!stex->has_viewport_src_rect ||
- !G_APPROX_VALUE (stex->viewport_src_rect.origin.x,
- src_rect->origin.x, FLT_EPSILON) ||
- !G_APPROX_VALUE (stex->viewport_src_rect.origin.y,
- src_rect->origin.y, FLT_EPSILON) ||
- !G_APPROX_VALUE (stex->viewport_src_rect.size.width,
- src_rect->size.width, FLT_EPSILON) ||
- !G_APPROX_VALUE (stex->viewport_src_rect.size.height,
- src_rect->size.height, FLT_EPSILON))
- {
- stex->has_viewport_src_rect = TRUE;
- stex->viewport_src_rect = *src_rect;
- meta_shaped_texture_reset_pipelines (stex);
- invalidate_size (stex);
- }
-}
-
-void
-meta_shaped_texture_reset_viewport_src_rect (MetaShapedTexture *stex)
-{
- if (!stex->has_viewport_src_rect)
- return;
-
- stex->has_viewport_src_rect = FALSE;
- meta_shaped_texture_reset_pipelines (stex);
- invalidate_size (stex);
-}
-
-/**
- * meta_shaped_texture_set_viewport_dst_size:
- * @stex: #MetaShapedTexture
- * @dst_width: The final viewport width (> 0)
- * @dst_height: The final viewport height (> 0)
- *
- * Sets a viewport size on @stex of the given @width and @height, which may
- * lead to scaling the texture. If you need to have cropping, use
- * meta_shaped_texture_set_viewport_src_rect() first, after which the scaling
- * stemming from this method will be applied.
- *
- * If you no longer want to have any scaling, use
- * meta_shaped_texture_reset_viewport_dst_size() to clear the current
- * parameters.
- */
-void
-meta_shaped_texture_set_viewport_dst_size (MetaShapedTexture *stex,
- int dst_width,
- int dst_height)
-{
- 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);
- }
-}
-
-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);
-}
-
-static gboolean
-should_get_via_offscreen (MetaShapedTexture *stex)
-{
- if (!cogl_texture_is_get_data_supported (stex->texture))
- return TRUE;
-
- if (stex->has_viewport_src_rect || stex->has_viewport_dst_size)
- return TRUE;
-
- 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;
-}
-
-static cairo_surface_t *
-get_image_via_offscreen (MetaShapedTexture *stex,
- cairo_rectangle_int_t *clip,
- int image_width,
- int image_height)
-{
- 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;
- graphene_matrix_t projection_matrix;
- cairo_rectangle_int_t fallback_clip;
- ClutterColor clear_color;
- ClutterPaintContext *paint_context;
- cairo_surface_t *surface;
-
- if (!clip)
- {
- fallback_clip = (cairo_rectangle_int_t) {
- .width = image_width,
- .height = image_height,
- };
- clip = &fallback_clip;
- }
-
- 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);
- g_object_unref (fb);
- return FALSE;
- }
-
- cogl_framebuffer_push_matrix (fb);
- graphene_matrix_init_translate (&projection_matrix,
- &GRAPHENE_POINT3D_INIT (-(image_width / 2.0),
- -(image_height / 2.0),
- 0));
- graphene_matrix_scale (&projection_matrix,
- 1.0 / (image_width / 2.0),
- -1.0 / (image_height / 2.0), 0);
-
- 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, NULL,
- CLUTTER_PAINT_FLAG_NONE);
-
- 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));
- g_object_unref (fb);
-
- cairo_surface_mark_dirty (surface);
-
- return surface;
-}
-
-/**
- * meta_shaped_texture_get_image:
- * @stex: A #MetaShapedTexture
- * @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.
- *
- * Flattens the two layers of the shaped texture into one ARGB32
- * image by alpha blending the two 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_shaped_texture_get_image (MetaShapedTexture *stex,
- cairo_rectangle_int_t *clip)
-{
- cairo_rectangle_int_t *image_clip = NULL;
- CoglTexture *texture, *mask_texture;
- cairo_surface_t *surface;
-
- g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
-
- texture = COGL_TEXTURE (stex->texture);
-
- if (texture == NULL)
- return NULL;
-
- meta_shaped_texture_ensure_size_valid (stex);
-
- if (stex->dst_width == 0 || stex->dst_height == 0)
- return NULL;
-
- if (clip != NULL)
- {
- 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 (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,
- 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),
- cogl_texture_get_height (texture));
-
- cogl_texture_get_data (texture, CLUTTER_CAIRO_FORMAT_ARGB32,
- cairo_image_surface_get_stride (surface),
- cairo_image_surface_get_data (surface));
-
- cairo_surface_mark_dirty (surface);
-
- if (image_clip)
- cogl_object_unref (texture);
-
- mask_texture = stex->mask_texture;
- if (mask_texture != NULL)
- {
- cairo_t *cr;
- cairo_surface_t *mask_surface;
-
- 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),
- cogl_texture_get_height (mask_texture));
-
- cogl_texture_get_data (mask_texture, COGL_PIXEL_FORMAT_A_8,
- cairo_image_surface_get_stride (mask_surface),
- cairo_image_surface_get_data (mask_surface));
-
- cairo_surface_mark_dirty (mask_surface);
-
- cr = cairo_create (surface);
- cairo_set_source_surface (cr, mask_surface, 0, 0);
- cairo_set_operator (cr, CAIRO_OPERATOR_DEST_IN);
- cairo_paint (cr);
- cairo_destroy (cr);
-
- cairo_surface_destroy (mask_surface);
-
- 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);
-}
-
-/**
- * meta_shaped_texture_set_buffer_scale:
- * @stex: A #MetaShapedTexture
- * @buffer_scale: The scale that should be applied to coorsinate space
- *
- * Instructs @stex to interpret the geometry of the input texture by scaling it
- * with @buffer_scale. This means that the #CoglTexture that is provided by a
- * client is already scaled by that factor.
- */
-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;
-}
-
-/**
- * meta_shaped_texture_get_width:
- * @stex: A #MetaShapedTexture
- *
- * Returns: The final width of @stex after its shaping operations are applied.
- */
-int
-meta_shaped_texture_get_width (MetaShapedTexture *stex)
-{
- g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), 0);
-
- meta_shaped_texture_ensure_size_valid (stex);
-
- return stex->dst_width;
-}
-
-/**
- * meta_shaped_texture_get_height:
- * @stex: A #MetaShapedTexture
- *
- * Returns: The final height of @stex after its shaping operations are applied.
- */
-int
-meta_shaped_texture_get_height (MetaShapedTexture *stex)
-{
- g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), 0);
-
- meta_shaped_texture_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
deleted file mode 100644
index a182ad851..000000000
--- a/src/compositor/meta-surface-actor-wayland.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/* -*- 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 gboolean
-meta_surface_actor_wayland_is_opaque (MetaSurfaceActor *actor)
-{
- MetaShapedTexture *stex = meta_surface_actor_get_texture (actor);
-
- return meta_shaped_texture_is_opaque (stex);
-}
-
-CoglScanout *
-meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
- CoglOnscreen *onscreen)
-{
- MetaWaylandSurface *surface;
- CoglScanout *scanout;
-
- surface = meta_surface_actor_wayland_get_surface (self);
- if (!surface)
- return NULL;
-
- scanout = meta_wayland_surface_try_acquire_scanout (surface, onscreen);
- if (!scanout)
- return NULL;
-
- return scanout;
-}
-
-#define UNOBSCURED_TRESHOLD 0.1
-
-ClutterStageView *
-meta_surface_actor_wayland_get_current_primary_view (MetaSurfaceActor *actor,
- ClutterStage *stage)
-{
- ClutterStageView *current_primary_view = NULL;
- float highest_refresh_rate = 0.f;
- float biggest_unobscurred_fraction = 0.f;
- GList *l;
-
- for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
- {
- ClutterStageView *stage_view = l->data;
- float refresh_rate;
- float unobscurred_fraction = 1.f;
-
- if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (actor)))
- {
- if (!clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (actor),
- stage_view))
- continue;
- }
- else
- {
- if (l->next || biggest_unobscurred_fraction > 0.f)
- {
- if (meta_surface_actor_is_obscured_on_stage_view (actor,
- stage_view,
- &unobscurred_fraction))
- continue;
- }
- else
- {
- if (meta_surface_actor_is_obscured (actor))
- continue;
- }
- }
-
- refresh_rate = clutter_stage_view_get_refresh_rate (stage_view);
-
- if ((refresh_rate > highest_refresh_rate &&
- (unobscurred_fraction > UNOBSCURED_TRESHOLD ||
- biggest_unobscurred_fraction < UNOBSCURED_TRESHOLD)) ||
- (biggest_unobscurred_fraction < UNOBSCURED_TRESHOLD &&
- unobscurred_fraction > UNOBSCURED_TRESHOLD))
- {
- current_primary_view = stage_view;
- highest_refresh_rate = refresh_rate;
- biggest_unobscurred_fraction = unobscurred_fraction;
- }
- }
-
- return current_primary_view;
-}
-
-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->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
deleted file mode 100644
index 10eb3326a..000000000
--- a/src/compositor/meta-surface-actor-wayland.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- 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);
-
-CoglScanout * meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
- CoglOnscreen *onscreen);
-
-ClutterStageView * meta_surface_actor_wayland_get_current_primary_view (MetaSurfaceActor *actor,
- ClutterStage *stage);
-
-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
deleted file mode 100644
index 41ae2dffb..000000000
--- a/src/compositor/meta-surface-actor-x11.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/* -*- 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!");
-
- 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",
- 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);
-}
-
-void
-meta_surface_actor_x11_handle_updates (MetaSurfaceActorX11 *self)
-{
- 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)
-{
- if (!meta_surface_actor_x11_is_opaque (META_SURFACE_ACTOR (self)))
- return FALSE;
-
- if (!self->does_full_damage &&
- !meta_window_is_override_redirect (self->window))
- return FALSE;
-
- return TRUE;
-}
-
-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->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
deleted file mode 100644
index 0a8517236..000000000
--- a/src/compositor/meta-surface-actor-x11.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- 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);
-
-void meta_surface_actor_x11_handle_updates (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
deleted file mode 100644
index 48042b227..000000000
--- a/src/compositor/meta-surface-actor.c
+++ /dev/null
@@ -1,698 +0,0 @@
-/* -*- 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 = CLUTTER_ACTOR (surface_actor);
-
- /* Fail if we have any mapped clones. */
- if (clutter_actor_has_mapped_clones (actor))
- return 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 = NULL;
- 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;
- }
-
- g_assert (scaled_region != NULL);
- 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 (actor, pick_context))
- 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;
-}
-
-gboolean
-meta_surface_actor_is_obscured_on_stage_view (MetaSurfaceActor *self,
- ClutterStageView *stage_view,
- float *unobscurred_fraction)
-{
- cairo_region_t *unobscured_region;
-
- unobscured_region = effective_unobscured_region (self);
-
- if (unobscured_region)
- {
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
- cairo_region_t *intersection_region;
- cairo_rectangle_int_t stage_rect;
- float x, y;
- float bounds_width, bounds_height;
- float bounds_size;
- int intersection_size = 0;
- int n_rects, i;
-
- if (cairo_region_is_empty (unobscured_region))
- return TRUE;
-
- intersection_region = cairo_region_copy (unobscured_region);
- clutter_actor_get_transformed_position (CLUTTER_ACTOR (self), &x, &y);
- cairo_region_translate (intersection_region, x, y);
-
- clutter_stage_view_get_layout (stage_view, &stage_rect);
- cairo_region_intersect_rectangle (intersection_region,
- &stage_rect);
-
- if (cairo_region_is_empty (intersection_region))
- {
- cairo_region_destroy (intersection_region);
- return TRUE;
- }
- else if (!unobscurred_fraction)
- {
- cairo_region_destroy (intersection_region);
- return FALSE;
- }
-
- clutter_content_get_preferred_size (CLUTTER_CONTENT (priv->texture),
- &bounds_width,
- &bounds_height);
- bounds_size = bounds_width * bounds_height;
-
- n_rects = cairo_region_num_rectangles (intersection_region);
- for (i = 0; i < n_rects; i++)
- {
- cairo_rectangle_int_t rect;
-
- cairo_region_get_rectangle (intersection_region, i, &rect);
- intersection_size += (rect.width - rect.x) * (rect.height - rect.x);
- }
- cairo_region_destroy (intersection_region);
-
- g_return_val_if_fail (bounds_size > 0, FALSE);
-
- *unobscurred_fraction = CLAMP (intersection_size / bounds_size, 0, 1);
- return FALSE;
- }
-
- return !clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (self),
- stage_view);
-}
-
-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_set_frozen (MetaSurfaceActor *self,
- gboolean frozen)
-{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
-
- if (priv->frozen == frozen)
- return;
-
- 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
deleted file mode 100644
index a61251049..000000000
--- a/src/compositor/meta-surface-actor.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- 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);
- 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);
-gboolean meta_surface_actor_is_obscured_on_stage_view (MetaSurfaceActor *self,
- ClutterStageView *stage_view,
- float *unobscurred_fraction);
-
-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);
-
-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
deleted file mode 100644
index 917bf1235..000000000
--- a/src/compositor/meta-sync-ring.c
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * This is based on an original C++ implementation for compiz that
- * carries the following copyright notice:
- *
- *
- * Copyright © 2011 NVIDIA 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 NVIDIA
- * Corporation not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. NVIDIA Corporation makes no representations about the
- * suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL NVIDIA CORPORATION 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.
- *
- * Authors: James Jones <jajones@nvidia.com>
- */
-
-#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 "clutter/clutter.h"
-#include "cogl/cogl.h"
-#include "meta/util.h"
-
-/* Theory of operation:
- *
- * We use a ring of NUM_SYNCS fence objects. On each frame we advance
- * to the next fence in the ring. For each fence we do:
- *
- * 1. fence is XSyncTriggerFence()'d and glWaitSync()'d
- * 2. NUM_SYNCS / 2 frames later, fence should be triggered
- * 3. fence is XSyncResetFence()'d
- * 4. NUM_SYNCS / 2 frames later, fence should be reset
- * 5. go back to 1 and re-use fence
- *
- * glClientWaitSync() and XAlarms are used in steps 2 and 4,
- * respectively, to double-check the expectections.
- */
-
-#define NUM_SYNCS 10
-#define MAX_SYNC_WAIT_TIME (1 * 1000 * 1000 * 1000) /* one sec */
-#define MAX_REBOOT_ATTEMPTS 2
-
-typedef enum
-{
- META_SYNC_STATE_READY,
- META_SYNC_STATE_WAITING,
- META_SYNC_STATE_DONE,
- META_SYNC_STATE_RESET_PENDING,
-} MetaSyncState;
-
-typedef struct
-{
- Display *xdisplay;
-
- XSyncFence xfence;
- GLsync gl_x11_sync;
- GLsync gpu_fence;
-
- XSyncCounter xcounter;
- XSyncAlarm xalarm;
- XSyncValue next_counter_value;
-
- MetaSyncState state;
-} MetaSync;
-
-typedef struct
-{
- Display *xdisplay;
- int xsync_event_base;
- int xsync_error_base;
-
- GHashTable *alarm_to_sync;
-
- MetaSync *syncs_array[NUM_SYNCS];
- guint current_sync_idx;
- MetaSync *current_sync;
- guint warmup_syncs;
-
- guint reboots;
-} MetaSyncRing;
-
-static MetaSyncRing meta_sync_ring = { 0 };
-
-static XSyncValue SYNC_VALUE_ZERO;
-static XSyncValue SYNC_VALUE_ONE;
-
-static const char* (*meta_gl_get_string) (GLenum name);
-static void (*meta_gl_get_integerv) (GLenum pname,
- GLint *params);
-static const char* (*meta_gl_get_stringi) (GLenum name,
- GLuint index);
-static void (*meta_gl_delete_sync) (GLsync sync);
-static GLenum (*meta_gl_client_wait_sync) (GLsync sync,
- GLbitfield flags,
- GLuint64 timeout);
-static void (*meta_gl_wait_sync) (GLsync sync,
- GLbitfield flags,
- GLuint64 timeout);
-static GLsync (*meta_gl_import_sync) (GLenum external_sync_type,
- GLintptr external_sync,
- GLbitfield flags);
-static GLsync (*meta_gl_fence_sync) (GLenum condition,
- GLbitfield flags);
-
-static MetaSyncRing *
-meta_sync_ring_get (void)
-{
- if (meta_sync_ring.reboots > MAX_REBOOT_ATTEMPTS)
- return NULL;
-
- return &meta_sync_ring;
-}
-
-static gboolean
-load_gl_symbol (const char *name,
- void **func)
-{
- *func = cogl_get_proc_address (name);
- if (!*func)
- {
- meta_verbose ("MetaSyncRing: failed to resolve required GL symbol \"%s\"", name);
- return FALSE;
- }
- return TRUE;
-}
-
-static gboolean
-check_gl_extensions (void)
-{
- ClutterBackend *backend;
- CoglContext *cogl_context;
- CoglDisplay *cogl_display;
- CoglRenderer *cogl_renderer;
-
- backend = clutter_get_default_backend ();
- cogl_context = clutter_backend_get_cogl_context (backend);
- cogl_display = cogl_context_get_display (cogl_context);
- cogl_renderer = cogl_display_get_renderer (cogl_display);
-
- switch (cogl_renderer_get_driver (cogl_renderer))
- {
- case COGL_DRIVER_GL3:
- {
- int num_extensions, i;
- gboolean arb_sync = FALSE;
- gboolean x11_sync_object = FALSE;
-
- meta_gl_get_integerv (GL_NUM_EXTENSIONS, &num_extensions);
-
- for (i = 0; i < num_extensions; ++i)
- {
- const char *ext = meta_gl_get_stringi (GL_EXTENSIONS, i);
-
- if (g_strcmp0 ("GL_ARB_sync", ext) == 0)
- arb_sync = TRUE;
- else if (g_strcmp0 ("GL_EXT_x11_sync_object", ext) == 0)
- x11_sync_object = TRUE;
- }
-
- return arb_sync && x11_sync_object;
- }
- case COGL_DRIVER_GL:
- {
- 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);
- }
- default:
- break;
- }
-
- return FALSE;
-}
-
-static gboolean
-load_required_symbols (void)
-{
- static gboolean success = FALSE;
-
- if (success)
- return TRUE;
-
- /* We don't link against libGL directly because cogl may want to
- * use something else. This assumes that cogl has been initialized
- * and dynamically loaded libGL at this point.
- */
-
- if (!load_gl_symbol ("glGetString", (void **) &meta_gl_get_string))
- goto out;
- if (!load_gl_symbol ("glGetIntegerv", (void **) &meta_gl_get_integerv))
- goto out;
- if (!load_gl_symbol ("glGetStringi", (void **) &meta_gl_get_stringi))
- goto out;
-
- if (!check_gl_extensions ())
- {
- meta_verbose ("MetaSyncRing: couldn't find required GL extensions");
- goto out;
- }
-
- if (!load_gl_symbol ("glDeleteSync", (void **) &meta_gl_delete_sync))
- goto out;
- if (!load_gl_symbol ("glClientWaitSync", (void **) &meta_gl_client_wait_sync))
- goto out;
- if (!load_gl_symbol ("glWaitSync", (void **) &meta_gl_wait_sync))
- goto out;
- if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync))
- goto out;
- if (!load_gl_symbol ("glFenceSync", (void **) &meta_gl_fence_sync))
- goto out;
-
- success = TRUE;
- out:
- return success;
-}
-
-static void
-meta_sync_insert (MetaSync *self)
-{
- g_return_if_fail (self->state == META_SYNC_STATE_READY);
-
- XSyncTriggerFence (self->xdisplay, self->xfence);
- XFlush (self->xdisplay);
-
- meta_gl_wait_sync (self->gl_x11_sync, 0, GL_TIMEOUT_IGNORED);
- self->gpu_fence = meta_gl_fence_sync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-
- self->state = META_SYNC_STATE_WAITING;
-}
-
-static GLenum
-meta_sync_check_update_finished (MetaSync *self,
- GLuint64 timeout)
-{
- GLenum status = GL_WAIT_FAILED;
-
- switch (self->state)
- {
- case META_SYNC_STATE_DONE:
- status = GL_ALREADY_SIGNALED;
- break;
- case META_SYNC_STATE_WAITING:
- status = meta_gl_client_wait_sync (self->gpu_fence, 0, timeout);
- if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED)
- {
- self->state = META_SYNC_STATE_DONE;
- meta_gl_delete_sync (self->gpu_fence);
- self->gpu_fence = 0;
- }
- break;
- default:
- break;
- }
-
- g_warn_if_fail (status != GL_WAIT_FAILED);
-
- return status;
-}
-
-static void
-meta_sync_reset (MetaSync *self)
-{
- XSyncAlarmAttributes attrs;
- int overflow;
-
- g_return_if_fail (self->state == META_SYNC_STATE_DONE);
-
- XSyncResetFence (self->xdisplay, self->xfence);
-
- attrs.trigger.wait_value = self->next_counter_value;
-
- XSyncChangeAlarm (self->xdisplay, self->xalarm, XSyncCAValue, &attrs);
- XSyncSetCounter (self->xdisplay, self->xcounter, self->next_counter_value);
-
- XSyncValueAdd (&self->next_counter_value,
- self->next_counter_value,
- SYNC_VALUE_ONE,
- &overflow);
-
- self->state = META_SYNC_STATE_RESET_PENDING;
-}
-
-static void
-meta_sync_handle_event (MetaSync *self,
- XSyncAlarmNotifyEvent *event)
-{
- g_return_if_fail (event->alarm == self->xalarm);
- g_return_if_fail (self->state == META_SYNC_STATE_RESET_PENDING);
-
- self->state = META_SYNC_STATE_READY;
-}
-
-static MetaSync *
-meta_sync_new (Display *xdisplay)
-{
- MetaSync *self;
- XSyncAlarmAttributes attrs;
-
- self = g_malloc0 (sizeof (MetaSync));
-
- self->xdisplay = xdisplay;
-
- self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), FALSE);
- self->gl_x11_sync = 0;
- self->gpu_fence = 0;
-
- self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO);
-
- attrs.trigger.counter = self->xcounter;
- attrs.trigger.value_type = XSyncAbsolute;
- attrs.trigger.wait_value = SYNC_VALUE_ONE;
- attrs.trigger.test_type = XSyncPositiveTransition;
- attrs.events = TRUE;
- self->xalarm = XSyncCreateAlarm (xdisplay,
- XSyncCACounter |
- XSyncCAValueType |
- XSyncCAValue |
- XSyncCATestType |
- XSyncCAEvents,
- &attrs);
-
- XSyncIntToValue (&self->next_counter_value, 1);
-
- self->state = META_SYNC_STATE_READY;
-
- return self;
-}
-
-static void
-meta_sync_import (MetaSync *self)
-{
- g_return_if_fail (self->gl_x11_sync == 0);
- self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0);
-}
-
-static Bool
-alarm_event_predicate (Display *dpy,
- XEvent *event,
- XPointer data)
-{
- MetaSyncRing *ring = meta_sync_ring_get ();
-
- if (!ring)
- return False;
-
- if (event->type == ring->xsync_event_base + XSyncAlarmNotify)
- {
- if (((MetaSync *) data)->xalarm == ((XSyncAlarmNotifyEvent *) event)->alarm)
- return True;
- }
- return False;
-}
-
-static void
-meta_sync_free (MetaSync *self)
-{
- /* When our assumptions don't hold, something has gone wrong but we
- * don't know what, so we reboot the ring. While doing that, we
- * trigger fences before deleting them to try to get ourselves out
- * of a potentially stuck GPU state.
- */
- switch (self->state)
- {
- case META_SYNC_STATE_WAITING:
- meta_gl_delete_sync (self->gpu_fence);
- break;
- case META_SYNC_STATE_DONE:
- /* nothing to do */
- break;
- case META_SYNC_STATE_RESET_PENDING:
- {
- XEvent event;
- XIfEvent (self->xdisplay, &event, alarm_event_predicate, (XPointer) self);
- meta_sync_handle_event (self, (XSyncAlarmNotifyEvent *) &event);
- }
- G_GNUC_FALLTHROUGH;
- case META_SYNC_STATE_READY:
- XSyncTriggerFence (self->xdisplay, self->xfence);
- XFlush (self->xdisplay);
- break;
- default:
- break;
- }
-
- meta_gl_delete_sync (self->gl_x11_sync);
- XSyncDestroyFence (self->xdisplay, self->xfence);
- XSyncDestroyCounter (self->xdisplay, self->xcounter);
- XSyncDestroyAlarm (self->xdisplay, self->xalarm);
-
- g_free (self);
-}
-
-gboolean
-meta_sync_ring_init (Display *xdisplay)
-{
- gint major, minor;
- guint i;
- MetaSyncRing *ring = meta_sync_ring_get ();
-
- if (!ring)
- return FALSE;
-
- g_return_val_if_fail (xdisplay != NULL, FALSE);
- g_return_val_if_fail (ring->xdisplay == NULL, FALSE);
-
- if (!load_required_symbols ())
- return FALSE;
-
- if (!XSyncQueryExtension (xdisplay, &ring->xsync_event_base, &ring->xsync_error_base) ||
- !XSyncInitialize (xdisplay, &major, &minor))
- return FALSE;
-
- XSyncIntToValue (&SYNC_VALUE_ZERO, 0);
- XSyncIntToValue (&SYNC_VALUE_ONE, 1);
-
- ring->xdisplay = xdisplay;
-
- ring->alarm_to_sync = g_hash_table_new (NULL, NULL);
-
- for (i = 0; i < NUM_SYNCS; ++i)
- {
- MetaSync *sync = meta_sync_new (ring->xdisplay);
- ring->syncs_array[i] = sync;
- g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, sync);
- }
- /* Since the connection we create the X fences on isn't the same as
- * the one used for the GLX context, we need to XSync() here to
- * ensure glImportSync() succeeds. */
- XSync (xdisplay, False);
- for (i = 0; i < NUM_SYNCS; ++i)
- meta_sync_import (ring->syncs_array[i]);
-
- ring->current_sync_idx = 0;
- ring->current_sync = ring->syncs_array[0];
- ring->warmup_syncs = 0;
-
- return TRUE;
-}
-
-void
-meta_sync_ring_destroy (void)
-{
- guint i;
- MetaSyncRing *ring = meta_sync_ring_get ();
-
- if (!ring)
- return;
-
- g_return_if_fail (ring->xdisplay != NULL);
-
- ring->current_sync_idx = 0;
- ring->current_sync = NULL;
- ring->warmup_syncs = 0;
-
- for (i = 0; i < NUM_SYNCS; ++i)
- meta_sync_free (ring->syncs_array[i]);
-
- g_hash_table_destroy (ring->alarm_to_sync);
-
- ring->xsync_event_base = 0;
- ring->xsync_error_base = 0;
- ring->xdisplay = NULL;
-}
-
-static gboolean
-meta_sync_ring_reboot (Display *xdisplay)
-{
- MetaSyncRing *ring = meta_sync_ring_get ();
-
- if (!ring)
- return FALSE;
-
- meta_sync_ring_destroy ();
-
- ring->reboots += 1;
-
- if (!meta_sync_ring_get ())
- {
- meta_warning ("MetaSyncRing: Too many reboots -- disabling");
- return FALSE;
- }
-
- return meta_sync_ring_init (xdisplay);
-}
-
-gboolean
-meta_sync_ring_after_frame (void)
-{
- MetaSyncRing *ring = meta_sync_ring_get ();
-
- if (!ring)
- return FALSE;
-
- g_return_val_if_fail (ring->xdisplay != NULL, FALSE);
-
- if (ring->warmup_syncs >= NUM_SYNCS / 2)
- {
- guint reset_sync_idx = (ring->current_sync_idx + NUM_SYNCS - (NUM_SYNCS / 2)) % NUM_SYNCS;
- MetaSync *sync_to_reset = ring->syncs_array[reset_sync_idx];
-
- GLenum status = meta_sync_check_update_finished (sync_to_reset, 0);
- if (status == GL_TIMEOUT_EXPIRED)
- {
- meta_warning ("MetaSyncRing: We should never wait for a sync -- add more syncs?");
- status = meta_sync_check_update_finished (sync_to_reset, MAX_SYNC_WAIT_TIME);
- }
-
- if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED)
- {
- meta_warning ("MetaSyncRing: Timed out waiting for sync object.");
- return meta_sync_ring_reboot (ring->xdisplay);
- }
-
- meta_sync_reset (sync_to_reset);
- }
- else
- {
- ring->warmup_syncs += 1;
- }
-
- ring->current_sync_idx += 1;
- ring->current_sync_idx %= NUM_SYNCS;
-
- ring->current_sync = ring->syncs_array[ring->current_sync_idx];
-
- return TRUE;
-}
-
-gboolean
-meta_sync_ring_insert_wait (void)
-{
- MetaSyncRing *ring = meta_sync_ring_get ();
-
- if (!ring)
- return FALSE;
-
- g_return_val_if_fail (ring->xdisplay != NULL, FALSE);
-
- if (ring->current_sync->state != META_SYNC_STATE_READY)
- {
- meta_warning ("MetaSyncRing: Sync object is not ready -- were events handled properly?");
- if (!meta_sync_ring_reboot (ring->xdisplay))
- return FALSE;
- }
-
- meta_sync_insert (ring->current_sync);
-
- return TRUE;
-}
-
-void
-meta_sync_ring_handle_event (XEvent *xevent)
-{
- XSyncAlarmNotifyEvent *event;
- MetaSync *sync;
- MetaSyncRing *ring = meta_sync_ring_get ();
-
- if (!ring)
- return;
-
- g_return_if_fail (ring->xdisplay != NULL);
-
- if (xevent->type != (ring->xsync_event_base + XSyncAlarmNotify))
- return;
-
- event = (XSyncAlarmNotifyEvent *) xevent;
-
- sync = g_hash_table_lookup (ring->alarm_to_sync, (gpointer) event->alarm);
- if (sync)
- meta_sync_handle_event (sync, event);
-}
diff --git a/src/compositor/meta-sync-ring.h b/src/compositor/meta-sync-ring.h
deleted file mode 100644
index d9739455b..000000000
--- a/src/compositor/meta-sync-ring.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _META_SYNC_RING_H_
-#define _META_SYNC_RING_H_
-
-#include <glib.h>
-#include <X11/Xlib.h>
-
-gboolean meta_sync_ring_init (Display *dpy);
-void meta_sync_ring_destroy (void);
-gboolean meta_sync_ring_after_frame (void);
-gboolean meta_sync_ring_insert_wait (void);
-void meta_sync_ring_handle_event (XEvent *event);
-
-#endif /* _META_SYNC_RING_H_ */
diff --git a/src/compositor/meta-texture-tower.c b/src/compositor/meta-texture-tower.c
deleted file mode 100644
index 1fc4623e5..000000000
--- a/src/compositor/meta-texture-tower.c
+++ /dev/null
@@ -1,484 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * MetaTextureTower
- *
- * Mipmap emulation by creation of scaled down images
- *
- * Copyright (C) 2009 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 <math.h>
-#include <string.h>
-
-#include "compositor/meta-texture-tower.h"
-
-#ifndef M_LOG2E
-#define M_LOG2E 1.4426950408889634074
-#endif
-
-#define MAX_TEXTURE_LEVELS 12
-
-/* If the texture format in memory doesn't match this, then Mesa
- * will do the conversion, so things will still work, but it might
- * be slow depending on how efficient Mesa is. These should be the
- * native formats unless the display is 16bpp. If conversions
- * here are a bottleneck, investigate whether we are converting when
- * storing window data *into* the texture before adding extra code
- * to handle multiple texture formats.
- */
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-#define TEXTURE_FORMAT COGL_PIXEL_FORMAT_BGRA_8888_PRE
-#else
-#define TEXTURE_FORMAT COGL_PIXEL_FORMAT_ARGB_8888_PRE
-#endif
-
-typedef struct
-{
- guint16 x1;
- guint16 y1;
- guint16 x2;
- guint16 y2;
-} Box;
-
-struct _MetaTextureTower
-{
- int n_levels;
- CoglTexture *textures[MAX_TEXTURE_LEVELS];
- CoglOffscreen *fbos[MAX_TEXTURE_LEVELS];
- Box invalid[MAX_TEXTURE_LEVELS];
- CoglPipeline *pipeline_template;
-};
-
-/**
- * meta_texture_tower_new:
- *
- * Creates a new texture tower. The base texture has to be set with
- * meta_texture_tower_set_base_texture() before use.
- *
- * Return value: the new texture tower. Free with meta_texture_tower_free()
- */
-MetaTextureTower *
-meta_texture_tower_new (void)
-{
- MetaTextureTower *tower;
-
- tower = g_new0 (MetaTextureTower, 1);
-
- return tower;
-}
-
-/**
- * meta_texture_tower_free:
- * @tower: a #MetaTextureTower
- *
- * Frees a texture tower created with meta_texture_tower_new().
- */
-void
-meta_texture_tower_free (MetaTextureTower *tower)
-{
- g_return_if_fail (tower != NULL);
-
- if (tower->pipeline_template != NULL)
- cogl_object_unref (tower->pipeline_template);
-
- meta_texture_tower_set_base_texture (tower, NULL);
-
- g_free (tower);
-}
-
-/**
- * meta_texture_tower_set_base_texture:
- * @tower: a #MetaTextureTower
- * @texture: the new texture used as a base for scaled down versions
- *
- * Sets the base texture that is the scaled texture that the
- * scaled textures of the tower are derived from. The texture itself
- * will be used as level 0 of the tower and will be referenced until
- * unset or until the tower is freed.
- */
-void
-meta_texture_tower_set_base_texture (MetaTextureTower *tower,
- CoglTexture *texture)
-{
- int i;
-
- g_return_if_fail (tower != NULL);
-
- if (texture == tower->textures[0])
- return;
-
- if (tower->textures[0] != NULL)
- {
- for (i = 1; i < tower->n_levels; i++)
- {
- cogl_clear_object (&tower->textures[i]);
- g_clear_object (&tower->fbos[i]);
- }
-
- cogl_object_unref (tower->textures[0]);
- }
-
- tower->textures[0] = texture;
-
- if (tower->textures[0] != NULL)
- {
- int width, height;
-
- cogl_object_ref (tower->textures[0]);
-
- width = cogl_texture_get_width (tower->textures[0]);
- height = cogl_texture_get_height (tower->textures[0]);
-
- tower->n_levels = 1 + MAX ((int)(M_LOG2E * log (width)), (int)(M_LOG2E * log (height)));
- tower->n_levels = MIN(tower->n_levels, MAX_TEXTURE_LEVELS);
-
- meta_texture_tower_update_area (tower, 0, 0, width, height);
- }
- else
- {
- tower->n_levels = 0;
- }
-}
-
-/**
- * meta_texture_tower_update_area:
- * @tower: a #MetaTextureTower
- * @x: X coordinate of upper left of rectangle that changed
- * @y: Y coordinate of upper left of rectangle that changed
- * @width: width of rectangle that changed
- * @height: height rectangle that changed
- *
- * Mark a region of the base texture as having changed; the next
- * time a scaled down version of the base texture is retrieved,
- * the appropriate area of the scaled down texture will be updated.
- */
-void
-meta_texture_tower_update_area (MetaTextureTower *tower,
- int x,
- int y,
- int width,
- int height)
-{
- int texture_width, texture_height;
- Box invalid;
- int i;
-
- g_return_if_fail (tower != NULL);
-
- if (tower->textures[0] == NULL)
- return;
-
- texture_width = cogl_texture_get_width (tower->textures[0]);
- texture_height = cogl_texture_get_height (tower->textures[0]);
-
- invalid.x1 = x;
- invalid.y1 = y;
- invalid.x2 = x + width;
- invalid.y2 = y + height;
-
- for (i = 1; i < tower->n_levels; i++)
- {
- texture_width = MAX (1, texture_width / 2);
- texture_height = MAX (1, texture_height / 2);
-
- invalid.x1 = invalid.x1 / 2;
- invalid.y1 = invalid.y1 / 2;
- invalid.x2 = MIN (texture_width, (invalid.x2 + 1) / 2);
- invalid.y2 = MIN (texture_height, (invalid.y2 + 1) / 2);
-
- if (tower->invalid[i].x1 == tower->invalid[i].x2 ||
- tower->invalid[i].y1 == tower->invalid[i].y2)
- {
- tower->invalid[i] = invalid;
- }
- else
- {
- tower->invalid[i].x1 = MIN (tower->invalid[i].x1, invalid.x1);
- tower->invalid[i].y1 = MIN (tower->invalid[i].y1, invalid.y1);
- tower->invalid[i].x2 = MAX (tower->invalid[i].x2, invalid.x2);
- tower->invalid[i].y2 = MAX (tower->invalid[i].y2, invalid.y2);
- }
- }
-}
-
-/* It generally looks worse if we scale up a window texture by even a
- * small amount than if we scale it down using bilinear filtering, so
- * we always pick the *larger* adjacent level. */
-#define LOD_BIAS (-0.49)
-
-/* This determines the appropriate level of detail to use when drawing the
- * texture, in a way that corresponds to what the GL specification does
- * when mip-mapping. This is probably fancier and slower than what we need,
- * but we do the computation only once each time we paint a window, and
- * its easier to just use the equations from the specification than to
- * come up with something simpler.
- *
- * If window is being painted at an angle from the viewer, then we have to
- * pick a point in the texture; we use the middle of the texture (which is
- * why the width/height are passed in.) This is not the normal case for
- * Meta.
- */
-static int
-get_paint_level (ClutterPaintContext *paint_context,
- int width,
- int height)
-{
- CoglFramebuffer *framebuffer;
- graphene_matrix_t projection, modelview, pm;
- float xx, xy, xw;
- float yx, yy, yw;
- float wx, wy, ww;
- float v[4];
- double viewport_width, viewport_height;
- double u0, v0;
- double xc, yc, wc;
- double dxdu_, dxdv_, dydu_, dydv_;
- double det_, det_sq;
- double rho_sq;
- double lambda;
-
- /* See
- * http://www.opengl.org/registry/doc/glspec32.core.20090803.pdf
- * Section 3.8.9, p. 1.6.2. Here we have
- *
- * u(x,y) = x_o;
- * v(x,y) = y_o;
- *
- * Since we are mapping 1:1 from object coordinates into pixel
- * texture coordinates, the clip coordinates are:
- *
- * (x_c) (x_o) (u)
- * (y_c) = (M_projection)(M_modelview) (y_o) = (PM) (v)
- * (z_c) (z_o) (0)
- * (w_c) (w_o) (1)
- */
-
- framebuffer = clutter_paint_context_get_framebuffer (paint_context);
- cogl_framebuffer_get_projection_matrix (framebuffer, &projection);
- cogl_framebuffer_get_modelview_matrix (framebuffer, &modelview);
-
- graphene_matrix_multiply (&modelview, &projection, &pm);
-
- xx = graphene_matrix_get_value (&pm, 0, 0);
- xy = graphene_matrix_get_value (&pm, 0, 1);
- xw = graphene_matrix_get_value (&pm, 0, 3);
- yx = graphene_matrix_get_value (&pm, 1, 0);
- yy = graphene_matrix_get_value (&pm, 1, 1);
- yw = graphene_matrix_get_value (&pm, 1, 3);
- wx = graphene_matrix_get_value (&pm, 3, 0);
- wy = graphene_matrix_get_value (&pm, 3, 1);
- ww = graphene_matrix_get_value (&pm, 3, 3);
-
- cogl_framebuffer_get_viewport4fv (framebuffer, v);
- viewport_width = v[2];
- viewport_height = v[3];
-
- u0 = width / 2.;
- v0 = height / 2.;
-
- xc = xx * u0 + yx * v0 + wx;
- yc = xy * u0 + yy * v0 + wy;
- wc = xw * u0 + yw * v0 + ww;
-
- /* We'll simplify the equations below for a bit of micro-optimization.
- * The commented out code is the unsimplified version.
-
- // Partial derivates of window coordinates:
- //
- // x_w = 0.5 * viewport_width * x_c / w_c + viewport_center_x
- // y_w = 0.5 * viewport_height * y_c / w_c + viewport_center_y
- //
- // with respect to u, v, using
- // d(a/b)/dx = da/dx * (1/b) - a * db/dx / (b^2)
-
- dxdu = 0.5 * viewport_width * (xx - xw * (xc/wc)) / wc;
- dxdv = 0.5 * viewport_width * (yx - yw * (xc/wc)) / wc;
- dydu = 0.5 * viewport_height * (xy - xw * (yc/wc)) / wc;
- dydv = 0.5 * viewport_height * (yy - yw * (yc/wc)) / wc;
-
- // Compute the inverse partials as the matrix inverse
- det = dxdu * dydv - dxdv * dydu;
-
- dudx = dydv / det;
- dudy = - dxdv / det;
- dvdx = - dydu / det;
- dvdy = dvdu / det;
-
- // Scale factor; maximum of the distance in texels for a change of 1 pixel
- // in the X direction or 1 pixel in the Y direction
- rho = MAX (sqrt (dudx * dudx + dvdx * dvdx), sqrt(dudy * dudy + dvdy * dvdy));
-
- // Level of detail
- lambda = log2 (rho) + LOD_BIAS;
- */
-
- /* dxdu * wc, etc */
- dxdu_ = 0.5 * viewport_width * (xx - xw * (xc/wc));
- dxdv_ = 0.5 * viewport_width * (yx - yw * (xc/wc));
- dydu_ = 0.5 * viewport_height * (xy - xw * (yc/wc));
- dydv_ = 0.5 * viewport_height * (yy - yw * (yc/wc));
-
- /* det * wc^2 */
- det_ = dxdu_ * dydv_ - dxdv_ * dydu_;
- det_sq = det_ * det_;
- if (det_sq == 0.0)
- return -1;
-
- /* (rho * det * wc)^2 */
- rho_sq = MAX (dydv_ * dydv_ + dydu_ * dydu_, dxdv_ * dxdv_ + dxdu_ * dxdu_);
- lambda = 0.5 * M_LOG2E * log (rho_sq * wc * wc / det_sq) + LOD_BIAS;
-
-#if 0
- g_print ("%g %g %g\n", 0.5 * viewport_width * xx / ww, 0.5 * viewport_height * yy / ww, lambda);
-#endif
-
- if (lambda <= 0.)
- return 0;
- else
- return (int)(0.5 + lambda);
-}
-
-static void
-texture_tower_create_texture (MetaTextureTower *tower,
- int level,
- int width,
- int height)
-{
- 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;
- tower->invalid[level].x2 = width;
- tower->invalid[level].y2 = height;
-}
-
-static void
-texture_tower_revalidate (MetaTextureTower *tower,
- int level)
-{
- CoglTexture *source_texture = tower->textures[level - 1];
- int source_texture_width = cogl_texture_get_width (source_texture);
- int source_texture_height = cogl_texture_get_height (source_texture);
- CoglTexture *dest_texture = tower->textures[level];
- int dest_texture_width = cogl_texture_get_width (dest_texture);
- int dest_texture_height = cogl_texture_get_height (dest_texture);
- Box *invalid = &tower->invalid[level];
- CoglFramebuffer *fb;
- GError *catch_error = NULL;
- CoglPipeline *pipeline;
-
- if (tower->fbos[level] == NULL)
- tower->fbos[level] = cogl_offscreen_new_with_texture (dest_texture);
-
- fb = COGL_FRAMEBUFFER (tower->fbos[level]);
-
- if (!cogl_framebuffer_allocate (fb, &catch_error))
- {
- g_error_free (catch_error);
- return;
- }
-
- cogl_framebuffer_orthographic (fb, 0, 0, dest_texture_width, dest_texture_height, -1., 1.);
-
- if (!tower->pipeline_template)
- {
- 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);
- }
-
- pipeline = cogl_pipeline_copy (tower->pipeline_template);
- cogl_pipeline_set_layer_texture (pipeline, 0, tower->textures[level - 1]);
-
- cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
- invalid->x1, invalid->y1,
- invalid->x2, invalid->y2,
- (2. * invalid->x1) / source_texture_width,
- (2. * invalid->y1) / source_texture_height,
- (2. * invalid->x2) / source_texture_width,
- (2. * invalid->y2) / source_texture_height);
-
- cogl_object_unref (pipeline);
-
- tower->invalid[level].x1 = tower->invalid[level].x2 = 0;
- tower->invalid[level].y1 = tower->invalid[level].y2 = 0;
-}
-
-/**
- * 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
- * be rendered with vertex coordinates that correspond to its
- * size in pixels, so a 200x200 texture will be rendered on the
- * rectangle (0, 0, 200, 200).
- *
- * Return value: the COGL texture handle to use for painting, or
- * %NULL if no base texture has yet been set.
- */
-CoglTexture *
-meta_texture_tower_get_paint_texture (MetaTextureTower *tower,
- ClutterPaintContext *paint_context)
-{
- int texture_width, texture_height;
- int level;
-
- g_return_val_if_fail (tower != NULL, NULL);
-
- if (tower->textures[0] == NULL)
- return NULL;
-
- texture_width = cogl_texture_get_width (tower->textures[0]);
- texture_height = cogl_texture_get_height (tower->textures[0]);
-
- 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);
-
- if (tower->textures[level] == NULL ||
- (tower->invalid[level].x2 != tower->invalid[level].x1 &&
- tower->invalid[level].y2 != tower->invalid[level].y1))
- {
- int i;
-
- for (i = 1; i <= level; i++)
- {
- /* Use "floor" convention here to be consistent with the NPOT texture extension */
- texture_width = MAX (1, texture_width / 2);
- texture_height = MAX (1, texture_height / 2);
-
- if (tower->textures[i] == NULL)
- texture_tower_create_texture (tower, i, texture_width, texture_height);
- }
-
- for (i = 1; i <= level; i++)
- {
- if (tower->invalid[level].x2 != tower->invalid[level].x1 &&
- tower->invalid[level].y2 != tower->invalid[level].y1)
- texture_tower_revalidate (tower, i);
- }
- }
-
- return tower->textures[level];
-}
diff --git a/src/compositor/meta-texture-tower.h b/src/compositor/meta-texture-tower.h
deleted file mode 100644
index 1f5b37146..000000000
--- a/src/compositor/meta-texture-tower.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * MetaTextureTower
- *
- * Mipmap emulation by creation of scaled down images
- *
- * Copyright (C) 2009 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_TEXTURE_TOWER_H__
-#define __META_TEXTURE_TOWER_H__
-
-#include "clutter/clutter.h"
-
-G_BEGIN_DECLS
-
-/**
- * SECTION:MetaTextureTower
- * @short_description: mipmap emulation by creation of scaled down images
- *
- * A #MetaTextureTower is used to get good looking scaled down images when
- * we can't use the GL drivers mipmap support. There are two separate reasons
- *
- * - Some cards (including radeon cards <= r5xx) only support
- * TEXTURE_RECTANGLE_ARB and not NPOT textures. Rectangular textures
- * are defined not to support mipmapping.
- * - Even when NPOT textures are available, the combination of NPOT
- * textures, texture_from_pixmap, and mipmapping doesn't typically
- * work, since the X server doesn't allocate pixmaps in the right
- * layout for mipmapping.
- *
- * So, what we do is create the "mipmap" levels ourselves by successive
- * power-of-two scaledowns, and when rendering pick the single texture
- * that best matches the scale we are rendering at. (Since we aren't
- * typically using perspective transforms, we'll frequently have a single
- * scale for the entire texture.)
- */
-
-typedef struct _MetaTextureTower MetaTextureTower;
-
-MetaTextureTower *meta_texture_tower_new (void);
-void meta_texture_tower_free (MetaTextureTower *tower);
-void meta_texture_tower_set_base_texture (MetaTextureTower *tower,
- CoglTexture *texture);
-void meta_texture_tower_update_area (MetaTextureTower *tower,
- int x,
- int y,
- int width,
- int height);
-CoglTexture *meta_texture_tower_get_paint_texture (MetaTextureTower *tower,
- ClutterPaintContext *paint_context);
-
-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
deleted file mode 100644
index 64741e416..000000000
--- a/src/compositor/meta-window-actor-private.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-#ifndef META_WINDOW_ACTOR_PRIVATE_H
-#define META_WINDOW_ACTOR_PRIVATE_H
-
-#include <X11/extensions/Xdamage.h>
-
-#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 (*before_paint) (MetaWindowActor *actor,
- ClutterStageView *stage_view);
- void (*after_paint) (MetaWindowActor *actor,
- ClutterStageView *stage_view);
-
- void (*queue_destroy) (MetaWindowActor *actor);
- void (*set_frozen) (MetaWindowActor *actor,
- gboolean frozen);
- void (*update_regions) (MetaWindowActor *actor);
- gboolean (*can_freeze_commits) (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_size_change (MetaWindowActor *self,
- MetaSizeChange which_change,
- MetaRectangle *old_frame_rect,
- MetaRectangle *old_buffer_rect);
-
-void meta_window_actor_before_paint (MetaWindowActor *self,
- ClutterStageView *stage_view);
-void meta_window_actor_after_paint (MetaWindowActor *self,
- ClutterStageView *stage_view);
-void meta_window_actor_frame_complete (MetaWindowActor *self,
- ClutterFrameInfo *frame_info,
- gint64 presentation_time);
-
-gboolean meta_window_actor_effect_in_progress (MetaWindowActor *self);
-
-MetaWindowActorChanges meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
- gboolean did_placement);
-
-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_sync_updates_frozen (MetaWindowActor *self);
-void meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
- gboolean no_delay_frame);
-
-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);
-
-gboolean meta_window_actor_is_frozen (MetaWindowActor *self);
-
-gboolean meta_window_actor_is_opaque (MetaWindowActor *self);
-
-void meta_window_actor_update_regions (MetaWindowActor *self);
-
-gboolean meta_window_actor_can_freeze_commits (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
deleted file mode 100644
index b1fe61641..000000000
--- a/src/compositor/meta-window-actor-wayland.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 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)
-
-typedef struct _SurfaceTreeTraverseData
-{
- MetaWindowActor *window_actor;
- int index;
-} SurfaceTreeTraverseData;
-
-static gboolean
-set_surface_actor_index (GNode *node,
- gpointer data)
-{
- MetaWaylandSurface *surface = node->data;
- MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface);
- SurfaceTreeTraverseData *traverse_data = data;
-
- if (clutter_actor_contains (CLUTTER_ACTOR (traverse_data->window_actor),
- CLUTTER_ACTOR (surface_actor)))
- {
- clutter_actor_set_child_at_index (
- CLUTTER_ACTOR (traverse_data->window_actor),
- CLUTTER_ACTOR (surface_actor),
- traverse_data->index);
- }
- else
- {
- clutter_actor_insert_child_at_index (
- CLUTTER_ACTOR (traverse_data->window_actor),
- CLUTTER_ACTOR (surface_actor),
- traverse_data->index);
- }
- traverse_data->index++;
-
- 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;
- SurfaceTreeTraverseData traverse_data;
-
- traverse_data = (SurfaceTreeTraverseData) {
- .window_actor = actor,
- .index = 0,
- };
- g_node_traverse (root_node,
- G_IN_ORDER,
- G_TRAVERSE_LEAVES,
- -1,
- set_surface_actor_index,
- &traverse_data);
-}
-
-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_before_paint (MetaWindowActor *actor,
- ClutterStageView *stage_view)
-{
-}
-
-static void
-meta_window_actor_wayland_after_paint (MetaWindowActor *actor,
- ClutterStageView *stage_view)
-{
-}
-
-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 gboolean
-meta_window_actor_wayland_can_freeze_commits (MetaWindowActor *actor)
-{
- return FALSE;
-}
-
-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->before_paint = meta_window_actor_wayland_before_paint;
- window_actor_class->after_paint = meta_window_actor_wayland_after_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;
- window_actor_class->can_freeze_commits = meta_window_actor_wayland_can_freeze_commits;
-}
-
-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
deleted file mode 100644
index d94de8106..000000000
--- a/src/compositor/meta-window-actor-wayland.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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
deleted file mode 100644
index e18b1b28b..000000000
--- a/src/compositor/meta-window-actor-x11.c
+++ /dev/null
@@ -1,1693 +0,0 @@
-/*
- * 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 "clutter/clutter-frame-clock.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/window-x11.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;
- gboolean pending_schedule_update_now;
- ClutterFrameClock *frame_clock;
-
- 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_free (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_debug ("%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_new0 (FrameData, 1);
- 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)
- {
- if (actor_x11->frame_clock)
- clutter_frame_clock_schedule_update_now (actor_x11->frame_clock);
- else
- actor_x11->pending_schedule_update_now = TRUE;
- }
-
- 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
- * before_paint/after_paint functions get called, enabling us to
- * send a _NET_WM_FRAME_DRAWN. We need to do full damage to ensure that
- * the window is actually repainted, otherwise any subregion we would pass
- * might end up being either outside of any stage view, or be occluded by
- * something else, which could potentially result in no frame being drawn
- * after all. If the window is completely obscured, or completely off
- * screen we fire off the send_frame_messages timeout.
- */
- if (is_obscured ||
- !clutter_actor_peek_stage_views (CLUTTER_ACTOR (actor)))
- {
- queue_send_frame_messages_timeout (actor_x11);
- }
- else if (surface)
- {
- clutter_actor_queue_redraw (CLUTTER_ACTOR (surface));
- 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 efficiency
- * 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)
-{
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
- MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
- MetaSurfaceActor *surface;
- MetaSurfaceActorX11 *surface_x11;
-
- if (meta_window_actor_is_destroyed (META_WINDOW_ACTOR (actor_x11)))
- return FALSE;
-
- if (!meta_window_x11_can_unredirect (window_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, &params);
-
- 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));
- clutter_actor_invalidate_paint_volume (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;
- }
-
- if (META_IS_SURFACE_ACTOR_X11 (surface))
- {
- MetaSurfaceActorX11 *surface_x11 = META_SURFACE_ACTOR_X11 (surface);
-
- meta_surface_actor_x11_handle_updates (surface_x11);
- }
-
- 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
-handle_stage_views_changed (MetaWindowActorX11 *actor_x11)
-{
- ClutterActor *actor = CLUTTER_ACTOR (actor_x11);
-
- actor_x11->frame_clock = clutter_actor_pick_frame_clock (actor, NULL);
- if (actor_x11->frame_clock && actor_x11->pending_schedule_update_now)
- {
- clutter_frame_clock_schedule_update_now (actor_x11->frame_clock);
- actor_x11->pending_schedule_update_now = FALSE;
- }
-}
-
-static void
-meta_window_actor_x11_before_paint (MetaWindowActor *actor,
- ClutterStageView *stage_view)
-{
- 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, &params);
-
- /* 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_after_paint (MetaWindowActor *actor,
- ClutterStageView *stage_view)
-{
- 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 gboolean
-meta_window_actor_x11_can_freeze_commits (MetaWindowActor *actor)
-{
- ClutterActor *clutter_actor = CLUTTER_ACTOR (actor);
-
- return clutter_actor_is_mapped (clutter_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->before_paint = meta_window_actor_x11_before_paint;
- window_actor_class->after_paint = meta_window_actor_x11_after_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;
- window_actor_class->can_freeze_commits = meta_window_actor_x11_can_freeze_commits;
-
- 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);
-
- g_signal_connect (self, "stage-views-changed",
- G_CALLBACK (handle_stage_views_changed), 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
deleted file mode 100644
index 86b80034d..000000000
--- a/src/compositor/meta-window-actor-x11.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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
deleted file mode 100644
index d4fc9a43a..000000000
--- a/src/compositor/meta-window-actor.c
+++ /dev/null
@@ -1,1559 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * SECTION:meta-window-actor
- * @title: MetaWindowActor
- * @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 <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
-
-typedef enum
-{
- INITIALLY_FROZEN,
- DRAWING_FIRST_FRAME,
- EMITTED_FIRST_FRAME
-} FirstFrameState;
-
-typedef struct _MetaWindowActorPrivate
-{
- MetaWindow *window;
- MetaCompositor *compositor;
-
- MetaSurfaceActor *surface;
-
- int geometry_scale;
-
- /*
- * These need to be counters rather than flags, since more plugins
- * can implement same effect; the practicality of stacking effects
- * might be dubious, but we have to at least handle it correctly.
- */
- gint minimize_in_progress;
- gint unminimize_in_progress;
- gint size_change_in_progress;
- gint map_in_progress;
- gint destroy_in_progress;
-
- guint freeze_count;
-
- guint visible : 1;
- guint disposed : 1;
-
- guint needs_destroy : 1;
-
- guint updates_frozen : 1;
- guint first_frame_state : 2; /* FirstFrameState */
-} MetaWindowActorPrivate;
-
-enum
-{
- FIRST_FRAME,
- EFFECTS_COMPLETED,
- DAMAGED,
- THAWED,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-enum
-{
- PROP_META_WINDOW = 1,
-};
-
-static void meta_window_actor_dispose (GObject *object);
-static void meta_window_actor_constructed (GObject *object);
-static void meta_window_actor_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void meta_window_actor_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-
-static void meta_window_actor_real_assign_surface_actor (MetaWindowActor *self,
- MetaSurfaceActor *surface_actor);
-
-static void cullable_iface_init (MetaCullableInterface *iface);
-
-static void screen_cast_window_iface_init (MetaScreenCastWindowInterface *iface);
-
-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);
- GParamSpec *pspec;
-
- object_class->dispose = meta_window_actor_dispose;
- 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;
-
- 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_ONLY);
-
- g_object_class_install_property (object_class,
- PROP_META_WINDOW,
- pspec);
-}
-
-static void
-meta_window_actor_init (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- priv->geometry_scale = 1;
-}
-
-static void
-window_appears_focused_notify (MetaWindow *mw,
- GParamSpec *arg1,
- gpointer data)
-{
- clutter_actor_queue_redraw (CLUTTER_ACTOR (data));
-}
-
-gboolean
-meta_window_actor_is_opaque (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaWindow *window = priv->window;
-
- if (window->opacity != 0xff)
- return FALSE;
-
- if (!priv->surface)
- return FALSE;
-
- return meta_surface_actor_is_opaque (priv->surface);
-}
-
-gboolean
-meta_window_actor_is_frozen (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- return priv->surface == NULL || priv->freeze_count > 0;
-}
-
-void
-meta_window_actor_update_regions (MetaWindowActor *self)
-{
- META_WINDOW_ACTOR_GET_CLASS (self)->update_regions (self);
-}
-
-gboolean
-meta_window_actor_can_freeze_commits (MetaWindowActor *self)
-{
- g_return_val_if_fail (META_IS_WINDOW_ACTOR (self), FALSE);
-
- return META_WINDOW_ACTOR_GET_CLASS (self)->can_freeze_commits (self);
-}
-
-static void
-meta_window_actor_set_frozen (MetaWindowActor *self,
- gboolean frozen)
-{
- ClutterActor *child;
- ClutterActorIter iter;
-
- clutter_actor_iter_init (&iter, CLUTTER_ACTOR (self));
- while (clutter_actor_iter_next (&iter, &child))
- {
- if (META_IS_SURFACE_ACTOR (child))
- meta_surface_actor_set_frozen (META_SURFACE_ACTOR (child), frozen);
- }
-
- META_WINDOW_ACTOR_GET_CLASS (self)->set_frozen (self, frozen);
-}
-
-/**
- * meta_window_actor_freeze:
- * @self: The #MetaWindowActor
- *
- * Freezes the #MetaWindowActor, which inhibits updates and geometry
- * changes of the window. This property is refcounted, so make sure
- * to call meta_window_actor_thaw() the exact same amount of times
- * as this function to allow updates again.
- */
-void
-meta_window_actor_freeze (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv;
-
- g_return_if_fail (META_IS_WINDOW_ACTOR (self));
-
- priv = meta_window_actor_get_instance_private (self);
-
- if (priv->freeze_count == 0 && priv->surface)
- meta_window_actor_set_frozen (self, TRUE);
-
- priv->freeze_count ++;
-}
-
-static void
-meta_window_actor_sync_thawed_state (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- if (priv->first_frame_state == INITIALLY_FROZEN)
- priv->first_frame_state = DRAWING_FIRST_FRAME;
-
- if (priv->surface)
- meta_window_actor_set_frozen (self, FALSE);
-
- /* We sometimes ignore moves and resizes on frozen windows */
- meta_window_actor_sync_actor_geometry (self, FALSE);
-}
-
-/**
- * meta_window_actor_thaw:
- * @self: The #MetaWindowActor
- *
- * Thaws/unfreezes the #MetaWindowActor to allow updates and geometry
- * changes after a window was frozen using meta_window_actor_freeze().
- */
-void
-meta_window_actor_thaw (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv;
-
- g_return_if_fail (META_IS_WINDOW_ACTOR (self));
-
- 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
-meta_window_actor_real_assign_surface_actor (MetaWindowActor *self,
- MetaSurfaceActor *surface_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);
-}
-
-void
-meta_window_actor_assign_surface_actor (MetaWindowActor *self,
- MetaSurfaceActor *surface_actor)
-{
- META_WINDOW_ACTOR_GET_CLASS (self)->assign_surface_actor (self,
- surface_actor);
-}
-
-static void
-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;
-
- 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 =
- meta_window_actor_get_instance_private (self);
- MetaWindow *window = priv->window;
-
- priv->compositor = window->display->compositor;
-
- /* Hang our compositor window state off the MetaWindow for fast retrieval */
- meta_window_set_compositor_private (window, object);
-
- init_surface_actor (self);
-
- meta_window_actor_update_opacity (self);
-
- meta_window_actor_sync_updates_frozen (self);
-
- if (meta_window_actor_is_frozen (self))
- priv->first_frame_state = INITIALLY_FROZEN;
- else
- priv->first_frame_state = DRAWING_FIRST_FRAME;
-
- 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 =
- meta_window_actor_get_instance_private (self);
- MetaCompositor *compositor = priv->compositor;
-
- if (priv->disposed)
- {
- G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object);
- return;
- }
-
- priv->disposed = TRUE;
-
- meta_compositor_remove_window_actor (compositor, self);
-
- g_clear_object (&priv->window);
-
- if (priv->surface)
- {
- clutter_actor_remove_child (CLUTTER_ACTOR (self),
- CLUTTER_ACTOR (priv->surface));
- g_clear_object (&priv->surface);
- }
-
- G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (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 =
- meta_window_actor_get_instance_private (self);
-
- switch (prop_id)
- {
- case PROP_META_WINDOW:
- 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);
- break;
- }
-}
-
-static void
-meta_window_actor_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- 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;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/**
- * 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)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- return priv->window;
-}
-
-/**
- * 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 =
- meta_window_actor_get_instance_private (self);
-
- if (priv->surface)
- return meta_surface_actor_get_texture (priv->surface);
- else
- return NULL;
-}
-
-/**
- * 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 =
- meta_window_actor_get_instance_private (self);
-
- return priv->surface;
-}
-
-/**
- * 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
- */
-gboolean
-meta_window_actor_is_destroyed (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- return priv->disposed || priv->needs_destroy;
-}
-
-void
-meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
- gboolean no_delay_frame)
-{
- META_WINDOW_ACTOR_GET_CLASS (self)->queue_frame_drawn (self,
- no_delay_frame);
-}
-
-gboolean
-meta_window_actor_effect_in_progress (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- return (priv->minimize_in_progress ||
- priv->size_change_in_progress ||
- priv->map_in_progress ||
- priv->destroy_in_progress);
-}
-
-static gboolean
-is_freeze_thaw_effect (MetaPluginEffect event)
-{
- switch (event)
- {
- case META_PLUGIN_DESTROY:
- return TRUE;
- break;
- default:
- return FALSE;
- }
-}
-
-static gboolean
-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;
-
- 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_SIZE_CHANGE:
- case META_PLUGIN_SWITCH_WORKSPACE:
- g_assert_not_reached ();
- break;
- }
-
- g_assert (counter);
-
- use_freeze_thaw = is_freeze_thaw_effect (event);
-
- if (use_freeze_thaw)
- meta_window_actor_freeze (self);
-
- (*counter)++;
-
- if (!meta_plugin_manager_event_simple (plugin_mgr, self, event))
- {
- (*counter)--;
- if (use_freeze_thaw)
- meta_window_actor_thaw (self);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-meta_window_actor_after_effects (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- ClutterStage *stage;
- ClutterSeat *seat;
-
- stage = CLUTTER_STAGE (clutter_actor_get_stage (CLUTTER_ACTOR (self)));
- seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
-
- if (priv->needs_destroy)
- {
- clutter_actor_destroy (CLUTTER_ACTOR (self));
- }
- else
- {
- g_signal_emit (self, signals[EFFECTS_COMPLETED], 0);
- meta_window_actor_sync_visibility (self);
- meta_window_actor_sync_actor_geometry (self, FALSE);
- }
-
- clutter_stage_repick_device (stage, clutter_seat_get_pointer (seat));
-}
-
-void
-meta_window_actor_effect_completed (MetaWindowActor *self,
- MetaPluginEffect event)
-{
- 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.
- * In this case priv->window will == NULL */
-
- 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;
- 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:
- /*
- * Make sure that the actor is at the correct place in case
- * the plugin fscked.
- */
- priv->map_in_progress--;
-
- if (priv->map_in_progress < 0)
- {
- g_warning ("Error in map accounting.");
- priv->map_in_progress = 0;
- inconsistent = TRUE;
- }
- break;
- case META_PLUGIN_DESTROY:
- priv->destroy_in_progress--;
-
- if (priv->destroy_in_progress < 0)
- {
- g_warning ("Error in destroy accounting.");
- priv->destroy_in_progress = 0;
- inconsistent = TRUE;
- }
- break;
- case META_PLUGIN_SIZE_CHANGE:
- priv->size_change_in_progress--;
- if (priv->size_change_in_progress < 0)
- {
- g_warning ("Error in size change accounting.");
- priv->size_change_in_progress = 0;
- inconsistent = TRUE;
- }
- break;
- case META_PLUGIN_SWITCH_WORKSPACE:
- g_assert_not_reached ();
- break;
- }
-
- 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);
-}
-
-void
-meta_window_actor_queue_destroy (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaWindow *window = priv->window;
- MetaWindowType window_type = meta_window_get_window_type (window);
-
- meta_window_set_compositor_private (window, NULL);
-
- META_WINDOW_ACTOR_GET_CLASS (self)->queue_destroy (self);
-
- if (window_type == META_WINDOW_DROPDOWN_MENU ||
- window_type == META_WINDOW_POPUP_MENU ||
- window_type == META_WINDOW_TOOLTIP ||
- window_type == META_WINDOW_NOTIFICATION ||
- window_type == META_WINDOW_COMBO ||
- window_type == META_WINDOW_DND ||
- window_type == META_WINDOW_OVERRIDE_OTHER)
- {
- /*
- * No effects, just kill it.
- */
- clutter_actor_destroy (CLUTTER_ACTOR (self));
- return;
- }
-
- priv->needs_destroy = TRUE;
-
- if (!meta_window_actor_effect_in_progress (self))
- clutter_actor_destroy (CLUTTER_ACTOR (self));
-}
-
-MetaWindowActorChanges
-meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
- gboolean did_placement)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaRectangle window_rect;
- ClutterActor *actor = CLUTTER_ACTOR (self);
- MetaWindowActorChanges changes = 0;
-
- meta_window_get_buffer_rect (priv->window, &window_rect);
-
- /* 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,
- * or because the user is resizing from the left/top. But on initial placement
- * we need to assign a position, since immediately after the window
- * is shown, the map effect will go into effect and prevent further geometry
- * updates.
- */
- if (meta_window_actor_is_frozen (self) && !did_placement)
- return META_WINDOW_ACTOR_CHANGE_POSITION | META_WINDOW_ACTOR_CHANGE_SIZE;
-
- if (clutter_actor_has_allocation (actor))
- {
- ClutterActorBox box;
- float old_x, old_y;
- float old_width, old_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 (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
- {
- 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 =
- meta_window_actor_get_instance_private (self);
- MetaCompositor *compositor = priv->compositor;
- MetaPluginEffect event;
-
- g_return_if_fail (!priv->visible);
-
- priv->visible = TRUE;
-
- switch (effect)
- {
- case META_COMP_EFFECT_CREATE:
- event = META_PLUGIN_MAP;
- break;
- case META_COMP_EFFECT_UNMINIMIZE:
- event = META_PLUGIN_UNMINIMIZE;
- break;
- case META_COMP_EFFECT_NONE:
- event = META_PLUGIN_NONE;
- break;
- default:
- g_assert_not_reached();
- }
-
- 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));
- }
-}
-
-void
-meta_window_actor_hide (MetaWindowActor *self,
- MetaCompEffect effect)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaCompositor *compositor = priv->compositor;
- MetaPluginEffect event;
-
- g_return_if_fail (priv->visible);
-
- priv->visible = FALSE;
-
- /* If a plugin is animating a workspace transition, we have to
- * hold off on hiding the window, and do it after the workspace
- * switch completes
- */
- if (meta_compositor_is_switching_workspace (compositor))
- return;
-
- switch (effect)
- {
- case META_COMP_EFFECT_DESTROY:
- event = META_PLUGIN_DESTROY;
- break;
- case META_COMP_EFFECT_MINIMIZE:
- event = META_PLUGIN_MINIMIZE;
- break;
- case META_COMP_EFFECT_NONE:
- event = META_PLUGIN_NONE;
- break;
- default:
- g_assert_not_reached();
- }
-
- if (!start_simple_effect (self, event))
- clutter_actor_hide (CLUTTER_ACTOR (self));
-}
-
-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++;
-
- if (!meta_plugin_manager_event_size_change (plugin_mgr, self,
- which_change, old_frame_rect, old_buffer_rect))
- priv->size_change_in_progress--;
-}
-
-#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
-
-#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)
-{
- 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);
-
- cairo_surface_write_to_png (surface, filename);
- cairo_destroy (cr);
- cairo_surface_destroy (surface);
-}
-#endif
-
-
-static void
-meta_window_actor_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_window_actor_reset_culling (MetaCullable *cullable)
-{
- meta_cullable_reset_culling_children (cullable);
-}
-
-static void
-cullable_iface_init (MetaCullableInterface *iface)
-{
- iface->cull_out = meta_window_actor_cull_out;
- iface->reset_culling = meta_window_actor_reset_culling;
-}
-
-void
-meta_window_actor_sync_visibility (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- if (CLUTTER_ACTOR_IS_VISIBLE (self) != priv->visible)
- {
- if (priv->visible)
- clutter_actor_show (CLUTTER_ACTOR (self));
- else
- clutter_actor_hide (CLUTTER_ACTOR (self));
- }
-}
-
-void
-meta_window_actor_before_paint (MetaWindowActor *self,
- ClutterStageView *stage_view)
-{
- if (meta_window_actor_is_destroyed (self))
- return;
-
- META_WINDOW_ACTOR_GET_CLASS (self)->before_paint (self, stage_view);
-}
-
-void
-meta_window_actor_after_paint (MetaWindowActor *self,
- ClutterStageView *stage_view)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- META_WINDOW_ACTOR_GET_CLASS (self)->after_paint (self, stage_view);
-
- if (meta_window_actor_is_destroyed (self))
- return;
-
- if (priv->first_frame_state == DRAWING_FIRST_FRAME)
- {
- priv->first_frame_state = EMITTED_FIRST_FRAME;
- g_signal_emit (self, signals[FIRST_FRAME], 0);
- }
-}
-
-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);
-}
-
-void
-meta_window_actor_update_opacity (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaWindow *window = priv->window;
-
- if (priv->surface)
- clutter_actor_set_opacity (CLUTTER_ACTOR (priv->surface), window->opacity);
-}
-
-static void
-meta_window_actor_set_updates_frozen (MetaWindowActor *self,
- gboolean updates_frozen)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
-
- updates_frozen = updates_frozen != FALSE;
-
- 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);
- }
-}
-
-void
-meta_window_actor_sync_updates_frozen (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (self);
- MetaWindow *window = priv->window;
-
- meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (window));
-}
-
-MetaWindowActor *
-meta_window_actor_from_window (MetaWindow *window)
-{
- return META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
-}
-
-void
-meta_window_actor_set_geometry_scale (MetaWindowActor *window_actor,
- int geometry_scale)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (window_actor);
- graphene_matrix_t child_transform;
-
- if (priv->geometry_scale == geometry_scale)
- return;
-
- priv->geometry_scale = geometry_scale;
-
- graphene_matrix_init_scale (&child_transform,
- geometry_scale,
- geometry_scale,
- 1);
- clutter_actor_set_child_transform (CLUTTER_ACTOR (window_actor),
- &child_transform);
-}
-
-int
-meta_window_actor_get_geometry_scale (MetaWindowActor *window_actor)
-{
- MetaWindowActorPrivate *priv =
- meta_window_actor_get_instance_private (window_actor);
-
- return priv->geometry_scale;
-}
-
-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;
-
- 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,
- };
-}
-
-static void
-meta_window_actor_transform_relative_position (MetaScreenCastWindow *screen_cast_window,
- double x,
- double y,
- double *x_out,
- double *y_out)
-
-{
- 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, };
-
- meta_window_actor_get_buffer_bounds (screen_cast_window, &bounds);
-
- v1.x = CLAMP ((float) x,
- bounds.x,
- bounds.x + bounds.width);
- v1.y = CLAMP ((float) y,
- bounds.y,
- bounds.y + bounds.height);
-
- clutter_actor_apply_transform_to_point (CLUTTER_ACTOR (priv->surface),
- &v1,
- &v2);
-
- *x_out = (double) v2.x;
- *y_out = (double) v2.y;
-}
-
-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;
-
- window = priv->window;
- if (!meta_window_has_pointer (window))
- return FALSE;
-
- if (cursor_sprite &&
- meta_cursor_sprite_get_cogl_texture (cursor_sprite) &&
- out_cursor_scale)
- {
- MetaShapedTexture *stex;
- double texture_scale;
- float cursor_texture_scale;
-
- 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);
-
- *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);
- }
-
- return TRUE;
-}
-
-static void
-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;
-
- 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 (cr_width == bounds->width && cr_height == bounds->height)
- {
- memcpy (data, cr_data, cr_height * cr_stride);
- }
- else
- {
- int width = MIN (bounds->width, cr_width);
- int height = MIN (bounds->height, cr_height);
- int stride = width * bpp;
- uint8_t *src, *dst;
-
- 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++)
- {
- memset (dst, 0, bounds->width * bpp);
- dst += bounds->width * bpp;
- }
- }
-
- cairo_surface_destroy (image);
-}
-
-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 (meta_window_actor_is_destroyed (window_actor))
- return FALSE;
-
- clutter_actor_get_size (actor, &width, &height);
-
- if (width == 0 || height == 0)
- return FALSE;
-
- resource_scale = clutter_actor_get_resource_scale (actor);
-
- clutter_actor_inhibit_culling (actor);
-
- width = ceilf (width * resource_scale);
- height = ceilf (height * resource_scale);
-
- clutter_actor_get_position (actor, &x, &y);
-
- 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);
-
- 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);
-
- cogl_framebuffer_push_rectangle_clip (framebuffer,
- scaled_clip.x, scaled_clip.y,
- scaled_clip.x + scaled_clip.width,
- scaled_clip.y + scaled_clip.height);
-
- cogl_framebuffer_push_matrix (framebuffer);
- cogl_framebuffer_scale (framebuffer, resource_scale, resource_scale, 1);
- cogl_framebuffer_translate (framebuffer, -x, -y, 0);
-
- paint_context =
- clutter_paint_context_new_for_framebuffer (framebuffer, NULL,
- CLUTTER_PAINT_FLAG_NONE);
- clutter_actor_paint (actor, paint_context);
- clutter_paint_context_destroy (paint_context);
-
- cogl_framebuffer_pop_matrix (framebuffer);
- cogl_framebuffer_pop_clip (framebuffer);
-
- clutter_actor_uninhibit_culling (actor);
-
- return TRUE;
-}
-
-static gboolean
-meta_window_actor_has_damage (MetaScreenCastWindow *screen_cast_window)
-{
- return clutter_actor_has_damage (CLUTTER_ACTOR (screen_cast_window));
-}
-
-static void
-screen_cast_window_iface_init (MetaScreenCastWindowInterface *iface)
-{
- 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_notify_damaged (MetaWindowActor *window_actor)
-{
- 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;
-
- if (!priv->surface)
- return NULL;
-
- clutter_actor_inhibit_culling (actor);
-
- if (clutter_actor_get_n_children (actor) == 1)
- {
- MetaShapedTexture *stex;
- MetaRectangle *surface_clip = NULL;
-
- if (clip)
- {
-
- int geometry_scale;
-
- geometry_scale =
- meta_window_actor_get_geometry_scale (self);
-
- 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;
- }
-
- stex = meta_surface_actor_get_texture (priv->surface);
- surface = meta_shaped_texture_get_image (stex, surface_clip);
- goto out;
- }
-
- clutter_actor_get_size (actor, &width, &height);
-
- if (width == 0 || height == 0)
- goto out;
-
- resource_scale = clutter_actor_get_resource_scale (actor);
-
- width = ceilf (width * resource_scale);
- height = ceilf (height * resource_scale);
-
- texture = cogl_texture_2d_new_with_size (cogl_context, width, height);
- if (!texture)
- goto out;
-
- cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (texture),
- FALSE);
-
- offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture));
- framebuffer = COGL_FRAMEBUFFER (offscreen);
-
- cogl_object_unref (texture);
-
- if (!cogl_framebuffer_allocate (framebuffer, &error))
- {
- g_warning ("Failed to allocate framebuffer for screenshot: %s",
- error->message);
- g_object_unref (framebuffer);
- cogl_object_unref (texture);
- goto out;
- }
-
- cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);
- clutter_actor_get_position (actor, &x, &y);
-
- 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);
-
- paint_context =
- clutter_paint_context_new_for_framebuffer (framebuffer, NULL,
- CLUTTER_PAINT_FLAG_NONE);
- clutter_actor_paint (actor, paint_context);
- clutter_paint_context_destroy (paint_context);
-
- if (clip)
- {
- 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
- {
- scaled_clip = (MetaRectangle) {
- .width = width,
- .height = height,
- };
- }
-
- 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));
-
- g_object_unref (framebuffer);
-
- cairo_surface_mark_dirty (surface);
-
-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
deleted file mode 100644
index c3467066b..000000000
--- a/src/compositor/meta-window-group-private.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* -*- 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
deleted file mode 100644
index d526805fe..000000000
--- a/src/compositor/meta-window-group.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-#include "config.h"
-
-#include <gdk/gdk.h>
-#include <math.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
-{
- ClutterActorClass parent_class;
-};
-
-struct _MetaWindowGroup
-{
- ClutterActor parent;
-
- MetaDisplay *display;
-};
-
-static void cullable_iface_init (MetaCullableInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR,
- G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
-
-static void
-meta_window_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_window_group_reset_culling (MetaCullable *cullable)
-{
- meta_cullable_reset_culling_children (cullable);
-}
-
-static void
-cullable_iface_init (MetaCullableInterface *iface)
-{
- iface->cull_out = meta_window_group_cull_out;
- iface->reset_culling = meta_window_group_reset_culling;
-}
-
-static void
-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;
- cairo_rectangle_int_t visible_rect;
- int paint_x_origin, paint_y_origin;
- int screen_width, screen_height;
-
- redraw_clip = clutter_paint_context_get_redraw_clip (paint_context);
- if (!redraw_clip)
- {
- 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
- * group under the current model-view matrix and the position of the actor.
- * If they are both simply integer translations, then we can compensate
- * easily, otherwise we give up.
- *
- * Possible cleanup: work entirely in paint space - we can compute the
- * combination of the model-view matrix with the local matrix for each child
- * actor and get a total transformation for that actor for how we are
- * painting currently, and never worry about how actors are positioned
- * on the stage.
- */
- if (clutter_actor_is_in_clone_paint (actor))
- {
- 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;
- }
-
- visible_rect.x = visible_rect.y = 0;
- 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 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);
-
- cairo_region_translate (clip_region, -paint_x_origin, -paint_y_origin);
-
- meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region);
-
- cairo_region_destroy (unobscured_region);
- cairo_region_destroy (clip_region);
-
- parent_actor_class->paint (actor, paint_context);
-
- 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 *self,
- ClutterPaintVolume *volume)
-{
- 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
-meta_window_group_class_init (MetaWindowGroupClass *klass)
-{
- ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (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 *
-meta_window_group_new (MetaDisplay *display)
-{
- MetaWindowGroup *window_group;
-
- window_group = g_object_new (META_TYPE_WINDOW_GROUP, NULL);
-
- window_group->display = display;
-
- return CLUTTER_ACTOR (window_group);
-}
diff --git a/src/compositor/meta-window-shape.c b/src/compositor/meta-window-shape.c
deleted file mode 100644
index 3bb6409c4..000000000
--- a/src/compositor/meta-window-shape.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * MetaWindowShape
- *
- * Extracted invariant window shape
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "meta/meta-window-shape.h"
-
-#include <string.h>
-
-#include "compositor/region-utils.h"
-
-struct _MetaWindowShape
-{
- guint ref_count;
-
- int top, right, bottom, left;
- int n_rectangles;
- cairo_rectangle_int_t *rectangles;
- guint hash;
-};
-
-MetaWindowShape *
-meta_window_shape_new (cairo_region_t *region)
-{
- MetaWindowShape *shape;
- MetaRegionIterator iter;
- cairo_rectangle_int_t extents;
- int max_yspan_y1 = 0;
- int max_yspan_y2 = 0;
- int max_xspan_x1 = -1;
- int max_xspan_x2 = -1;
- guint hash;
-
- shape = g_new0 (MetaWindowShape, 1);
- shape->ref_count = 1;
-
- cairo_region_get_extents (region, &extents);
-
- shape->n_rectangles = cairo_region_num_rectangles (region);
-
- if (shape->n_rectangles == 0)
- {
- shape->rectangles = NULL;
- shape->top = shape->right = shape->bottom = shape->left = 0;
- shape->hash = 0;
- return shape;
- }
-
- for (meta_region_iterator_init (&iter, region);
- !meta_region_iterator_at_end (&iter);
- meta_region_iterator_next (&iter))
- {
- int max_line_xspan_x1 = -1;
- int max_line_xspan_x2 = -1;
-
- if (iter.rectangle.width > max_line_xspan_x2 - max_line_xspan_x1)
- {
- max_line_xspan_x1 = iter.rectangle.x;
- max_line_xspan_x2 = iter.rectangle.x + iter.rectangle.width;
- }
-
- if (iter.line_end)
- {
- if (iter.rectangle.height > max_yspan_y2 - max_yspan_y1)
- {
- max_yspan_y1 = iter.rectangle.y;
- max_yspan_y2 = iter.rectangle.y + iter.rectangle.height;
- }
-
- if (max_xspan_x1 < 0) /* First line */
- {
- max_xspan_x1 = max_line_xspan_x1;
- max_xspan_x2 = max_line_xspan_x2;
- }
- else
- {
- max_xspan_x1 = MAX (max_xspan_x1, max_line_xspan_x1);
- max_xspan_x2 = MIN (max_xspan_x2, max_line_xspan_x2);
-
- if (max_xspan_x2 < max_xspan_x1)
- max_xspan_x2 = max_xspan_x1;
- }
- }
- }
-
-#if 0
- g_print ("xspan: %d -> %d, yspan: %d -> %d\n",
- max_xspan_x1, max_xspan_x2,
- max_yspan_y1, max_yspan_y2);
-#endif
-
- shape->top = max_yspan_y1 - extents.y;
- shape->right = extents.x + extents.width - max_xspan_x2;
- shape->bottom = extents.y + extents.height - max_yspan_y2;
- shape->left = max_xspan_x1 - extents.x;
-
- shape->rectangles = g_new (cairo_rectangle_int_t, shape->n_rectangles);
-
- hash = 0;
- for (meta_region_iterator_init (&iter, region);
- !meta_region_iterator_at_end (&iter);
- meta_region_iterator_next (&iter))
- {
- int x1, x2, y1, y2;
-
- x1 = iter.rectangle.x;
- x2 = iter.rectangle.x + iter.rectangle.width;
- y1 = iter.rectangle.y;
- y2 = iter.rectangle.y + iter.rectangle.height;
-
- if (x1 > max_xspan_x1)
- x1 -= MIN (x1, max_xspan_x2 - 1) - max_xspan_x1;
- if (x2 > max_xspan_x1)
- x2 -= MIN (x2, max_xspan_x2 - 1) - max_xspan_x1;
- if (y1 > max_yspan_y1)
- y1 -= MIN (y1, max_yspan_y2 - 1) - max_yspan_y1;
- if (y2 > max_yspan_y1)
- y2 -= MIN (y2, max_yspan_y2 - 1) - max_yspan_y1;
-
- shape->rectangles[iter.i].x = x1 - extents.x;
- shape->rectangles[iter.i].y = y1 - extents.y;
- shape->rectangles[iter.i].width = x2 - x1;
- shape->rectangles[iter.i].height = y2 - y1;
-
-#if 0
- g_print ("%d: +%d+%dx%dx%d => +%d+%dx%dx%d\n",
- iter.i, iter.rectangle.x, iter.rectangle.y, iter.rectangle.width, iter.rectangle.height,
- shape->rectangles[iter.i].x, shape->rectangles[iter.i].y,
- hape->rectangles[iter.i].width, shape->rectangles[iter.i].height);
-#endif
-
- hash = hash * 31 + x1 * 17 + x2 * 27 + y1 * 37 + y2 * 43;
- }
-
- shape->hash = hash;
-
-#if 0
- g_print ("%d %d %d %d: %#x\n\n", shape->top, shape->right, shape->bottom, shape->left, shape->hash);
-#endif
-
- return shape;
-}
-
-MetaWindowShape *
-meta_window_shape_ref (MetaWindowShape *shape)
-{
- shape->ref_count++;
-
- return shape;
-}
-
-void
-meta_window_shape_unref (MetaWindowShape *shape)
-{
- shape->ref_count--;
- if (shape->ref_count == 0)
- {
- g_free (shape->rectangles);
- g_free (shape);
- }
-}
-
-guint
-meta_window_shape_hash (MetaWindowShape *shape)
-{
- return shape->hash;
-}
-
-gboolean
-meta_window_shape_equal (MetaWindowShape *shape_a,
- MetaWindowShape *shape_b)
-{
- if (shape_a->n_rectangles != shape_b->n_rectangles)
- return FALSE;
-
- return memcmp (shape_a->rectangles, shape_b->rectangles,
- sizeof (cairo_rectangle_int_t) * shape_a->n_rectangles) == 0;
-}
-
-void
-meta_window_shape_get_borders (MetaWindowShape *shape,
- int *border_top,
- int *border_right,
- int *border_bottom,
- int *border_left)
-{
- if (border_top)
- *border_top = shape->top;
- if (border_right)
- *border_right = shape->right;
- if (border_bottom)
- *border_bottom = shape->bottom;
- if (border_left)
- *border_left = shape->left;
-}
-
-/**
- * meta_window_shape_to_region:
- * @shape: a #MetaWindowShape
- * @center_width: size of the central region horizontally
- * @center_height: size of the central region vertically
- *
- * Converts the shape to to a cairo_region_t using the given width
- * and height for the central scaled region.
- *
- * Return value: a newly created region
- */
-cairo_region_t *
-meta_window_shape_to_region (MetaWindowShape *shape,
- int center_width,
- int center_height)
-{
- cairo_region_t *region;
- int i;
-
- region = cairo_region_create ();
-
- for (i = 0; i < shape->n_rectangles; i++)
- {
- cairo_rectangle_int_t rect = shape->rectangles[i];
-
- if (rect.x <= shape->left && rect.x + rect.width >= shape->left + 1)
- rect.width += center_width;
- else if (rect.x >= shape->left + 1)
- rect.x += center_width;
-
- if (rect.y <= shape->top && rect.y + rect.height >= shape->top + 1)
- rect.height += center_height;
- else if (rect.y >= shape->top + 1)
- rect.y += center_height;
-
- cairo_region_union_rectangle (region, &rect);
- }
-
- return region;
-}
-
-G_DEFINE_BOXED_TYPE (MetaWindowShape, meta_window_shape,
- meta_window_shape_ref, meta_window_shape_unref)
diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c
deleted file mode 100644
index c89c84121..000000000
--- a/src/compositor/plugins/default.c
+++ /dev/null
@@ -1,923 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (c) 2008 Intel Corp.
- *
- * Author: Tomas Frydrych <tf@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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/display.h"
-
-#include <glib/gi18n-lib.h>
-#include <gmodule.h>
-#include <string.h>
-
-#include "clutter/clutter.h"
-#include "meta/meta-backend.h"
-#include "meta/meta-background-actor.h"
-#include "meta/meta-background-content.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 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))
-#define META_DEFAULT_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DEFAULT_PLUGIN, MetaDefaultPluginClass))
-#define META_IS_DEFAULT_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_DEFAULT_PLUGIN_TYPE))
-#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))
-
-typedef struct _MetaDefaultPlugin MetaDefaultPlugin;
-typedef struct _MetaDefaultPluginClass MetaDefaultPluginClass;
-typedef struct _MetaDefaultPluginPrivate MetaDefaultPluginPrivate;
-
-struct _MetaDefaultPlugin
-{
- MetaPlugin parent;
-
- MetaDefaultPluginPrivate *priv;
-};
-
-struct _MetaDefaultPluginClass
-{
- MetaPluginClass parent_class;
-};
-
-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 switch_workspace (MetaPlugin *plugin,
- gint from,
- gint to,
- MetaMotionDirection direction);
-
-static void kill_window_effects (MetaPlugin *plugin,
- MetaWindowActor *actor);
-static void kill_switch_workspace (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);
-
-static const MetaPluginInfo * plugin_info (MetaPlugin *plugin);
-
-/*
- * Plugin private data that we store in the .plugin_private member.
- */
-struct _MetaDefaultPluginPrivate
-{
- /* Valid only when switch_workspace effect is in progress */
- ClutterTimeline *tml_switch_workspace1;
- ClutterTimeline *tml_switch_workspace2;
- ClutterActor *desktop1;
- ClutterActor *desktop2;
-
- ClutterActor *background_group;
-
- 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.
- */
-typedef struct _ActorPrivate
-{
- ClutterActor *orig_parent;
-
- ClutterTimeline *tml_minimize;
- ClutterTimeline *tml_destroy;
- ClutterTimeline *tml_map;
-} ActorPrivate;
-
-/* callback data for when animations complete */
-typedef struct
-{
- ClutterActor *actor;
- MetaPlugin *plugin;
-} EffectCompleteData;
-
-
-typedef struct _DisplayTilePreview
-{
- ClutterActor *actor;
-
- GdkRGBA *preview_color;
-
- MetaRectangle tile_rect;
-} DisplayTilePreview;
-
-static void
-meta_default_plugin_dispose (GObject *object)
-{
- /* MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (object)->priv;
- */
- G_OBJECT_CLASS (meta_default_plugin_parent_class)->dispose (object);
-}
-
-static void
-meta_default_plugin_finalize (GObject *object)
-{
- G_OBJECT_CLASS (meta_default_plugin_parent_class)->finalize (object);
-}
-
-static void
-meta_default_plugin_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_default_plugin_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- switch (prop_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_default_plugin_class_init (MetaDefaultPluginClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- MetaPluginClass *plugin_class = META_PLUGIN_CLASS (klass);
-
- gobject_class->finalize = meta_default_plugin_finalize;
- gobject_class->dispose = meta_default_plugin_dispose;
- gobject_class->set_property = meta_default_plugin_set_property;
- gobject_class->get_property = meta_default_plugin_get_property;
-
- plugin_class->start = start;
- plugin_class->map = map;
- plugin_class->minimize = minimize;
- 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;
- plugin_class->kill_switch_workspace = kill_switch_workspace;
- plugin_class->confirm_display_change = confirm_display_change;
-}
-
-static void
-meta_default_plugin_init (MetaDefaultPlugin *self)
-{
- MetaDefaultPluginPrivate *priv;
-
- self->priv = priv = meta_default_plugin_get_instance_private (self);
-
- priv->info.name = "Default Effects";
- priv->info.version = "0.1";
- priv->info.author = "Intel Corp.";
- priv->info.license = "GPL";
- priv->info.description = "This is an example of a plugin implementation.";
-}
-
-/*
- * Actor private data accessor
- */
-static void
-free_actor_private (gpointer data)
-{
- if (G_LIKELY (data != NULL))
- g_free (data);
-}
-
-static ActorPrivate *
-get_actor_private (MetaWindowActor *actor)
-{
- ActorPrivate *priv = g_object_get_qdata (G_OBJECT (actor), actor_data_quark);
-
- if (G_UNLIKELY (actor_data_quark == 0))
- actor_data_quark = g_quark_from_static_string (ACTOR_DATA_KEY);
-
- if (G_UNLIKELY (!priv))
- {
- priv = g_new0 (ActorPrivate, 1);
-
- g_object_set_qdata_full (G_OBJECT (actor),
- actor_data_quark, priv,
- free_actor_private);
- }
-
- 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;
- MetaDisplay *display = meta_plugin_get_display (plugin);
- GList *l = meta_get_window_actors (display);
-
- while (l)
- {
- ClutterActor *a = l->data;
- MetaWindowActor *window_actor = META_WINDOW_ACTOR (a);
- ActorPrivate *apriv = get_actor_private (window_actor);
-
- if (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;
- }
-
- l = l->next;
- }
-
- clutter_actor_destroy (priv->desktop1);
- clutter_actor_destroy (priv->desktop2);
-
- priv->tml_switch_workspace1 = NULL;
- priv->tml_switch_workspace2 = NULL;
- priv->desktop1 = NULL;
- priv->desktop2 = NULL;
-
- 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++)
- {
- MetaBackgroundContent *background_content;
- ClutterContent *content;
- MetaRectangle rect;
- ClutterActor *background_actor;
- MetaBackground *background;
- uint8_t red;
- uint8_t green;
- uint8_t blue;
- ClutterColor color;
-
- meta_display_get_monitor_geometry (display, i, &rect);
-
- background_actor = meta_background_actor_new (display, i);
- content = clutter_actor_get_content (background_actor);
- background_content = META_BACKGROUND_CONTENT (content);
-
- 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.
- */
-
- blue = g_rand_int_range (rand, 0, 255);
- green = g_rand_int_range (rand, 0, 255);
- red = g_rand_int_range (rand, 0, 255);
- clutter_color_init (&color, red, green, blue, 255);
-
- background = meta_background_new (display);
- meta_background_set_color (background, &color);
- meta_background_content_set_background (background_content, background);
- g_object_unref (background);
-
- meta_background_content_set_vignette (background_content, 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)
-{
- MetaDisplay *display;
- MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv;
- GList *l;
- ClutterActor *workspace0 = clutter_actor_new ();
- ClutterActor *workspace1 = clutter_actor_new ();
- ClutterActor *stage;
- int screen_width, screen_height;
-
- display = meta_plugin_get_display (plugin);
- stage = meta_get_stage_for_display (display);
-
- meta_display_get_size (display,
- &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_actor_add_child (stage, workspace1);
- clutter_actor_add_child (stage, workspace0);
-
- if (from == to)
- {
- meta_plugin_switch_workspace_completed (plugin);
- return;
- }
-
- 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;
-
- 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);
-
- 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)
- {
- /* Sticky window */
- apriv->orig_parent = NULL;
- }
- else
- {
- /* Window on some other desktop */
- clutter_actor_hide (actor);
- apriv->orig_parent = NULL;
- }
-
- l = l->prev;
- }
-
- priv->desktop1 = workspace0;
- priv->desktop2 = workspace1;
-
- 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);
-
- priv->tml_switch_workspace2 = actor_animate (workspace1, CLUTTER_EASE_IN_SINE,
- SWITCH_TIMEOUT,
- "scale-x", 0.0,
- "scale-y", 0.0,
- NULL);
-}
-
-
-/*
- * Minimize effect completion callback; this function restores actor state, and
- * calls the manager callback function.
- */
-static void
-on_minimize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
-{
- /*
- * Must reverse the effect of the effect; must hide it first to ensure
- * that the restoration will not be visible.
- */
- MetaPlugin *plugin = data->plugin;
- ActorPrivate *apriv;
- MetaWindowActor *window_actor = META_WINDOW_ACTOR (data->actor);
-
- apriv = get_actor_private (META_WINDOW_ACTOR (data->actor));
- apriv->tml_minimize = NULL;
-
- clutter_actor_hide (data->actor);
-
- /* 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);
-
- /* Now notify the manager that we are done with this effect */
- meta_plugin_minimize_completed (plugin, window_actor);
-
- g_free (data);
-}
-
-/*
- * Simple minimize handler: it applies a scale effect (which must be reversed on
- * completion).
- */
-static void
-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);
-
-
- type = meta_window_get_window_type (meta_window);
-
- if (!meta_window_get_icon_geometry(meta_window, &icon_geometry))
- {
- icon_geometry.x = 0;
- icon_geometry.y = 0;
- }
-
- if (type == META_WINDOW_NORMAL)
- {
- 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->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);
-}
-
-static void
-on_map_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_map = NULL;
-
- /* Now notify the manager that we are done with this effect */
- meta_plugin_map_completed (plugin, window_actor);
-
- g_free (data);
-}
-
-/*
- * Simple map handler: it applies a scale effect which must be reversed on
- * completion).
- */
-static void
-map (MetaPlugin *plugin, MetaWindowActor *window_actor)
-{
- MetaWindowType type;
- ClutterActor *actor = CLUTTER_ACTOR (window_actor);
- MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor);
-
- type = meta_window_get_window_type (meta_window);
-
- if (type == META_WINDOW_NORMAL)
- {
- EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
- ActorPrivate *apriv = get_actor_private (window_actor);
-
- 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);
-
- 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);
- }
- else
- meta_plugin_map_completed (plugin, window_actor);
-}
-
-/*
- * Destroy effect completion callback; this is a simple effect that requires no
- * further action than notifying the manager that the effect is completed.
- */
-static void
-on_destroy_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
-{
- MetaPlugin *plugin = data->plugin;
- MetaWindowActor *window_actor = META_WINDOW_ACTOR (data->actor);
- ActorPrivate *apriv = get_actor_private (window_actor);
-
- apriv->tml_destroy = NULL;
-
- meta_plugin_destroy_completed (plugin, window_actor);
-}
-
-/*
- * Simple TV-out like effect.
- */
-static void
-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)
- {
- 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);
-
- apriv->tml_destroy = timeline;
- data->plugin = plugin;
- data->actor = actor;
- g_signal_connect (apriv->tml_destroy, "completed",
- G_CALLBACK (on_destroy_effect_complete),
- data);
- }
- else
- meta_plugin_destroy_completed (plugin, window_actor);
-}
-
-/*
- * Tile preview private data accessor
- */
-static void
-free_display_tile_preview (DisplayTilePreview *preview)
-{
-
- if (G_LIKELY (preview != NULL)) {
- clutter_actor_destroy (preview->actor);
- g_free (preview);
- }
-}
-
-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)
- {
- display_tile_preview_data_quark =
- g_quark_from_static_string (DISPLAY_TILE_PREVIEW_DATA_KEY);
- }
-
- preview = g_object_get_qdata (G_OBJECT (display),
- display_tile_preview_data_quark);
- if (!preview)
- {
- preview = g_new0 (DisplayTilePreview, 1);
-
- 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);
- }
-
- 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)
- {
- 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)
- finish_timeline (apriv->tml_destroy);
-}
-
-static const MetaPluginInfo *
-plugin_info (MetaPlugin *plugin)
-{
- MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv;
-
- 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
deleted file mode 100644
index 9dd06814d..000000000
--- a/src/compositor/plugins/meson.build
+++ /dev/null
@@ -1,20 +0,0 @@
-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,
- gsettings_desktop_schemas_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
deleted file mode 100644
index ac4048a98..000000000
--- a/src/compositor/region-utils.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Utilities for region manipulation
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.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
- * that are unsorted or overlap; unioning such a set of rectangles 1-by-1
- * using cairo_region_union_rectangle() produces O(N^2) behavior (if the union
- * adds or removes rectangles in the middle of the region, then it has to
- * move all the rectangles after that.) To avoid this behavior, MetaRegionBuilder
- * creates regions for small groups of rectangles and merges them together in
- * a binary tree.
- *
- * Possible improvement: From a glance at the code, accumulating all the rectangles
- * into a flat array and then calling the (not usefully documented)
- * cairo_region_create_rectangles() would have the same behavior and would be
- * simpler and a bit more efficient.
- */
-
-/* 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
-
-void
-meta_region_builder_init (MetaRegionBuilder *builder)
-{
- int i;
- for (i = 0; i < META_REGION_BUILDER_MAX_LEVELS; i++)
- builder->levels[i] = NULL;
- builder->n_levels = 1;
-}
-
-void
-meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
- int x,
- int y,
- int width,
- int height)
-{
- cairo_rectangle_int_t rect;
- int i;
-
- if (builder->levels[0] == NULL)
- builder->levels[0] = cairo_region_create ();
-
- rect.x = x;
- rect.y = y;
- rect.width = width;
- rect.height = height;
-
- cairo_region_union_rectangle (builder->levels[0], &rect);
- if (cairo_region_num_rectangles (builder->levels[0]) >= MAX_CHUNK_RECTANGLES)
- {
- for (i = 1; i < builder->n_levels + 1; i++)
- {
- if (builder->levels[i] == NULL)
- {
- if (i < META_REGION_BUILDER_MAX_LEVELS)
- {
- builder->levels[i] = builder->levels[i - 1];
- builder->levels[i - 1] = NULL;
- if (i == builder->n_levels)
- builder->n_levels++;
- }
-
- break;
- }
- else
- {
- cairo_region_union (builder->levels[i], builder->levels[i - 1]);
- cairo_region_destroy (builder->levels[i - 1]);
- builder->levels[i - 1] = NULL;
- }
- }
- }
-}
-
-cairo_region_t *
-meta_region_builder_finish (MetaRegionBuilder *builder)
-{
- cairo_region_t *result = NULL;
- int i;
-
- for (i = 0; i < builder->n_levels; i++)
- {
- if (builder->levels[i])
- {
- if (result == NULL)
- result = builder->levels[i];
- else
- {
- cairo_region_union(result, builder->levels[i]);
- cairo_region_destroy (builder->levels[i]);
- }
- }
- }
-
- if (result == NULL)
- result = cairo_region_create ();
-
- return result;
-}
-
-
-/* MetaRegionIterator */
-
-void
-meta_region_iterator_init (MetaRegionIterator *iter,
- cairo_region_t *region)
-{
- iter->region = region;
- iter->i = 0;
- iter->n_rectangles = cairo_region_num_rectangles (region);
- iter->line_start = TRUE;
-
- if (iter->n_rectangles > 1)
- {
- cairo_region_get_rectangle (region, 0, &iter->rectangle);
- cairo_region_get_rectangle (region, 1, &iter->next_rectangle);
-
- iter->line_end = iter->next_rectangle.y != iter->rectangle.y;
- }
- else if (iter->n_rectangles > 0)
- {
- cairo_region_get_rectangle (region, 0, &iter->rectangle);
- iter->line_end = TRUE;
- }
-}
-
-gboolean
-meta_region_iterator_at_end (MetaRegionIterator *iter)
-{
- return iter->i >= iter->n_rectangles;
-}
-
-void
-meta_region_iterator_next (MetaRegionIterator *iter)
-{
- iter->i++;
- iter->rectangle = iter->next_rectangle;
- iter->line_start = iter->line_end;
-
- if (iter->i + 1 < iter->n_rectangles)
- {
- cairo_region_get_rectangle (iter->region, iter->i + 1, &iter->next_rectangle);
- iter->line_end = iter->next_rectangle.y != iter->rectangle.y;
- }
- else
- {
- 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,
- int y,
- int width,
- int height,
- int x_amount,
- int y_amount,
- gboolean flip)
-{
- if (flip)
- meta_region_builder_add_rectangle (builder,
- y - y_amount, x - x_amount,
- height + 2 * y_amount, width + 2 * x_amount);
- else
- meta_region_builder_add_rectangle (builder,
- x - x_amount, y - y_amount,
- width + 2 * x_amount, height + 2 * y_amount);
-}
-
-static cairo_region_t *
-expand_region (cairo_region_t *region,
- int x_amount,
- int y_amount,
- gboolean flip)
-{
- MetaRegionBuilder builder;
- int n;
- int i;
-
- meta_region_builder_init (&builder);
-
- n = cairo_region_num_rectangles (region);
- for (i = 0; i < n; i++)
- {
- cairo_rectangle_int_t rect;
-
- cairo_region_get_rectangle (region, i, &rect);
- add_expanded_rect (&builder,
- rect.x, rect.y, rect.width, rect.height,
- x_amount, y_amount, flip);
- }
-
- return meta_region_builder_finish (&builder);
-}
-
-/* This computes a (clipped version) of the inverse of the region
- * and expands it by the given amount */
-static cairo_region_t *
-expand_region_inverse (cairo_region_t *region,
- int x_amount,
- int y_amount,
- gboolean flip)
-{
- MetaRegionBuilder builder;
- MetaRegionIterator iter;
- cairo_rectangle_int_t extents;
-
- int last_x;
-
- meta_region_builder_init (&builder);
-
- cairo_region_get_extents (region, &extents);
- add_expanded_rect (&builder,
- extents.x, extents.y - 1, extents.width, 1,
- x_amount, y_amount, flip);
- add_expanded_rect (&builder,
- extents.x - 1, extents.y, 1, extents.height,
- x_amount, y_amount, flip);
- add_expanded_rect (&builder,
- extents.x + extents.width, extents.y, 1, extents.height,
- x_amount, y_amount, flip);
- add_expanded_rect (&builder,
- extents.x, extents.y + extents.height, extents.width, 1,
- x_amount, y_amount, flip);
-
- last_x = extents.x;
- for (meta_region_iterator_init (&iter, region);
- !meta_region_iterator_at_end (&iter);
- meta_region_iterator_next (&iter))
- {
- if (iter.rectangle.x > last_x)
- add_expanded_rect (&builder,
- last_x, iter.rectangle.y,
- iter.rectangle.x - last_x, iter.rectangle.height,
- x_amount, y_amount, flip);
-
- if (iter.line_end)
- {
- if (extents.x + extents.width > iter.rectangle.x + iter.rectangle.width)
- add_expanded_rect (&builder,
- iter.rectangle.x + iter.rectangle.width, iter.rectangle.y,
- (extents.x + extents.width) - (iter.rectangle.x + iter.rectangle.width), iter.rectangle.height,
- x_amount, y_amount, flip);
- last_x = extents.x;
- }
- else
- last_x = iter.rectangle.x + iter.rectangle.width;
- }
-
- return meta_region_builder_finish (&builder);
-}
-
-/**
- * meta_make_border_region:
- * @region: a #cairo_region_t
- * @x_amount: distance from the border to extend horizontally
- * @y_amount: distance from the border to extend vertically
- * @flip: if true, the result is computed with x and y interchanged
- *
- * Computes the "border region" of a given region, which is roughly
- * speaking the set of points near the boundary of the region. If we
- * define the operation of growing a region as computing the set of
- * points within a given manhattan distance of the region, then the
- * border is 'grow(region) intersect grow(inverse(region))'.
- *
- * If we create an image by filling the region with a solid color,
- * the border is the region affected by blurring the region.
- *
- * Return value: a new region which is the border of the given region
- */
-cairo_region_t *
-meta_make_border_region (cairo_region_t *region,
- int x_amount,
- int y_amount,
- gboolean flip)
-{
- cairo_region_t *border_region;
- cairo_region_t *inverse_region;
-
- border_region = expand_region (region, x_amount, y_amount, flip);
- inverse_region = expand_region_inverse (region, x_amount, y_amount, flip);
- cairo_region_intersect (border_region, inverse_region);
- cairo_region_destroy (inverse_region);
-
- return border_region;
-}
-
-cairo_region_t *
-meta_region_transform (const 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
deleted file mode 100644
index 298c5540e..000000000
--- a/src/compositor/region-utils.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * Utilities for region manipulation
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __META_REGION_UTILS_H__
-#define __META_REGION_UTILS_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
- * @rectangle: current rectangle
- * @line_start: whether the current rectangle starts a horizontal band
- * @line_end: whether the current rectangle ends a horizontal band
- *
- * cairo_region_t is a yx banded region; sometimes its useful to iterate through
- * such a region treating the start and end of each horizontal band in a distinct
- * fashion.
- *
- * Usage:
- *
- * MetaRegionIterator iter;
- * for (meta_region_iterator_init (&iter, region);
- * !meta_region_iterator_at_end (&iter);
- * meta_region_iterator_next (&iter))
- * {
- * [ Use iter.rectangle, iter.line_start, iter.line_end ]
- * }
- */
-typedef struct _MetaRegionIterator MetaRegionIterator;
-
-struct _MetaRegionIterator {
- cairo_region_t *region;
- cairo_rectangle_int_t rectangle;
- gboolean line_start;
- gboolean line_end;
- int i;
-
- /*< private >*/
- int n_rectangles;
- 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_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 (const 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/bell.c b/src/core/bell.c
deleted file mode 100644
index f0c6f9463..000000000
--- a/src/core/bell.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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:bell
- * @short_description: Ring the bell or flash the screen
- *
- * 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.
- *
- * Visual bells come in at meta_bell_notify(), which checks we are actually
- * in visual mode and calls through to bell_visual_notify(). That
- * 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 focused window
- * 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>.
- *
- * Several of the functions in this file are ifdeffed out entirely if we are
- * found not to have the XKB extension, which is required to do these clever
- * things with bells; some others are entirely no-ops in that case.
- */
-
-#include "config.h"
-
-#include "core/bell.h"
-
-#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
-{
- IS_AUDIBLE_CHANGED,
- LAST_SIGNAL
-};
-
-static guint bell_signals [LAST_SIGNAL] = { 0 };
-
-static void
-prefs_changed_callback (MetaPreference pref,
- gpointer data)
-{
- MetaBell *bell = data;
-
- if (pref == META_PREF_AUDIBLE_BELL)
- {
- g_signal_emit (bell, bell_signals[IS_AUDIBLE_CHANGED], 0,
- meta_prefs_bell_is_audible ());
- }
-}
-
-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 ())
- {
- case G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH:
- bell_flash_fullscreen (display);
- break;
- case G_DESKTOP_VISUAL_BELL_FRAME_FLASH:
- bell_flash_frame (display, window);
- break;
- }
-}
-
-static gboolean
-bell_audible_notify (MetaDisplay *display,
- MetaWindow *window)
-{
- MetaSoundPlayer *player;
-
- player = meta_display_get_sound_player (display);
- meta_sound_player_play_from_theme (player,
- "bell-window-system",
- _("Bell event"),
- NULL);
- return TRUE;
-}
-
-gboolean
-meta_bell_notify (MetaDisplay *display,
- MetaWindow *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);
-
- return TRUE;
-}
diff --git a/src/core/bell.h b/src/core/bell.h
deleted file mode 100644
index f86cbb7c2..000000000
--- a/src/core/bell.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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 "core/display-private.h"
-#include "core/frame.h"
-
-struct _MetaBell
-{
- GObject parent;
-};
-
-#define META_TYPE_BELL (meta_bell_get_type ())
-G_DECLARE_FINAL_TYPE (MetaBell, meta_bell, META, BELL, GObject)
-
-MetaBell * meta_bell_new (MetaDisplay *display);
-
-/**
- * meta_bell_notify:
- * @display: The display the bell event came in on
- * @window: The window the bell event was received on
- *
- * 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.
- */
-gboolean meta_bell_notify (MetaDisplay *display,
- MetaWindow *window);
diff --git a/src/core/boxes-private.h b/src/core/boxes-private.h
deleted file mode 100644
index d39816495..000000000
--- a/src/core/boxes-private.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_BOXES_PRIVATE_H
-#define META_BOXES_PRIVATE_H
-
-#include <glib-object.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 */
-
-typedef enum
-{
- FIXED_DIRECTION_NONE = 0,
- FIXED_DIRECTION_X = 1 << 0,
- 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)) *
- * g_list_length (edge_list)
- */
-#define RECT_LENGTH 27
-#define EDGE_LENGTH 37
-char* meta_rectangle_to_string (const MetaRectangle *rect,
- char *output);
-char* meta_rectangle_region_to_string (GList *region,
- const char *separator_string,
- char *output);
-char* meta_rectangle_edge_to_string (const MetaEdge *edge,
- char *output);
-char* meta_rectangle_edge_list_to_string (
- GList *edge_list,
- const char *separator_string,
- char *output);
-
-/* 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 simplifies the routine a little bit as it
- * 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,
- MetaGravity gravity,
- int new_width,
- int new_height);
-
-/* find a list of rectangles with the property that a window is contained
- * in the given region if and only if it is contained in one of the
- * rectangles in the list.
- *
- * In this case, the region is given by taking basic_rect, removing from
- * it the intersections with all the rectangles in the all_struts list,
- * then expanding all the rectangles in the resulting list by the given
- * amounts on each side.
- *
- * 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);
-
-/* Expand all rectangles in region by the given amount on each side */
-GList* meta_rectangle_expand_region (GList *region,
- const int left_expand,
- const int right_expand,
- const int top_expand,
- const int bottom_expand);
-/* Same as for meta_rectangle_expand_region except that rectangles not at
- * least min_x or min_y in size are not expanded in that direction
- */
-GList* meta_rectangle_expand_region_conditionally (
- GList *region,
- const int left_expand,
- const int right_expand,
- const int top_expand,
- const int bottom_expand,
- const int min_x,
- const int min_y);
-
-/* Expand rect in direction to the size of expand_to, and then clip out any
- * overlapping struts oriented orthogonal 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,
- const MetaDirection direction,
- const GSList *all_struts);
-
-/* Free the list created by
- * meta_rectangle_get_minimal_spanning_set_for_region()
- * or
- * meta_rectangle_find_onscreen_edges ()
- * 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);
-
-/* 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,
- MetaRectangle *rect,
- const MetaRectangle *min_size);
-
-/* 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);
-
-/* 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,
- MetaRectangle *rect);
-
-/* Finds the point on the line connecting (x1,y1) to (x2,y2) which is closest
- * 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,
- double *valx, double *valy);
-
-/***************************************************************************/
-/* */
-/* Switching gears to code for edges instead of just rectangles */
-/* */
-/***************************************************************************/
-
-/* Return whether an edge overlaps or is adjacent to the rectangle in the
- * nonzero-width dimension of the edge.
- */
-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
- * given rectangle list. Returns the result.
- */
-GList* meta_rectangle_remove_intersections_with_boxes_from_edges (
- GList *edges,
- const GSList *rectangles);
-
-/* 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
deleted file mode 100644
index 9a9633e05..000000000
--- a/src/core/boxes.c
+++ /dev/null
@@ -1,2183 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * SECTION:boxes
- * @Title: MetaRectangle
- * @Short_Description: Simple box operations
- */
-
-/*
- * Copyright (C) 2005, 2006 Elijah Newren
- * [meta_rectangle_intersect() is copyright the GTK+ Team according to Havoc,
- * see gdkrectangle.c. As far as Havoc knows, he probably wrote
- * meta_rectangle_equal(), and I'm guessing it's (C) Red Hat. So...]
- * Copyright (C) 1995-2000 GTK+ Team
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#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 g_malloc()/g_free() for consistency.
- */
-
-MetaRectangle *
-meta_rectangle_copy (const MetaRectangle *rect)
-{
- return g_memdup2 (rect, sizeof (MetaRectangle));
-}
-
-void
-meta_rectangle_free (MetaRectangle *rect)
-{
- g_free (rect);
-}
-
-G_DEFINE_BOXED_TYPE (MetaRectangle, meta_rectangle,
- meta_rectangle_copy, meta_rectangle_free);
-
-char*
-meta_rectangle_to_string (const MetaRectangle *rect,
- char *output)
-{
- /* 25 chars: 2 commas, space, plus, trailing \0 + 5 for each digit.
- * Should be more than enough space. Note that of this space, the
- * trailing \0 will be overwritten for all but the last rectangle.
- */
- g_snprintf (output, RECT_LENGTH, "%d,%d +%d,%d",
- rect->x, rect->y, rect->width, rect->height);
-
- return output;
-}
-
-char*
-meta_rectangle_region_to_string (GList *region,
- const char *separator_string,
- char *output)
-{
- /* 27 chars: 2 commas, 2 square brackets, space, plus, trailing \0 + 5
- * for each digit. Should be more than enough space. Note that of this
- * space, the trailing \0 will be overwritten for all but the last
- * rectangle.
- */
- char rect_string[RECT_LENGTH];
-
- GList *tmp = region;
- char *cur = output;
-
- if (region == NULL)
- g_snprintf (output, 10, "(EMPTY)");
-
- while (tmp)
- {
- MetaRectangle *rect = tmp->data;
- g_snprintf (rect_string, RECT_LENGTH, "[%d,%d +%d,%d]",
- rect->x, rect->y, rect->width, rect->height);
- cur = g_stpcpy (cur, rect_string);
- tmp = tmp->next;
- if (tmp)
- cur = g_stpcpy (cur, separator_string);
- }
-
- return output;
-}
-
-char*
-meta_rectangle_edge_to_string (const MetaEdge *edge,
- char *output)
-{
- /* 25 chars: 2 commas, space, plus, trailing \0 + 5 for each digit.
- * Should be more than enough space. Note that of this space, the
- * trailing \0 will be overwritten for all but the last rectangle.
- *
- * Plus 2 for parenthesis, 4 for 2 more numbers, 2 more commas, and
- * 2 more spaces, for a total of 10 more.
- */
- g_snprintf (output, EDGE_LENGTH, "[%d,%d +%d,%d], %2d, %2d",
- edge->rect.x, edge->rect.y, edge->rect.width, edge->rect.height,
- edge->side_type, edge->edge_type);
-
- return output;
-}
-
-char*
-meta_rectangle_edge_list_to_string (GList *edge_list,
- const char *separator_string,
- char *output)
-{
- /* 27 chars: 2 commas, 2 square brackets, space, plus, trailing \0 + 5 for
- * each digit. Should be more than enough space. Note that of this
- * space, the trailing \0 will be overwritten for all but the last
- * rectangle.
- *
- * Plus 2 for parenthesis, 4 for 2 more numbers, 2 more commas, and
- * 2 more spaces, for a total of 10 more.
- */
- char rect_string[EDGE_LENGTH];
-
- char *cur = output;
- GList *tmp = edge_list;
-
- if (edge_list == NULL)
- g_snprintf (output, 10, "(EMPTY)");
-
- while (tmp)
- {
- MetaEdge *edge = tmp->data;
- MetaRectangle *rect = &edge->rect;
- g_snprintf (rect_string, EDGE_LENGTH, "([%d,%d +%d,%d], %2d, %2d)",
- rect->x, rect->y, rect->width, rect->height,
- edge->side_type, edge->edge_type);
- cur = g_stpcpy (cur, rect_string);
- tmp = tmp->next;
- if (tmp)
- cur = g_stpcpy (cur, separator_string);
- }
-
- return output;
-}
-
-MetaRectangle
-meta_rect (int x, int y, int width, int height)
-{
- MetaRectangle temporary;
- temporary.x = x;
- temporary.y = y;
- temporary.width = width;
- temporary.height = height;
-
- return temporary;
-}
-
-int
-meta_rectangle_area (const MetaRectangle *rect)
-{
- g_return_val_if_fail (rect != NULL, 0);
- return rect->width * rect->height;
-}
-
-/**
- * meta_rectangle_intersect:
- * @src1: a #MetaRectangle
- * @src2: another #MetaRectangle
- * @dest: (out caller-allocates): an empty #MetaRectangle, to be filled
- * with the coordinates of the intersection.
- *
- * Returns: TRUE is some intersection exists and is not degenerate, FALSE
- * otherwise.
- */
-gboolean
-meta_rectangle_intersect (const MetaRectangle *src1,
- const MetaRectangle *src2,
- MetaRectangle *dest)
-{
- int dest_x, dest_y;
- int dest_w, dest_h;
- int return_val;
-
- g_return_val_if_fail (src1 != NULL, FALSE);
- g_return_val_if_fail (src2 != NULL, FALSE);
- g_return_val_if_fail (dest != NULL, FALSE);
-
- return_val = FALSE;
-
- dest_x = MAX (src1->x, src2->x);
- dest_y = MAX (src1->y, src2->y);
- dest_w = MIN (src1->x + src1->width, src2->x + src2->width) - dest_x;
- dest_h = MIN (src1->y + src1->height, src2->y + src2->height) - dest_y;
-
- if (dest_w > 0 && dest_h > 0)
- {
- dest->x = dest_x;
- dest->y = dest_y;
- dest->width = dest_w;
- dest->height = dest_h;
- return_val = TRUE;
- }
- else
- {
- dest->width = 0;
- dest->height = 0;
- }
-
- return return_val;
-}
-
-gboolean
-meta_rectangle_equal (const MetaRectangle *src1,
- const MetaRectangle *src2)
-{
- return ((src1->x == src2->x) &&
- (src1->y == src2->y) &&
- (src1->width == src2->width) &&
- (src1->height == src2->height));
-}
-
-/**
- * meta_rectangle_union:
- * @rect1: a #MetaRectangle
- * @rect2: another #MetaRectangle
- * @dest: (out caller-allocates): an empty #MetaRectangle, to be filled
- * with the coordinates of the bounding box.
- */
-void
-meta_rectangle_union (const MetaRectangle *rect1,
- const MetaRectangle *rect2,
- MetaRectangle *dest)
-{
- int dest_x, dest_y;
- int dest_w, dest_h;
-
- dest_x = rect1->x;
- dest_y = rect1->y;
- dest_w = rect1->width;
- dest_h = rect1->height;
-
- if (rect2->x < dest_x)
- {
- dest_w += dest_x - rect2->x;
- dest_x = rect2->x;
- }
- if (rect2->y < dest_y)
- {
- dest_h += dest_y - rect2->y;
- dest_y = rect2->y;
- }
- if (rect2->x + rect2->width > dest_x + dest_w)
- dest_w = rect2->x + rect2->width - dest_x;
- if (rect2->y + rect2->height > dest_y + dest_h)
- dest_h = rect2->y + rect2->height - dest_y;
-
- dest->x = dest_x;
- dest->y = dest_y;
- dest->width = dest_w;
- dest->height = dest_h;
-}
-
-gboolean
-meta_rectangle_overlap (const MetaRectangle *rect1,
- const MetaRectangle *rect2)
-{
- g_return_val_if_fail (rect1 != NULL, FALSE);
- g_return_val_if_fail (rect2 != NULL, FALSE);
-
- return !((rect1->x + rect1->width <= rect2->x) ||
- (rect2->x + rect2->width <= rect1->x) ||
- (rect1->y + rect1->height <= rect2->y) ||
- (rect2->y + rect2->height <= rect1->y));
-}
-
-gboolean
-meta_rectangle_vert_overlap (const MetaRectangle *rect1,
- const MetaRectangle *rect2)
-{
- return (rect1->y < rect2->y + rect2->height &&
- rect2->y < rect1->y + rect1->height);
-}
-
-gboolean
-meta_rectangle_horiz_overlap (const MetaRectangle *rect1,
- const MetaRectangle *rect2)
-{
- return (rect1->x < rect2->x + rect2->width &&
- rect2->x < rect1->x + rect1->width);
-}
-
-gboolean
-meta_rectangle_could_fit_rect (const MetaRectangle *outer_rect,
- const MetaRectangle *inner_rect)
-{
- return (outer_rect->width >= inner_rect->width &&
- outer_rect->height >= inner_rect->height);
-}
-
-gboolean
-meta_rectangle_contains_rect (const MetaRectangle *outer_rect,
- const MetaRectangle *inner_rect)
-{
- return
- inner_rect->x >= outer_rect->x &&
- inner_rect->y >= outer_rect->y &&
- inner_rect->x + inner_rect->width <= outer_rect->x + outer_rect->width &&
- inner_rect->y + inner_rect->height <= outer_rect->y + outer_rect->height;
-}
-
-void
-meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect,
- MetaRectangle *rect,
- MetaGravity gravity,
- int new_width,
- int new_height)
-{
- /* FIXME: I'm too deep into this to know whether the below comment is
- * still clear or not now that I've moved it out of constraints.c.
- * boxes.h has a good comment, but I'm not sure if the below info is also
- * helpful on top of that (or whether it has superfluous info).
- */
-
- /* These formulas may look overly simplistic at first but you can work
- * everything out with a left_frame_with, right_frame_width,
- * 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 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, META_GRAVITY_NORTH_WEST for this function
- * means to just leave the upper left corner of the outer window
- * 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
- * (since frame size doesn't change)--thus making the two
- * equivalent.
- */
-
- /* First, the x direction */
- switch (gravity)
- {
- case META_GRAVITY_NORTH_WEST:
- case META_GRAVITY_WEST:
- case META_GRAVITY_SOUTH_WEST:
- rect->x = old_rect->x;
- break;
-
- 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.
- */
- new_width -= (old_rect->width - new_width) % 2;
- rect->x = old_rect->x + (old_rect->width - new_width)/2;
- break;
-
- 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 META_GRAVITY_STATIC:
- default:
- rect->x = old_rect->x;
- break;
- }
- rect->width = new_width;
-
- /* Next, the y direction */
- switch (gravity)
- {
- case META_GRAVITY_NORTH_WEST:
- case META_GRAVITY_NORTH:
- case META_GRAVITY_NORTH_EAST:
- rect->y = old_rect->y;
- break;
-
- 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.
- */
- new_height -= (old_rect->height - new_height) % 2;
- rect->y = old_rect->y + (old_rect->height - new_height)/2;
- break;
-
- 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 META_GRAVITY_STATIC:
- default:
- rect->y = old_rect->y;
- break;
- }
- rect->height = new_height;
-}
-
-/* Not so simple helper function for get_minimal_spanning_set_for_region() */
-static GList*
-merge_spanning_rects_in_region (GList *region)
-{
- /* NOTE FOR ANY OPTIMIZATION PEOPLE OUT THERE: Please see the
- * documentation of get_minimal_spanning_set_for_region() for performance
- * considerations that also apply to this function.
- */
-
- GList* compare;
- compare = region;
-
- if (region == NULL)
- {
- g_warning ("Region to merge was empty! Either you have a some "
- "pathological STRUT list or there's a bug somewhere!");
- return NULL;
- }
-
- while (compare && compare->next)
- {
- MetaRectangle *a = compare->data;
- GList *other = compare->next;
-
- g_assert (a->width > 0 && a->height > 0);
-
- while (other)
- {
- MetaRectangle *b = other->data;
- GList *delete_me = NULL;
-
- g_assert (b->width > 0 && b->height > 0);
-
- /* If a contains b, just remove b */
- if (meta_rectangle_contains_rect (a, b))
- {
- delete_me = other;
- }
- /* If b contains a, just remove a */
- else if (meta_rectangle_contains_rect (b, a))
- {
- delete_me = compare;
- }
- /* If a and b might be mergeable horizontally */
- else if (a->y == b->y && a->height == b->height)
- {
- /* If a and b overlap */
- if (meta_rectangle_overlap (a, b))
- {
- int new_x = MIN (a->x, b->x);
- a->width = MAX (a->x + a->width, b->x + b->width) - new_x;
- a->x = new_x;
- delete_me = other;
- }
- /* If a and b are adjacent */
- else if (a->x + a->width == b->x || a->x == b->x + b->width)
- {
- int new_x = MIN (a->x, b->x);
- a->width = MAX (a->x + a->width, b->x + b->width) - new_x;
- a->x = new_x;
- delete_me = other;
- }
- }
- /* If a and b might be mergeable vertically */
- else if (a->x == b->x && a->width == b->width)
- {
- /* If a and b overlap */
- if (meta_rectangle_overlap (a, b))
- {
- int new_y = MIN (a->y, b->y);
- a->height = MAX (a->y + a->height, b->y + b->height) - new_y;
- a->y = new_y;
- delete_me = other;
- }
- /* If a and b are adjacent */
- else if (a->y + a->height == b->y || a->y == b->y + b->height)
- {
- int new_y = MIN (a->y, b->y);
- a->height = MAX (a->y + a->height, b->y + b->height) - new_y;
- a->y = new_y;
- delete_me = other;
- }
- }
-
- other = other->next;
-
- /* Delete any rectangle in the list that is no longer wanted */
- if (delete_me != NULL)
- {
- /* Deleting the rect we compare others to is a little tricker */
- if (compare == delete_me)
- {
- compare = compare->next;
- other = compare->next;
- a = compare->data;
- }
-
- /* Okay, we can free it now */
- g_free (delete_me->data);
- region = g_list_delete_link (region, delete_me);
- }
-
- }
-
- compare = compare->next;
- }
-
- return region;
-}
-
-/* Simple helper function for get_minimal_spanning_set_for_region()... */
-static gint
-compare_rect_areas (gconstpointer a, gconstpointer b)
-{
- const MetaRectangle *a_rect = (gconstpointer) a;
- const MetaRectangle *b_rect = (gconstpointer) b;
-
- int a_area = meta_rectangle_area (a_rect);
- int b_area = meta_rectangle_area (b_rect);
-
- return b_area - a_area; /* positive ret value denotes b > a, ... */
-}
-
-/* ... and another helper for get_minimal_spanning_set_for_region()... */
-static gboolean
-check_strut_align (MetaStrut *strut, const MetaRectangle *rect)
-{
- /* Check whether @strut actually aligns to the side of @rect it claims */
- switch (strut->side)
- {
- case META_SIDE_TOP:
- return BOX_TOP (strut->rect) <= BOX_TOP (*rect);
- case META_SIDE_BOTTOM:
- return BOX_BOTTOM (strut->rect) >= BOX_BOTTOM (*rect);
- case META_SIDE_LEFT:
- return BOX_LEFT (strut->rect) <= BOX_LEFT (*rect);
- case META_SIDE_RIGHT:
- return BOX_RIGHT (strut->rect) >= BOX_RIGHT (*rect);
- default:
- return FALSE;
- }
-}
-
-/**
- * meta_rectangle_get_minimal_spanning_set_for_region:
- * @basic_rect: Input rectangle
- * @all_struts: (element-type Meta.Rectangle): List of struts
- *
- * This function is trying to find a "minimal spanning set (of rectangles)"
- * for a given region.
- *
- * The region is given by taking basic_rect, then removing the areas
- * covered by all the rectangles in the all_struts list, and then expanding
- * the resulting region by the given number of pixels in each direction.
- *
- * A "minimal spanning set (of rectangles)" is the best name I could come
- * up with for the concept I had in mind. Basically, for a given region, I
- * want a set of rectangles with the property that a window is contained in
- * the region if and only if it is contained within at least one of the
- * rectangles.
- *
- * Returns: (transfer full) (element-type Meta.Rectangle): Minimal spanning set
- */
-GList*
-meta_rectangle_get_minimal_spanning_set_for_region (
- const MetaRectangle *basic_rect,
- const GSList *all_struts)
-{
- /* NOTE FOR OPTIMIZERS: This function *might* be somewhat slow,
- * especially due to the call to merge_spanning_rects_in_region() (which
- * is O(n^2) where n is the size of the list generated in this function).
- * This is made more onerous due to the fact that it involves a fair
- * number of memory allocation and deallocation calls. However, n is 1
- * for default installations of Gnome (because partial struts aren't used
- * by default and only partial struts increase the size of the spanning
- * set generated). With one partial strut, n will be 2 or 3. With 2
- * partial struts, n will probably be 4 or 5. So, n probably isn't large
- * enough to make this worth bothering. Further, it is only called from
- * workspace.c:ensure_work_areas_validated (at least as of the time of
- * writing this comment), which in turn should only be called if the
- * strut list changes or the screen or monitor size changes. If it ever
- * does show up on profiles (most likely because people start using
- * ridiculously huge numbers of partial struts), possible optimizations
- * include:
- *
- * (1) rewrite merge_spanning_rects_in_region() to be O(n) or O(nlogn).
- * I'm not totally sure it's possible, but with a couple copies of
- * the list and sorting them appropriately, I believe it might be.
- * (2) only call merge_spanning_rects_in_region() with a subset of the
- * full list of rectangles. I believe from some of my preliminary
- * debugging and thinking about it that it is possible to figure out
- * apriori groups of rectangles which are only merge candidates with
- * each other. (See testboxes.c:get_screen_region() when which==2
- * and track the steps of this function carefully to see what gave
- * me the hint that this might work)
- * (3) figure out how to avoid merge_spanning_rects_in_region(). I think
- * it might be possible to modify this function to make that
- * possible, and I spent just a little while thinking about it, but n
- * wasn't large enough to convince me to care yet.
- * (4) Some of the stuff Rob mentioned at http://mail.gnome.org/archives\
- * /metacity-devel-list/2005-November/msg00028.html. (Sorry for the
- * URL splitting.)
- */
-
- GList *ret;
- GList *tmp_list;
- const GSList *strut_iter;
- MetaRectangle *temp_rect;
-
- /* The algorithm is basically as follows:
- * Initialize rectangle_set to basic_rect
- * Foreach strut:
- * Foreach rectangle in rectangle_set:
- * - Split the rectangle into new rectangles that don't overlap the
- * strut (but which are as big as possible otherwise)
- * - Remove the old (pre-split) rectangle from the rectangle_set,
- * and replace it with the new rectangles generated from the
- * splitting
- */
-
- temp_rect = g_new (MetaRectangle, 1);
- *temp_rect = *basic_rect;
- ret = g_list_prepend (NULL, temp_rect);
-
- for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next)
- {
- GList *rect_iter;
- MetaStrut *strut = (MetaStrut*)strut_iter->data;
- MetaRectangle *strut_rect = &strut->rect;
-
- tmp_list = ret;
- ret = NULL;
- rect_iter = tmp_list;
- while (rect_iter)
- {
- MetaRectangle *rect = (MetaRectangle*) rect_iter->data;
-
- if (!meta_rectangle_overlap (strut_rect, rect) ||
- !check_strut_align (strut, basic_rect))
- ret = g_list_prepend (ret, rect);
- else
- {
- /* If there is area in rect left of strut */
- if (BOX_LEFT (*rect) < BOX_LEFT (*strut_rect))
- {
- temp_rect = g_new (MetaRectangle, 1);
- *temp_rect = *rect;
- temp_rect->width = BOX_LEFT (*strut_rect) - BOX_LEFT (*rect);
- ret = g_list_prepend (ret, temp_rect);
- }
- /* If there is area in rect right of strut */
- if (BOX_RIGHT (*rect) > BOX_RIGHT (*strut_rect))
- {
- int new_x;
- temp_rect = g_new (MetaRectangle, 1);
- *temp_rect = *rect;
- new_x = BOX_RIGHT (*strut_rect);
- temp_rect->width = BOX_RIGHT(*rect) - new_x;
- temp_rect->x = new_x;
- ret = g_list_prepend (ret, temp_rect);
- }
- /* If there is area in rect above strut */
- if (BOX_TOP (*rect) < BOX_TOP (*strut_rect))
- {
- temp_rect = g_new (MetaRectangle, 1);
- *temp_rect = *rect;
- temp_rect->height = BOX_TOP (*strut_rect) - BOX_TOP (*rect);
- ret = g_list_prepend (ret, temp_rect);
- }
- /* If there is area in rect below strut */
- if (BOX_BOTTOM (*rect) > BOX_BOTTOM (*strut_rect))
- {
- int new_y;
- temp_rect = g_new (MetaRectangle, 1);
- *temp_rect = *rect;
- new_y = BOX_BOTTOM (*strut_rect);
- temp_rect->height = BOX_BOTTOM (*rect) - new_y;
- temp_rect->y = new_y;
- ret = g_list_prepend (ret, temp_rect);
- }
- g_free (rect);
- }
- rect_iter = rect_iter->next;
- }
- g_list_free (tmp_list);
- }
-
- /* Sort by maximal area, just because I feel like it... */
- ret = g_list_sort (ret, compare_rect_areas);
-
- /* Merge rectangles if possible so that the list really is minimal */
- ret = merge_spanning_rects_in_region (ret);
-
- return ret;
-}
-
-/**
- * meta_rectangle_expand_region: (skip)
- *
- */
-GList*
-meta_rectangle_expand_region (GList *region,
- const int left_expand,
- const int right_expand,
- const int top_expand,
- const int bottom_expand)
-{
- return meta_rectangle_expand_region_conditionally (region,
- left_expand,
- right_expand,
- top_expand,
- bottom_expand,
- 0,
- 0);
-}
-
-/**
- * meta_rectangle_expand_region_conditionally: (skip)
- *
- */
-GList*
-meta_rectangle_expand_region_conditionally (GList *region,
- const int left_expand,
- const int right_expand,
- const int top_expand,
- const int bottom_expand,
- const int min_x,
- const int min_y)
-{
- GList *tmp_list = region;
- while (tmp_list)
- {
- MetaRectangle *rect = (MetaRectangle*) tmp_list->data;
- if (rect->width >= min_x)
- {
- rect->x -= left_expand;
- rect->width += (left_expand + right_expand);
- }
- if (rect->height >= min_y)
- {
- rect->y -= top_expand;
- rect->height += (top_expand + bottom_expand);
- }
- tmp_list = tmp_list->next;
- }
-
- return region;
-}
-
-void
-meta_rectangle_expand_to_avoiding_struts (MetaRectangle *rect,
- const MetaRectangle *expand_to,
- const MetaDirection direction,
- const GSList *all_struts)
-{
- const GSList *strut_iter;
-
- /* If someone wants this function to handle more fine-grained
- * direction expanding in the future (e.g. only left, or fully
- * horizontal plus upward), feel free. But I'm hard-coding for both
- * horizontal directions (exclusive-)or both vertical directions.
- */
- g_assert ((direction == META_DIRECTION_HORIZONTAL) ^
- (direction == META_DIRECTION_VERTICAL ));
-
- if (direction == META_DIRECTION_HORIZONTAL)
- {
- rect->x = expand_to->x;
- rect->width = expand_to->width;
- }
- else
- {
- rect->y = expand_to->y;
- rect->height = expand_to->height;
- }
-
-
- /* Run over all struts */
- for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next)
- {
- MetaStrut *strut = (MetaStrut*) strut_iter->data;
-
- /* Skip struts that don't overlap */
- if (!meta_rectangle_overlap (&strut->rect, rect))
- continue;
-
- if (direction == META_DIRECTION_HORIZONTAL)
- {
- if (strut->side == META_SIDE_LEFT)
- {
- int offset = BOX_RIGHT(strut->rect) - BOX_LEFT(*rect);
- rect->x += offset;
- rect->width -= offset;
- }
- else if (strut->side == META_SIDE_RIGHT)
- {
- int offset = BOX_RIGHT (*rect) - BOX_LEFT(strut->rect);
- rect->width -= offset;
- }
- /* else ignore the strut */
- }
- else /* direction == META_DIRECTION_VERTICAL */
- {
- if (strut->side == META_SIDE_TOP)
- {
- int offset = BOX_BOTTOM(strut->rect) - BOX_TOP(*rect);
- rect->y += offset;
- rect->height -= offset;
- }
- else if (strut->side == META_SIDE_BOTTOM)
- {
- int offset = BOX_BOTTOM(*rect) - BOX_TOP(strut->rect);
- rect->height -= offset;
- }
- /* else ignore the strut */
- }
- } /* end loop over struts */
-} /* end meta_rectangle_expand_to_avoiding_struts */
-
-void
-meta_rectangle_free_list_and_elements (GList *filled_list)
-{
- g_list_free_full (filled_list, g_free);
-}
-
-gboolean
-meta_rectangle_could_fit_in_region (const GList *spanning_rects,
- const MetaRectangle *rect)
-{
- const GList *temp;
- gboolean could_fit;
-
- temp = spanning_rects;
- could_fit = FALSE;
- while (!could_fit && temp != NULL)
- {
- could_fit = could_fit || meta_rectangle_could_fit_rect (temp->data, rect);
- temp = temp->next;
- }
-
- return could_fit;
-}
-
-gboolean
-meta_rectangle_contained_in_region (const GList *spanning_rects,
- const MetaRectangle *rect)
-{
- const GList *temp;
- gboolean contained;
-
- temp = spanning_rects;
- contained = FALSE;
- while (!contained && temp != NULL)
- {
- contained = contained || meta_rectangle_contains_rect (temp->data, rect);
- temp = temp->next;
- }
-
- return contained;
-}
-
-gboolean
-meta_rectangle_overlaps_with_region (const GList *spanning_rects,
- const MetaRectangle *rect)
-{
- const GList *temp;
- gboolean overlaps;
-
- temp = spanning_rects;
- overlaps = FALSE;
- while (!overlaps && temp != NULL)
- {
- overlaps = overlaps || meta_rectangle_overlap (temp->data, rect);
- temp = temp->next;
- }
-
- return overlaps;
-}
-
-
-void
-meta_rectangle_clamp_to_fit_into_region (const GList *spanning_rects,
- FixedDirections fixed_directions,
- MetaRectangle *rect,
- const MetaRectangle *min_size)
-{
- const GList *temp;
- const MetaRectangle *best_rect = NULL;
- int best_overlap = 0;
-
- /* First, find best rectangle from spanning_rects to which we can clamp
- * rect to fit into.
- */
- for (temp = spanning_rects; temp; temp = temp->next)
- {
- MetaRectangle *compare_rect = temp->data;
- int maximal_overlap_amount_for_compare;
-
- /* If x is fixed and the entire width of rect doesn't fit in compare,
- * skip this rectangle.
- */
- if ((fixed_directions & FIXED_DIRECTION_X) &&
- (compare_rect->x > rect->x ||
- compare_rect->x + compare_rect->width < rect->x + rect->width))
- continue;
-
- /* If y is fixed and the entire height of rect doesn't fit in compare,
- * skip this rectangle.
- */
- if ((fixed_directions & FIXED_DIRECTION_Y) &&
- (compare_rect->y > rect->y ||
- compare_rect->y + compare_rect->height < rect->y + rect->height))
- continue;
-
- /* If compare can't hold the min_size window, skip this rectangle. */
- if (compare_rect->width < min_size->width ||
- compare_rect->height < min_size->height)
- continue;
-
- /* Determine maximal overlap amount */
- maximal_overlap_amount_for_compare =
- MIN (rect->width, compare_rect->width) *
- MIN (rect->height, compare_rect->height);
-
- /* See if this is the best rect so far */
- if (maximal_overlap_amount_for_compare > best_overlap)
- {
- best_rect = compare_rect;
- best_overlap = maximal_overlap_amount_for_compare;
- }
- }
-
- /* Clamp rect appropriately */
- if (best_rect == NULL)
- {
- g_warning ("No rect whose size to clamp to found!");
-
- /* If it doesn't fit, at least make it no bigger than it has to be */
- if (!(fixed_directions & FIXED_DIRECTION_X))
- rect->width = min_size->width;
- if (!(fixed_directions & FIXED_DIRECTION_Y))
- rect->height = min_size->height;
- }
- else
- {
- rect->width = MIN (rect->width, best_rect->width);
- rect->height = MIN (rect->height, best_rect->height);
- }
-}
-
-void
-meta_rectangle_clip_to_region (const GList *spanning_rects,
- FixedDirections fixed_directions,
- MetaRectangle *rect)
-{
- const GList *temp;
- const MetaRectangle *best_rect = NULL;
- int best_overlap = 0;
-
- /* First, find best rectangle from spanning_rects to which we will clip
- * rect into.
- */
- for (temp = spanning_rects; temp; temp = temp->next)
- {
- MetaRectangle *compare_rect = temp->data;
- MetaRectangle overlap;
- int maximal_overlap_amount_for_compare;
-
- /* If x is fixed and the entire width of rect doesn't fit in compare,
- * skip the rectangle.
- */
- if ((fixed_directions & FIXED_DIRECTION_X) &&
- (compare_rect->x > rect->x ||
- compare_rect->x + compare_rect->width < rect->x + rect->width))
- continue;
-
- /* If y is fixed and the entire height of rect doesn't fit in compare,
- * skip the rectangle.
- */
- if ((fixed_directions & FIXED_DIRECTION_Y) &&
- (compare_rect->y > rect->y ||
- compare_rect->y + compare_rect->height < rect->y + rect->height))
- continue;
-
- /* Determine maximal overlap amount */
- meta_rectangle_intersect (rect, compare_rect, &overlap);
- maximal_overlap_amount_for_compare = meta_rectangle_area (&overlap);
-
- /* See if this is the best rect so far */
- if (maximal_overlap_amount_for_compare > best_overlap)
- {
- best_rect = compare_rect;
- best_overlap = maximal_overlap_amount_for_compare;
- }
- }
-
- /* Clip rect appropriately */
- if (best_rect == NULL)
- {
- g_warning ("No rect to clip to found!");
- }
- else
- {
- /* Extra precaution with checking fixed direction shouldn't be needed
- * due to logic above, but it shouldn't hurt either.
- */
- if (!(fixed_directions & FIXED_DIRECTION_X))
- {
- /* Find the new left and right */
- int new_x = MAX (rect->x, best_rect->x);
- rect->width = MIN ((rect->x + rect->width) - new_x,
- (best_rect->x + best_rect->width) - new_x);
- rect->x = new_x;
- }
-
- /* Extra precaution with checking fixed direction shouldn't be needed
- * due to logic above, but it shouldn't hurt either.
- */
- if (!(fixed_directions & FIXED_DIRECTION_Y))
- {
- /* Clip the top, if needed */
- int new_y = MAX (rect->y, best_rect->y);
- rect->height = MIN ((rect->y + rect->height) - new_y,
- (best_rect->y + best_rect->height) - new_y);
- rect->y = new_y;
- }
- }
-}
-
-void
-meta_rectangle_shove_into_region (const GList *spanning_rects,
- FixedDirections fixed_directions,
- MetaRectangle *rect)
-{
- const GList *temp;
- const MetaRectangle *best_rect = NULL;
- int best_overlap = 0;
- int shortest_distance = G_MAXINT;
-
- /* First, find best rectangle from spanning_rects to which we will shove
- * rect into.
- */
-
- for (temp = spanning_rects; temp; temp = temp->next)
- {
- MetaRectangle *compare_rect = temp->data;
- int maximal_overlap_amount_for_compare;
- int dist_to_compare;
-
- /* If x is fixed and the entire width of rect doesn't fit in compare,
- * skip this rectangle.
- */
- if ((fixed_directions & FIXED_DIRECTION_X) &&
- (compare_rect->x > rect->x ||
- compare_rect->x + compare_rect->width < rect->x + rect->width))
- continue;
-
- /* If y is fixed and the entire height of rect doesn't fit in compare,
- * skip this rectangle.
- */
- if ((fixed_directions & FIXED_DIRECTION_Y) &&
- (compare_rect->y > rect->y ||
- compare_rect->y + compare_rect->height < rect->y + rect->height))
- continue;
-
- /* Determine maximal overlap amount between rect & compare_rect */
- maximal_overlap_amount_for_compare =
- MIN (rect->width, compare_rect->width) *
- MIN (rect->height, compare_rect->height);
-
- /* Determine distance necessary to put rect into compare_rect */
- dist_to_compare = 0;
- if (compare_rect->x > rect->x)
- dist_to_compare += compare_rect->x - rect->x;
- if (compare_rect->x + compare_rect->width < rect->x + rect->width)
- dist_to_compare += (rect->x + rect->width) -
- (compare_rect->x + compare_rect->width);
- if (compare_rect->y > rect->y)
- dist_to_compare += compare_rect->y - rect->y;
- if (compare_rect->y + compare_rect->height < rect->y + rect->height)
- dist_to_compare += (rect->y + rect->height) -
- (compare_rect->y + compare_rect->height);
-
- /* See if this is the best rect so far */
- if ((maximal_overlap_amount_for_compare > best_overlap) ||
- (maximal_overlap_amount_for_compare == best_overlap &&
- dist_to_compare < shortest_distance))
- {
- best_rect = compare_rect;
- best_overlap = maximal_overlap_amount_for_compare;
- shortest_distance = dist_to_compare;
- }
- }
-
- /* Shove rect appropriately */
- if (best_rect == NULL)
- {
- g_warning ("No rect to shove into found!");
- }
- else
- {
- /* Extra precaution with checking fixed direction shouldn't be needed
- * due to logic above, but it shouldn't hurt either.
- */
- if (!(fixed_directions & FIXED_DIRECTION_X))
- {
- /* Shove to the right, if needed */
- if (best_rect->x > rect->x)
- rect->x = best_rect->x;
-
- /* Shove to the left, if needed */
- if (best_rect->x + best_rect->width < rect->x + rect->width)
- rect->x = (best_rect->x + best_rect->width) - rect->width;
- }
-
- /* Extra precaution with checking fixed direction shouldn't be needed
- * due to logic above, but it shouldn't hurt either.
- */
- if (!(fixed_directions & FIXED_DIRECTION_Y))
- {
- /* Shove down, if needed */
- if (best_rect->y > rect->y)
- rect->y = best_rect->y;
-
- /* Shove up, if needed */
- if (best_rect->y + best_rect->height < rect->y + rect->height)
- rect->y = (best_rect->y + best_rect->height) - rect->height;
- }
- }
-}
-
-void
-meta_rectangle_find_linepoint_closest_to_point (double x1,
- double y1,
- double x2,
- double y2,
- double px,
- double py,
- double *valx,
- double *valy)
-{
- /* I'll use the shorthand rx, ry for the return values, valx & valy.
- * Now, we need (rx,ry) to be on the line between (x1,y1) and (x2,y2).
- * For that to happen, we first need the slope of the line from (x1,y1)
- * to (rx,ry) must match the slope of (x1,y1) to (x2,y2), i.e.:
- * (ry-y1) (y2-y1)
- * ------- = -------
- * (rx-x1) (x2-x1)
- * If x1==x2, though, this gives divide by zero errors, so we want to
- * rewrite the equation by multiplying both sides by (rx-x1)*(x2-x1):
- * (ry-y1)(x2-x1) = (y2-y1)(rx-x1)
- * This is a valid requirement even when x1==x2 (when x1==x2, this latter
- * equation will basically just mean that rx must be equal to both x1 and
- * x2)
- *
- * The other requirement that we have is that the line from (rx,ry) to
- * (px,py) must be perpendicular to the line from (x1,y1) to (x2,y2). So
- * we just need to get a vector in the direction of each line, take the
- * dot product of the two, and ensure that the result is 0:
- * (rx-px)*(x2-x1) + (ry-py)*(y2-y1) = 0.
- *
- * This gives us two equations and two unknowns:
- *
- * (ry-y1)(x2-x1) = (y2-y1)(rx-x1)
- * (rx-px)*(x2-x1) + (ry-py)*(y2-y1) = 0.
- *
- * This particular pair of equations is always solvable so long as
- * (x1,y1) and (x2,y2) are not the same point (and note that anyone who
- * calls this function that way is braindead because it means that they
- * really didn't specify a line after all). However, the caller should
- * be careful to avoid making (x1,y1) and (x2,y2) too close (e.g. like
- * 10^{-8} apart in each coordinate), otherwise roundoff error could
- * cause issues. Solving these equations by hand (or using Maple(TM) or
- * Mathematica(TM) or whatever) results in slightly messy expressions,
- * but that's all the below few lines do.
- */
-
- double diffx, diffy, den;
- diffx = x2 - x1;
- diffy = y2 - y1;
- den = diffx * diffx + diffy * diffy;
-
- *valx = (py * diffx * diffy + px * diffx * diffx +
- y2 * x1 * diffy - y1 * x2 * diffy) / den;
- *valy = (px * diffx * diffy + py * diffy * diffy +
- x2 * y1 * diffx - x1 * y2 * diffx) / den;
-}
-
-/***************************************************************************/
-/* */
-/* Switching gears to code for edges instead of just rectangles */
-/* */
-/***************************************************************************/
-
-gboolean
-meta_rectangle_edge_aligns (const MetaRectangle *rect, const MetaEdge *edge)
-{
- /* The reason for the usage of <= below instead of < is because we are
- * interested in in-the-way-or-adject'ness. So, a left (i.e. vertical
- * edge) occupying y positions 0-9 (which has a y of 0 and a height of
- * 10) and a rectangle with top at y=10 would be considered to "align" by
- * this function.
- */
- switch (edge->side_type)
- {
- case META_SIDE_LEFT:
- case META_SIDE_RIGHT:
- return BOX_TOP (*rect) <= BOX_BOTTOM (edge->rect) &&
- BOX_TOP (edge->rect) <= BOX_BOTTOM (*rect);
- case META_SIDE_TOP:
- case META_SIDE_BOTTOM:
- return BOX_LEFT (*rect) <= BOX_RIGHT (edge->rect) &&
- BOX_LEFT (edge->rect) <= BOX_RIGHT (*rect);
- default:
- g_assert_not_reached ();
- return FALSE;
- }
-}
-
-static GList*
-get_rect_minus_overlap (const GList *rect_in_list,
- MetaRectangle *overlap)
-{
- MetaRectangle *temp;
- MetaRectangle *rect = rect_in_list->data;
- GList *ret = NULL;
-
- if (BOX_LEFT (*rect) < BOX_LEFT (*overlap))
- {
- temp = g_new (MetaRectangle, 1);
- *temp = *rect;
- temp->width = BOX_LEFT (*overlap) - BOX_LEFT (*rect);
- ret = g_list_prepend (ret, temp);
- }
- if (BOX_RIGHT (*rect) > BOX_RIGHT (*overlap))
- {
- temp = g_new (MetaRectangle, 1);
- *temp = *rect;
- temp->x = BOX_RIGHT (*overlap);
- temp->width = BOX_RIGHT (*rect) - BOX_RIGHT (*overlap);
- ret = g_list_prepend (ret, temp);
- }
- if (BOX_TOP (*rect) < BOX_TOP (*overlap))
- {
- temp = g_new (MetaRectangle, 1);
- temp->x = overlap->x;
- temp->width = overlap->width;
- temp->y = BOX_TOP (*rect);
- temp->height = BOX_TOP (*overlap) - BOX_TOP (*rect);
- ret = g_list_prepend (ret, temp);
- }
- if (BOX_BOTTOM (*rect) > BOX_BOTTOM (*overlap))
- {
- temp = g_new (MetaRectangle, 1);
- temp->x = overlap->x;
- temp->width = overlap->width;
- temp->y = BOX_BOTTOM (*overlap);
- temp->height = BOX_BOTTOM (*rect) - BOX_BOTTOM (*overlap);
- ret = g_list_prepend (ret, temp);
- }
-
- return ret;
-}
-
-static GList*
-replace_rect_with_list (GList *old_element,
- GList *new_list)
-{
- GList *ret;
- g_assert (old_element != NULL);
-
- if (!new_list)
- {
- /* If there is no new list, just remove the old_element */
- ret = g_list_remove_link (old_element, old_element);
- }
- else
- {
- /* Fix up the prev and next pointers everywhere */
- ret = new_list;
- if (old_element->prev)
- {
- old_element->prev->next = new_list;
- new_list->prev = old_element->prev;
- }
- if (old_element->next)
- {
- GList *tmp = g_list_last (new_list);
- old_element->next->prev = tmp;
- tmp->next = old_element->next;
- }
- }
-
- /* Free the old_element and return the appropriate "next" point */
- g_free (old_element->data);
- g_list_free_1 (old_element);
- return ret;
-}
-
-/* Make a copy of the strut list, make sure that copy only contains parts
- * of the old_struts that intersect with the region rect, and then do some
- * magic to make all the new struts disjoint (okay, we we break up struts
- * that aren't disjoint in a way that the overlapping part is only included
- * once, so it's not really magic...).
- */
-static GList*
-get_disjoint_strut_rect_list_in_region (const GSList *old_struts,
- const MetaRectangle *region)
-{
- GList *strut_rects;
- GList *tmp;
-
- /* First, copy the list */
- strut_rects = NULL;
- while (old_struts)
- {
- MetaRectangle *cur = &((MetaStrut*)old_struts->data)->rect;
- MetaRectangle *copy = g_new (MetaRectangle, 1);
- *copy = *cur;
- if (meta_rectangle_intersect (copy, region, copy))
- strut_rects = g_list_prepend (strut_rects, copy);
- else
- g_free (copy);
-
- old_struts = old_struts->next;
- }
-
- /* Now, loop over the list and check for intersections, fixing things up
- * where they do intersect.
- */
- tmp = strut_rects;
- while (tmp)
- {
- GList *compare;
-
- MetaRectangle *cur = tmp->data;
-
- compare = tmp->next;
- while (compare)
- {
- MetaRectangle *comp = compare->data;
- MetaRectangle overlap;
-
- if (meta_rectangle_intersect (cur, comp, &overlap))
- {
- /* Get a list of rectangles for each strut that don't overlap
- * the intersection region.
- */
- GList *cur_leftover = get_rect_minus_overlap (tmp, &overlap);
- GList *comp_leftover = get_rect_minus_overlap (compare, &overlap);
-
- /* Add the intersection region to cur_leftover */
- MetaRectangle *overlap_allocated = g_new (MetaRectangle, 1);
- *overlap_allocated = overlap;
- cur_leftover = g_list_prepend (cur_leftover, overlap_allocated);
-
- /* Fix up tmp, compare, and cur -- maybe struts too */
- if (strut_rects == tmp)
- {
- strut_rects = replace_rect_with_list (tmp, cur_leftover);
- tmp = strut_rects;
- }
- else
- tmp = replace_rect_with_list (tmp, cur_leftover);
- compare = replace_rect_with_list (compare, comp_leftover);
-
- if (compare == NULL)
- break;
-
- cur = tmp->data;
- }
-
- compare = compare->next;
- }
-
- tmp = tmp->next;
- }
-
- return strut_rects;
-}
-
-gint
-meta_rectangle_edge_cmp_ignore_type (gconstpointer a, gconstpointer b)
-{
- const MetaEdge *a_edge_rect = (gconstpointer) a;
- const MetaEdge *b_edge_rect = (gconstpointer) b;
- int a_compare, b_compare;
-
- /* Edges must be both vertical or both horizontal, or it doesn't make
- * sense to compare them.
- */
- g_assert ((a_edge_rect->rect.width == 0 && b_edge_rect->rect.width == 0) ||
- (a_edge_rect->rect.height == 0 && b_edge_rect->rect.height == 0));
-
- a_compare = b_compare = 0; /* gcc-3.4.2 sucks at figuring initialized'ness */
-
- if (a_edge_rect->side_type == META_SIDE_LEFT ||
- a_edge_rect->side_type == META_SIDE_RIGHT)
- {
- a_compare = a_edge_rect->rect.x;
- b_compare = b_edge_rect->rect.x;
- if (a_compare == b_compare)
- {
- a_compare = a_edge_rect->rect.y;
- b_compare = b_edge_rect->rect.y;
- }
- }
- else if (a_edge_rect->side_type == META_SIDE_TOP ||
- a_edge_rect->side_type == META_SIDE_BOTTOM)
- {
- a_compare = a_edge_rect->rect.y;
- b_compare = b_edge_rect->rect.y;
- if (a_compare == b_compare)
- {
- a_compare = a_edge_rect->rect.x;
- b_compare = b_edge_rect->rect.x;
- }
- }
- else
- g_assert ("Some idiot wanted to sort sides of different types.");
-
- return a_compare - b_compare; /* positive value denotes a > b ... */
-}
-
-/* To make things easily testable, provide a nice way of sorting edges */
-gint
-meta_rectangle_edge_cmp (gconstpointer a, gconstpointer b)
-{
- const MetaEdge *a_edge_rect = (gconstpointer) a;
- const MetaEdge *b_edge_rect = (gconstpointer) b;
-
- int a_compare, b_compare;
-
- a_compare = a_edge_rect->side_type;
- b_compare = b_edge_rect->side_type;
-
- if (a_compare == b_compare)
- return meta_rectangle_edge_cmp_ignore_type (a, b);
-
- return a_compare - b_compare; /* positive value denotes a > b ... */
-}
-
-/* Determine whether two given edges overlap */
-static gboolean
-edges_overlap (const MetaEdge *edge1,
- const MetaEdge *edge2)
-{
- if (edge1->rect.width == 0 && edge2->rect.width == 0)
- {
- return meta_rectangle_vert_overlap (&edge1->rect, &edge2->rect) &&
- edge1->rect.x == edge2->rect.x;
- }
- else if (edge1->rect.height == 0 && edge2->rect.height == 0)
- {
- return meta_rectangle_horiz_overlap (&edge1->rect, &edge2->rect) &&
- edge1->rect.y == edge2->rect.y;
- }
- else
- {
- return FALSE;
- }
-}
-
-static gboolean
-rectangle_and_edge_intersection (const MetaRectangle *rect,
- const MetaEdge *edge,
- MetaEdge *overlap,
- int *handle_type)
-{
- const MetaRectangle *rect2 = &edge->rect;
- MetaRectangle *result = &overlap->rect;
- gboolean intersect = TRUE;
-
- /* We don't know how to set these, so set them to invalid values */
- overlap->edge_type = -1;
- overlap->side_type = -1;
-
- /* Figure out what the intersection is */
- result->x = MAX (rect->x, rect2->x);
- result->y = MAX (rect->y, rect2->y);
- result->width = MIN (BOX_RIGHT (*rect), BOX_RIGHT (*rect2)) - result->x;
- result->height = MIN (BOX_BOTTOM (*rect), BOX_BOTTOM (*rect2)) - result->y;
-
- /* Find out if the intersection is empty; have to do it this way since
- * edges have a thickness of 0
- */
- if ((result->width < 0 || result->height < 0) ||
- (result->width == 0 && result->height == 0))
- {
- result->width = 0;
- result->height = 0;
- intersect = FALSE;
- }
- else
- {
- /* Need to figure out the handle_type, a somewhat weird quantity:
- * 0 - overlap is in middle of rect
- * -1 - overlap is at the side of rect, and is on the opposite side
- * of rect than the edge->side_type side
- * 1 - overlap is at the side of rect, and the side of rect it is
- * on is the edge->side_type side
- */
- switch (edge->side_type)
- {
- case META_SIDE_LEFT:
- if (result->x == rect->x)
- *handle_type = 1;
- else if (result->x == BOX_RIGHT (*rect))
- *handle_type = -1;
- else
- *handle_type = 0;
- break;
- case META_SIDE_RIGHT:
- if (result->x == rect->x)
- *handle_type = -1;
- else if (result->x == BOX_RIGHT (*rect))
- *handle_type = 1;
- else
- *handle_type = 0;
- break;
- case META_SIDE_TOP:
- if (result->y == rect->y)
- *handle_type = 1;
- else if (result->y == BOX_BOTTOM (*rect))
- *handle_type = -1;
- else
- *handle_type = 0;
- break;
- case META_SIDE_BOTTOM:
- if (result->y == rect->y)
- *handle_type = -1;
- else if (result->y == BOX_BOTTOM (*rect))
- *handle_type = 1;
- else
- *handle_type = 0;
- break;
- default:
- g_assert_not_reached ();
- }
- }
- return intersect;
-}
-
-/* Add all edges of the given rect to cur_edges and return the result. If
- * rect_is_internal is false, the side types are switched (LEFT<->RIGHT and
- * TOP<->BOTTOM).
- */
-static GList*
-add_edges (GList *cur_edges,
- const MetaRectangle *rect,
- gboolean rect_is_internal)
-{
- MetaEdge *temp_edge;
- int i;
-
- for (i=0; i<4; i++)
- {
- temp_edge = g_new (MetaEdge, 1);
- temp_edge->rect = *rect;
- switch (i)
- {
- case 0:
- temp_edge->side_type =
- rect_is_internal ? META_SIDE_LEFT : META_SIDE_RIGHT;
- temp_edge->rect.width = 0;
- break;
- case 1:
- temp_edge->side_type =
- rect_is_internal ? META_SIDE_RIGHT : META_SIDE_LEFT;
- temp_edge->rect.x += temp_edge->rect.width;
- temp_edge->rect.width = 0;
- break;
- case 2:
- temp_edge->side_type =
- rect_is_internal ? META_SIDE_TOP : META_SIDE_BOTTOM;
- temp_edge->rect.height = 0;
- break;
- case 3:
- temp_edge->side_type =
- rect_is_internal ? META_SIDE_BOTTOM : META_SIDE_TOP;
- temp_edge->rect.y += temp_edge->rect.height;
- temp_edge->rect.height = 0;
- break;
- }
- temp_edge->edge_type = META_EDGE_SCREEN;
- cur_edges = g_list_prepend (cur_edges, temp_edge);
- }
-
- return cur_edges;
-}
-
-/* Remove any part of old_edge that intersects remove and add any resulting
- * edges to cur_list. Return cur_list when finished.
- */
-static GList*
-split_edge (GList *cur_list,
- const MetaEdge *old_edge,
- const MetaEdge *remove)
-{
- MetaEdge *temp_edge;
- switch (old_edge->side_type)
- {
- case META_SIDE_LEFT:
- case META_SIDE_RIGHT:
- g_assert (meta_rectangle_vert_overlap (&old_edge->rect, &remove->rect));
- if (BOX_TOP (old_edge->rect) < BOX_TOP (remove->rect))
- {
- temp_edge = g_new (MetaEdge, 1);
- *temp_edge = *old_edge;
- temp_edge->rect.height = BOX_TOP (remove->rect)
- - BOX_TOP (old_edge->rect);
- cur_list = g_list_prepend (cur_list, temp_edge);
- }
- if (BOX_BOTTOM (old_edge->rect) > BOX_BOTTOM (remove->rect))
- {
- temp_edge = g_new (MetaEdge, 1);
- *temp_edge = *old_edge;
- temp_edge->rect.y = BOX_BOTTOM (remove->rect);
- temp_edge->rect.height = BOX_BOTTOM (old_edge->rect)
- - BOX_BOTTOM (remove->rect);
- cur_list = g_list_prepend (cur_list, temp_edge);
- }
- break;
- case META_SIDE_TOP:
- case META_SIDE_BOTTOM:
- g_assert (meta_rectangle_horiz_overlap (&old_edge->rect, &remove->rect));
- if (BOX_LEFT (old_edge->rect) < BOX_LEFT (remove->rect))
- {
- temp_edge = g_new (MetaEdge, 1);
- *temp_edge = *old_edge;
- temp_edge->rect.width = BOX_LEFT (remove->rect)
- - BOX_LEFT (old_edge->rect);
- cur_list = g_list_prepend (cur_list, temp_edge);
- }
- if (BOX_RIGHT (old_edge->rect) > BOX_RIGHT (remove->rect))
- {
- temp_edge = g_new (MetaEdge, 1);
- *temp_edge = *old_edge;
- temp_edge->rect.x = BOX_RIGHT (remove->rect);
- temp_edge->rect.width = BOX_RIGHT (old_edge->rect)
- - BOX_RIGHT (remove->rect);
- cur_list = g_list_prepend (cur_list, temp_edge);
- }
- break;
- default:
- g_assert_not_reached ();
- }
-
- return cur_list;
-}
-
-/* Split up edge and remove preliminary edges from strut_edges depending on
- * if and how rect and edge intersect.
- */
-static void
-fix_up_edges (MetaRectangle *rect, MetaEdge *edge,
- GList **strut_edges, GList **edge_splits,
- gboolean *edge_needs_removal)
-{
- MetaEdge overlap;
- int handle_type;
-
- if (!rectangle_and_edge_intersection (rect, edge, &overlap, &handle_type))
- return;
-
- if (handle_type == 0 || handle_type == 1)
- {
- /* Put the result of removing overlap from edge into edge_splits */
- *edge_splits = split_edge (*edge_splits, edge, &overlap);
- *edge_needs_removal = TRUE;
- }
-
- if (handle_type == -1 || handle_type == 1)
- {
- /* Remove the overlap from strut_edges */
- /* First, loop over the edges of the strut */
- GList *tmp = *strut_edges;
- while (tmp)
- {
- MetaEdge *cur = tmp->data;
- /* If this is the edge that overlaps, then we need to split it */
- if (edges_overlap (cur, &overlap))
- {
- GList *delete_me = tmp;
-
- /* Split this edge into some new ones */
- *strut_edges = split_edge (*strut_edges, cur, &overlap);
-
- /* Delete the old one */
- tmp = tmp->next;
- g_free (cur);
- *strut_edges = g_list_delete_link (*strut_edges, delete_me);
- }
- else
- tmp = tmp->next;
- }
- }
-}
-
-/**
- * meta_rectangle_remove_intersections_with_boxes_from_edges: (skip)
- *
- * This function removes intersections of edges with the rectangles from the
- * list of edges.
- */
-GList*
-meta_rectangle_remove_intersections_with_boxes_from_edges (
- GList *edges,
- const GSList *rectangles)
-{
- const GSList *rect_iter;
- const int opposing = 1;
-
- /* Now remove all intersections of rectangles with the edge list */
- rect_iter = rectangles;
- while (rect_iter)
- {
- MetaRectangle *rect = rect_iter->data;
- GList *edge_iter = edges;
- while (edge_iter)
- {
- MetaEdge *edge = edge_iter->data;
- MetaEdge overlap;
- int handle;
- gboolean edge_iter_advanced = FALSE;
-
- /* If this edge overlaps with this rect... */
- if (rectangle_and_edge_intersection (rect, edge, &overlap, &handle))
- {
-
- /* "Intersections" where the edges touch but are opposite
- * sides (e.g. a left edge against the right edge) should not
- * be split. Note that the comments in
- * rectangle_and_edge_intersection() say that opposing edges
- * occur when handle is -1, BUT you need to remember that we
- * treat the left side of a window as a right edge because
- * it's what the right side of the window being moved should
- * be-resisted-by/snap-to. So opposing is really 1. Anyway,
- * we just keep track of it in the opposing constant set up
- * above and if handle isn't equal to that, then we know the
- * edge should be split.
- */
- if (handle != opposing)
- {
- /* Keep track of this edge so we can delete it below */
- GList *delete_me = edge_iter;
- edge_iter = edge_iter->next;
- edge_iter_advanced = TRUE;
-
- /* Split the edge and add the result to beginning of edges */
- edges = split_edge (edges, edge, &overlap);
-
- /* Now free the edge... */
- g_free (edge);
- edges = g_list_delete_link (edges, delete_me);
- }
- }
-
- if (!edge_iter_advanced)
- edge_iter = edge_iter->next;
- }
-
- rect_iter = rect_iter->next;
- }
-
- return edges;
-}
-
-/**
- * meta_rectangle_find_onscreen_edges: (skip)
- *
- * This function is trying to find all the edges of an onscreen region.
- */
-GList*
-meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect,
- const GSList *all_struts)
-{
- GList *ret;
- GList *fixed_strut_rects;
- GList *edge_iter;
- const GList *strut_rect_iter;
-
- /* The algorithm is basically as follows:
- * Make sure the struts are disjoint
- * Initialize the edge_set to the edges of basic_rect
- * Foreach strut:
- * Put together a preliminary new edge from the edges of the strut
- * Foreach edge in edge_set:
- * - Split the edge if it is partially contained inside the strut
- * - If the edge matches an edge of the strut (i.e. a strut just
- * against the edge of the screen or a not-next-to-edge-of-screen
- * strut adjacent to another), then both the edge from the
- * edge_set and the preliminary edge for the strut will need to
- * be split
- * Add any remaining "preliminary" strut edges to the edge_set
- */
-
- /* Make sure the struts are disjoint */
- fixed_strut_rects =
- get_disjoint_strut_rect_list_in_region (all_struts, basic_rect);
-
- /* Start off the list with the edges of basic_rect */
- ret = add_edges (NULL, basic_rect, TRUE);
-
- strut_rect_iter = fixed_strut_rects;
- while (strut_rect_iter)
- {
- MetaRectangle *strut_rect = (MetaRectangle*) strut_rect_iter->data;
-
- /* Get the new possible edges we may need to add from the strut */
- GList *new_strut_edges = add_edges (NULL, strut_rect, FALSE);
-
- edge_iter = ret;
- while (edge_iter)
- {
- MetaEdge *cur_edge = edge_iter->data;
- GList *splits_of_cur_edge = NULL;
- gboolean edge_needs_removal = FALSE;
-
- fix_up_edges (strut_rect, cur_edge,
- &new_strut_edges, &splits_of_cur_edge,
- &edge_needs_removal);
-
- if (edge_needs_removal)
- {
- /* Delete the old edge */
- GList *delete_me = edge_iter;
- edge_iter = edge_iter->next;
- g_free (cur_edge);
- ret = g_list_delete_link (ret, delete_me);
-
- /* Add the new split parts of the edge */
- ret = g_list_concat (splits_of_cur_edge, ret);
- }
- else
- {
- edge_iter = edge_iter->next;
- }
-
- /* edge_iter was already advanced above */
- }
-
- ret = g_list_concat (new_strut_edges, ret);
- strut_rect_iter = strut_rect_iter->next;
- }
-
- /* Sort the list */
- ret = g_list_sort (ret, meta_rectangle_edge_cmp);
-
- /* Free the fixed struts list */
- meta_rectangle_free_list_and_elements (fixed_strut_rects);
-
- return ret;
-}
-
-/**
- * meta_rectangle_find_nonintersected_monitor_edges: (skip)
- *
- */
-GList*
-meta_rectangle_find_nonintersected_monitor_edges (
- const GList *monitor_rects,
- const GSList *all_struts)
-{
- /* This function cannot easily be merged with
- * meta_rectangle_find_onscreen_edges() because real screen edges
- * and strut edges both are of the type "there ain't anything
- * immediately on the other side"; monitor edges are different.
- */
- GList *ret;
- const GList *cur;
- GSList *temp_rects;
-
- /* Initialize the return list to be empty */
- ret = NULL;
-
- /* start of ret with all the edges of monitors that are adjacent to
- * another monitor.
- */
- cur = monitor_rects;
- while (cur)
- {
- MetaRectangle *cur_rect = cur->data;
- const GList *compare = monitor_rects;
- while (compare)
- {
- MetaRectangle *compare_rect = compare->data;
-
- /* Check if cur might be horizontally adjacent to compare */
- if (meta_rectangle_vert_overlap(cur_rect, compare_rect))
- {
- MetaSide side_type;
- int y = MAX (cur_rect->y, compare_rect->y);
- int height = MIN (BOX_BOTTOM (*cur_rect) - y,
- BOX_BOTTOM (*compare_rect) - y);
- int width = 0;
- int x;
-
- if (BOX_LEFT (*cur_rect) == BOX_RIGHT (*compare_rect))
- {
- /* compare_rect is to the left of cur_rect */
- x = BOX_LEFT (*cur_rect);
- side_type = META_SIDE_LEFT;
- }
- else if (BOX_RIGHT (*cur_rect) == BOX_LEFT (*compare_rect))
- {
- /* compare_rect is to the right of cur_rect */
- x = BOX_RIGHT (*cur_rect);
- side_type = META_SIDE_RIGHT;
- }
- else
- /* These rectangles aren't adjacent after all */
- x = INT_MIN;
-
- /* If the rectangles really are adjacent */
- if (x != INT_MIN)
- {
- /* We need a left edge for the monitor on the right, and
- * a right edge for the monitor on the left. Just fill
- * up the edges and stick 'em on the list.
- */
- MetaEdge *new_edge = g_new (MetaEdge, 1);
-
- new_edge->rect = meta_rect (x, y, width, height);
- new_edge->side_type = side_type;
- new_edge->edge_type = META_EDGE_MONITOR;
-
- ret = g_list_prepend (ret, new_edge);
- }
- }
-
- /* Check if cur might be vertically adjacent to compare */
- if (meta_rectangle_horiz_overlap(cur_rect, compare_rect))
- {
- MetaSide side_type;
- int x = MAX (cur_rect->x, compare_rect->x);
- int width = MIN (BOX_RIGHT (*cur_rect) - x,
- BOX_RIGHT (*compare_rect) - x);
- int height = 0;
- int y;
-
- if (BOX_TOP (*cur_rect) == BOX_BOTTOM (*compare_rect))
- {
- /* compare_rect is to the top of cur_rect */
- y = BOX_TOP (*cur_rect);
- side_type = META_SIDE_TOP;
- }
- else if (BOX_BOTTOM (*cur_rect) == BOX_TOP (*compare_rect))
- {
- /* compare_rect is to the bottom of cur_rect */
- y = BOX_BOTTOM (*cur_rect);
- side_type = META_SIDE_BOTTOM;
- }
- else
- /* These rectangles aren't adjacent after all */
- y = INT_MIN;
-
- /* If the rectangles really are adjacent */
- if (y != INT_MIN)
- {
- /* We need a top edge for the monitor on the bottom, and
- * a bottom edge for the monitor on the top. Just fill
- * up the edges and stick 'em on the list.
- */
- MetaEdge *new_edge = g_new (MetaEdge, 1);
-
- new_edge->rect = meta_rect (x, y, width, height);
- new_edge->side_type = side_type;
- new_edge->edge_type = META_EDGE_MONITOR;
-
- ret = g_list_prepend (ret, new_edge);
- }
- }
-
- compare = compare->next;
- }
- cur = cur->next;
- }
-
- temp_rects = NULL;
- for (; all_struts; all_struts = all_struts->next)
- temp_rects = g_slist_prepend (temp_rects,
- &((MetaStrut*)all_struts->data)->rect);
- ret = meta_rectangle_remove_intersections_with_boxes_from_edges (ret,
- temp_rects);
- g_slist_free (temp_rects);
-
- /* Sort the list */
- ret = g_list_sort (ret, meta_rectangle_edge_cmp);
-
- 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
deleted file mode 100644
index 4b1d95338..000000000
--- a/src/core/constraints.c
+++ /dev/null
@@ -1,1878 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Mutter size/position constraints */
-
-/*
- * Copyright (C) 2002, 2003 Red Hat, Inc.
- * Copyright (C) 2003, 2004 Rob Adams
- * 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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/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
- // understanding this file can be shown by the steps needed to add a new
- // constraint, which are:
- // 1) Add a new entry in the ConstraintPriority enum; higher values
- // have higher priority
- // 2) Write a new function following the format of the example below,
- // "constrain_whatever".
- // 3) Add your function to the all_constraints and all_constraint_names
- // arrays (the latter of which is for debugging purposes)
- //
- // An example constraint function, constrain_whatever:
- //
- // /* constrain_whatever does the following:
- // * Quits (returning true) if priority is higher than PRIORITY_WHATEVER
- // * If check_only is TRUE
- // * Returns whether the constraint is satisfied or not
- // * otherwise
- // * Enforces the constraint
- // * Note that the value of PRIORITY_WHATEVER is centralized with the
- // * priorities of other constraints in the definition of ConstrainPriority
- // * for easier maintenance and shuffling of priorities.
- // */
- // static gboolean
- // constrain_whatever (MetaWindow *window,
- // ConstraintInfo *info,
- // ConstraintPriority priority,
- // gboolean check_only)
- // {
- // if (priority > PRIORITY_WHATEVER)
- // return TRUE;
- //
- // /* Determine whether constraint applies; note that if the constraint
- // * cannot possibly be satisfied, constraint_applies should be set to
- // * false. If we don't do this, all constraints with a lesser priority
- // * will be dropped along with this one, and we'd rather apply as many as
- // * possible.
- // */
- // if (!constraint_applies)
- // return TRUE;
- //
- // /* Determine whether constraint is already satisfied; if we're only
- // * checking the status of whether the constraint is satisfied, we end
- // * here.
- // */
- // if (check_only || constraint_already_satisfied)
- // return constraint_already_satisfied;
- //
- // /* Enforce constraints */
- // return TRUE; /* Note that we exited early if check_only is FALSE; also,
- // * we know we can return TRUE here because we exited early
- // * if the constraint could not be satisfied; not that the
- // * return value is heeded in this case...
- // */
- // }
-#endif
-
-typedef enum
-{
- PRIORITY_MINIMUM = 0, /* Dummy value used for loop start = min(all priorities) */
- PRIORITY_ASPECT_RATIO = 0,
- PRIORITY_ENTIRELY_VISIBLE_ON_SINGLE_MONITOR = 0,
- PRIORITY_ENTIRELY_VISIBLE_ON_WORKAREA = 1,
- PRIORITY_SIZE_HINTS_INCREMENTS = 1,
- PRIORITY_MAXIMIZATION = 2,
- PRIORITY_TILING = 2,
- PRIORITY_FULLSCREEN = 2,
- 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;
-
-typedef enum
-{
- ACTION_MOVE,
- ACTION_RESIZE,
- ACTION_MOVE_AND_RESIZE
-} ActionType;
-
-typedef struct
-{
- MetaRectangle orig;
- MetaRectangle current;
- MetaRectangle temporary;
- int rel_x;
- int rel_y;
- ActionType action_type;
- gboolean is_user_action;
-
- /* I know that these two things probably look similar at first, but they
- * have much different uses. See doc/how-constraints-works.txt for for
- * explanation of the differences and similarity between resize_gravity
- * and fixed_directions
- */
- MetaGravity resize_gravity;
- FixedDirections fixed_directions;
-
- /* work_area_monitor - current monitor region minus struts
- * entire_monitor - current monitor, including strut regions
- */
- MetaRectangle work_area_monitor;
- MetaRectangle entire_monitor;
-
- /* Spanning rectangles for the non-covered (by struts) region of the
- * screen and also for just the current monitor
- */
- 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,
- gboolean check_only);
-static gboolean constrain_maximization (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_tiling (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_fullscreen (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_size_increments (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_size_limits (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_aspect_ratio (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_to_single_monitor (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_fully_onscreen (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_titlebar_visible (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-static gboolean constrain_partially_onscreen (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-
-static void setup_constraint_info (ConstraintInfo *info,
- MetaWindow *window,
- MetaMoveResizeFlags flags,
- MetaGravity resize_gravity,
- const MetaRectangle *orig,
- MetaRectangle *new);
-static void place_window_if_needed (MetaWindow *window,
- ConstraintInfo *info);
-static void update_onscreen_requirements (MetaWindow *window,
- ConstraintInfo *info);
-
-typedef gboolean (* ConstraintFunc) (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only);
-
-typedef struct {
- ConstraintFunc func;
- const char* name;
-} 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"},
- {constrain_fullscreen, "constrain_fullscreen"},
- {constrain_size_increments, "constrain_size_increments"},
- {constrain_size_limits, "constrain_size_limits"},
- {constrain_aspect_ratio, "constrain_aspect_ratio"},
- {constrain_to_single_monitor, "constrain_to_single_monitor"},
- {constrain_fully_onscreen, "constrain_fully_onscreen"},
- {constrain_titlebar_visible, "constrain_titlebar_visible"},
- {constrain_partially_onscreen, "constrain_partially_onscreen"},
- {NULL, NULL}
-};
-
-static gboolean
-do_all_constraints (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- const Constraint *constraint;
- gboolean satisfied;
-
- constraint = &all_constraints[0];
- satisfied = TRUE;
- while (constraint->func != NULL)
- {
- satisfied = satisfied &&
- (*constraint->func) (window, info, priority, check_only);
-
- if (!check_only)
- {
- /* Log how the constraint modified the position */
- meta_topic (META_DEBUG_GEOMETRY,
- "info->current is %d,%d +%d,%d after %s",
- info->current.x, info->current.y,
- info->current.width, info->current.height,
- constraint->name);
- }
- else if (!satisfied)
- {
- /* Log which constraint was not satisfied */
- meta_topic (META_DEBUG_GEOMETRY,
- "constraint %s not satisfied.",
- constraint->name);
- return FALSE;
- }
- ++constraint;
- }
-
- return TRUE;
-}
-
-void
-meta_window_constrain (MetaWindow *window,
- MetaMoveResizeFlags flags,
- MetaGravity resize_gravity,
- const MetaRectangle *orig,
- MetaRectangle *new,
- MetaRectangle *temporary,
- int *rel_x,
- int *rel_y)
-{
- ConstraintInfo info;
- ConstraintPriority priority = PRIORITY_MINIMUM;
- gboolean satisfied = FALSE;
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Constraining %s in move from %d,%d %dx%d to %d,%d %dx%d",
- window->desc,
- orig->x, orig->y, orig->width, orig->height,
- new->x, new->y, new->width, new->height);
-
- setup_constraint_info (&info,
- window,
- flags,
- resize_gravity,
- orig,
- new);
- place_window_if_needed (window, &info);
-
- while (!satisfied && priority <= PRIORITY_MAXIMUM) {
- gboolean check_only = TRUE;
-
- /* Individually enforce all the high-enough priority constraints */
- do_all_constraints (window, &info, priority, !check_only);
-
- /* Check if all high-enough priority constraints are simultaneously
- * satisfied
- */
- satisfied = do_all_constraints (window, &info, priority, check_only);
-
- /* Drop the least important constraints if we can't satisfy them all */
- priority++;
- }
-
- /* 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);
-}
-
-static void
-setup_constraint_info (ConstraintInfo *info,
- MetaWindow *window,
- MetaMoveResizeFlags flags,
- MetaGravity resize_gravity,
- const MetaRectangle *orig,
- MetaRectangle *new)
-{
- 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;
-
- if (info->current.width < 1)
- info->current.width = 1;
- if (info->current.height < 1)
- info->current.height = 1;
-
- if (flags & META_MOVE_RESIZE_MOVE_ACTION && flags & META_MOVE_RESIZE_RESIZE_ACTION)
- info->action_type = ACTION_MOVE_AND_RESIZE;
- else if (flags & META_MOVE_RESIZE_RESIZE_ACTION)
- info->action_type = ACTION_RESIZE;
- 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()).");
-
- info->is_user_action = (flags & META_MOVE_RESIZE_USER_ACTION);
-
- info->resize_gravity = resize_gravity;
-
- /* FIXME: fixed_directions might be more sane if we (a) made it
- * depend on the grab_op type instead of current amount of movement
- * (thus implying that it only has effect when user_action is true,
- * and (b) ignored it for aspect ratio windows -- at least in those
- * cases where both directions do actually change size.
- */
- info->fixed_directions = FIXED_DIRECTION_NONE;
- /* If x directions don't change but either y direction does */
- if ( orig->x == new->x && orig->x + orig->width == new->x + new->width &&
- (orig->y != new->y || orig->y + orig->height != new->y + new->height))
- {
- info->fixed_directions = FIXED_DIRECTION_X;
- }
- /* If y directions don't change but either x direction does */
- if ( orig->y == new->y && orig->y + orig->height == new->y + new->height &&
- (orig->x != new->x || orig->x + orig->width != new->x + new->width ))
- {
- info->fixed_directions = FIXED_DIRECTION_Y;
- }
- /* The point of fixed directions is just that "move to nearest valid
- * position" is sometimes a poorer choice than "move to nearest
- * valid position but only change this coordinate" for windows the
- * user is explicitly moving. This isn't ever true for things that
- * aren't explicit user interaction, though, so just clear it out.
- */
- if (!info->is_user_action)
- info->fixed_directions = FIXED_DIRECTION_NONE;
-
- 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 && meta_window_has_fullscreen_monitors (window))
- {
- 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
- {
- info->entire_monitor = logical_monitor->rect;
- if (window->fullscreen)
- meta_window_adjust_fullscreen_monitor_rect (window, &info->entire_monitor);
- }
-
- 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, logical_monitor);
-
- /* Log all this information for debugging */
- meta_topic (META_DEBUG_GEOMETRY,
- "Setting up constraint info:\n"
- " orig: %d,%d +%d,%d\n"
- " new : %d,%d +%d,%d\n"
- " action_type : %s\n"
- " is_user_action : %s\n"
- " resize_gravity : %s\n"
- " fixed_directions: %s\n"
- " work_area_monitor: %d,%d +%d,%d\n"
- " entire_monitor : %d,%d +%d,%d",
- info->orig.x, info->orig.y, info->orig.width, info->orig.height,
- info->current.x, info->current.y,
- info->current.width, info->current.height,
- (info->action_type == ACTION_MOVE) ? "Move" :
- (info->action_type == ACTION_RESIZE) ? "Resize" :
- (info->action_type == ACTION_MOVE_AND_RESIZE) ? "Move&Resize" :
- "Freakin' Invalid Stupid",
- (info->is_user_action) ? "true" : "false",
- meta_gravity_to_string (info->resize_gravity),
- (info->fixed_directions == FIXED_DIRECTION_NONE) ? "None" :
- (info->fixed_directions == FIXED_DIRECTION_X) ? "X fixed" :
- (info->fixed_directions == FIXED_DIRECTION_Y) ? "Y fixed" :
- "Freakin' Invalid Stupid",
- info->work_area_monitor.x, info->work_area_monitor.y,
- info->work_area_monitor.width,
- info->work_area_monitor.height,
- info->entire_monitor.x, info->entire_monitor.y,
- 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)
-{
- gboolean did_placement;
-
- /* Do placement if any, so we go ahead and apply position
- * constraints in a move-only context. Don't place
- * maximized/minimized/fullscreen windows until they are
- * unmaximized, unminimized and unfullscreened.
- */
- did_placement = FALSE;
- if (!window->placed &&
- window->calc_placement &&
- !(window->maximized_horizontally ||
- window->maximized_vertically) &&
- !window->minimized &&
- !window->fullscreen)
- {
- MetaBackend *backend = meta_get_backend ();
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- MetaRectangle orig_rect;
- MetaRectangle placed_rect;
- MetaWorkspace *cur_workspace;
- MetaLogicalMonitor *logical_monitor;
-
- placed_rect = (MetaRectangle) {
- .x = window->rect.x,
- .y = window->rect.y,
- .width = info->current.width,
- .height = info->current.height
- };
-
- 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
- */
- 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, logical_monitor);
-
- info->current.x = placed_rect.x;
- info->current.y = placed_rect.y;
-
- /* Since we just barely placed the window, there's no reason to
- * consider any of the directions fixed.
- */
- info->fixed_directions = FIXED_DIRECTION_NONE;
- }
-
- if (window->placed || did_placement)
- {
- if (window->maximize_horizontally_after_placement ||
- window->maximize_vertically_after_placement)
- {
- /* define a sane saved_rect so that the user can unmaximize to
- * something reasonable.
- */
- if (info->current.width >= info->work_area_monitor.width)
- {
- info->current.width = .75 * info->work_area_monitor.width;
- info->current.x = info->work_area_monitor.x +
- .125 * info->work_area_monitor.width;
- }
- if (info->current.height >= info->work_area_monitor.height)
- {
- info->current.height = .75 * info->work_area_monitor.height;
- info->current.y = info->work_area_monitor.y +
- .083 * info->work_area_monitor.height;
- }
-
- /* idle_move_resize() uses the unconstrained_rect, so make sure it
- * uses the placed coordinates (bug #556696).
- */
- window->unconstrained_rect = info->current;
-
- if (window->maximize_horizontally_after_placement ||
- window->maximize_vertically_after_placement)
- meta_window_maximize_internal (window,
- (window->maximize_horizontally_after_placement ?
- META_MAXIMIZE_HORIZONTAL : 0 ) |
- (window->maximize_vertically_after_placement ?
- META_MAXIMIZE_VERTICAL : 0), &info->current);
-
- window->maximize_horizontally_after_placement = FALSE;
- window->maximize_vertically_after_placement = FALSE;
- }
- if (window->minimize_after_placement)
- {
- meta_window_minimize (window);
- window->minimize_after_placement = FALSE;
- }
- }
-}
-
-static void
-update_onscreen_requirements (MetaWindow *window,
- ConstraintInfo *info)
-{
- gboolean old;
-
- /* We only apply the various onscreen requirements to normal windows */
- if (window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK)
- return;
-
- /* We don't want to update the requirements for fullscreen windows;
- * fullscreen windows are specially handled anyway, and it updating
- * the requirements when windows enter fullscreen mode mess up the
- * handling of the window when it leaves that mode (especially when
- * the application sends a bunch of configurerequest events). See
- * #353699.
- */
- if (window->fullscreen)
- return;
-
- /* USABILITY NOTE: Naturally, I only want the require_fully_onscreen,
- * require_on_single_monitor, and require_titlebar_visible flags to
- * *become false* due to user interactions (which is allowed since
- * certain constraints are ignored for user interactions regardless of
- * the setting of these flags). However, whether to make these flags
- * *become true* due to just an application interaction is a little
- * trickier. It's possible that users may find not doing that strange
- * since two application interactions that resize in opposite ways don't
- * necessarily end up cancelling--but it may also be strange for the user
- * to have an application resize the window so that it's onscreen, the
- * user forgets about it, and then later the app is able to resize itself
- * off the screen. Anyway, for now, I think the latter is the more
- * problematic case but this may need to be revisited.
- */
-
- /* Update whether we want future constraint runs to require the
- * window to be on fully onscreen.
- */
- old = window->require_fully_onscreen;
- window->require_fully_onscreen =
- meta_rectangle_contained_in_region (info->usable_screen_region,
- &info->current);
- if (old != window->require_fully_onscreen)
- meta_topic (META_DEBUG_GEOMETRY,
- "require_fully_onscreen for %s toggled to %s",
- window->desc,
- window->require_fully_onscreen ? "TRUE" : "FALSE");
-
- /* Update whether we want future constraint runs to require the
- * window to be on a single monitor.
- */
- old = window->require_on_single_monitor;
- window->require_on_single_monitor =
- meta_rectangle_contained_in_region (info->usable_monitor_region,
- &info->current);
- if (old != window->require_on_single_monitor)
- meta_topic (META_DEBUG_GEOMETRY,
- "require_on_single_monitor for %s toggled to %s",
- window->desc,
- window->require_on_single_monitor ? "TRUE" : "FALSE");
-
- /* Update whether we want future constraint runs to require the
- * titlebar to be visible.
- */
- 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",
- window->desc,
- window->require_titlebar_visible ? "TRUE" : "FALSE");
- }
-}
-
-static inline void
-get_size_limits (MetaWindow *window,
- MetaRectangle *min_size,
- MetaRectangle *max_size)
-{
- /* We pack the results into MetaRectangle structs just for convenience; 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;
-
- 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)
- {
- placement_rule->anchor &= ~META_PLACEMENT_ANCHOR_RIGHT;
- placement_rule->anchor |= META_PLACEMENT_ANCHOR_LEFT;
- }
-
- 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, &current_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, &current_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
- {
- 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
- {
- 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
-constrain_modal_dialog (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- int x, y;
- MetaWindow *parent = meta_window_get_transient_for (window);
- MetaRectangle child_rect, parent_rect;
- gboolean constraint_already_satisfied;
-
- if (!parent ||
- !meta_window_is_attached_dialog (window) ||
- meta_window_get_placement_rule (window))
- return TRUE;
-
- /* 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);
-
- if (check_only || constraint_already_satisfied)
- return constraint_already_satisfied;
-
- info->current.y = y;
- info->current.x = x;
- /* The calculated position above may need adjustment to make sure the
- * dialog does not end up partially off-screen */
- return do_screen_and_monitor_relative_constraints (window,
- info->usable_screen_region,
- info,
- check_only);
-}
-
-static gboolean
-constrain_maximization (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
- MetaRectangle target_size;
- MetaRectangle min_size, max_size;
- gboolean hminbad, vminbad;
- gboolean horiz_equal, vert_equal;
- gboolean constraint_already_satisfied;
-
- if (priority > PRIORITY_MAXIMIZATION)
- return TRUE;
-
- /* Determine whether constraint applies; exit if it doesn't */
- if ((!window->maximized_horizontally && !window->maximized_vertically) ||
- META_WINDOW_TILED_SIDE_BY_SIDE (window))
- return TRUE;
-
- /* Calculate target_size = maximized size of (window + frame) */
- 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;
- }
- else
- {
- /* Amount of maximization possible in a single direction depends
- * on which struts could occlude the window given its current
- * position. For example, a vertical partial strut on the right
- * is only relevant for a horizontally maximized window when the
- * window is at a vertical position where it could be occluded
- * by that partial strut.
- */
- MetaDirection direction;
- GSList *active_workspace_struts;
-
- if (window->maximized_horizontally)
- direction = META_DIRECTION_HORIZONTAL;
- else
- direction = META_DIRECTION_VERTICAL;
- active_workspace_struts = workspace_manager->active_workspace->all_struts;
-
- target_size = info->current;
- meta_rectangle_expand_to_avoiding_struts (&target_size,
- &info->entire_monitor,
- direction,
- active_workspace_struts);
- }
-
- /* Check min size constraints; max size constraints are ignored for maximized
- * windows, as per bug 327543.
- */
- 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)
- return TRUE;
-
- /* Determine whether constraint is already satisfied; exit if it is */
- horiz_equal = target_size.x == info->current.x &&
- target_size.width == info->current.width;
- vert_equal = target_size.y == info->current.y &&
- target_size.height == info->current.height;
- constraint_already_satisfied =
- (horiz_equal || !window->maximized_horizontally) &&
- (vert_equal || !window->maximized_vertically);
- if (check_only || constraint_already_satisfied)
- return constraint_already_satisfied;
-
- /*** Enforce constraint ***/
- if (window->maximized_horizontally)
- {
- info->current.x = target_size.x;
- info->current.width = target_size.width;
- }
- if (window->maximized_vertically)
- {
- info->current.y = target_size.y;
- info->current.height = target_size.height;
- }
- return TRUE;
-}
-
-static gboolean
-constrain_tiling (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- MetaRectangle target_size;
- MetaRectangle min_size, max_size;
- gboolean hminbad, vminbad;
- gboolean horiz_equal, vert_equal;
- gboolean constraint_already_satisfied;
-
- if (priority > PRIORITY_TILING)
- return TRUE;
-
- /* Determine whether constraint applies; exit if it doesn't */
- 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
- */
- 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, &min_size, &max_size);
- hminbad = target_size.width < min_size.width;
- vminbad = target_size.height < min_size.height;
- if (hminbad || vminbad)
- return TRUE;
-
- /* Determine whether constraint is already satisfied; exit if it is */
- horiz_equal = target_size.x == info->current.x &&
- target_size.width == info->current.width;
- vert_equal = target_size.y == info->current.y &&
- target_size.height == info->current.height;
- constraint_already_satisfied = horiz_equal && vert_equal;
- if (check_only || constraint_already_satisfied)
- return constraint_already_satisfied;
-
- /*** Enforce constraint ***/
- info->current.x = target_size.x;
- info->current.width = target_size.width;
- info->current.y = target_size.y;
- info->current.height = target_size.height;
-
- return TRUE;
-}
-
-
-static gboolean
-constrain_fullscreen (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- MetaRectangle min_size, max_size, monitor;
- gboolean too_big, too_small, constraint_already_satisfied;
-
- if (priority > PRIORITY_FULLSCREEN)
- return TRUE;
-
- /* Determine whether constraint applies; exit if it doesn't */
- if (!window->fullscreen)
- return TRUE;
-
- monitor = info->entire_monitor;
-
- 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)
- return TRUE;
-
- /* Determine whether constraint is already satisfied; exit if it is */
- constraint_already_satisfied =
- meta_rectangle_equal (&info->current, &monitor);
- if (check_only || constraint_already_satisfied)
- return constraint_already_satisfied;
-
- /*** Enforce constraint ***/
- info->current = monitor;
- return TRUE;
-}
-
-static gboolean
-constrain_size_increments (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- int bh, hi, bw, wi, extra_height, extra_width;
- 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_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 = (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;
- if (window->maximized_vertically)
- extra_height *= 0;
- /* constraint is satisfied iff there is no extra height or width */
- constraint_already_satisfied =
- (extra_height == 0 && extra_width == 0);
-
- if (check_only || constraint_already_satisfied)
- return constraint_already_satisfied;
-
- /*** Enforce constraint ***/
- 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
- * happens.
- */
- if (new_width < window->size_hints.min_width)
- new_width += ((window->size_hints.min_width - new_width)/wi + 1)*wi;
- if (new_height < window->size_hints.min_height)
- new_height += ((window->size_hints.min_height - new_height)/hi + 1)*hi;
-
- {
- 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,
- &info->current,
- info->resize_gravity,
- new_width,
- new_height);
- return TRUE;
-}
-
-static gboolean
-constrain_size_limits (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- MetaRectangle min_size, max_size;
- gboolean too_big, too_small, constraint_already_satisfied;
- int new_width, new_height;
- MetaRectangle *start_rect;
-
- if (priority > PRIORITY_SIZE_HINTS_LIMITS)
- return TRUE;
-
- /* Determine whether constraint applies; exit if it doesn't.
- *
- * Note: The old code didn't apply this constraint for fullscreen or
- * maximized windows--but that seems odd to me. *shrug*
- */
- if (info->action_type == ACTION_MOVE)
- return TRUE;
-
- /* Determine whether constraint is already satisfied; exit if it is */
- 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);
- if (window->maximized_vertically)
- max_size.height = MAX (max_size.height, info->current.height);
- too_small = !meta_rectangle_could_fit_rect (&info->current, &min_size);
- too_big = !meta_rectangle_could_fit_rect (&max_size, &info->current);
- constraint_already_satisfied = !too_big && !too_small;
- if (check_only || constraint_already_satisfied)
- return constraint_already_satisfied;
-
- /*** Enforce constraint ***/
- new_width = CLAMP (info->current.width, min_size.width, max_size.width);
- new_height = CLAMP (info->current.height, min_size.height, max_size.height);
-
- start_rect = get_start_rect_for_resize (window, info);
-
- meta_rectangle_resize_with_gravity (start_rect,
- &info->current,
- info->resize_gravity,
- new_width,
- new_height);
- return TRUE;
-}
-
-static gboolean
-constrain_aspect_ratio (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- double minr, maxr;
- gboolean constraints_are_inconsistent, constraint_already_satisfied;
- int fudge, new_width, new_height;
- double best_width, best_height;
- double alt_width, alt_height;
- MetaRectangle *start_rect;
- MetaRectangle client_rect;
-
- if (priority > PRIORITY_ASPECT_RATIO)
- return TRUE;
-
- /* Determine whether constraint applies; exit if it doesn't. */
- minr = window->size_hints.min_aspect.x /
- (double)window->size_hints.min_aspect.y;
- maxr = window->size_hints.max_aspect.x /
- (double)window->size_hints.max_aspect.y;
- constraints_are_inconsistent = minr > maxr;
- if (constraints_are_inconsistent ||
- META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
- META_WINDOW_TILED_SIDE_BY_SIDE (window) ||
- info->action_type == ACTION_MOVE)
- return TRUE;
-
- /* Determine whether constraint is already satisfied; exit if it is. We
- * need the following to hold:
- *
- * width
- * minr <= ------ <= maxr
- * height
- *
- * But we need to allow for some slight fudging since width and height
- * are integers instead of floating point numbers (this is particularly
- * important when minr == maxr), so we allow width and height to be off
- * a little bit from strictly satisfying these equations. For just one
- * sided resizing, we have to make the fudge factor a little bigger
- * because of how meta_rectangle_resize_with_gravity treats those as
- * being a resize increment (FIXME: I should handle real resize
- * increments better here...)
- */
- switch (info->resize_gravity)
- {
- case META_GRAVITY_WEST:
- case META_GRAVITY_NORTH:
- case META_GRAVITY_SOUTH:
- case META_GRAVITY_EAST:
- fudge = 2;
- break;
-
- 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 =
- 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 = client_rect.width;
- new_height = client_rect.height;
-
- switch (info->resize_gravity)
- {
- 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 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 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 */
- alt_width = CLAMP (new_width, new_height * minr, new_height * maxr);
- alt_height = CLAMP (new_height, new_width / maxr, new_width / minr);
-
- /* The line connecting the points (alt_width, new_height) and
- * (new_width, alt_height) provide a range of
- * valid-for-the-aspect-ratio-constraint sizes. We want the
- * size in that range closest to the value requested, i.e. the
- * point on the line which is closest to the point (new_width,
- * new_height)
- */
- meta_rectangle_find_linepoint_closest_to_point (alt_width, new_height,
- new_width, alt_height,
- new_width, new_height,
- &best_width, &best_height);
-
- /* Yeah, I suck for doing implicit rounding -- sue me */
- new_width = best_width;
- new_height = best_height;
-
- break;
- }
-
- {
- 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,
- info->resize_gravity,
- new_width,
- new_height);
-
- return TRUE;
-}
-
-static gboolean
-do_screen_and_monitor_relative_constraints (
- MetaWindow *window,
- GList *region_spanning_rectangles,
- ConstraintInfo *info,
- gboolean check_only)
-{
- gboolean exit_early = FALSE, constraint_satisfied;
- MetaRectangle how_far_it_can_be_smushed, min_size, max_size;
-
-#ifdef WITH_VERBOSE_MODE
- if (meta_is_verbose ())
- {
- /* First, log some debugging information */
- char spanning_region[1 + 28 * g_list_length (region_spanning_rectangles)];
-
- meta_topic (META_DEBUG_GEOMETRY,
- "screen/monitor constraint; region_spanning_rectangles: %s",
- meta_rectangle_region_to_string (region_spanning_rectangles, ", ",
- spanning_region));
- }
-#endif
-
- /* Determine whether constraint applies; exit if it doesn't */
- how_far_it_can_be_smushed = info->current;
- get_size_limits (window, &min_size, &max_size);
-
- if (info->action_type != ACTION_MOVE)
- {
- if (!(info->fixed_directions & FIXED_DIRECTION_X))
- how_far_it_can_be_smushed.width = min_size.width;
-
- if (!(info->fixed_directions & FIXED_DIRECTION_Y))
- how_far_it_can_be_smushed.height = min_size.height;
- }
- if (!meta_rectangle_could_fit_in_region (region_spanning_rectangles,
- &how_far_it_can_be_smushed))
- exit_early = TRUE;
-
- /* Determine whether constraint is already satisfied; exit if it is */
- constraint_satisfied =
- meta_rectangle_contained_in_region (region_spanning_rectangles,
- &info->current);
- if (exit_early || constraint_satisfied || check_only)
- return constraint_satisfied;
-
- /* Enforce constraint */
-
- /* Clamp rectangle size for resize or move+resize actions */
- if (info->action_type != ACTION_MOVE)
- meta_rectangle_clamp_to_fit_into_region (region_spanning_rectangles,
- info->fixed_directions,
- &info->current,
- &min_size);
-
- if (info->is_user_action && info->action_type == ACTION_RESIZE)
- /* For user resize, clip to the relevant region */
- meta_rectangle_clip_to_region (region_spanning_rectangles,
- 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);
-
- return TRUE;
-}
-
-static gboolean
-constrain_to_single_monitor (MetaWindow *window,
- ConstraintInfo *info,
- 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;
-
- /* 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) 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 ||
- 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 */
- return do_screen_and_monitor_relative_constraints (window,
- info->usable_monitor_region,
- info,
- check_only);
-}
-
-static gboolean
-constrain_fully_onscreen (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- if (priority > PRIORITY_ENTIRELY_VISIBLE_ON_WORKAREA)
- return TRUE;
-
- /* 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).
- */
- if (window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK ||
- window->fullscreen ||
- !window->require_fully_onscreen ||
- info->is_user_action ||
- meta_window_get_placement_rule (window))
- return TRUE;
-
- /* Have a helper function handle the constraint for us */
- return do_screen_and_monitor_relative_constraints (window,
- info->usable_screen_region,
- info,
- check_only);
-}
-
-static gboolean
-constrain_titlebar_visible (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- gboolean unconstrained_user_action;
- gboolean retval;
- int bottom_amount;
- int horiz_amount_offscreen, vert_amount_offscreen;
- int horiz_amount_onscreen, vert_amount_onscreen;
-
- if (priority > PRIORITY_TITLEBAR_VISIBLE)
- return TRUE;
-
- /* Allow the titlebar beyond the top of the screen only if the user wasn't
- * clicking on the frame to start the move.
- */
- unconstrained_user_action =
- info->is_user_action && !window->display->grab_frame_action;
-
- /* 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).
- */
- if (window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK ||
- window->fullscreen ||
- !window->require_titlebar_visible ||
- unconstrained_user_action ||
- meta_window_get_placement_rule (window))
- return TRUE;
-
- /* Determine how much offscreen things are allowed. We first need to
- * figure out how much must remain on the screen. For that, we use 25%
- * window width/height but clamp to the range of (10,75) pixels. This is
- * somewhat of a seat of my pants random guess at what might look good.
- * Then, the amount that is allowed off is just the window size minus
- * this amount (but no less than 0 for tiny windows).
- */
- horiz_amount_onscreen = info->current.width / 4;
- vert_amount_onscreen = info->current.height / 4;
- 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);
- vert_amount_offscreen = MAX (vert_amount_offscreen, 0);
- /* Allow the titlebar to touch the bottom panel; If there is no titlebar,
- * require vert_amount to remain on the screen.
- */
- if (window->frame)
- {
- 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;
-
- /* Extend the region, have a helper function handle the constraint,
- * then return the region to its original size.
- */
- meta_rectangle_expand_region_conditionally (info->usable_screen_region,
- horiz_amount_offscreen,
- horiz_amount_offscreen,
- 0, /* Don't let titlebar off */
- bottom_amount,
- horiz_amount_onscreen,
- vert_amount_onscreen);
- retval =
- do_screen_and_monitor_relative_constraints (window,
- info->usable_screen_region,
- info,
- check_only);
- meta_rectangle_expand_region_conditionally (info->usable_screen_region,
- -horiz_amount_offscreen,
- -horiz_amount_offscreen,
- 0, /* Don't let titlebar off */
- -bottom_amount,
- horiz_amount_onscreen,
- vert_amount_onscreen);
-
- return retval;
-}
-
-static gboolean
-constrain_partially_onscreen (MetaWindow *window,
- ConstraintInfo *info,
- ConstraintPriority priority,
- gboolean check_only)
-{
- gboolean retval;
- int top_amount, bottom_amount;
- int horiz_amount_offscreen, vert_amount_offscreen;
- int horiz_amount_onscreen, vert_amount_onscreen;
-
- if (priority > PRIORITY_PARTIALLY_VISIBLE_ON_WORKAREA)
- return TRUE;
-
- /* 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).
- */
- if (window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK ||
- meta_window_get_placement_rule (window))
- return TRUE;
-
- /* Determine how much offscreen things are allowed. We first need to
- * figure out how much must remain on the screen. For that, we use 25%
- * window width/height but clamp to the range of (10,75) pixels. This is
- * somewhat of a seat of my pants random guess at what might look good.
- * Then, the amount that is allowed off is just the window size minus
- * this amount (but no less than 0 for tiny windows).
- */
- horiz_amount_onscreen = info->current.width / 4;
- vert_amount_onscreen = info->current.height / 4;
- 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);
- vert_amount_offscreen = MAX (vert_amount_offscreen, 0);
- top_amount = vert_amount_offscreen;
- /* Allow the titlebar to touch the bottom panel; If there is no titlebar,
- * require vert_amount to remain on the screen.
- */
- if (window->frame)
- {
- 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;
-
- /* Extend the region, have a helper function handle the constraint,
- * then return the region to its original size.
- */
- meta_rectangle_expand_region_conditionally (info->usable_screen_region,
- horiz_amount_offscreen,
- horiz_amount_offscreen,
- top_amount,
- bottom_amount,
- horiz_amount_onscreen,
- vert_amount_onscreen);
- retval =
- do_screen_and_monitor_relative_constraints (window,
- info->usable_screen_region,
- info,
- check_only);
- meta_rectangle_expand_region_conditionally (info->usable_screen_region,
- -horiz_amount_offscreen,
- -horiz_amount_offscreen,
- -top_amount,
- -bottom_amount,
- horiz_amount_onscreen,
- vert_amount_onscreen);
-
- return retval;
-}
diff --git a/src/core/constraints.h b/src/core/constraints.h
deleted file mode 100644
index eaa4e4594..000000000
--- a/src/core/constraints.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_CONSTRAINTS_H
-#define META_CONSTRAINTS_H
-
-#include "core/frame.h"
-#include "core/window-private.h"
-#include "meta/util.h"
-
-void meta_window_constrain (MetaWindow *window,
- MetaMoveResizeFlags flags,
- MetaGravity resize_gravity,
- const MetaRectangle *orig,
- MetaRectangle *new,
- MetaRectangle *intermediate,
- int *rel_x,
- int *rel_y);
-
-#endif /* META_CONSTRAINTS_H */
diff --git a/src/core/delete.c b/src/core/delete.c
deleted file mode 100644
index 058764b08..000000000
--- a/src/core/delete.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Mutter window deletion */
-
-/*
- * Copyright (C) 2001, 2002 Havoc Pennington
- * Copyright (C) 2004 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/>.
- */
-
-#define _XOPEN_SOURCE /* for kill() */
-
-#include "config.h"
-
-#include <errno.h>
-
-#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
-close_dialog_response_cb (MetaCloseDialog *dialog,
- MetaCloseDialogResponse response,
- MetaWindow *window)
-{
- if (response == META_CLOSE_DIALOG_RESPONSE_FORCE_CLOSE)
- meta_window_kill (window);
-}
-
-static void
-meta_window_ensure_close_dialog (MetaWindow *window)
-{
- MetaDisplay *display;
-
- if (window->close_dialog)
- return;
-
- 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);
-}
-
-void
-meta_window_set_alive (MetaWindow *window,
- gboolean is_alive)
-{
- if (is_alive && window->close_dialog)
- {
- meta_close_dialog_hide (window->close_dialog);
- }
- else if (!is_alive)
- {
- meta_window_ensure_close_dialog (window);
- meta_close_dialog_show (window->close_dialog);
-
- if (window->display &&
- window->display->event_route == META_EVENT_ROUTE_NORMAL &&
- window == window->display->focus_window)
- meta_close_dialog_focus (window->close_dialog);
- }
-}
-
-void
-meta_window_check_alive (MetaWindow *window,
- guint32 timestamp)
-{
- meta_display_ping_window (window, timestamp);
-}
-
-void
-meta_window_delete (MetaWindow *window,
- guint32 timestamp)
-{
- META_WINDOW_GET_CLASS (window)->delete (window, timestamp);
-
- meta_window_check_alive (window, timestamp);
-}
-
-void
-meta_window_kill (MetaWindow *window)
-{
- pid_t pid = meta_window_get_pid (window);
-
- if (pid > 0)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Killing %s with kill()",
- window->desc);
-
- if (kill (pid, 9) == 0)
- return;
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Failed to signal %s: %s",
- window->desc, strerror (errno));
- }
-
- META_WINDOW_GET_CLASS (window)->kill (window);
-}
-
-void
-meta_window_free_delete_dialog (MetaWindow *window)
-{
- 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
deleted file mode 100644
index 8efac0b49..000000000
--- a/src/core/display-private.h
+++ /dev/null
@@ -1,434 +0,0 @@
-/* -*- 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_DISPLAY_PRIVATE_H
-#define META_DISPLAY_PRIVATE_H
-
-#include "meta/display.h"
-
-#include <glib.h>
-#include <X11/extensions/sync.h>
-#include <X11/Xlib.h>
-
-#include "clutter/clutter.h"
-#include "core/keybindings-private.h"
-#include "core/meta-gesture-tracker-private.h"
-#include "core/meta-pad-action-mapper.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 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 */
-
-/* This is basically a bogus number, just has to be large enough
- * to handle the expected case of the alt+tab operation, where
- * we want to ignore serials from UnmapNotify on the tab popup,
- * and the LeaveNotify/EnterNotify from the pointer ungrab. It
- * also has to be big enough to hold ignored serials from the point
- * where we reshape the stage to the point where we get events back.
- */
-#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;
-
- MetaX11Display *x11_display;
-
- int clutter_event_filter;
-
- /* 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;
-
- /* last timestamp passed to XSetInputFocus */
- guint32 last_focus_time;
-
- /* last user interaction time in any app */
- guint32 last_user_time;
-
- /* whether we're using mousenav (only relevant for sloppy&mouse focus modes;
- * !mouse_mode means "keynav mode")
- */
- guint mouse_mode : 1;
-
- /* Helper var used when focus_new_windows setting is 'strict'; only
- * relevant in 'strict' mode and if the focus window is a terminal.
- * In that case, we don't allow new windows to take focus away from
- * a terminal, but if the user explicitly did something that should
- * allow a different window to gain focus (e.g. global keybinding or
- * clicking on a dock), then we will allow the transfer.
- */
- guint allow_terminal_deactivation : 1;
-
- /*< private-ish >*/
- 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];
-
- 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 mutter.
- *
- * It can be useful to plugins which want to sort windows in a
- * stable fashion.
- */
- guint32 window_sequence_counter;
-
- /* 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;
-
- /* Event routing */
- MetaEventRoute event_route;
-
- /* current window operation */
- MetaGrabOp grab_op;
- MetaWindow *grab_window;
- int grab_button;
- int grab_anchor_root_x;
- int grab_anchor_root_y;
- MetaRectangle grab_anchor_window_pos;
- MetaTileMode grab_tile_mode;
- int grab_tile_monitor_number;
- int grab_latest_motion_x;
- int grab_latest_motion_y;
- guint grab_have_pointer : 1;
- guint grab_have_keyboard : 1;
- guint grab_frame_action : 1;
- 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. */
- int64_t grab_last_moveresize_time;
- MetaEdgeResistanceData *grab_edge_resistance_data;
- unsigned int grab_last_edge_resistance_flags;
-
- int grab_resize_timeout_id;
-
- MetaKeyBindingManager key_binding_manager;
-
- /* Opening the display */
- unsigned int display_opening : 1;
-
- /* Closing down the display */
- int closing;
-
- /* Managed by compositor.c */
- MetaCompositor *compositor;
-
- MetaGestureTracker *gesture_tracker;
- ClutterEventSequence *pointer_emulating_sequence;
-
- ClutterActor *current_pad_osd;
- MetaPadActionMapper *pad_action_mapper;
-
- MetaStartupNotification *startup_notification;
-
- MetaCursor current_cursor;
-
- MetaStack *stack;
- MetaStackTracker *stack_tracker;
-
- guint tile_preview_timeout_id;
- guint preview_tile_mode : 2;
-
- 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
-{
- GObjectClass parent_class;
-};
-
-#define XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) \
- ( (( (time1) < (time2) ) && ( (time2) - (time1) < ((guint32)-1)/2 )) || \
- (( (time1) > (time2) ) && ( (time1) - (time2) > ((guint32)-1)/2 )) \
- )
-/**
- * XSERVER_TIME_IS_BEFORE:
- *
- * See the docs for meta_display_xserver_time_is_before().
- */
-#define XSERVER_TIME_IS_BEFORE(time1, time2) \
- ( (time1) == 0 || \
- (XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) && \
- (time2) != 0) \
- )
-
-MetaDisplay * meta_display_new (MetaContext *context,
- GError **error);
-
-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);
-
-/* Each MetaWindow is uniquely identified by a 64-bit "stamp"; unlike a
- * a MetaWindow *, a stamp will never be recycled
- */
-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);
-
-META_EXPORT_TEST
-MetaDisplay* meta_get_display (void);
-
-void meta_display_reload_cursor (MetaDisplay *display);
-void meta_display_update_cursor (MetaDisplay *display);
-
-void meta_display_check_threshold_reached (MetaDisplay *display,
- int x,
- int y);
-void meta_display_grab_window_buttons (MetaDisplay *display,
- Window xwindow);
-void meta_display_ungrab_window_buttons (MetaDisplay *display,
- Window xwindow);
-
-void meta_display_grab_focus_window_button (MetaDisplay *display,
- MetaWindow *window);
-void meta_display_ungrab_focus_window_button (MetaDisplay *display,
- MetaWindow *window);
-
-/* Next function is defined in edge-resistance.c */
-void meta_display_cleanup_edges (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_ping_window (MetaWindow *window,
- guint32 serial);
-void meta_display_pong_for_serial (MetaDisplay *display,
- guint32 serial);
-
-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);
-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);
-
-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_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_shutdown_x11 (MetaDisplay *display);
-
-#endif
diff --git a/src/core/display.c b/src/core/display.c
deleted file mode 100644
index 5d4a4da21..000000000
--- a/src/core/display.c
+++ /dev/null
@@ -1,3852 +0,0 @@
-/* -*- 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:display
- * @title: MetaDisplay
- * @short_description: Mutter display representation
- *
- * The display is represented as a #MetaDisplay struct.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <X11/Xatom.h>
-#include <X11/Xcursor/Xcursor.h>
-#include <X11/extensions/shape.h>
-#include <X11/extensions/Xcomposite.h>
-#include <X11/extensions/Xdamage.h>
-#include <X11/extensions/Xfixes.h>
-
-#include "backends/meta-backend-private.h"
-#include "backends/meta-cursor-sprite-xcursor.h"
-#include "backends/meta-cursor-tracker-private.h"
-#include "backends/meta-input-device-private.h"
-#include "backends/meta-input-mapper-private.h"
-#include "backends/meta-stage-private.h"
-#include "backends/x11/meta-backend-x11.h"
-#include "backends/x11/meta-clutter-backend-x11.h"
-#include "backends/x11/meta-event-x11.h"
-#include "backends/x11/cm/meta-backend-x11-cm.h"
-#include "backends/x11/nested/meta-backend-x11-nested.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/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-native.h"
-#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
-
-/*
- * 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"
- * message within a reasonable time. Here we have a system which lets us
- * nominate one function to be called if we get the pong in time and another
- * function if we don't. The system is rather more complicated than it needs
- * to be, since we only ever use it to destroy windows which are asked to
- * close themselves and don't do so within a reasonable amount of time, and
- * therefore we always use the same callbacks. It's possible that we might
- * use it for other things in future, or on the other hand we might decide
- * 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.
- */
-typedef struct
-{
- MetaWindow *window;
- guint32 serial;
- guint ping_timeout_id;
-} MetaPingData;
-
-typedef struct _MetaDisplayPrivate
-{
- MetaContext *context;
-} MetaDisplayPrivate;
-
-G_DEFINE_TYPE_WITH_PRIVATE (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,
- 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
-{
- PROP_0,
-
- PROP_COMPOSITOR_MODIFIERS,
- PROP_FOCUS_WINDOW
-};
-
-static guint display_signals [LAST_SIGNAL] = { 0 };
-
-#define META_GRAB_OP_GET_BASE_TYPE(op) (op & 0x00FF)
-
-/*
- * The display we're managing. This is a singleton object. (Historically,
- * this was a list of displays, but there was never any way to add more
- * than one element to it.) The goofy name is because we don't want it
- * to shadow the parameter in its object methods.
- */
-static MetaDisplay *the_display = NULL;
-
-static void on_monitors_changed_internal (MetaMonitorManager *monitor_manager,
- MetaDisplay *display);
-
-static void prefs_changed_callback (MetaPreference pref,
- void *data);
-
-static int mru_cmp (gconstpointer a,
- gconstpointer b);
-
-static void
-meta_display_get_property(GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaDisplay *display = META_DISPLAY (object);
-
- switch (prop_id)
- {
- case PROP_COMPOSITOR_MODIFIERS:
- g_value_set_flags (value, meta_display_get_compositor_modifiers (display));
- break;
- case PROP_FOCUS_WINDOW:
- g_value_set_object (value, display->focus_window);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_display_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_display_class_init (MetaDisplayClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (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),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 1, META_TYPE_WINDOW);
-
- display_signals[WINDOW_DEMANDS_ATTENTION] =
- g_signal_new ("window-demands-attention",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 1, META_TYPE_WINDOW);
-
- display_signals[WINDOW_MARKED_URGENT] =
- g_signal_new ("window-marked-urgent",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 1,
- META_TYPE_WINDOW);
-
- display_signals[GRAB_OP_BEGIN] =
- g_signal_new ("grab-op-begin",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 2,
- META_TYPE_WINDOW,
- META_TYPE_GRAB_OP);
-
- display_signals[GRAB_OP_END] =
- g_signal_new ("grab-op-end",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 2,
- META_TYPE_WINDOW,
- META_TYPE_GRAB_OP);
-
- /**
- * 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,
- g_signal_accumulator_true_handled,
- NULL, NULL,
- G_TYPE_BOOLEAN, 1,
- G_TYPE_STRING);
-
- /**
- * 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,
- g_signal_accumulator_true_handled,
- NULL, NULL,
- G_TYPE_BOOLEAN, 0);
-
- display_signals[SHOW_RESIZE_POPUP] =
- g_signal_new ("show-resize-popup",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- 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",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
- /**
- * 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
- *
- * Requests the pad button mapping OSD to be shown.
- *
- * Returns: (transfer none) (nullable): The OSD actor
- */
- 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_COMPOSITOR_MODIFIERS,
- g_param_spec_flags ("compositor-modifiers",
- "Compositor modifiers",
- "Modifiers reserved for compositor actions",
- CLUTTER_TYPE_MODIFIER_TYPE,
- 0,
- G_PARAM_READABLE));
-
- g_object_class_install_property (object_class,
- PROP_FOCUS_WINDOW,
- g_param_spec_object ("focus-window",
- "Focus window",
- "Currently focused window",
- META_TYPE_WINDOW,
- G_PARAM_READABLE));
-
-}
-
-
-/**
- * ping_data_free:
- *
- * 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 */
- g_clear_handle_id (&ping_data->ping_timeout_id, g_source_remove);
-
- g_free (ping_data);
-}
-
-void
-meta_display_remove_pending_pings_for_window (MetaDisplay *display,
- MetaWindow *window)
-{
- GSList *tmp;
- GSList *dead;
-
- /* could obviously be more efficient, don't care */
-
- /* build list to be removed */
- dead = NULL;
- for (tmp = display->pending_pings; tmp; tmp = tmp->next)
- {
- MetaPingData *ping_data = tmp->data;
-
- if (ping_data->window == window)
- dead = g_slist_prepend (dead, ping_data);
- }
-
- /* remove what we found */
- for (tmp = dead; tmp; tmp = tmp->next)
- {
- MetaPingData *ping_data = tmp->data;
-
- display->pending_pings = g_slist_remove (display->pending_pings, ping_data);
- ping_data_free (ping_data);
- }
-
- g_slist_free (dead);
-}
-
-static MetaCompositor *
-create_compositor (MetaDisplay *display)
-{
- MetaBackend *backend = meta_get_backend ();
-
-#ifdef HAVE_WAYLAND
-#ifdef HAVE_NATIVE_BACKEND
- if (META_IS_BACKEND_NATIVE (backend))
- return META_COMPOSITOR (meta_compositor_native_new (display, backend));
-#endif
- if (META_IS_BACKEND_X11_NESTED (backend))
- return META_COMPOSITOR (meta_compositor_server_new (display, backend));
-#endif
- return META_COMPOSITOR (meta_compositor_x11_new (display, backend));
-}
-
-static void
-meta_display_init (MetaDisplay *disp)
-{
- /* Some stuff could go in here that's currently in _open,
- * but it doesn't really matter. */
-}
-
-void
-meta_display_cancel_touch (MetaDisplay *display)
-{
-#ifdef HAVE_WAYLAND
- MetaWaylandCompositor *compositor;
-
- if (!meta_is_wayland_compositor ())
- return;
-
- compositor = meta_wayland_compositor_get_default ();
- meta_wayland_touch_cancel (compositor->seat->touch);
-#endif
-}
-
-static void
-gesture_tracker_state_changed (MetaGestureTracker *tracker,
- ClutterEventSequence *sequence,
- MetaSequenceState state,
- MetaDisplay *display)
-{
- switch (state)
- {
- case META_SEQUENCE_NONE:
- case META_SEQUENCE_PENDING_END:
- return;
- case META_SEQUENCE_ACCEPTED:
- meta_display_cancel_touch (display);
-
- G_GNUC_FALLTHROUGH;
- case META_SEQUENCE_REJECTED:
- {
- MetaBackend *backend;
-
- backend = meta_get_backend ();
- meta_backend_finish_touch_sequence (backend, sequence, state);
- break;
- }
- }
-}
-
-static void
-on_ui_scaling_factor_changed (MetaSettings *settings,
- MetaDisplay *display)
-{
- meta_display_reload_cursor (display);
-}
-
-static gboolean
-meta_display_init_x11_display (MetaDisplay *display,
- GError **error)
-{
- MetaX11Display *x11_display;
-
- x11_display = meta_x11_display_new (display, error);
- if (!x11_display)
- return FALSE;
-
- display->x11_display = x11_display;
- g_signal_emit (display, display_signals[X11_DISPLAY_SETUP], 0);
-
- meta_x11_display_create_guard_window (x11_display);
-
- 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);
- }
-
- return TRUE;
-}
-
-#ifdef HAVE_WAYLAND
-gboolean
-meta_display_init_x11_finish (MetaDisplay *display,
- GAsyncResult *result,
- GError **error)
-{
- MetaX11Display *x11_display;
-
- g_assert (g_task_get_source_tag (G_TASK (result)) == meta_display_init_x11);
-
- 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");
-
- return FALSE;
- }
-
- if (display->x11_display)
- return TRUE;
-
- x11_display = meta_x11_display_new (display, error);
- if (!x11_display)
- return FALSE;
-
- display->x11_display = x11_display;
- g_signal_emit (display, display_signals[X11_DISPLAY_SETUP], 0);
-
- meta_x11_display_create_guard_window (x11_display);
-
- 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);
- }
-
- return TRUE;
-}
-
-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;
-
- if (!meta_xwayland_start_xserver_finish (manager, result, &error))
- {
- if (error)
- g_task_return_error (task, error);
- else
- g_task_return_boolean (task, FALSE);
-
- return;
- }
-
- g_signal_emit (display, display_signals[INIT_XSERVER], 0, task, &retval);
-
- if (!retval)
- {
- /* No handlers for this signal, proceed right away */
- g_task_return_boolean (task, TRUE);
- }
-}
-
-void
-meta_display_init_x11 (MetaDisplay *display,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
-
- g_autoptr (GTask) task = NULL;
-
- task = g_task_new (display, cancellable, callback, user_data);
- g_task_set_source_tag (task, meta_display_init_x11);
-
- meta_xwayland_start_xserver (&compositor->xwayland_manager,
- cancellable,
- (GAsyncReadyCallback) on_xserver_started,
- g_steal_pointer (&task));
-}
-
-static void
-on_x11_initialized (MetaDisplay *display,
- GAsyncResult *result,
- gpointer user_data)
-{
- g_autoptr (GError) error = NULL;
-
- if (!meta_display_init_x11_finish (display, result, &error))
- g_critical ("Failed to init X11 display: %s", error->message);
-}
-#endif
-
-void
-meta_display_shutdown_x11 (MetaDisplay *display)
-{
- if (!display->x11_display)
- return;
-
- 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);
-}
-
-MetaDisplay *
-meta_display_new (MetaContext *context,
- GError **error)
-{
- MetaDisplay *display;
- MetaDisplayPrivate *priv;
- int i;
- guint32 timestamp;
- Window old_active_xwindow = None;
- MetaBackend *backend = meta_get_backend ();
- MetaMonitorManager *monitor_manager;
- MetaSettings *settings;
-
- g_assert (the_display == NULL);
- display = the_display = g_object_new (META_TYPE_DISPLAY, NULL);
-
- priv = meta_display_get_instance_private (display);
- priv->context = context;
-
- display->closing = 0;
- display->display_opening = TRUE;
-
- 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;
-
- display->current_cursor = -1; /* invalid/unset */
- display->tile_preview_timeout_id = 0;
- display->check_fullscreen_later = 0;
- display->work_area_later = 0;
-
- 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 */
-
- i = 0;
- while (i < N_IGNORED_CROSSING_SERIALS)
- {
- display->ignored_crossing_serials[i] = 0;
- ++i;
- }
-
- display->current_time = META_CURRENT_TIME;
-
- display->grab_resize_timeout_id = 0;
- display->grab_have_keyboard = FALSE;
-
- 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_display_cleanup_edges (display);
-
- meta_display_init_keys (display);
-
- meta_prefs_add_listener (prefs_changed_callback, display);
-
- /* Get events */
- meta_display_init_events (display);
-
- display->stamps = g_hash_table_new (g_int64_hash,
- g_int64_equal);
- display->wayland_windows = g_hash_table_new (NULL, NULL);
-
- monitor_manager = meta_backend_get_monitor_manager (backend);
- g_signal_connect (monitor_manager, "monitors-changed-internal",
- G_CALLBACK (on_monitors_changed_internal), display);
-
- display->pad_action_mapper = meta_pad_action_mapper_new (monitor_manager);
-
- settings = meta_backend_get_settings (backend);
- g_signal_connect (settings, "ui-scaling-factor-changed",
- G_CALLBACK (on_ui_scaling_factor_changed), display);
-
- display->compositor = create_compositor (display);
-
- meta_display_set_cursor (display, META_CURSOR_DEFAULT);
-
- display->stack = meta_stack_new (display);
- display->stack_tracker = meta_stack_tracker_new (display);
-
- display->workspace_manager = meta_workspace_manager_new (display);
-
- display->startup_notification = meta_startup_notification_new (display);
-
- display->bell = meta_bell_new (display);
-
- display->selection = meta_selection_new (display);
- meta_clipboard_manager_init (display);
-
-#ifdef HAVE_WAYLAND
- if (meta_is_wayland_compositor ())
- {
- MetaX11DisplayPolicy x11_display_policy;
-
- x11_display_policy = meta_context_get_x11_display_policy (context);
- if (x11_display_policy == META_X11_DISPLAY_POLICY_MANDATORY)
- {
- meta_display_init_x11 (display, NULL,
- (GAsyncReadyCallback) on_x11_initialized,
- NULL);
- }
-
- timestamp = meta_display_get_current_time_roundtrip (display);
- }
- else
-#endif
- {
- if (!meta_display_init_x11_display (display, error))
- {
- g_object_unref (display);
- return NULL;
- }
-
- timestamp = display->x11_display->timestamp;
- }
-
- display->last_focus_time = timestamp;
- display->last_user_time = timestamp;
-
- 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);
-
- if (!meta_compositor_do_manage (display->compositor, error))
- {
- g_object_unref (display);
- return NULL;
- }
-
- if (display->x11_display)
- {
- 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);
- }
-
- /* 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);
-
- /* 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);
- }
-
- display->sound_player = g_object_new (META_TYPE_SOUND_PLAYER, NULL);
-
- /* Done opening new display */
- display->display_opening = FALSE;
-
- return display;
-}
-
-static gint
-ptrcmp (gconstpointer a, gconstpointer b)
-{
- if (a < b)
- return -1;
- else if (a > b)
- return 1;
- else
- return 0;
-}
-
-/**
- * meta_display_list_windows:
- * @display: a #MetaDisplay
- * @flags: options for listing
- *
- * Lists windows for the display, the @flags parameter for
- * now determines whether override-redirect windows will be
- * included.
- *
- * Return value: (transfer container): the list of windows.
- */
-GSList*
-meta_display_list_windows (MetaDisplay *display,
- MetaListWindowsFlags flags)
-{
- GSList *winlist;
- GSList *prev;
- GSList *tmp;
- GHashTableIter iter;
- gpointer key, value;
-
- winlist = NULL;
-
- 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);
- }
-
- /* Uniquify the list, since both frame windows and plain
- * windows are in the hash
- */
- winlist = g_slist_sort (winlist, ptrcmp);
-
- prev = NULL;
- tmp = winlist;
- while (tmp != NULL)
- {
- GSList *next;
-
- next = tmp->next;
-
- if (next &&
- next->data == tmp->data)
- {
- /* Delete tmp from list */
-
- if (prev)
- prev->next = next;
-
- if (tmp == winlist)
- winlist = next;
-
- g_slist_free_1 (tmp);
-
- /* leave prev unchanged */
- }
- else
- {
- prev = tmp;
- }
-
- tmp = next;
- }
-
- if (flags & META_LIST_SORTED)
- winlist = g_slist_sort (winlist, mru_cmp);
-
- return winlist;
-}
-
-void
-meta_display_close (MetaDisplay *display,
- guint32 timestamp)
-{
- g_assert (display != NULL);
-
- if (display->closing != 0)
- {
- /* The display's already been closed. */
- return;
- }
-
- g_assert (display == the_display);
-
- 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);
-
- 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_display_free_events (display);
-
- g_clear_pointer (&display->compositor, meta_compositor_destroy);
-
- meta_display_shutdown_x11 (display);
-
- 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->wayland_windows);
- g_hash_table_destroy (display->stamps);
-
- meta_display_shutdown_keys (display);
-
- 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_clear_object (&display->pad_action_mapper);
-
- the_display = NULL;
-}
-
-/**
- * meta_display_for_x_display:
- * @xdisplay: An X display
- *
- * 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.
- *
- * Returns: The singleton X display, or %NULL if @xdisplay isn't the one
- * we're managing.
- */
-MetaDisplay*
-meta_display_for_x_display (Display *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",
- xdisplay);
-
- return NULL;
-}
-
-/**
- * meta_get_display:
- *
- * Accessor for the singleton MetaDisplay.
- *
- * Returns: The only #MetaDisplay there is. This can be %NULL, but only
- * during startup.
- */
-MetaDisplay*
-meta_get_display (void)
-{
- return the_display;
-}
-
-static inline gboolean
-grab_op_is_window (MetaGrabOp op)
-{
- return META_GRAB_OP_GET_BASE_TYPE (op) == META_GRAB_OP_WINDOW_BASE;
-}
-
-gboolean
-meta_grab_op_is_mouse (MetaGrabOp op)
-{
- if (!grab_op_is_window (op))
- return FALSE;
-
- return (op & META_GRAB_OP_WINDOW_FLAG_KEYBOARD) == 0;
-}
-
-gboolean
-meta_grab_op_is_keyboard (MetaGrabOp op)
-{
- if (!grab_op_is_window (op))
- return FALSE;
-
- return (op & META_GRAB_OP_WINDOW_FLAG_KEYBOARD) != 0;
-}
-
-gboolean
-meta_grab_op_is_resizing (MetaGrabOp 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_EVENT_ROUTE_NORMAL:
- case META_EVENT_ROUTE_WAYLAND_POPUP:
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-/**
- * meta_display_xserver_time_is_before:
- * @display: a #MetaDisplay
- * @time1: An event timestamp
- * @time2: An event timestamp
- *
- * Xserver time can wraparound, thus comparing two timestamps needs to take
- * this into account. If no wraparound has occurred, this is equivalent to
- * time1 < time2
- * Otherwise, we need to account for the fact that wraparound can occur
- * and the fact that a timestamp of 0 must be special-cased since it
- * means "older than anything else".
- *
- * Note that this is NOT an equivalent for time1 <= time2; if that's what
- * you need then you'll need to swap the order of the arguments and negate
- * the result.
- */
-gboolean
-meta_display_xserver_time_is_before (MetaDisplay *display,
- guint32 time1,
- guint32 time2)
-{
- return XSERVER_TIME_IS_BEFORE(time1, time2);
-}
-
-/**
- * meta_display_get_last_user_time:
- * @display: a #MetaDisplay
- *
- * Returns: Timestamp of the last user interaction event with a window
- */
-guint32
-meta_display_get_last_user_time (MetaDisplay *display)
-{
- return display->last_user_time;
-}
-
-/* Get time of current event, or CurrentTime if none. */
-guint32
-meta_display_get_current_time (MetaDisplay *display)
-{
- return display->current_time;
-}
-
-guint32
-meta_display_get_current_time_roundtrip (MetaDisplay *display)
-{
- 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);
-}
-
-/**
- * meta_display_add_ignored_crossing_serial:
- * @display: a #MetaDisplay
- * @serial: the serial to ignore
- *
- * Save the specified serial and ignore crossing events with that
- * serial for the purpose of focus-follows-mouse. This can be used
- * for certain changes to the window hierarchy that we don't want
- * to change the focus window, even if they cause the pointer to
- * end up in a new window.
- */
-void
-meta_display_add_ignored_crossing_serial (MetaDisplay *display,
- unsigned long serial)
-{
- int i;
-
- /* don't add the same serial more than once */
- if (display->ignored_crossing_serials[N_IGNORED_CROSSING_SERIALS-1] == serial)
- return;
-
- /* shift serials to the left */
- i = 0;
- while (i < (N_IGNORED_CROSSING_SERIALS - 1))
- {
- display->ignored_crossing_serials[i] = display->ignored_crossing_serials[i+1];
- ++i;
- }
- /* put new one on the end */
- display->ignored_crossing_serials[i] = serial;
-}
-
-static gboolean
-window_raise_with_delay_callback (void *data)
-{
- MetaWindow *window = data;
-
- 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->display->stack) != window)
- {
- if (meta_window_has_pointer (window))
- meta_window_raise (window);
- else
- meta_topic (META_DEBUG_FOCUS,
- "Pointer not inside window, not raising %s",
- window->desc);
- }
-
- return G_SOURCE_REMOVE;
-}
-
-void
-meta_display_queue_autoraise_callback (MetaDisplay *display,
- MetaWindow *window)
-{
- meta_topic (META_DEBUG_FOCUS,
- "Queuing an autoraise timeout for %s with delay %d",
- window->desc,
- meta_prefs_get_auto_raise_delay ());
-
- 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,
- window, NULL);
- g_source_set_name_by_id (display->autoraise_timeout_id, "[mutter] window_raise_with_delay_callback");
- display->autoraise_window = window;
-}
-
-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 ();
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- ClutterSeat *seat = clutter_backend_get_default_seat (clutter_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");
-
- meta_stage_set_active (stage, focus_window == NULL);
- meta_wayland_compositor_set_input_focus (compositor, focus_window);
-
- clutter_stage_repick_device (CLUTTER_STAGE (stage),
- clutter_seat_get_pointer (seat));
-#endif
-}
-
-void
-meta_display_update_focus_window (MetaDisplay *display,
- MetaWindow *window)
-{
- if (display->focus_window == window)
- return;
-
- if (display->focus_window)
- {
- MetaWindow *previous;
-
- meta_topic (META_DEBUG_FOCUS,
- "%s is now the previous focus window due to being focused out or unmapped",
- display->focus_window->desc);
-
- /* 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;
-
- meta_window_set_focused_internal (previous, FALSE);
- }
-
- display->focus_window = window;
-
- if (display->focus_window)
- {
- meta_topic (META_DEBUG_FOCUS, "* Focus --> %s",
- display->focus_window->desc);
- meta_window_set_focused_internal (display->focus_window, TRUE);
- }
- else
- meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL");
-
- if (meta_is_wayland_compositor ())
- meta_display_sync_wayland_input_focus (display);
-
- g_object_notify (G_OBJECT (display), "focus-window");
-}
-
-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 (*timestamp == META_CURRENT_TIME)
- {
- *timestamp = meta_display_get_current_time_roundtrip (display);
- return FALSE;
- }
- else if (XSERVER_TIME_IS_BEFORE (*timestamp, display->last_focus_time))
- {
- if (XSERVER_TIME_IS_BEFORE (*timestamp, display->last_user_time))
- return TRUE;
- else
- {
- *timestamp = display->last_focus_time;
- return FALSE;
- }
- }
-
- return FALSE;
-}
-
-void
-meta_display_set_input_focus (MetaDisplay *display,
- MetaWindow *window,
- gboolean focus_frame,
- guint32 timestamp)
-{
- if (meta_display_timestamp_too_old (display, &timestamp))
- return;
-
- if (display->x11_display)
- {
- meta_x11_display_set_input_focus (display->x11_display, window,
- focus_frame, timestamp);
- }
-
- meta_display_update_focus_window (display, window);
-
- display->last_focus_time = timestamp;
-
- if (window == NULL || window != display->autoraise_window)
- meta_display_remove_autoraise_callback (display);
-}
-
-void
-meta_display_unset_input_focus (MetaDisplay *display,
- guint32 timestamp)
-{
- meta_display_set_input_focus (display, NULL, FALSE, timestamp);
-}
-
-void
-meta_display_register_wayland_window (MetaDisplay *display,
- MetaWindow *window)
-{
- g_hash_table_add (display->wayland_windows, window);
-}
-
-void
-meta_display_unregister_wayland_window (MetaDisplay *display,
- MetaWindow *window)
-{
- g_hash_table_remove (display->wayland_windows, window);
-}
-
-MetaWindow*
-meta_display_lookup_stamp (MetaDisplay *display,
- guint64 stamp)
-{
- return g_hash_table_lookup (display->stamps, &stamp);
-}
-
-void
-meta_display_register_stamp (MetaDisplay *display,
- guint64 *stampp,
- MetaWindow *window)
-{
- g_return_if_fail (g_hash_table_lookup (display->stamps, stampp) == NULL);
-
- g_hash_table_insert (display->stamps, stampp, window);
-}
-
-void
-meta_display_unregister_stamp (MetaDisplay *display,
- guint64 stamp)
-{
- g_return_if_fail (g_hash_table_lookup (display->stamps, &stamp) != NULL);
-
- g_hash_table_remove (display->stamps, &stamp);
-}
-
-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);
- }
-}
-
-/* We return a pointer into a ring of static buffers. This is to make
- * using this function for debug-logging convenient and avoid temporary
- * 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;
-
- result = buffer[pos];
- pos = (pos + 1) % 5;
-
- window = meta_display_lookup_stack_id (display, stack_id);
-
- 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);
-
- return result;
-}
-
-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);
-}
-
-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 META_GRAB_OP_RESIZING_S:
- case META_GRAB_OP_KEYBOARD_RESIZING_S:
- return META_CURSOR_SOUTH_RESIZE;
- break;
- case META_GRAB_OP_RESIZING_SW:
- case META_GRAB_OP_KEYBOARD_RESIZING_SW:
- return META_CURSOR_SW_RESIZE;
- break;
- case META_GRAB_OP_RESIZING_N:
- case META_GRAB_OP_KEYBOARD_RESIZING_N:
- return META_CURSOR_NORTH_RESIZE;
- break;
- case META_GRAB_OP_RESIZING_NE:
- case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- return META_CURSOR_NE_RESIZE;
- break;
- case META_GRAB_OP_RESIZING_NW:
- case META_GRAB_OP_KEYBOARD_RESIZING_NW:
- return META_CURSOR_NW_RESIZE;
- break;
- case META_GRAB_OP_RESIZING_W:
- case META_GRAB_OP_KEYBOARD_RESIZING_W:
- return META_CURSOR_WEST_RESIZE;
- break;
- case META_GRAB_OP_RESIZING_E:
- case META_GRAB_OP_KEYBOARD_RESIZING_E:
- return META_CURSOR_EAST_RESIZE;
- break;
- 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;
- default:
- break;
- }
-
- return META_CURSOR_DEFAULT;
-}
-
-static void
-root_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
- float best_scale,
- int x,
- int y,
- MetaDisplay *display)
-{
- MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor);
- MetaBackend *backend = meta_get_backend ();
-
- if (meta_is_stage_views_scaled ())
- {
- if (best_scale != 0.0f)
- {
- float ceiled_scale;
-
- ceiled_scale = ceilf (best_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);
- }
- }
- 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);
-
- /* 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 void
-manage_root_cursor_sprite_scale (MetaDisplay *display,
- MetaCursorSpriteXcursor *sprite_xcursor)
-{
- g_signal_connect_object (sprite_xcursor,
- "prepare-at",
- G_CALLBACK (root_cursor_prepare_at),
- display,
- 0);
-}
-
-void
-meta_display_reload_cursor (MetaDisplay *display)
-{
- MetaCursor cursor = display->current_cursor;
- MetaCursorSpriteXcursor *sprite_xcursor;
- MetaBackend *backend = meta_get_backend ();
- MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
-
- sprite_xcursor = meta_cursor_sprite_xcursor_new (cursor);
-
- 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);
-
- g_signal_emit (display, display_signals[CURSOR_UPDATED], 0, display);
-}
-
-void
-meta_display_set_cursor (MetaDisplay *display,
- MetaCursor cursor)
-{
- if (cursor == display->current_cursor)
- return;
-
- display->current_cursor = cursor;
- meta_display_reload_cursor (display);
-}
-
-void
-meta_display_update_cursor (MetaDisplay *display)
-{
- meta_display_set_cursor (display, meta_cursor_for_grab_op (display->grab_op));
-}
-
-static MetaWindow *
-get_first_freefloating_window (MetaWindow *window)
-{
- while (meta_window_is_attached_dialog (window))
- window = meta_window_get_transient_for (window);
-
- /* Attached dialogs should always have a non-NULL transient-for */
- g_assert (window != NULL);
-
- return window;
-}
-
-static MetaEventRoute
-get_event_route_from_grab_op (MetaGrabOp op)
-{
- switch (META_GRAB_OP_GET_BASE_TYPE (op))
- {
- 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:
- g_assert_not_reached ();
- return 0;
- }
-}
-
-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)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaWindow *grab_window = NULL;
- MetaEventRoute event_route;
-
- g_assert (window != NULL);
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Doing grab op %u on window %s button %d pointer already grabbed: %d pointer pos %d,%d",
- op, window->desc, button, pointer_already_grabbed,
- root_x, root_y);
-
- if (display->grab_op != META_GRAB_OP_NONE)
- {
- meta_warning ("Attempt to perform window operation %u on window %s when operation %u on %s already in effect",
- 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
- {
- display->grab_initial_x = root_x;
- display->grab_initial_y = root_y;
- display->grab_threshold_movement_reached = FALSE;
- }
- }
-
- grab_window = window;
-
- /* 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);
-
- g_assert (grab_window != NULL);
- g_assert (op != META_GRAB_OP_NONE);
-
- display->grab_have_pointer = FALSE;
-
- if (pointer_already_grabbed)
- display->grab_have_pointer = TRUE;
-
- 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);
- }
-
- if (meta_backend_grab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp))
- display->grab_have_pointer = TRUE;
-
- if (!display->grab_have_pointer && !meta_grab_op_is_keyboard (op))
- {
- meta_topic (META_DEBUG_WINDOW_OPS, "XIGrabDevice() failed");
- return FALSE;
- }
-
- /* Grab keys when beginning window ops; see #126497 */
- if (event_route == META_EVENT_ROUTE_WINDOW_OP)
- {
- 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");
- 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_button = button;
- 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 = 0;
- display->grab_last_edge_resistance_flags = META_EDGE_RESISTANCE_DEFAULT;
- display->grab_frame_action = frame_action;
-
- meta_display_update_cursor (display);
-
- 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",
- display->grab_op, window ? window->desc : "(null)");
-
- meta_window_get_frame_rect (display->grab_window,
- &display->grab_initial_window_pos);
- display->grab_anchor_window_pos = display->grab_initial_window_pos;
-
- if (meta_is_wayland_compositor ())
- {
- meta_display_sync_wayland_input_focus (display);
- meta_display_cancel_touch (display);
- }
-
- g_signal_emit (display, display_signals[GRAB_OP_BEGIN], 0,
- display->grab_window, display->grab_op);
-
- if (display->event_route == META_EVENT_ROUTE_WINDOW_OP)
- meta_window_grab_op_began (display->grab_window, display->grab_op);
-
- return TRUE;
-}
-
-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", grab_op, timestamp);
-
- if (display->event_route == META_EVENT_ROUTE_NORMAL ||
- display->event_route == META_EVENT_ROUTE_COMPOSITOR_GRAB)
- return;
-
- g_assert (grab_window != NULL);
-
- /* 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->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 (!meta_prefs_get_raise_on_click () &&
- !display->grab_threshold_movement_reached)
- meta_window_raise (display->grab_window);
-
- meta_window_grab_op_ended (grab_window, grab_op);
- }
-
- if (display->grab_have_pointer)
- {
- 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", timestamp);
- meta_window_ungrab_all_keys (grab_window, timestamp);
- }
-
- display->event_route = META_EVENT_ROUTE_NORMAL;
- display->grab_window = NULL;
- display->grab_button = 0;
- display->grab_tile_mode = META_TILE_NONE;
- display->grab_tile_monitor_number = -1;
- display->grab_anchor_root_x = 0;
- display->grab_anchor_root_y = 0;
- display->grab_latest_motion_x = 0;
- display->grab_latest_motion_y = 0;
- display->grab_last_moveresize_time = 0;
- display->grab_last_edge_resistance_flags = META_EDGE_RESISTANCE_DEFAULT;
- display->grab_frame_action = FALSE;
-
- meta_display_update_cursor (display);
-
- 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,
- 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
- * Mutter doesn't currently have a grab. %META_GRAB_OP_COMPOSITOR will
- * be returned if a compositor-plugin modal operation is in effect
- * (See mutter_begin_modal_for_plugin())
- */
-MetaGrabOp
-meta_display_get_grab_op (MetaDisplay *display)
-{
- return display->grab_op;
-}
-
-void
-meta_display_check_threshold_reached (MetaDisplay *display,
- int x,
- int y)
-{
- /* Don't bother doing the check again if we've already reached the threshold */
- if (meta_prefs_get_raise_on_click () ||
- display->grab_threshold_movement_reached)
- return;
-
- if (ABS (display->grab_initial_x - x) >= 8 ||
- ABS (display->grab_initial_y - y) >= 8)
- display->grab_threshold_movement_reached = TRUE;
-}
-
-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);
-}
-
-/*
- * Stores whether syncing is currently enabled.
- */
-static gboolean is_syncing = FALSE;
-
-/**
- * meta_is_syncing:
- *
- * Returns whether X synchronisation is currently enabled.
- *
- * 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 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)
-{
- return is_syncing;
-}
-
-/**
- * meta_set_syncing:
- * @setting: whether to turn syncing on or off
- *
- * A handy way to turn on synchronisation on or off for every display.
- */
-void
-meta_set_syncing (gboolean setting)
-{
- if (setting != is_syncing)
- {
- is_syncing = setting;
- if (meta_get_display ())
- XSynchronize (meta_get_display ()->x11_display->xdisplay, is_syncing);
- }
-}
-
-/**
- * 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.
- *
- * 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 = data;
- MetaWindow *window = ping_data->window;
- MetaDisplay *display = window->display;
-
- meta_window_set_alive (window, FALSE);
-
- ping_data->ping_timeout_id = 0;
-
- meta_topic (META_DEBUG_PING,
- "Ping %u on window %s timed out",
- ping_data->serial, ping_data->window->desc);
-
- 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
- * a response, we call a different callback. The window must have
- * the hint showing that it can respond to a ping; if it doesn't,
- * 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.
- */
-void
-meta_display_ping_window (MetaWindow *window,
- guint32 serial)
-{
- GSList *l;
- MetaDisplay *display = window->display;
- MetaPingData *ping_data;
- unsigned int check_alive_timeout;
-
- check_alive_timeout = meta_prefs_get_check_alive_timeout ();
- if (check_alive_timeout == 0)
- return;
-
- if (serial == 0)
- {
- meta_warning ("Tried to ping window %s with a bad serial! Not allowed.",
- window->desc);
- return;
- }
-
- if (!meta_window_can_ping (window))
- return;
-
- for (l = display->pending_pings; l; l = l->next)
- {
- MetaPingData *ping_data = l->data;
-
- if (window == ping_data->window)
- {
- meta_topic (META_DEBUG_PING,
- "Window %s already is being pinged with serial %u",
- window->desc, ping_data->serial);
- return;
- }
-
- if (serial == ping_data->serial)
- {
- meta_warning ("Ping serial %u was reused for window %s, "
- "previous use was for window %s.",
- serial, window->desc, ping_data->window->desc);
- return;
- }
- }
-
- 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_topic (META_DEBUG_PING,
- "Sending ping with serial %u to window %s",
- serial, window->desc);
-
- 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 response
- *
- * 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.
- */
-void
-meta_display_pong_for_serial (MetaDisplay *display,
- guint32 serial)
-{
- GSList *tmp;
-
- meta_topic (META_DEBUG_PING, "Received a pong with serial %u", serial);
-
- for (tmp = display->pending_pings; tmp; tmp = tmp->next)
- {
- MetaPingData *ping_data = tmp->data;
-
- if (serial == ping_data->serial)
- {
- meta_topic (META_DEBUG_PING,
- "Matching ping found for pong %u",
- ping_data->serial);
-
- /* Remove the ping data from the list */
- display->pending_pings = g_slist_remove (display->pending_pings,
- ping_data);
-
- /* Remove the timeout */
- 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;
- }
- }
-}
-
-static MetaGroup *
-get_focused_group (MetaDisplay *display)
-{
- if (display->focus_window)
- return display->focus_window->group;
- else
- return NULL;
-}
-
-#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_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,
- MetaWorkspace *workspace,
- GList *start,
- gboolean skip_first)
-{
- GList *tmp;
-
- g_return_val_if_fail (start != NULL, NULL);
- g_return_val_if_fail (workspace != NULL, NULL);
-
- tmp = start;
- if (skip_first)
- tmp = tmp->next;
-
- while (tmp != NULL)
- {
- MetaWindow *window = tmp->data;
-
- if (IN_TAB_CHAIN (window, type))
- return window;
-
- tmp = tmp->next;
- }
-
- tmp = workspace->mru_list;
- while (tmp != start)
- {
- MetaWindow *window = tmp->data;
-
- if (IN_TAB_CHAIN (window, type))
- return window;
-
- tmp = tmp->next;
- }
-
- return NULL;
-}
-
-static MetaWindow*
-find_tab_backward (MetaDisplay *display,
- MetaTabList type,
- MetaWorkspace *workspace,
- GList *start,
- gboolean skip_last)
-{
- GList *tmp;
-
- g_return_val_if_fail (start != NULL, NULL);
- g_return_val_if_fail (workspace != NULL, NULL);
-
- tmp = start;
- if (skip_last)
- tmp = tmp->prev;
- while (tmp != NULL)
- {
- MetaWindow *window = tmp->data;
-
- if (IN_TAB_CHAIN (window, type))
- return window;
-
- tmp = tmp->prev;
- }
-
- tmp = g_list_last (workspace->mru_list);
- while (tmp != start)
- {
- MetaWindow *window = tmp->data;
-
- if (IN_TAB_CHAIN (window, type))
- return window;
-
- tmp = tmp->prev;
- }
-
- 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
- * @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 contains 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,
- MetaWorkspace *workspace)
-{
- 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;
-
- 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.
- */
- for (tmp = mru_list; tmp; tmp = tmp->next)
- {
- MetaWindow *window = tmp->data;
-
- if (!window->minimized && 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;
-
- if (window->minimized && IN_TAB_CHAIN (window, type))
- tab_list = g_list_prepend (tab_list, window);
- }
-
- tab_list = g_list_reverse (tab_list);
-
- /* If filtering by workspace, include windows from
- * other workspaces that demand attention
- */
- if (workspace)
- for (w = windows; w; w = w->next)
- {
- MetaWindow *l_window = w->data;
-
- 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);
- }
-
- 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_memdup2 (_children, sizeof (uint64_t) * 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;
-
- switch (pref)
- {
- case META_PREF_DRAGGABLE_BORDER_WIDTH:
- meta_display_queue_retheme_all_windows (display);
- break;
- case META_PREF_CURSOR_THEME:
- case META_PREF_CURSOR_SIZE:
- meta_display_reload_cursor (display);
- break;
- default:
- break;
- }
-}
-
-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...",
- 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...",
- 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...",
- 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_context:
- * @display: a #MetaDisplay
- *
- * Returns: (transfer none): the #MetaContext
- */
-MetaContext *
-meta_display_get_context (MetaDisplay *display)
-{
- MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
-
- return priv->context;
-}
-
-/**
- * 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;
-}
-
-MetaGestureTracker *
-meta_display_get_gesture_tracker (MetaDisplay *display)
-{
- return display->gesture_tracker;
-}
-
-gboolean
-meta_display_show_restart_message (MetaDisplay *display,
- const char *message)
-{
- gboolean result = FALSE;
-
- g_signal_emit (display,
- display_signals[SHOW_RESTART_MESSAGE], 0,
- message, &result);
-
- return result;
-}
-
-gboolean
-meta_display_request_restart (MetaDisplay *display)
-{
- gboolean result = FALSE;
-
- g_signal_emit (display,
- display_signals[RESTART], 0,
- &result);
-
- return result;
-}
-
-gboolean
-meta_display_show_resize_popup (MetaDisplay *display,
- gboolean show,
- MetaRectangle *rect,
- int display_w,
- int display_h)
-{
- gboolean result = FALSE;
-
- g_signal_emit (display,
- display_signals[SHOW_RESIZE_POPUP], 0,
- show, rect, display_w, display_h, &result);
-
- return result;
-}
-
-/**
- * meta_display_is_pointer_emulating_sequence:
- * @display: the display
- * @sequence: (nullable): a #ClutterEventSequence
- *
- * Tells whether the event sequence is the used for pointer emulation
- * and single-touch interaction.
- *
- * Returns: #TRUE if the sequence emulates pointer behavior
- **/
-gboolean
-meta_display_is_pointer_emulating_sequence (MetaDisplay *display,
- ClutterEventSequence *sequence)
-{
- if (!sequence)
- return FALSE;
-
- return display->pointer_emulating_sequence == sequence;
-}
-
-void
-meta_display_request_pad_osd (MetaDisplay *display,
- ClutterInputDevice *pad,
- gboolean edition_mode)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaInputMapper *input_mapper;
- const gchar *layout_path = NULL;
- ClutterActor *osd;
- MetaLogicalMonitor *logical_monitor;
- GSettings *settings;
-#ifdef HAVE_LIBWACOM
- WacomDevice *wacom_device;
-#endif
-
- /* 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_mapper = meta_backend_get_input_mapper (meta_get_backend ());
-
- if (input_mapper)
- {
- settings = meta_input_mapper_get_tablet_settings (input_mapper, pad);
- logical_monitor =
- meta_input_mapper_get_device_logical_monitor (input_mapper, 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
- }
-
- if (!layout_path || !settings)
- return;
-
- if (!logical_monitor)
- logical_monitor = meta_backend_get_current_logical_monitor (backend);
-
- g_signal_emit (display, display_signals[SHOW_PAD_OSD], 0,
- pad, settings, layout_path,
- edition_mode, logical_monitor->number, &osd);
-
- if (osd)
- {
- display->current_pad_osd = osd;
- g_object_add_weak_pointer (G_OBJECT (display->current_pad_osd),
- (gpointer *) &display->current_pad_osd);
- }
-}
-
-gchar *
-meta_display_get_pad_action_label (MetaDisplay *display,
- ClutterInputDevice *pad,
- MetaPadActionType action_type,
- guint action_number)
-{
- gchar *label;
-
- /* First, lookup the action, as imposed by settings */
- label = meta_pad_action_mapper_get_action_label (display->pad_action_mapper,
- 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 ())
- {
- MetaWaylandCompositor *compositor;
- MetaWaylandTabletSeat *tablet_seat;
- MetaWaylandTabletPad *tablet_pad = NULL;
-
- 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);
-
- if (tablet_pad)
- {
- label = meta_wayland_tablet_pad_get_label (tablet_pad, action_type,
- action_number);
- }
-
- if (label)
- return label;
- }
-#endif
-
- return NULL;
-}
-
-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);
-}
-
-static gint
-lookup_tablet_monitor (MetaDisplay *display,
- ClutterInputDevice *device)
-{
- MetaInputMapper *input_mapper;
- MetaLogicalMonitor *monitor;
- gint monitor_idx = -1;
-
- input_mapper = meta_backend_get_input_mapper (meta_get_backend ());
- if (!input_mapper)
- return -1;
-
- monitor = meta_input_mapper_get_device_logical_monitor (input_mapper, device);
-
- if (monitor)
- {
- monitor_idx = meta_display_get_monitor_index_for_rect (display,
- &monitor->rect);
- }
-
- return monitor_idx;
-}
-
-void
-meta_display_show_tablet_mapping_notification (MetaDisplay *display,
- ClutterInputDevice *pad,
- const gchar *pretty_name)
-{
- 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);
-}
-
-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 (!pretty_name)
- pretty_name = clutter_input_device_get_device_name (pad);
-
- 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_display_show_osd (display, lookup_tablet_monitor (display, pad),
- "input-tablet-symbolic", message->str);
-
- g_signal_emit (display, display_signals[PAD_MODE_SWITCH], 0, pad,
- n_group, n_mode);
-
- g_string_free (message, TRUE);
-}
-
-void
-meta_display_foreach_window (MetaDisplay *display,
- MetaListWindowsFlags flags,
- MetaDisplayWindowFunc func,
- gpointer data)
-{
- GSList *windows;
-
- /* If we end up doing this often, just keeping a list
- * of windows might be sensible.
- */
-
- windows = meta_display_list_windows (display, flags);
-
- g_slist_foreach (windows, (GFunc) func, data);
-
- g_slist_free (windows);
-}
-
-static void
-meta_display_resize_func (MetaWindow *window,
- gpointer user_data)
-{
- if (window->struts)
- {
- meta_window_update_struts (window);
- }
- meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
-
- meta_window_recalc_features (window);
-}
-
-static void
-on_monitors_changed_internal (MetaMonitorManager *monitor_manager,
- MetaDisplay *display)
-{
- meta_workspace_manager_reload_work_areas (display->workspace_manager);
-
- /* 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);
-
- /* Queue a resize on all the windows */
- meta_display_foreach_window (display, META_LIST_DEFAULT,
- meta_display_resize_func, 0);
-
- meta_display_queue_check_fullscreen (display);
-}
-
-void
-meta_display_restacked (MetaDisplay *display)
-{
- g_signal_emit (display, display_signals[RESTACKED], 0);
-}
-
-static gboolean
-meta_display_update_tile_preview_timeout (gpointer data)
-{
- MetaDisplay *display = data;
- MetaWindow *window = display->grab_window;
- gboolean needs_preview = FALSE;
-
- display->tile_preview_timeout_id = 0;
-
- if (window)
- {
- 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;
-
- case META_TILE_MAXIMIZED:
- 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_tile_area (window, display->preview_tile_mode,
- &tile_rect);
- meta_compositor_show_tile_preview (display->compositor,
- window, &tile_rect, monitor);
- }
- else
- meta_compositor_hide_tile_preview (display->compositor);
-
- return FALSE;
-}
-
-#define TILE_PREVIEW_TIMEOUT_MS 200
-
-void
-meta_display_update_tile_preview (MetaDisplay *display,
- gboolean delay)
-{
- if (delay)
- {
- if (display->tile_preview_timeout_id > 0)
- return;
-
- 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);
-
- meta_display_update_tile_preview_timeout ((gpointer)display);
- }
-}
-
-void
-meta_display_hide_tile_preview (MetaDisplay *display)
-{
- g_clear_handle_id (&display->tile_preview_timeout_id, g_source_remove);
-
- 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)
-{
- GSList *startup_sequences, *l;
-
- startup_sequences =
- meta_startup_notification_get_sequences (display->startup_notification);
-
- for (l = startup_sequences; l; l = l->next)
- {
- MetaStartupSequence *sequence = l->data;
- const char *wmclass;
-
- wmclass = meta_startup_sequence_get_wmclass (sequence);
-
- if (wmclass != NULL &&
- ((window->res_class &&
- strcmp (wmclass, window->res_class) == 0) ||
- (window->res_name &&
- strcmp (wmclass, window->res_name) == 0)))
- return sequence;
- }
-
- return NULL;
-}
-
-/* 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)
-{
- const char *startup_id;
- MetaStartupSequence *sequence = NULL;
-
- /* 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\"",
- 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)
- {
- g_assert (window->startup_id == NULL);
- window->startup_id = g_strdup (meta_startup_sequence_get_id (sequence));
- startup_id = window->startup_id;
-
- meta_topic (META_DEBUG_STARTUP,
- "Ending legacy sequence %s due to window %s",
- meta_startup_sequence_get_id (sequence),
- window->desc);
-
- meta_startup_sequence_complete (sequence);
- }
- }
-
- /* Still no startup ID? Bail. */
- if (!startup_id)
- 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)
- {
- sequence =
- meta_startup_notification_lookup_sequence (display->startup_notification,
- startup_id);
- }
-
- if (sequence != NULL)
- {
- gboolean changed_something = FALSE;
-
- meta_topic (META_DEBUG_STARTUP,
- "Found startup sequence for window %s ID \"%s\"",
- window->desc, startup_id);
-
- if (!window->initial_workspace_set)
- {
- int space = meta_startup_sequence_get_workspace (sequence);
- if (space >= 0)
- {
- meta_topic (META_DEBUG_STARTUP,
- "Setting initial window workspace to %d based on startup info",
- space);
-
- window->initial_workspace_set = TRUE;
- window->initial_workspace = space;
- changed_something = TRUE;
- }
- }
-
- 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",
- 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\"",
- window->desc, startup_id);
- }
-
- return FALSE;
-}
-
-static gboolean
-set_work_area_later_func (MetaDisplay *display)
-{
- meta_topic (META_DEBUG_WORKAREA,
- "Running work area hint computation function");
-
- display->work_area_later = 0;
-
- g_signal_emit (display, display_signals[WORKAREAS_CHANGED], 0);
-
- return FALSE;
-}
-
-void
-meta_display_queue_workarea_recalc (MetaDisplay *display)
-{
- /* Recompute work area later before redrawing */
- if (display->work_area_later == 0)
- {
- meta_topic (META_DEBUG_WORKAREA,
- "Adding work area hint computation function");
- display->work_area_later =
- meta_later_add (META_LATER_BEFORE_REDRAW,
- (GSourceFunc) set_work_area_later_func,
- display,
- NULL);
- }
-}
-
-static gboolean
-check_fullscreen_func (gpointer data)
-{
- 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;
-
- 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))
- {
- gboolean covers_monitors = FALSE;
-
- if (window->hidden)
- 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;
- }
- else if (window->maximized_horizontally &&
- window->maximized_vertically)
- {
- MetaLogicalMonitor *logical_monitor;
-
- 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)
- {
- 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);
- }
- }
- }
-
- g_slist_free (obscured_monitors);
-
- for (l = logical_monitors; l; l = l->next)
- {
- 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)
- {
- 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_queue_check_fullscreen (MetaDisplay *display)
-{
- if (!display->check_fullscreen_later)
- display->check_fullscreen_later = meta_later_add (META_LATER_CHECK_FULLSCREEN,
- check_fullscreen_func,
- display, NULL);
-}
-
-int
-meta_display_get_monitor_index_for_rect (MetaDisplay *display,
- MetaRectangle *rect)
-{
- 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_from_rect (monitor_manager, rect);
- if (!logical_monitor)
- return -1;
-
- return logical_monitor->number;
-}
-
-int
-meta_display_get_monitor_neighbor_index (MetaDisplay *display,
- int which_monitor,
- MetaDisplayDirection direction)
-{
- 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;
-}
-
-/**
- * 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)
-{
- 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_n_monitors:
- * @display: a #MetaDisplay
- *
- * Gets the number of monitors that are joined together to form @display.
- *
- * Return value: the number of monitors
- */
-int
-meta_display_get_n_monitors (MetaDisplay *display)
-{
- 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_primary_monitor:
- * @display: a #MetaDisplay
- *
- * Gets the index of the primary monitor on this @display.
- *
- * Return value: a monitor index
- */
-int
-meta_display_get_primary_monitor (MetaDisplay *display)
-{
- 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_monitor_geometry:
- * @display: a #MetaDisplay
- * @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_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;
-}
-
-/**
- * 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_monitor_in_fullscreen:
- * @display: a #MetaDisplay
- * @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
- * MetaDisplay::in-fullscreen-changed.
- *
- * Returns: %TRUE if there is a fullscreen window covering the specified monitor.
- */
-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;
-}
-
-MetaWindow *
-meta_display_get_pointer_window (MetaDisplay *display,
- MetaWindow *not_this_one)
-{
- MetaWorkspaceManager *workspace_manager = display->workspace_manager;
- MetaBackend *backend = meta_get_backend ();
- MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
- MetaWindow *window;
- graphene_point_t point;
-
- if (not_this_one)
- meta_topic (META_DEBUG_FOCUS,
- "Focusing mouse window excluding %s", not_this_one->desc);
-
- meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
-
- window = meta_stack_get_default_focus_window_at_point (display->stack,
- workspace_manager->active_workspace,
- not_this_one,
- point.x, point.y);
-
- return window;
-}
-
-void
-meta_display_focus_default_window (MetaDisplay *display,
- guint32 timestamp)
-{
- MetaWorkspaceManager *workspace_manager = display->workspace_manager;
-
- meta_workspace_focus_default_window (workspace_manager->active_workspace,
- NULL,
- timestamp);
-}
-
-/**
- * meta_display_get_workspace_manager:
- * @display: a #MetaDisplay
- *
- * Returns: (transfer none): The workspace manager of the display
- */
-MetaWorkspaceManager *
-meta_display_get_workspace_manager (MetaDisplay *display)
-{
- return display->workspace_manager;
-}
-
-MetaStartupNotification *
-meta_display_get_startup_notification (MetaDisplay *display)
-{
- return display->startup_notification;
-}
-
-MetaWindow *
-meta_display_get_window_from_id (MetaDisplay *display,
- uint64_t window_id)
-{
- g_autoptr (GSList) windows = NULL;
- GSList *l;
-
- windows = meta_display_list_windows (display, META_LIST_DEFAULT);
- for (l = windows; l; l = l->next)
- {
- MetaWindow *window = l->data;
-
- if (window->id == window_id)
- return window;
- }
-
- return NULL;
-}
-
-uint64_t
-meta_display_generate_window_id (MetaDisplay *display)
-{
- 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_get_sound_player:
- * @display: a #MetaDisplay
- *
- * Returns: (transfer none): The sound player of the display
- */
-MetaSoundPlayer *
-meta_display_get_sound_player (MetaDisplay *display)
-{
- return display->sound_player;
-}
-
-/**
- * meta_display_get_selection:
- * @display: a #MetaDisplay
- *
- * Returns: (transfer none): The selection manager of the display
- */
-MetaSelection *
-meta_display_get_selection (MetaDisplay *display)
-{
- return display->selection;
-}
diff --git a/src/core/edge-resistance.c b/src/core/edge-resistance.c
deleted file mode 100644
index 3e42936e7..000000000
--- a/src/core/edge-resistance.c
+++ /dev/null
@@ -1,1310 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Edge resistance for move/resize 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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/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 != display->grab_window && \
- window->type != META_WINDOW_DESKTOP && \
- window->type != META_WINDOW_MENU && \
- window->type != META_WINDOW_SPLASHSCREEN
-
-struct ResistanceDataForAnEdge
-{
- gboolean timeout_setup;
- guint timeout_id;
- int timeout_edge_pos;
- gboolean timeout_over;
- GSourceFunc timeout_func;
- MetaWindow *window;
- int keyboard_buildup;
-};
-typedef struct ResistanceDataForAnEdge ResistanceDataForAnEdge;
-
-struct MetaEdgeResistanceData
-{
- GArray *left_edges;
- GArray *right_edges;
- GArray *top_edges;
- GArray *bottom_edges;
-
- ResistanceDataForAnEdge left_data;
- ResistanceDataForAnEdge right_data;
- ResistanceDataForAnEdge top_data;
- ResistanceDataForAnEdge bottom_data;
-};
-
-static void compute_resistance_and_snapping_edges (MetaDisplay *display);
-
-/* !WARNING!: this function can return invalid indices (namely, either -1 or
- * edges->len); this is by design, but you need to remember this.
- */
-static int
-find_index_of_edge_near_position (const GArray *edges,
- int position,
- gboolean want_interval_min,
- gboolean horizontal)
-{
- /* This is basically like a binary search, except that we're trying to
- * find a range instead of an exact value. So, if we have in our array
- * Value: 3 27 316 316 316 505 522 800 1213
- * Index: 0 1 2 3 4 5 6 7 8
- * and we call this function with position=500 & want_interval_min=TRUE
- * then we should get 5 (because 505 is the first value bigger than 500).
- * If we call this function with position=805 and want_interval_min=FALSE
- * then we should get 7 (because 800 is the last value smaller than 800).
- * A couple more, to make things clear:
- * position want_interval_min correct_answer
- * 316 TRUE 2
- * 316 FALSE 4
- * 2 FALSE -1
- * 2000 TRUE 9
- */
- int low, high, mid;
- int compare;
- MetaEdge *edge;
-
- /* 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;
- high = edges->len - 1;
- while (low < high)
- {
- mid = low + (high - low)/2;
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
-
- if (compare == position)
- break;
-
- if (compare > position)
- high = mid - 1;
- else
- low = mid + 1;
- }
-
- /* mid should now be _really_ close to the index we want, so we start
- * linearly searching. However, note that we don't know if mid is less
- * than or greater than what we need and it's possible that there are
- * several equal values equal to what we were searching for and we ended
- * up in the middle of them instead of at the end. So we may need to
- * move mid multiple locations over.
- */
- if (want_interval_min)
- {
- while (compare >= position && mid > 0)
- {
- mid--;
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
- }
- while (compare < position && mid < (int)edges->len - 1)
- {
- mid++;
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
- }
-
- /* Special case for no values in array big enough */
- if (compare < position)
- return edges->len;
-
- /* Return the found value */
- return mid;
- }
- else
- {
- while (compare <= position && mid < (int)edges->len - 1)
- {
- mid++;
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
- }
- while (compare > position && mid > 0)
- {
- mid--;
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
- }
-
- /* Special case for no values in array small enough */
- if (compare > position)
- return -1;
-
- /* Return the found value */
- return mid;
- }
-}
-
-static gboolean
-points_on_same_side (int ref, int pt1, int pt2)
-{
- return (pt1 - ref) * (pt2 - ref) > 0;
-}
-
-static int
-find_nearest_position (const GArray *edges,
- int position,
- int old_position,
- const MetaRectangle *new_rect,
- gboolean horizontal,
- gboolean only_forward)
-{
- /* This is basically just a binary search except that we're looking
- * for the value closest to position, rather than finding that
- * actual value. Also, we ignore any edges that aren't relevant
- * given the horizontal/vertical position of new_rect.
- */
- int low, high, mid;
- int compare;
- MetaEdge *edge;
- int best, best_dist, i;
- gboolean edges_align;
-
- /* 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;
- high = edges->len - 1;
- while (low < high)
- {
- mid = low + (high - low)/2;
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
-
- if (compare == position)
- break;
-
- if (compare > position)
- high = mid - 1;
- else
- low = mid + 1;
- }
-
- /* mid should now be _really_ close to the index we want, so we
- * start searching nearby for something that overlaps and is closer
- * than the original position.
- */
- best = old_position;
- best_dist = INT_MAX;
-
- /* Start the search at mid */
- edge = g_array_index (edges, MetaEdge*, mid);
- compare = horizontal ? edge->rect.x : edge->rect.y;
- edges_align = meta_rectangle_edge_aligns (new_rect, edge);
- if (edges_align &&
- (!only_forward || !points_on_same_side (position, compare, old_position)))
- {
- int dist = ABS (compare - position);
- if (dist < best_dist)
- {
- best = compare;
- best_dist = dist;
- }
- }
-
- /* Now start searching higher than mid */
- for (i = mid + 1; i < (int)edges->len; i++)
- {
- edge = g_array_index (edges, MetaEdge*, i);
- compare = horizontal ? edge->rect.x : edge->rect.y;
-
- edges_align = horizontal ?
- meta_rectangle_vert_overlap (&edge->rect, new_rect) :
- meta_rectangle_horiz_overlap (&edge->rect, new_rect);
-
- if (edges_align &&
- (!only_forward ||
- !points_on_same_side (position, compare, old_position)))
- {
- int dist = ABS (compare - position);
- if (dist < best_dist)
- {
- best = compare;
- best_dist = dist;
- }
- break;
- }
- }
-
- /* Now start searching lower than mid */
- for (i = mid-1; i >= 0; i--)
- {
- edge = g_array_index (edges, MetaEdge*, i);
- compare = horizontal ? edge->rect.x : edge->rect.y;
-
- edges_align = horizontal ?
- meta_rectangle_vert_overlap (&edge->rect, new_rect) :
- meta_rectangle_horiz_overlap (&edge->rect, new_rect);
-
- if (edges_align &&
- (!only_forward ||
- !points_on_same_side (position, compare, old_position)))
- {
- int dist = ABS (compare - position);
- if (dist < best_dist)
- {
- best = compare;
- best_dist = dist;
- }
- break;
- }
- }
-
- /* Return the best one found */
- return best;
-}
-
-static gboolean
-movement_towards_edge (MetaSide side, int increment)
-{
- switch (side)
- {
- case META_SIDE_LEFT:
- case META_SIDE_TOP:
- return increment < 0;
- case META_SIDE_RIGHT:
- case META_SIDE_BOTTOM:
- return increment > 0;
- default:
- g_assert_not_reached ();
- return FALSE;
- }
-}
-
-static gboolean
-edge_resistance_timeout (gpointer data)
-{
- ResistanceDataForAnEdge *resistance_data = data;
-
- resistance_data->timeout_over = TRUE;
- resistance_data->timeout_id = 0;
- (*resistance_data->timeout_func)(resistance_data->window);
-
- return FALSE;
-}
-
-static int
-apply_edge_resistance (MetaWindow *window,
- int old_pos,
- int new_pos,
- const MetaRectangle *old_rect,
- const MetaRectangle *new_rect,
- GArray *edges,
- ResistanceDataForAnEdge *resistance_data,
- GSourceFunc timeout_func,
- gboolean xdir,
- gboolean include_windows,
- gboolean keyboard_op)
-{
- int i, begin, end;
- int last_edge;
- gboolean increasing = new_pos > old_pos;
- int increment = increasing ? 1 : -1;
-
- const int PIXEL_DISTANCE_THRESHOLD_TOWARDS_WINDOW = 16;
- const int PIXEL_DISTANCE_THRESHOLD_AWAYFROM_WINDOW = 0;
- const int PIXEL_DISTANCE_THRESHOLD_TOWARDS_MONITOR = 32;
- const int PIXEL_DISTANCE_THRESHOLD_AWAYFROM_MONITOR = 0;
- const int PIXEL_DISTANCE_THRESHOLD_TOWARDS_SCREEN = 32;
- const int PIXEL_DISTANCE_THRESHOLD_AWAYFROM_SCREEN = 0;
- const int TIMEOUT_RESISTANCE_LENGTH_MS_WINDOW = 0;
- const int TIMEOUT_RESISTANCE_LENGTH_MS_MONITOR = 0;
- const int TIMEOUT_RESISTANCE_LENGTH_MS_SCREEN = 0;
-
- /* Quit if no movement was specified */
- if (old_pos == new_pos)
- return new_pos;
-
- /* Remove the old timeout if it's no longer relevant */
- if (resistance_data->timeout_setup &&
- ((resistance_data->timeout_edge_pos > old_pos &&
- resistance_data->timeout_edge_pos > new_pos) ||
- (resistance_data->timeout_edge_pos < old_pos &&
- resistance_data->timeout_edge_pos < new_pos)))
- {
- resistance_data->timeout_setup = FALSE;
- 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. */
- begin = find_index_of_edge_near_position (edges, old_pos, increasing, xdir);
- end = find_index_of_edge_near_position (edges, new_pos, !increasing, xdir);
-
- /* begin and end can be outside the array index, if the window is partially
- * off the screen
- */
- last_edge = edges->len - 1;
- begin = CLAMP (begin, 0, last_edge);
- end = CLAMP (end, 0, last_edge);
-
- /* Loop over all these edges we're moving past/to. */
- i = begin;
- while ((increasing && i <= end) ||
- (!increasing && i >= end))
- {
- gboolean edges_align;
- MetaEdge *edge = g_array_index (edges, MetaEdge*, i);
- int compare = xdir ? edge->rect.x : edge->rect.y;
-
- /* Find out if this edge is relevant */
- edges_align = meta_rectangle_edge_aligns (new_rect, edge) ||
- meta_rectangle_edge_aligns (old_rect, edge);
-
- /* Nothing to do unless the edges align */
- if (!edges_align)
- {
- /* Go to the next edge in the range */
- i += increment;
- continue;
- }
-
- /* Rest is easier to read if we split on keyboard vs. mouse op */
- if (keyboard_op)
- {
- if ((old_pos < compare && compare < new_pos) ||
- (old_pos > compare && compare > new_pos))
- return compare;
- }
- else /* mouse op */
- {
- int threshold;
-
- /* TIMEOUT RESISTANCE: If the edge is relevant and we're moving
- * towards it, then we may want to have some kind of time delay
- * before the user can move past this edge.
- */
- if (movement_towards_edge (edge->side_type, increment))
- {
- /* First, determine the length of time for the resistance */
- int timeout_length_ms = 0;
- switch (edge->edge_type)
- {
- case META_EDGE_WINDOW:
- if (include_windows)
- timeout_length_ms = TIMEOUT_RESISTANCE_LENGTH_MS_WINDOW;
- break;
- case META_EDGE_MONITOR:
- timeout_length_ms = TIMEOUT_RESISTANCE_LENGTH_MS_MONITOR;
- break;
- case META_EDGE_SCREEN:
- timeout_length_ms = TIMEOUT_RESISTANCE_LENGTH_MS_SCREEN;
- break;
- }
-
- if (!resistance_data->timeout_setup &&
- timeout_length_ms != 0)
- {
- resistance_data->timeout_id =
- 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;
- resistance_data->timeout_func = timeout_func;
- resistance_data->window = window;
- }
- if (!resistance_data->timeout_over &&
- timeout_length_ms != 0)
- return compare;
- }
-
- /* PIXEL DISTANCE MOUSE RESISTANCE: If the edge matters and the
- * user hasn't moved at least threshold pixels past this edge,
- * stop movement at this edge. (Note that this is different from
- * keyboard resistance precisely because keyboard move ops are
- * relative to previous positions, whereas mouse move ops are
- * relative to differences in mouse position and mouse position
- * is an absolute quantity rather than a relative quantity)
- */
-
- /* First, determine the threshold */
- threshold = 0;
- switch (edge->edge_type)
- {
- case META_EDGE_WINDOW:
- if (!include_windows)
- break;
- if (movement_towards_edge (edge->side_type, increment))
- threshold = PIXEL_DISTANCE_THRESHOLD_TOWARDS_WINDOW;
- else
- threshold = PIXEL_DISTANCE_THRESHOLD_AWAYFROM_WINDOW;
- break;
- case META_EDGE_MONITOR:
- if (movement_towards_edge (edge->side_type, increment))
- threshold = PIXEL_DISTANCE_THRESHOLD_TOWARDS_MONITOR;
- else
- threshold = PIXEL_DISTANCE_THRESHOLD_AWAYFROM_MONITOR;
- break;
- case META_EDGE_SCREEN:
- if (movement_towards_edge (edge->side_type, increment))
- threshold = PIXEL_DISTANCE_THRESHOLD_TOWARDS_SCREEN;
- else
- threshold = PIXEL_DISTANCE_THRESHOLD_AWAYFROM_SCREEN;
- break;
- }
-
- if (ABS (compare - new_pos) < threshold)
- return compare;
- }
-
- /* Go to the next edge in the range */
- i += increment;
- }
-
- return new_pos;
-}
-
-static int
-apply_edge_snapping (int old_pos,
- int new_pos,
- const MetaRectangle *new_rect,
- GArray *edges,
- gboolean xdir,
- gboolean keyboard_op)
-{
- int snap_to;
-
- if (old_pos == new_pos)
- return new_pos;
-
- snap_to = find_nearest_position (edges,
- new_pos,
- old_pos,
- new_rect,
- xdir,
- keyboard_op);
-
- /* If mouse snap-moving, the user could easily accidentally move just a
- * couple pixels in a direction they didn't mean to move; so ignore snap
- * movement in those cases unless it's only a small number of pixels
- * anyway.
- */
- if (!keyboard_op &&
- ABS (snap_to - old_pos) >= 8 &&
- ABS (new_pos - old_pos) < 8)
- return old_pos;
- else
- /* Otherwise, return the snapping position found */
- return snap_to;
-}
-
-/* This function takes the position (including any frame) of the window and
- * a proposed new position (ignoring edge resistance/snapping), and then
- * applies edge resistance to EACH edge (separately) updating new_outer.
- * It returns true if new_outer is modified, false otherwise.
- *
- * display->grab_edge_resistance_data MUST already be setup or calling this
- * function will cause a crash.
- */
-static gboolean
-apply_edge_resistance_to_each_side (MetaDisplay *display,
- MetaWindow *window,
- const MetaRectangle *old_outer,
- MetaRectangle *new_outer,
- GSourceFunc timeout_func,
- MetaEdgeResistanceFlags flags,
- gboolean is_resize)
-{
- MetaEdgeResistanceData *edge_data;
- MetaRectangle modified_rect;
- gboolean modified;
- int new_left, new_right, new_top, new_bottom;
- gboolean auto_snap, keyboard_op;
-
- auto_snap = flags & META_EDGE_RESISTANCE_SNAP;
- keyboard_op = flags & META_EDGE_RESISTANCE_KEYBOARD_OP;
-
- if (display->grab_edge_resistance_data == NULL)
- compute_resistance_and_snapping_edges (display);
-
- edge_data = display->grab_edge_resistance_data;
-
- 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
- * sides of windows to both left and right edges.
- */
-
- new_left = apply_edge_snapping (BOX_LEFT (*old_outer),
- BOX_LEFT (*new_outer),
- new_outer,
- edge_data->left_edges,
- TRUE,
- keyboard_op);
-
- new_right = apply_edge_snapping (BOX_RIGHT (*old_outer),
- BOX_RIGHT (*new_outer),
- new_outer,
- edge_data->right_edges,
- TRUE,
- keyboard_op);
-
- new_top = apply_edge_snapping (BOX_TOP (*old_outer),
- BOX_TOP (*new_outer),
- new_outer,
- edge_data->top_edges,
- FALSE,
- keyboard_op);
-
- new_bottom = apply_edge_snapping (BOX_BOTTOM (*old_outer),
- BOX_BOTTOM (*new_outer),
- new_outer,
- edge_data->bottom_edges,
- 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
- {
- gboolean include_windows = flags & META_EDGE_RESISTANCE_WINDOWS;
-
- /* Disable edge resistance for resizes when windows have size
- * increment hints; see #346782. For all other cases, apply
- * them.
- */
- if (!is_resize || window->size_hints.width_inc == 1)
- {
- /* Now, apply the normal horizontal edge resistance */
- new_left = apply_edge_resistance (window,
- BOX_LEFT (*old_outer),
- BOX_LEFT (*new_outer),
- old_outer,
- new_outer,
- edge_data->left_edges,
- &edge_data->left_data,
- timeout_func,
- TRUE,
- include_windows,
- keyboard_op);
- new_right = apply_edge_resistance (window,
- BOX_RIGHT (*old_outer),
- BOX_RIGHT (*new_outer),
- old_outer,
- new_outer,
- edge_data->right_edges,
- &edge_data->right_data,
- timeout_func,
- TRUE,
- include_windows,
- keyboard_op);
- }
- else
- {
- new_left = new_outer->x;
- new_right = new_outer->x + new_outer->width;
- }
- /* Same for vertical resizes... */
- if (!is_resize || window->size_hints.height_inc == 1)
- {
- new_top = apply_edge_resistance (window,
- BOX_TOP (*old_outer),
- BOX_TOP (*new_outer),
- old_outer,
- new_outer,
- edge_data->top_edges,
- &edge_data->top_data,
- timeout_func,
- FALSE,
- include_windows,
- keyboard_op);
- new_bottom = apply_edge_resistance (window,
- BOX_BOTTOM (*old_outer),
- BOX_BOTTOM (*new_outer),
- old_outer,
- new_outer,
- edge_data->bottom_edges,
- &edge_data->bottom_data,
- timeout_func,
- FALSE,
- include_windows,
- keyboard_op);
- }
- else
- {
- new_top = new_outer->y;
- new_bottom = new_outer->y + new_outer->height;
- }
- }
-
- /* Determine whether anything changed, and save the changes */
- modified_rect = meta_rect (new_left,
- new_top,
- new_right - new_left,
- new_bottom - new_top);
- modified = !meta_rectangle_equal (new_outer, &modified_rect);
- *new_outer = modified_rect;
- return modified;
-}
-
-void
-meta_display_cleanup_edges (MetaDisplay *display)
-{
- guint i,j;
- MetaEdgeResistanceData *edge_data = display->grab_edge_resistance_data;
- GHashTable *edges_to_be_freed;
-
- if (edge_data == NULL) /* Not currently cached */
- return;
-
- /* We first need to clean out any window edges */
- edges_to_be_freed = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- g_free, NULL);
- for (i = 0; i < 4; i++)
- {
- GArray *tmp = NULL;
- MetaSide side;
- switch (i)
- {
- case 0:
- tmp = edge_data->left_edges;
- side = META_SIDE_LEFT;
- break;
- case 1:
- tmp = edge_data->right_edges;
- side = META_SIDE_RIGHT;
- break;
- case 2:
- tmp = edge_data->top_edges;
- side = META_SIDE_TOP;
- break;
- case 3:
- tmp = edge_data->bottom_edges;
- side = META_SIDE_BOTTOM;
- break;
- default:
- g_assert_not_reached ();
- }
-
- for (j = 0; j < tmp->len; j++)
- {
- MetaEdge *edge = g_array_index (tmp, MetaEdge*, j);
- if (edge->edge_type == META_EDGE_WINDOW &&
- edge->side_type == side)
- {
- /* The same edge will appear in two arrays, and we can't free
- * it yet we still need to compare edge->side_type for the other
- * array that it is in. So store it in a hash table for later
- * freeing. Could also do this in a simple linked list.
- */
- g_hash_table_insert (edges_to_be_freed, edge, edge);
- }
- }
- }
-
- /* 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 */
- g_array_free (edge_data->left_edges, TRUE);
- g_array_free (edge_data->right_edges, TRUE);
- g_array_free (edge_data->top_edges, TRUE);
- g_array_free (edge_data->bottom_edges, TRUE);
- edge_data->left_edges = NULL;
- edge_data->right_edges = NULL;
- edge_data->top_edges = NULL;
- edge_data->bottom_edges = NULL;
-
- /* Cleanup the timeouts */
- 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;
-}
-
-static int
-stupid_sort_requiring_extra_pointer_dereference (gconstpointer a,
- gconstpointer b)
-{
- const MetaEdge * const *a_edge = a;
- const MetaEdge * const *b_edge = b;
- return meta_rectangle_edge_cmp_ignore_type (*a_edge, *b_edge);
-}
-
-static void
-cache_edges (MetaDisplay *display,
- GList *window_edges,
- GList *monitor_edges,
- GList *screen_edges)
-{
- MetaEdgeResistanceData *edge_data;
- GList *tmp;
- int num_left, num_right, num_top, num_bottom;
- int i;
-
- /*
- * 0th: Print debugging information to the log about the edges
- */
-#ifdef WITH_VERBOSE_MODE
- if (meta_is_verbose())
- {
- int max_edges = MAX (MAX( g_list_length (window_edges),
- g_list_length (monitor_edges)),
- g_list_length (screen_edges));
- char big_buffer[(EDGE_LENGTH+2)*max_edges];
-
- meta_rectangle_edge_list_to_string (window_edges, ", ", big_buffer);
- meta_topic (META_DEBUG_EDGE_RESISTANCE,
- "Window edges for resistance : %s", big_buffer);
-
- meta_rectangle_edge_list_to_string (monitor_edges, ", ", big_buffer);
- meta_topic (META_DEBUG_EDGE_RESISTANCE,
- "Monitor edges for resistance: %s", big_buffer);
-
- meta_rectangle_edge_list_to_string (screen_edges, ", ", big_buffer);
- meta_topic (META_DEBUG_EDGE_RESISTANCE,
- "Screen edges for resistance : %s", big_buffer);
- }
-#endif
-
- /*
- * 1st: Get the total number of each kind of edge
- */
- num_left = num_right = num_top = num_bottom = 0;
- for (i = 0; i < 3; i++)
- {
- tmp = NULL;
- switch (i)
- {
- case 0:
- tmp = window_edges;
- break;
- case 1:
- tmp = monitor_edges;
- break;
- case 2:
- tmp = screen_edges;
- break;
- default:
- g_assert_not_reached ();
- }
-
- while (tmp)
- {
- MetaEdge *edge = tmp->data;
- switch (edge->side_type)
- {
- case META_SIDE_LEFT:
- num_left++;
- break;
- case META_SIDE_RIGHT:
- num_right++;
- break;
- case META_SIDE_TOP:
- num_top++;
- break;
- case META_SIDE_BOTTOM:
- num_bottom++;
- break;
- default:
- g_assert_not_reached ();
- }
- tmp = tmp->next;
- }
- }
-
- /*
- * 2nd: Allocate the edges
- */
- g_assert (display->grab_edge_resistance_data == NULL);
- display->grab_edge_resistance_data = g_new0 (MetaEdgeResistanceData, 1);
- edge_data = display->grab_edge_resistance_data;
- edge_data->left_edges = g_array_sized_new (FALSE,
- FALSE,
- sizeof(MetaEdge*),
- num_left + num_right);
- edge_data->right_edges = g_array_sized_new (FALSE,
- FALSE,
- sizeof(MetaEdge*),
- num_left + num_right);
- edge_data->top_edges = g_array_sized_new (FALSE,
- FALSE,
- sizeof(MetaEdge*),
- num_top + num_bottom);
- edge_data->bottom_edges = g_array_sized_new (FALSE,
- FALSE,
- sizeof(MetaEdge*),
- num_top + num_bottom);
-
- /*
- * 3rd: Add the edges to the arrays
- */
- for (i = 0; i < 3; i++)
- {
- tmp = NULL;
- switch (i)
- {
- case 0:
- tmp = window_edges;
- break;
- case 1:
- tmp = monitor_edges;
- break;
- case 2:
- tmp = screen_edges;
- break;
- default:
- g_assert_not_reached ();
- }
-
- while (tmp)
- {
- MetaEdge *edge = tmp->data;
- switch (edge->side_type)
- {
- case META_SIDE_LEFT:
- case META_SIDE_RIGHT:
- g_array_append_val (edge_data->left_edges, edge);
- g_array_append_val (edge_data->right_edges, edge);
- break;
- case META_SIDE_TOP:
- case META_SIDE_BOTTOM:
- g_array_append_val (edge_data->top_edges, edge);
- g_array_append_val (edge_data->bottom_edges, edge);
- break;
- default:
- g_assert_not_reached ();
- }
- tmp = tmp->next;
- }
- }
-
- /*
- * 4th: Sort the arrays (FIXME: This is kinda dumb since the arrays were
- * individually sorted earlier and we could have done this faster and
- * avoided this sort by sticking them into the array with some simple
- * merging of the lists).
- */
- g_array_sort (display->grab_edge_resistance_data->left_edges,
- stupid_sort_requiring_extra_pointer_dereference);
- g_array_sort (display->grab_edge_resistance_data->right_edges,
- stupid_sort_requiring_extra_pointer_dereference);
- g_array_sort (display->grab_edge_resistance_data->top_edges,
- stupid_sort_requiring_extra_pointer_dereference);
- g_array_sort (display->grab_edge_resistance_data->bottom_edges,
- stupid_sort_requiring_extra_pointer_dereference);
-}
-
-static void
-initialize_grab_edge_resistance_data (MetaDisplay *display)
-{
- MetaEdgeResistanceData *edge_data = display->grab_edge_resistance_data;
-
- edge_data->left_data.timeout_setup = FALSE;
- edge_data->right_data.timeout_setup = FALSE;
- edge_data->top_data.timeout_setup = FALSE;
- edge_data->bottom_data.timeout_setup = FALSE;
-
- edge_data->left_data.keyboard_buildup = 0;
- edge_data->right_data.keyboard_buildup = 0;
- edge_data->top_data.keyboard_buildup = 0;
- edge_data->bottom_data.keyboard_buildup = 0;
-}
-
-static void
-compute_resistance_and_snapping_edges (MetaDisplay *display)
-{
- GList *stacked_windows;
- GList *cur_window_iter;
- GList *edges;
- /* Lists of window positions (rects) and their relative stacking positions */
- int stack_position;
- GSList *obscuring_windows, *window_stacking;
- /* The portions of the above lists that still remain at the stacking position
- * 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,
- "Computing edges to resist-movement or snap-to for %s.",
- display->grab_window->desc);
-
- /*
- * 1st: Get the list of relevant windows, from bottom to top
- */
- stacked_windows =
- meta_stack_list_windows (display->stack,
- workspace_manager->active_workspace);
-
- /*
- * 2nd: we need to separate that stacked list into a list of windows that
- * can obscure other edges. To make sure we only have windows obscuring
- * those below it instead of going both ways, we also need to keep a
- * counter list. Messy, I know.
- */
- obscuring_windows = window_stacking = NULL;
- cur_window_iter = stacked_windows;
- stack_position = 0;
- while (cur_window_iter != NULL)
- {
- MetaWindow *cur_window = cur_window_iter->data;
- if (WINDOW_EDGES_RELEVANT (cur_window, display))
- {
- MetaRectangle *new_rect;
- new_rect = g_new (MetaRectangle, 1);
- meta_window_get_frame_rect (cur_window, new_rect);
- obscuring_windows = g_slist_prepend (obscuring_windows, new_rect);
- window_stacking =
- g_slist_prepend (window_stacking, GINT_TO_POINTER (stack_position));
- }
-
- stack_position++;
- cur_window_iter = cur_window_iter->next;
- }
- /* Put 'em in bottom to top order */
- rem_windows = obscuring_windows = g_slist_reverse (obscuring_windows);
- rem_win_stacking = window_stacking = g_slist_reverse (window_stacking);
-
- /*
- * 3rd: loop over the windows again, this time getting the edges from
- * them and removing intersections with the relevant obscuring_windows &
- * obscuring_docks.
- */
- edges = NULL;
- stack_position = 0;
- cur_window_iter = stacked_windows;
- while (cur_window_iter != NULL)
- {
- MetaRectangle cur_rect;
- MetaWindow *cur_window = cur_window_iter->data;
- 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
- * which are handled separately
- */
- if (WINDOW_EDGES_RELEVANT (cur_window, display) &&
- cur_window->type != META_WINDOW_DOCK)
- {
- 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_rect,
- &reduced);
-
- new_edges = NULL;
-
- /* Left side of this window is resistance for the right edge of
- * the window being moved.
- */
- new_edge = g_new (MetaEdge, 1);
- new_edge->rect = reduced;
- new_edge->rect.width = 0;
- new_edge->side_type = META_SIDE_RIGHT;
- new_edge->edge_type = META_EDGE_WINDOW;
- new_edges = g_list_prepend (new_edges, new_edge);
-
- /* Right side of this window is resistance for the left edge of
- * the window being moved.
- */
- new_edge = g_new (MetaEdge, 1);
- new_edge->rect = reduced;
- new_edge->rect.x += new_edge->rect.width;
- new_edge->rect.width = 0;
- 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.
- */
- new_edge = g_new (MetaEdge, 1);
- new_edge->rect = reduced;
- new_edge->rect.height = 0;
- new_edge->side_type = META_SIDE_BOTTOM;
- 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.
- */
- new_edge = g_new (MetaEdge, 1);
- new_edge->rect = reduced;
- new_edge->rect.y += new_edge->rect.height;
- new_edge->rect.height = 0;
- new_edge->side_type = META_SIDE_TOP;
- new_edge->edge_type = META_EDGE_WINDOW;
- new_edges = g_list_prepend (new_edges, new_edge);
-
- /* Update the remaining windows to only those at a higher
- * stacking position than this one.
- */
- while (rem_win_stacking &&
- stack_position >= GPOINTER_TO_INT (rem_win_stacking->data))
- {
- rem_windows = rem_windows->next;
- rem_win_stacking = rem_win_stacking->next;
- }
-
- /* Remove edge portions overlapped by rem_windows and rem_docks */
- new_edges =
- meta_rectangle_remove_intersections_with_boxes_from_edges (
- new_edges,
- rem_windows);
-
- /* Save the new edges */
- edges = g_list_concat (new_edges, edges);
- }
-
- stack_position++;
- cur_window_iter = cur_window_iter->next;
- }
-
- /*
- * 4th: Free the extra memory not needed and sort the list
- */
- g_list_free (stacked_windows);
- /* Free the memory used by the obscuring windows/docks lists */
- g_slist_free (window_stacking);
- 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...
- */
- edges = g_list_sort (edges, meta_rectangle_edge_cmp);
-
- /*
- * 5th: Cache the combination of these edges with the onscreen and
- * monitor edges in an array for quick access. Free the edges since
- * they've been cached elsewhere.
- */
- cache_edges (display,
- edges,
- workspace_manager->active_workspace->monitor_edges,
- workspace_manager->active_workspace->screen_edges);
- g_list_free (edges);
-
- /*
- * 6th: Initialize the resistance timeouts and buildups
- */
- initialize_grab_edge_resistance_data (display);
-}
-
-void
-meta_window_edge_resistance_for_move (MetaWindow *window,
- int *new_x,
- int *new_y,
- GSourceFunc timeout_func,
- MetaEdgeResistanceFlags flags)
-{
- MetaRectangle old_outer, proposed_outer, new_outer;
- MetaEdgeResistanceFlags saved_flags;
- gboolean is_resize, is_keyboard_op, snap;
-
- meta_window_get_frame_rect (window, &old_outer);
-
- proposed_outer = old_outer;
- proposed_outer.x = *new_x;
- proposed_outer.y = *new_y;
- new_outer = proposed_outer;
-
- snap = flags & META_EDGE_RESISTANCE_SNAP;
- is_keyboard_op = flags & META_EDGE_RESISTANCE_KEYBOARD_OP;
- saved_flags = flags & ~META_EDGE_RESISTANCE_KEYBOARD_OP;
-
- window->display->grab_last_edge_resistance_flags = saved_flags;
- is_resize = FALSE;
- if (apply_edge_resistance_to_each_side (window->display,
- window,
- &old_outer,
- &new_outer,
- timeout_func,
- flags,
- is_resize))
- {
- /* apply_edge_resistance_to_each_side independently applies
- * resistance to both the right and left edges of new_outer as both
- * could meet areas of resistance. But we don't want a resize, so we
- * just have both edges move according to the stricter of the
- * resistances. Same thing goes for top & bottom edges.
- */
- MetaRectangle *reference;
- int left_change, right_change, smaller_x_change;
- int top_change, bottom_change, smaller_y_change;
-
- if (snap && !is_keyboard_op)
- reference = &proposed_outer;
- else
- reference = &old_outer;
-
- left_change = BOX_LEFT (new_outer) - BOX_LEFT (*reference);
- right_change = BOX_RIGHT (new_outer) - BOX_RIGHT (*reference);
- if ( snap && is_keyboard_op && left_change == 0)
- smaller_x_change = right_change;
- else if (snap && is_keyboard_op && right_change == 0)
- smaller_x_change = left_change;
- else if (ABS (left_change) < ABS (right_change))
- smaller_x_change = left_change;
- else
- smaller_x_change = right_change;
-
- top_change = BOX_TOP (new_outer) - BOX_TOP (*reference);
- bottom_change = BOX_BOTTOM (new_outer) - BOX_BOTTOM (*reference);
- if ( snap && is_keyboard_op && top_change == 0)
- smaller_y_change = bottom_change;
- else if (snap && is_keyboard_op && bottom_change == 0)
- smaller_y_change = top_change;
- else if (ABS (top_change) < ABS (bottom_change))
- smaller_y_change = top_change;
- else
- smaller_y_change = bottom_change;
-
- *new_x = old_outer.x + smaller_x_change +
- (BOX_LEFT (*reference) - BOX_LEFT (old_outer));
- *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",
- proposed_outer.x, proposed_outer.y,
- *new_x, *new_y);
- }
-}
-
-void
-meta_window_edge_resistance_for_resize (MetaWindow *window,
- int *new_width,
- int *new_height,
- MetaGravity gravity,
- GSourceFunc timeout_func,
- MetaEdgeResistanceFlags flags)
-{
- MetaRectangle old_outer, new_outer;
- MetaEdgeResistanceFlags saved_flags;
- int proposed_outer_width, proposed_outer_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,
- proposed_outer_width,
- proposed_outer_height);
-
- saved_flags = flags & ~META_EDGE_RESISTANCE_KEYBOARD_OP;
- window->display->grab_last_edge_resistance_flags = saved_flags;
-
- if (apply_edge_resistance_to_each_side (window->display,
- window,
- &old_outer,
- &new_outer,
- timeout_func,
- flags,
- TRUE))
- {
- *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",
- proposed_outer_width, proposed_outer_height,
- new_outer.width, new_outer.height);
- }
-}
diff --git a/src/core/edge-resistance.h b/src/core/edge-resistance.h
deleted file mode 100644
index 4eb6abdca..000000000
--- a/src/core/edge-resistance.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_EDGE_RESISTANCE_H
-#define META_EDGE_RESISTANCE_H
-
-#include "core/window-private.h"
-
-void meta_window_edge_resistance_for_move (MetaWindow *window,
- int *new_x,
- int *new_y,
- GSourceFunc timeout_func,
- MetaEdgeResistanceFlags flags);
-void meta_window_edge_resistance_for_resize (MetaWindow *window,
- int *new_width,
- int *new_height,
- MetaGravity gravity,
- GSourceFunc timeout_func,
- MetaEdgeResistanceFlags flags);
-
-#endif /* META_EDGE_RESISTANCE_H */
-
diff --git a/src/core/events.c b/src/core/events.c
deleted file mode 100644
index 8afc720ef..000000000
--- a/src/core/events.c
+++ /dev/null
@@ -1,509 +0,0 @@
-/* -*- 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-manager.h"
-#include "backends/x11/meta-backend-x11.h"
-#include "backends/x11/meta-input-device-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)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaIdleManager *idle_manager;
-
- if (clutter_event_get_device (event) == NULL)
- return;
-
- if (event->any.flags & CLUTTER_EVENT_FLAG_SYNTHETIC ||
- event->type == CLUTTER_ENTER ||
- event->type == CLUTTER_LEAVE)
- return;
-
- idle_manager = meta_backend_get_idle_manager (backend);
- meta_idle_manager_reset_idle_time (idle_manager);
-}
-
-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)
-{
- ClutterInputDevice *device;
- Display *xdisplay;
- int event_mode;
- int device_id;
-
- if (event->type != CLUTTER_BUTTON_PRESS)
- return;
-
- if (!META_IS_BACKEND_X11 (backend))
- return;
-
- device = clutter_event_get_device (event);
- device_id = meta_input_device_x11_get_device_id (device);
- switch (unfreeze_method)
- {
- case EVENTS_UNFREEZE_SYNC:
- event_mode = XISyncDevice;
- meta_verbose ("Syncing events time %u device %i",
- (unsigned int) event->button.time, device_id);
- break;
- case EVENTS_UNFREEZE_REPLAY:
- event_mode = XIReplayDevice;
- meta_verbose ("Replaying events time %u device %i",
- (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_pad_action_mapper_handle_event (display->pad_action_mapper, 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)
- {
- MetaCursorRenderer *cursor_renderer;
- ClutterInputDevice *device;
-
- device = clutter_event_get_device (event);
- cursor_renderer = meta_backend_get_cursor_renderer_for_device (backend,
- device);
- if (cursor_renderer)
- meta_cursor_renderer_update_position (cursor_renderer);
-
- if (device == clutter_seat_get_pointer (clutter_input_device_get_seat (device)))
- {
- MetaCursorTracker *cursor_tracker =
- meta_backend_get_cursor_tracker (backend);
-
- meta_cursor_tracker_invalidate_position (cursor_tracker);
- }
- }
-#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.");
- }
- 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 (meta_is_wayland_compositor () &&
- event->type == CLUTTER_SCROLL &&
- meta_prefs_get_mouse_button_mods () > 0)
- {
- ClutterModifierType grab_mods;
-
- grab_mods = meta_display_get_compositor_modifiers (display);
- if ((clutter_event_get_state (event) & grab_mods) != 0)
- {
- 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
deleted file mode 100644
index 6338119ae..000000000
--- a/src/core/events.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 9c8cbb946..000000000
--- a/src/core/frame.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Mutter X window decorations */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2003, 2004 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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 "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 | FocusChangeMask)
-
-void
-meta_window_ensure_frame (MetaWindow *window)
-{
- MetaFrame *frame;
- XSetWindowAttributes attrs;
- gulong create_serial;
- MetaX11Display *x11_display;
-
- if (window->frame)
- return;
-
- x11_display = window->display->x11_display;
-
- frame = g_new (MetaFrame, 1);
-
- frame->window = window;
- frame->xwindow = None;
-
- frame->rect = window->rect;
- frame->child_x = 0;
- frame->child_y = 0;
- frame->bottom_height = 0;
- frame->right_width = 0;
- frame->current_cursor = 0;
-
- frame->borders_cached = FALSE;
-
- meta_verbose ("Frame geometry %d,%d %dx%d",
- frame->rect.x, frame->rect.y,
- frame->rect.width, frame->rect.height);
-
- 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", frame->window->desc, frame->xwindow);
- attrs.event_mask = EVENT_MASK;
- XChangeWindowAttributes (x11_display->xdisplay,
- frame->xwindow, CWEventMask, &attrs);
-
- meta_x11_display_register_x_window (x11_display, &frame->xwindow, window);
-
- meta_x11_error_trap_push (x11_display);
- if (window->mapped)
- {
- window->mapped = FALSE; /* the reparent will unmap the window,
- * we don't want to take that as a withdraw
- */
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Incrementing unmaps_pending on %s for reparent", window->desc);
- window->unmaps_pending += 1;
- }
-
- meta_stack_tracker_record_remove (window->display->stack_tracker,
- window->xwindow,
- XNextRequest (x11_display->xdisplay));
- XReparentWindow (x11_display->xdisplay,
- window->xwindow,
- frame->xwindow,
- frame->child_x,
- frame->child_y);
- window->reparents_pending += 1;
- /* FIXME handle this error */
- 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;
-
- /* Now that frame->xwindow is registered with window, we can set its
- * style and background.
- */
- meta_frame_update_style (frame);
- meta_frame_update_title (frame);
-
- meta_ui_map_frame (x11_display->ui, frame->xwindow);
-
- {
- 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);
-
- 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);
-
- XISelectEvents (xdisplay, frame->xwindow, &mask, 1);
- }
- }
-
- /* Move keybindings to frame instead of window */
- meta_window_grab_keys (window);
-}
-
-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", window->desc);
-
- frame = window->frame;
-
- meta_frame_calc_borders (frame, &borders);
-
- /* Unparent the client window; it may be destroyed,
- * thus the error trap.
- */
- meta_x11_error_trap_push (x11_display);
- if (window->mapped)
- {
- window->mapped = FALSE; /* Keep track of unmapping it, so we
- * can identify a withdraw initiated
- * by the client.
- */
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Incrementing unmaps_pending on %s for reparent back to root", window->desc);
- window->unmaps_pending += 1;
- }
-
- 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_x11_error_trap_pop (x11_display);
-
- 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)
- {
- cairo_region_destroy (window->frame_bounds);
- window->frame_bounds = NULL;
- }
-
- /* Move keybindings to window instead of frame */
- meta_window_grab_keys (window);
-
- g_free (frame);
-
- /* Put our state back where it should be */
- meta_window_queue (window, META_QUEUE_CALC_SHOWING);
- meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
-}
-
-
-MetaFrameFlags
-meta_frame_get_flags (MetaFrame *frame)
-{
- MetaFrameFlags flags;
-
- flags = 0;
-
- if (frame->window->border_only)
- {
- ; /* FIXME this may disable the _function_ as well as decor
- * in some cases, which is sort of wrong.
- */
- }
- else
- {
- flags |= META_FRAME_ALLOWS_MENU;
-
- if (frame->window->has_close_func)
- flags |= META_FRAME_ALLOWS_DELETE;
-
- if (frame->window->has_maximize_func)
- flags |= META_FRAME_ALLOWS_MAXIMIZE;
-
- if (frame->window->has_minimize_func)
- flags |= META_FRAME_ALLOWS_MINIMIZE;
-
- if (frame->window->has_shade_func)
- flags |= META_FRAME_ALLOWS_SHADE;
- }
-
- if (META_WINDOW_ALLOWS_MOVE (frame->window))
- flags |= META_FRAME_ALLOWS_MOVE;
-
- if (META_WINDOW_ALLOWS_HORIZONTAL_RESIZE (frame->window))
- flags |= META_FRAME_ALLOWS_HORIZONTAL_RESIZE;
-
- if (META_WINDOW_ALLOWS_VERTICAL_RESIZE (frame->window))
- flags |= META_FRAME_ALLOWS_VERTICAL_RESIZE;
-
- if (meta_window_appears_focused (frame->window))
- flags |= META_FRAME_HAS_FOCUS;
-
- if (frame->window->shaded)
- flags |= META_FRAME_SHADED;
-
- if (frame->window->on_all_workspaces_requested)
- flags |= META_FRAME_STUCK;
-
- /* FIXME: Should we have some kind of UI for windows that are just vertically
- * maximized or just horizontally maximized?
- */
- 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_RIGHT (frame->window))
- flags |= META_FRAME_TILED_RIGHT;
-
- if (frame->window->fullscreen)
- flags |= META_FRAME_FULLSCREEN;
-
- if (frame->window->wm_state_above)
- flags |= META_FRAME_ABOVE;
-
- return flags;
-}
-
-void
-meta_frame_borders_clear (MetaFrameBorders *self)
-{
- self->visible.top = self->invisible.top = self->total.top = 0;
- self->visible.bottom = self->invisible.bottom = self->total.bottom = 0;
- self->visible.left = self->invisible.left = self->total.left = 0;
- self->visible.right = self->invisible.right = self->total.right = 0;
-}
-
-void
-meta_frame_calc_borders (MetaFrame *frame,
- MetaFrameBorders *borders)
-{
- /* Save on if statements and potential uninitialized values
- * in callers -- if there's no frame, then zero the borders. */
- if (frame == NULL)
- meta_frame_borders_clear (borders);
- else
- {
- if (!frame->borders_cached)
- {
- meta_ui_frame_get_borders (frame->ui_frame, &frame->cached_borders);
- frame->borders_cached = TRUE;
- }
-
- *borders = frame->cached_borders;
- }
-}
-
-void
-meta_frame_clear_cached_borders (MetaFrame *frame)
-{
- frame->borders_cached = FALSE;
-}
-
-gboolean
-meta_frame_sync_to_window (MetaFrame *frame,
- gboolean need_resize)
-{
- meta_topic (META_DEBUG_GEOMETRY,
- "Syncing frame geometry %d,%d %dx%d (SE: %d,%d)",
- frame->rect.x, frame->rect.y,
- frame->rect.width, frame->rect.height,
- frame->rect.x + frame->rect.width,
- frame->rect.y + frame->rect.height);
-
- meta_ui_frame_move_resize (frame->ui_frame,
- frame->rect.x,
- frame->rect.y,
- frame->rect.width,
- frame->rect.height);
-
- return need_resize;
-}
-
-cairo_region_t *
-meta_frame_get_frame_bounds (MetaFrame *frame)
-{
- return meta_ui_frame_get_bounds (frame->ui_frame);
-}
-
-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_frame_queue_draw (frame->ui_frame);
-}
-
-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 (x11_display->xdisplay, frame->xwindow);
- else
- {
- 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);
- }
-}
-
-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
deleted file mode 100644
index 61a5ca725..000000000
--- a/src/core/frame.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_FRAME_PRIVATE_H
-#define META_FRAME_PRIVATE_H
-
-#include "core/window-private.h"
-#include "ui/frames.h"
-
-struct _MetaFrame
-{
- /* window we frame */
- MetaWindow *window;
-
- /* reparent window */
- Window xwindow;
-
- MetaCursor current_cursor;
-
- /* This rect is trusted info from where we put the
- * frame, not the result of ConfigureNotify
- */
- MetaRectangle rect;
-
- MetaFrameBorders cached_borders; /* valid if borders_cached is set */
-
- /* position of client, size of frame */
- int child_x;
- int child_y;
- int right_width;
- int bottom_height;
-
- guint need_reapply_frame_shape : 1;
- guint borders_cached : 1;
-
- MetaUIFrame *ui_frame;
-};
-
-void meta_window_ensure_frame (MetaWindow *window);
-void meta_window_destroy_frame (MetaWindow *window);
-void meta_frame_queue_draw (MetaFrame *frame);
-
-MetaFrameFlags meta_frame_get_flags (MetaFrame *frame);
-Window meta_frame_get_xwindow (MetaFrame *frame);
-
-/* These should ONLY be called from meta_window_move_resize_internal */
-void meta_frame_calc_borders (MetaFrame *frame,
- MetaFrameBorders *borders);
-
-gboolean meta_frame_sync_to_window (MetaFrame *frame,
- 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);
-
-void meta_frame_update_style (MetaFrame *frame);
-void meta_frame_update_title (MetaFrame *frame);
-
-#endif
diff --git a/src/core/keybindings-private.h b/src/core/keybindings-private.h
deleted file mode 100644
index 56792c200..000000000
--- a/src/core/keybindings-private.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file keybindings.h Grab and ungrab keys, and process the key events
- *
- * Performs global X grabs on the keys we need to be told about, like
- * 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_KEYBINDINGS_PRIVATE_H
-#define META_KEYBINDINGS_PRIVATE_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;
- 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;
- 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_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_prefs_add_keybinding (const char *name,
- GSettings *settings,
- MetaKeyBindingAction action,
- MetaKeyBindingFlags flags);
-
-gboolean meta_prefs_remove_keybinding (const char *name);
-
-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);
-
-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
deleted file mode 100644
index a6e16f084..000000000
--- a/src/core/keybindings.c
+++ /dev/null
@@ -1,4578 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Mutter Keybindings */
-/*
- * 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/>.
- */
-
-/**
- * SECTION:keybindings
- * @Title: MetaKeybinding
- * @Short_Description: Key bindings
- */
-
-#include "config.h"
-
-#include "backends/meta-backend-private.h"
-#include "backends/meta-keymap-utils.h"
-#include "backends/meta-logical-monitor.h"
-#include "backends/meta-monitor-manager-private.h"
-#include "backends/x11/meta-backend-x11.h"
-#include "backends/x11/meta-input-device-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
-
-#ifdef __linux__
-#include <linux/input.h>
-#elif !defined KEY_GRAVE
-#define KEY_GRAVE 0x29 /* assume the use of xf86-input-keyboard */
-#endif
-
-#define SCHEMA_COMMON_KEYBINDINGS "org.gnome.desktop.wm.keybindings"
-#define SCHEMA_MUTTER_KEYBINDINGS "org.gnome.mutter.keybindings"
-#define SCHEMA_MUTTER_WAYLAND_KEYBINDINGS "org.gnome.mutter.wayland.keybindings"
-
-#define META_KEY_BINDING_PRIMARY_LAYOUT 0
-#define META_KEY_BINDING_SECONDARY_LAYOUT 1
-
-/* 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 add_builtin_keybinding (MetaDisplay *display,
- const char *name,
- GSettings *settings,
- MetaKeyBindingFlags flags,
- MetaKeyBindingAction action,
- MetaKeyHandlerFunc handler,
- int handler_arg);
-
-static void
-resolved_key_combo_reset (MetaResolvedKeyCombo *resolved_combo)
-{
- g_free (resolved_combo->keycodes);
- resolved_combo->len = 0;
- resolved_combo->keycodes = NULL;
-}
-
-static void
-resolved_key_combo_copy (MetaResolvedKeyCombo *from,
- MetaResolvedKeyCombo *to)
-{
- to->len = from->len;
- to->keycodes = g_memdup2 (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_free (binding);
-}
-
-static MetaKeyBinding *
-meta_key_binding_copy (MetaKeyBinding *binding)
-{
- MetaKeyBinding *clone = g_memdup2 (binding, sizeof (MetaKeyBinding));
- resolved_key_combo_copy (&binding->resolved_combo,
- &clone->resolved_combo);
- return clone;
-}
-
-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)
-{
- return binding->name;
-}
-
-MetaVirtualModifier
-meta_key_binding_get_modifiers (MetaKeyBinding *binding)
-{
- 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->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
- * various other events. TODO: Possibly we should include them as event
- * handler functions and have some kind of flag to say they're unbindable.
- */
-
-static gboolean process_mouse_move_resize_grab (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event);
-
-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 void maybe_update_locate_pointer_keygrab (MetaDisplay *display,
- gboolean grab);
-
-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)
-{
- g_free (handler->name);
- if (handler->user_data_free_func && handler->user_data)
- handler->user_data_free_func (handler->user_data);
- g_free (handler);
-}
-
-typedef struct _MetaKeyGrab MetaKeyGrab;
-struct _MetaKeyGrab {
- char *name;
- guint action;
- MetaKeyCombo combo;
- gint flags;
-};
-
-static void
-meta_key_grab_free (MetaKeyGrab *grab)
-{
- g_free (grab->name);
- g_free (grab);
-}
-
-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 (MetaKeyBindingManager *keys)
-{
- 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;
- }
- }
-
- xkb_state_unref (scratch_state);
-
- keys->ignored_modifier_mask = (scroll_lock_mask | Mod2Mask | LockMask);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Ignoring modmask 0x%x scroll lock 0x%x hyper 0x%x super 0x%x meta 0x%x",
- keys->ignored_modifier_mask,
- scroll_lock_mask,
- keys->hyper_mask,
- keys->super_mask,
- keys->meta_mask);
-}
-
-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;
-
- num_syms = xkb_keymap_key_get_syms_by_level (keymap, keycode, layout, level, &syms);
- for (k = 0; k < num_syms; k++)
- {
- if (syms[k] == keysym)
- return TRUE;
- }
-
- return FALSE;
-}
-
-typedef struct
-{
- GArray *keycodes;
- xkb_keysym_t keysym;
- xkb_layout_index_t layout;
- xkb_level_index_t level;
-} FindKeysymData;
-
-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 (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;
- }
-
- if (missing)
- g_array_append_val (keycodes, keycode);
- }
-}
-
-static void
-add_keysym_keycodes_from_layout (int keysym,
- MetaKeyBindingKeyboardLayout *layout,
- GArray *keycodes)
-{
- xkb_level_index_t layout_level;
-
- 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);
- }
-}
-
-/* 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;
-
- 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);
-}
-
-typedef struct _CalculateLayoutLevelsState
-{
- 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_iso_next_group_combos (MetaKeyBindingManager *keys)
-{
- 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 (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"))
- {
- 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]);
-
- 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]);
-
- 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
-devirtualize_modifiers (MetaKeyBindingManager *keys,
- 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 |= 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;
-}
-
-static void
-index_binding (MetaKeyBindingManager *keys,
- MetaKeyBinding *binding)
-{
- int i;
-
- for (i = 0; i < binding->resolved_combo.len; i++)
- {
- MetaKeyBinding *existing;
- guint32 index_key;
-
- 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)
- {
- /* 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).",
- binding->combo.keysym,
- existing->combo.keysym,
- binding->resolved_combo.keycodes[i]);
- }
-
- g_hash_table_replace (keys->key_bindings_index,
- GINT_TO_POINTER (index_key), binding);
- }
-}
-
-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;
-
- resolve_key_combo (keys, &binding->combo, &binding->resolved_combo);
- index_binding (keys, binding);
-}
-
-typedef struct _FindLatinKeysymsState
-{
- MetaKeyBindingKeyboardLayout *layout;
- gboolean *required_keysyms_found;
- int n_required_keysyms;
-} FindLatinKeysymsState;
-
-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++)
- {
- xkb_keysym_t keysym = keysyms[i];
-
- if (keysym >= XKB_KEY_a && keysym <= XKB_KEY_z)
- {
- unsigned int keysym_index = keysym - XKB_KEY_a;
-
- if (!state->required_keysyms_found[keysym_index])
- {
- state->required_keysyms_found[keysym_index] = TRUE;
- state->n_required_keysyms--;
- }
- }
- }
-}
-
-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 };
- }
-}
-
-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 = meta_create_xkb_context ();
- 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
-reload_active_keyboard_layouts (MetaKeyBindingManager *keys)
-{
- 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);
-
- 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);
-
- p = prefs;
- while (p)
- {
- MetaKeyPref *pref = (MetaKeyPref*)p->data;
- GSList *tmp = pref->combos;
-
- while (tmp)
- {
- MetaKeyCombo *combo = tmp->data;
-
- if (combo && (combo->keysym != None || combo->keycode != 0))
- {
- MetaKeyHandler *handler = HANDLER (pref->name);
-
- b = g_new0 (MetaKeyBinding, 1);
- b->name = pref->name;
- b->handler = handler;
- b->flags = handler->flags;
- b->combo = *combo;
-
- g_hash_table_add (keys->key_bindings, b);
- }
-
- tmp = tmp->next;
- }
-
- p = p->next;
- }
-
- 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_new0 (MetaKeyBinding, 1);
- b->name = grab->name;
- b->handler = handler;
- b->flags = grab->flags;
- b->combo = grab->combo;
-
- g_hash_table_add (keys->key_bindings, b);
- }
-
- g = g->next;
- }
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- " %d bindings in table",
- g_hash_table_size (keys->key_bindings));
-}
-
-static void
-rebuild_key_binding_table (MetaKeyBindingManager *keys)
-{
- GList *prefs, *grabs;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Rebuilding key binding table from preferences");
-
- prefs = meta_prefs_get_keybindings ();
- grabs = g_hash_table_get_values (external_grabs);
- rebuild_binding_table (keys, prefs, grabs);
- g_list_free (prefs);
- g_list_free (grabs);
-}
-
-static void
-rebuild_special_bindings (MetaKeyBindingManager *keys)
-{
- MetaKeyCombo combo;
-
- meta_prefs_get_overlay_binding (&combo);
- keys->overlay_key_combo = combo;
-
- meta_prefs_get_locate_pointer_binding (&combo);
- keys->locate_pointer_key_combo = combo;
-}
-
-static void
-ungrab_key_bindings (MetaDisplay *display)
-{
- GSList *windows, *l;
-
- if (display->x11_display)
- meta_x11_display_ungrab_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_ungrab_keys (w);
- }
-
- g_slist_free (windows);
-}
-
-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);
- }
-
- g_slist_free (windows);
-}
-
-static MetaKeyBinding *
-get_keybinding (MetaKeyBindingManager *keys,
- MetaResolvedKeyCombo *resolved_combo)
-{
- MetaKeyBinding *binding = NULL;
- int i;
-
- for (i = 0; i < resolved_combo->len; i++)
- {
- guint32 key;
-
- 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 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,
- GSettings *settings,
- MetaKeyBindingFlags flags,
- MetaKeyBindingAction action,
- MetaKeyHandlerFunc func,
- int data,
- gpointer user_data,
- GDestroyNotify free_data)
-{
- MetaKeyHandler *handler;
-
- if (!meta_prefs_add_keybinding (name, settings, 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->user_data = user_data;
- handler->user_data_free_func = free_data;
-
- g_hash_table_insert (key_handlers, g_strdup (name), handler);
-
- return TRUE;
-}
-
-static gboolean
-add_builtin_keybinding (MetaDisplay *display,
- const char *name,
- GSettings *settings,
- MetaKeyBindingFlags flags,
- MetaKeyBindingAction action,
- MetaKeyHandlerFunc handler,
- int handler_arg)
-{
- return add_keybinding_internal (display, name, settings,
- flags | META_KEY_BINDING_BUILTIN,
- action, handler, handler_arg, NULL, NULL);
-}
-
-/**
- * meta_display_add_keybinding:
- * @display: a #MetaDisplay
- * @name: the binding's name
- * @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 "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1". The parser
- * is fairly liberal and allows lower or upper case, and also abbreviations
- * such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;". 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: the corresponding keybinding action if the keybinding was
- * added successfully, otherwise %META_KEYBINDING_ACTION_NONE
- */
-guint
-meta_display_add_keybinding (MetaDisplay *display,
- const char *name,
- GSettings *settings,
- MetaKeyBindingFlags flags,
- MetaKeyHandlerFunc handler,
- gpointer user_data,
- GDestroyNotify 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;
-}
-
-/**
- * meta_display_remove_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_keybinding().
- *
- * Returns: %TRUE if the binding has been removed successfully,
- * otherwise %FALSE
- */
-gboolean
-meta_display_remove_keybinding (MetaDisplay *display,
- const char *name)
-{
- if (!meta_prefs_remove_keybinding (name))
- return FALSE;
-
- g_hash_table_remove (key_handlers, name);
-
- return TRUE;
-}
-
-static guint
-get_keybinding_action (MetaKeyBindingManager *keys,
- MetaResolvedKeyCombo *resolved_combo)
-{
- MetaKeyBinding *binding;
-
- /* This is much more vague than the MetaDisplay::overlay-key signal,
- * which is only emitted if the overlay-key is the only key pressed;
- * as this method is primarily intended for plugins to allow processing
- * of mutter keybindings while holding a grab, the overlay-key-only-pressed
- * tracking is left to the plugin here.
- */
- if (resolved_key_combo_intersect (resolved_combo,
- &keys->overlay_resolved_key_combo))
- return META_KEYBINDING_ACTION_OVERLAY_KEY;
-
- if (resolved_key_combo_intersect (resolved_combo,
- &keys->locate_pointer_resolved_key_combo))
- return META_KEYBINDING_ACTION_LOCATE_POINTER_KEY;
-
- 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;
- }
-}
-
-static xkb_mod_mask_t
-mask_from_event_params (MetaKeyBindingManager *keys,
- unsigned long mask)
-{
- return mask & 0xff & ~keys->ignored_modifier_mask;
-}
-
-/**
- * meta_display_get_keybinding_action:
- * @display: A #MetaDisplay
- * @keycode: Raw keycode
- * @mask: Event mask
- *
- * 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.
- */
-guint
-meta_display_get_keybinding_action (MetaDisplay *display,
- unsigned int keycode,
- unsigned long mask)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
- xkb_keycode_t code = (xkb_keycode_t) keycode;
- MetaResolvedKeyCombo resolved_combo = { &code, 1 };
-
- resolved_combo.mask = mask_from_event_params (keys, mask);
- return get_keybinding_action (keys, &resolved_combo);
-}
-
-static void
-reload_keybindings (MetaDisplay *display)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
-
- ungrab_key_bindings (display);
-
- /* 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);
-
- reload_combos (keys);
-
- grab_key_bindings (display);
-}
-
-static GArray *
-calc_grab_modifiers (MetaKeyBindingManager *keys,
- unsigned int modmask)
-{
- unsigned int ignored_mask;
- XIGrabModifiers mods;
- GArray *mods_array = g_array_new (FALSE, TRUE, sizeof (XIGrabModifiers));
-
- /* 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)
- {
- 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);
-
- 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
- XIUngrabButton (xdisplay,
- META_VIRTUAL_CORE_POINTER_ID,
- button, xwindow, mods->len, (XIGrabModifiers *)mods->data);
-
- g_array_free (mods, TRUE);
-}
-
-ClutterModifierType
-meta_display_get_compositor_modifiers (MetaDisplay *display)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
- return keys->window_grab_modifiers;
-}
-
-static void
-meta_change_buttons_grab (MetaKeyBindingManager *keys,
- Window xwindow,
- gboolean grab,
- gboolean sync,
- int modmask)
-{
-#define MAX_BUTTON 3
-
- int i;
- for (i = 1; i <= MAX_BUTTON; i++)
- meta_change_button_grab (keys, xwindow, grab, sync, i, modmask);
-}
-
-void
-meta_display_grab_window_buttons (MetaDisplay *display,
- Window xwindow)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
-
- /* 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", 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()
- */
-
- 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);
- }
-}
-
-void
-meta_display_ungrab_window_buttons (MetaDisplay *display,
- Window xwindow)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
-
- if (keys->window_grab_modifiers == 0)
- return;
-
- meta_change_buttons_grab (keys, xwindow, FALSE, FALSE,
- keys->window_grab_modifiers);
-}
-
-static void
-update_window_grab_modifiers (MetaDisplay *display)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
- MetaVirtualModifier virtual_mods;
- unsigned int mods;
-
- virtual_mods = meta_prefs_get_mouse_button_mods ();
- devirtualize_modifiers (keys, virtual_mods, &mods);
-
- if (keys->window_grab_modifiers != mods)
- {
- keys->window_grab_modifiers = mods;
- g_object_notify (G_OBJECT (display), "compositor-modifiers");
- }
-}
-
-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", window->desc);
-
- if (window->have_focus_click_grab)
- {
- meta_verbose (" (well, not grabbing since we already have the grab)");
- 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)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
-
- meta_verbose ("Ungrabbing unfocused window buttons for %s", window->desc);
-
- 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:
- maybe_update_locate_pointer_keygrab (display,
- meta_prefs_is_locate_pointer_enabled());
- break;
- case META_PREF_KEYBINDINGS:
- 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 (display);
-
- 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;
- }
-}
-
-
-void
-meta_display_shutdown_keys (MetaDisplay *display)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
-
- meta_prefs_remove_listener (prefs_changed_callback, display);
-
- g_hash_table_destroy (keys->key_bindings_index);
- g_hash_table_destroy (keys->key_bindings);
-
- clear_active_keyboard_layouts (keys);
-}
-
-/* Grab/ungrab, ignoring all annoying modifiers like NumLock etc. */
-static void
-meta_change_keygrab (MetaKeyBindingManager *keys,
- Window xwindow,
- gboolean grab,
- MetaResolvedKeyCombo *resolved_combo)
-{
- 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);
-
- if (meta_is_wayland_compositor ())
- return;
-
- 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.
- */
-
- mods = calc_grab_modifiers (keys, resolved_combo->mask);
-
- for (i = 0; i < resolved_combo->len; i++)
- {
- xkb_keycode_t keycode = resolved_combo->keycodes[i];
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "%s keybinding keycode %d mask 0x%x on 0x%lx",
- grab ? "Grabbing" : "Ungrabbing",
- keycode, resolved_combo->mask, xwindow);
-
- if (grab)
- XIGrabKeycode (xdisplay,
- META_VIRTUAL_CORE_KEYBOARD_ID,
- keycode, xwindow,
- XIGrabModeSync, XIGrabModeAsync,
- False, &mask, mods->len, (XIGrabModifiers *)mods->data);
- else
- XIUngrabKeycode (xdisplay,
- META_VIRTUAL_CORE_KEYBOARD_ID,
- keycode, xwindow,
- mods->len, (XIGrabModifiers *)mods->data);
- }
-
- g_array_free (mods, TRUE);
-}
-
-typedef struct
-{
- MetaKeyBindingManager *keys;
- Window xwindow;
- gboolean only_per_window;
- gboolean grab;
-} ChangeKeygrabData;
-
-static void
-change_keygrab_foreach (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- 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
-change_binding_keygrabs (MetaKeyBindingManager *keys,
- Window xwindow,
- gboolean only_per_window,
- gboolean grab)
-{
- ChangeKeygrabData data;
-
- data.keys = keys;
- data.xwindow = xwindow;
- data.only_per_window = only_per_window;
- data.grab = grab;
-
- g_hash_table_foreach (keys->key_bindings, change_keygrab_foreach, &data);
-}
-
-static void
-maybe_update_locate_pointer_keygrab (MetaDisplay *display,
- gboolean grab)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
-
- if (!display->x11_display)
- return;
-
- 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
-meta_x11_display_change_keygrabs (MetaX11Display *x11_display,
- gboolean grab)
-{
- MetaKeyBindingManager *keys = &x11_display->display->key_binding_manager;
- int i;
-
- if (keys->overlay_resolved_key_combo.len != 0)
- meta_change_keygrab (keys, x11_display->xroot,
- grab, &keys->overlay_resolved_key_combo);
-
- maybe_update_locate_pointer_keygrab (x11_display->display, grab);
-
- 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]);
-
- change_binding_keygrabs (keys, x11_display->xroot,
- FALSE, grab);
-}
-
-void
-meta_x11_display_grab_keys (MetaX11Display *x11_display)
-{
- if (x11_display->keys_grabbed)
- return;
-
- 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;
-
- meta_x11_display_change_keygrabs (x11_display, FALSE);
-
- x11_display->keys_grabbed = FALSE;
-}
-
-static void
-change_window_keygrabs (MetaKeyBindingManager *keys,
- Window xwindow,
- gboolean grab)
-{
- change_binding_keygrabs (keys, xwindow, TRUE, grab);
-}
-
-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;
-
- if (window->type == META_WINDOW_DOCK
- || window->override_redirect)
- {
- if (window->keys_grabbed)
- change_window_keygrabs (keys, window->xwindow, FALSE);
- window->keys_grabbed = FALSE;
- return;
- }
-
- if (window->keys_grabbed)
- {
- if (window->frame && !window->grab_on_frame)
- change_window_keygrabs (keys, window->xwindow, FALSE);
- else if (window->frame == NULL &&
- window->grab_on_frame)
- ; /* continue to regrab on client window */
- else
- return; /* already all good */
- }
-
- change_window_keygrabs (keys,
- meta_window_x11_get_toplevel_xwindow (window),
- TRUE);
-
- window->keys_grabbed = TRUE;
- window->grab_on_frame = window->frame != NULL;
-}
-
-void
-meta_window_ungrab_keys (MetaWindow *window)
-{
- 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)
- change_window_keygrabs (keys, window->frame->xwindow, FALSE);
- else if (!window->grab_on_frame)
- change_window_keygrabs (keys, window->xwindow, FALSE);
-
- window->keys_grabbed = FALSE;
- }
-}
-
-static void
-handle_external_grab (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer user_data)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
- guint action = get_keybinding_action (keys, &binding->resolved_combo);
- meta_display_accelerator_activate (display, action, event);
-}
-
-
-guint
-meta_display_grab_accelerator (MetaDisplay *display,
- const char *accelerator,
- MetaKeyBindingFlags flags)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
- MetaKeyBinding *binding;
- MetaKeyGrab *grab;
- MetaKeyCombo combo = { 0 };
- MetaResolvedKeyCombo resolved_combo = { NULL, 0 };
-
- if (!meta_parse_accelerator (accelerator, &combo))
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Failed to parse accelerator");
- meta_warning ("\"%s\" is not a valid accelerator", accelerator);
-
- return META_KEYBINDING_ACTION_NONE;
- }
-
- resolve_key_combo (keys, &combo, &resolved_combo);
-
- if (resolved_combo.len == 0)
- return META_KEYBINDING_ACTION_NONE;
-
- if (get_keybinding (keys, &resolved_combo))
- {
- resolved_key_combo_reset (&resolved_combo);
- return META_KEYBINDING_ACTION_NONE;
- }
-
- if (!meta_is_wayland_compositor ())
- {
- meta_change_keygrab (keys, display->x11_display->xroot,
- TRUE, &resolved_combo);
- }
-
- 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;
-
- g_hash_table_insert (external_grabs, grab->name, grab);
-
- binding = g_new0 (MetaKeyBinding, 1);
- binding->name = grab->name;
- binding->handler = HANDLER ("external-grab");
- binding->combo = combo;
- binding->resolved_combo = resolved_combo;
- binding->flags = flags;
-
- g_hash_table_add (keys->key_bindings, binding);
- index_binding (keys, binding);
-
- return grab->action;
-}
-
-gboolean
-meta_display_ungrab_accelerator (MetaDisplay *display,
- guint action)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
- MetaKeyBinding *binding;
- MetaKeyGrab *grab;
- g_autofree char *key = NULL;
- MetaResolvedKeyCombo resolved_combo = { NULL, 0 };
-
- g_return_val_if_fail (action != META_KEYBINDING_ACTION_NONE, FALSE);
-
- key = meta_external_binding_name_for_action (action);
- grab = g_hash_table_lookup (external_grabs, key);
- if (!grab)
- return FALSE;
-
- resolve_key_combo (keys, &grab->combo, &resolved_combo);
- binding = get_keybinding (keys, &resolved_combo);
- if (binding)
- {
- 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);
- }
-
- g_hash_table_remove (external_grabs, key);
- resolved_key_combo_reset (&resolved_combo);
-
- return TRUE;
-}
-
-static gboolean
-grab_keyboard (Window xwindow,
- guint32 timestamp,
- int grab_mode)
-{
- int grab_status;
-
- 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);
-
- 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);
-}
-
-gboolean
-meta_window_grab_all_keys (MetaWindow *window,
- guint32 timestamp)
-{
- Window grabwindow;
- gboolean retval = TRUE;
-
- if (window->all_keys_grabbed)
- return FALSE;
-
- if (window->keys_grabbed)
- meta_window_ungrab_keys (window);
-
- /* Make sure the window is focused, otherwise the grab
- * won't do a lot of good.
- */
- meta_topic (META_DEBUG_FOCUS,
- "Focusing %s because we're grabbing all its keys",
- window->desc);
- meta_window_focus (window, timestamp);
-
- if (!meta_is_wayland_compositor ())
- {
- grabwindow = meta_window_x11_get_toplevel_xwindow (window);
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Grabbing all keys on window %s", window->desc);
- retval = grab_keyboard (grabwindow, timestamp, XIGrabModeAsync);
- }
- if (retval)
- {
- window->keys_grabbed = FALSE;
- window->all_keys_grabbed = TRUE;
- window->grab_on_frame = window->frame != NULL;
- }
-
- return retval;
-}
-
-void
-meta_window_ungrab_all_keys (MetaWindow *window,
- guint32 timestamp)
-{
- if (window->all_keys_grabbed)
- {
- if (!meta_is_wayland_compositor())
- ungrab_keyboard (timestamp);
-
- window->grab_on_frame = FALSE;
- window->all_keys_grabbed = FALSE;
- window->keys_grabbed = FALSE;
-
- /* Re-establish our standard bindings */
- meta_window_grab_keys (window);
- }
-}
-
-void
-meta_display_freeze_keyboard (MetaDisplay *display, guint32 timestamp)
-{
- MetaBackend *backend = meta_get_backend ();
-
- if (!META_IS_BACKEND_X11 (backend))
- return;
-
- 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);
-}
-
-void
-meta_display_unfreeze_keyboard (MetaDisplay *display, guint32 timestamp)
-{
- MetaBackend *backend = meta_get_backend ();
-
- if (!META_IS_BACKEND_X11 (backend))
- return;
-
- Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
-
- 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);
-}
-
-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,
- MetaKeyHandler *handler,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding)
-{
- if (handler->func)
- (* handler->func) (display,
- handler->flags & META_KEY_BINDING_PER_WINDOW ?
- window : NULL,
- event,
- binding,
- handler->user_data);
- else
- (* handler->default_func) (display,
- handler->flags & META_KEY_BINDING_PER_WINDOW ?
- window: NULL,
- event,
- binding,
- NULL);
-}
-
-static gboolean
-meta_key_binding_has_handler_func (MetaKeyBinding *binding)
-{
- return (!!binding->handler->func || !!binding->handler->default_func);
-}
-
-static gboolean
-process_event (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event)
-{
- 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 == CLUTTER_KEY_RELEASE)
- return FALSE;
-
- resolved_combo.mask = mask_from_event_params (keys, event->modifier_state);
-
- binding = get_keybinding (keys, &resolved_combo);
-
- if (!binding ||
- (!window && binding->flags & META_KEY_BINDING_PER_WINDOW))
- goto not_found;
-
- if (binding->handler == NULL)
- meta_bug ("Binding %s has no handler", binding->name);
-
- if (!meta_key_binding_has_handler_func (binding))
- goto not_found;
-
- if (display->focus_window &&
- !(binding->handler->flags & META_KEY_BINDING_NON_MASKABLE))
- {
- ClutterInputDevice *source;
-
- source = clutter_event_get_source_device ((ClutterEvent *) event);
- if (meta_window_shortcuts_inhibited (display->focus_window, source))
- goto not_found;
- }
-
- /* 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",
- binding->name);
- return TRUE;
- }
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Running handler for %s",
- 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");
- return FALSE;
-}
-
-static gboolean
-process_special_modifier_key (MetaDisplay *display,
- ClutterKeyEvent *event,
- MetaWindow *window,
- gboolean *modifier_press_only,
- MetaResolvedKeyCombo *resolved_key_combo,
- 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 (*modifier_press_only)
- {
- if (! resolved_key_combo_has_keycode (resolved_key_combo,
- event->hardware_keycode))
- {
- *modifier_press_only = FALSE;
-
- /* If this is a wayland session, we can avoid the shenanigans
- * about passive grabs below, and let the event continue to
- * be processed through the regular paths.
- */
- if (!xdisplay)
- return FALSE;
-
- /* OK, the user hit modifier+key rather than pressing and
- * releasing the modifier key alone. We want to handle the key
- * sequence "normally". Unfortunately, using
- * XAllowEvents(..., ReplayKeyboard, ...) doesn't quite
- * work, since global keybindings won't be activated ("this
- * time, however, the function ignores any passive grabs at
- * above (toward the root of) the grab_window of the grab
- * just released.") So, we first explicitly check for one of
- * our global keybindings, and if not found, we then replay
- * the event. Other clients with global grabs will be out of
- * luck.
- */
- if (process_event (display, window, event))
- {
- /* 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,
- meta_input_device_x11_get_device_id (event->device),
- XIAsyncDevice, event->time);
- }
- else
- {
- /* Replay the event so it gets delivered to our
- * per-window key bindings or to the application */
- if (xdisplay)
- XIAllowEvents (xdisplay,
- meta_input_device_x11_get_device_id (event->device),
- XIReplayDevice, event->time);
- }
- }
- else if (event->type == CLUTTER_KEY_RELEASE)
- {
- MetaKeyBinding *binding;
-
- *modifier_press_only = FALSE;
-
- /* We want to unfreeze events, but keep the grab so that if the user
- * starts typing into the overlay we get all the keys */
- if (xdisplay)
- XIAllowEvents (xdisplay,
- meta_input_device_x11_get_device_id (event->device),
- XIAsyncDevice, event->time);
-
- binding = get_keybinding (keys, resolved_key_combo);
- if (binding &&
- meta_compositor_filter_keybinding (display->compositor, binding))
- return TRUE;
- trigger_callback (display, NULL);
- }
- else
- {
- /* In some rare race condition, mutter might not receive the Super_L
- * KeyRelease event because:
- * - the compositor might end the modal mode and call XIUngrabDevice
- * while the key is still down
- * - passive grabs are only activated on KeyPress and not KeyRelease.
- *
- * In this case, modifier_press_only might be wrong.
- * Mutter still ought to acknowledge events, otherwise the X server
- * will not send the next events.
- *
- * https://bugzilla.gnome.org/show_bug.cgi?id=666101
- */
- if (xdisplay)
- XIAllowEvents (xdisplay,
- meta_input_device_x11_get_device_id (event->device),
- XIAsyncDevice, event->time);
- }
-
- return TRUE;
- }
- else if (event->type == CLUTTER_KEY_PRESS &&
- ((event->modifier_state & ~(IGNORED_MODIFIERS)) & CLUTTER_MODIFIER_MASK) == 0 &&
- resolved_key_combo_has_keycode (resolved_key_combo,
- event->hardware_keycode))
- {
- *modifier_press_only = TRUE;
- /* We keep the keyboard frozen - this allows us to use ReplayKeyboard
- * on the next event if it's not the release of the modifier key */
- if (xdisplay)
- XIAllowEvents (xdisplay,
- meta_input_device_x11_get_device_id (event->device),
- XISyncDevice, event->time);
-
- return TRUE;
- }
- else
- return FALSE;
-}
-
-
-static gboolean
-process_overlay_key (MetaDisplay *display,
- ClutterKeyEvent *event,
- MetaWindow *window)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
-
- if (display->focus_window && !keys->overlay_key_only_pressed)
- {
- ClutterInputDevice *source;
-
- source = clutter_event_get_source_device ((ClutterEvent *) event);
- if (meta_window_shortcuts_inhibited (display->focus_window, source))
- return FALSE;
- }
-
- return process_special_modifier_key (display,
- event,
- window,
- &keys->overlay_key_only_pressed,
- &keys->overlay_resolved_key_combo,
- (GFunc) meta_display_overlay_key_activate);
-}
-
-static void
-handle_locate_pointer (MetaDisplay *display)
-{
- meta_compositor_locate_pointer (display->compositor);
-}
-
-static gboolean
-process_locate_pointer_key (MetaDisplay *display,
- ClutterKeyEvent *event,
- MetaWindow *window)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
-
- return process_special_modifier_key (display,
- event,
- window,
- &keys->locate_pointer_key_only_pressed,
- &keys->locate_pointer_resolved_key_combo,
- (GFunc) handle_locate_pointer);
-}
-
-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;
-
- if (event->type == CLUTTER_KEY_RELEASE)
- return FALSE;
-
- activate = FALSE;
- mask = mask_from_event_params (keys, event->modifier_state);
-
- 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;
- }
- }
- }
-
- return activate;
-}
-
-static gboolean
-process_key_event (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event)
-{
- gboolean keep_grab;
- gboolean all_keys_grabbed;
-
- all_keys_grabbed = window ? window->all_keys_grabbed : FALSE;
- if (!all_keys_grabbed)
- {
- if (process_overlay_key (display, event, window))
- return TRUE;
-
- if (process_locate_pointer_key (display, event, window))
- return FALSE; /* Continue with the event even if handled */
-
- if (process_iso_next_group (display, event))
- return TRUE;
- }
-
- {
- MetaBackend *backend = meta_get_backend ();
- if (META_IS_BACKEND_X11 (backend))
- {
- Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
- XIAllowEvents (xdisplay,
- meta_input_device_x11_get_device_id (event->device),
- XIAsyncDevice, event->time);
- }
- }
-
- 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 == display->grab_window)
- {
- 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");
- keep_grab = process_keyboard_move_grab (display, window, event);
- }
- else
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Processing event for keyboard resize");
- keep_grab = process_keyboard_resize_grab (display, window, event);
- }
- }
- else
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Processing event for mouse-only move/resize");
- keep_grab = process_mouse_move_resize_grab (display, window, event);
- }
- }
- if (!keep_grab)
- meta_display_end_grab_op (display, event->time);
-
- return TRUE;
- }
-
- /* Do the normal keybindings */
- return process_event (display, window, event);
-}
-
-/* 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)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
-
- switch (event->type)
- {
- case CLUTTER_BUTTON_PRESS:
- case CLUTTER_BUTTON_RELEASE:
- case CLUTTER_TOUCH_BEGIN:
- case CLUTTER_TOUCH_END:
- case CLUTTER_SCROLL:
- keys->overlay_key_only_pressed = FALSE;
- keys->locate_pointer_key_only_pressed = FALSE;
- return FALSE;
-
- case CLUTTER_KEY_PRESS:
- case CLUTTER_KEY_RELEASE:
- return process_key_event (display, window, (ClutterKeyEvent *) event);
-
- default:
- return FALSE;
- }
-}
-
-static gboolean
-process_mouse_move_resize_grab (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event)
-{
- /* don't care about releases, but eat them, don't end grab */
- if (event->type == CLUTTER_KEY_RELEASE)
- return TRUE;
-
- if (event->keyval == CLUTTER_KEY_Escape)
- {
- MetaTileMode tile_mode;
-
- /* Hide the tiling preview if necessary */
- if (display->preview_tile_mode != META_TILE_NONE)
- meta_display_hide_tile_preview (display);
-
- /* Restore the original 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
- * window was a maximized window that had been "shaken loose" we
- * 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 || 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;
- }
-
- return TRUE;
-}
-
-static gboolean
-process_keyboard_move_grab (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event)
-{
- MetaEdgeResistanceFlags flags;
- gboolean handled;
- MetaRectangle frame_rect;
- int x, y;
- int incr;
-
- handled = FALSE;
-
- /* don't care about releases, but eat them, don't end grab */
- if (event->type == CLUTTER_KEY_RELEASE)
- return TRUE;
-
- /* don't end grab on modifier key presses */
- if (is_modifier (event->keyval))
- return TRUE;
-
- meta_window_get_frame_rect (window, &frame_rect);
- x = frame_rect.x;
- y = frame_rect.y;
-
- flags = META_EDGE_RESISTANCE_KEYBOARD_OP | META_EDGE_RESISTANCE_WINDOWS;
-
- if ((event->modifier_state & CLUTTER_SHIFT_MASK) != 0)
- flags |= META_EDGE_RESISTANCE_SNAP;
-
-#define SMALL_INCREMENT 1
-#define NORMAL_INCREMENT 10
-
- if (flags & META_EDGE_RESISTANCE_SNAP)
- incr = 1;
- else if (event->modifier_state & CLUTTER_CONTROL_MASK)
- incr = SMALL_INCREMENT;
- else
- incr = NORMAL_INCREMENT;
-
- 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
- * 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_BOTH);
- 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);
- }
-
- /* When moving by increments, we still snap to edges if the move
- * to the edge is smaller than the increment. This is because
- * Shift + arrow to snap is sort of a hidden feature. This way
- * people using just arrows shouldn't get too frustrated.
- */
- switch (event->keyval)
- {
- 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 CLUTTER_KEY_KP_End:
- case CLUTTER_KEY_KP_Next:
- case CLUTTER_KEY_Down:
- case CLUTTER_KEY_KP_Down:
- y += incr;
- handled = TRUE;
- break;
- }
-
- switch (event->keyval)
- {
- 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 CLUTTER_KEY_KP_Prior:
- case CLUTTER_KEY_KP_Next:
- case CLUTTER_KEY_Right:
- case CLUTTER_KEY_KP_Right:
- x += incr;
- handled = TRUE;
- break;
- }
-
- if (handled)
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Computed new window location %d,%d due to keypress",
- x, y);
-
- meta_window_edge_resistance_for_move (window,
- &x,
- &y,
- NULL,
- flags);
-
- meta_window_move_frame (window, TRUE, x, y);
- meta_window_update_keyboard_move (window);
- }
-
- return handled;
-}
-
-static gboolean
-process_keyboard_resize_grab_op_change (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event)
-{
- gboolean handled;
-
- handled = FALSE;
- switch (display->grab_op)
- {
- case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
- switch (event->keyval)
- {
- case CLUTTER_KEY_Up:
- case CLUTTER_KEY_KP_Up:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
- handled = TRUE;
- break;
- case CLUTTER_KEY_Down:
- case CLUTTER_KEY_KP_Down:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
- handled = TRUE;
- break;
- case CLUTTER_KEY_Left:
- case CLUTTER_KEY_KP_Left:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
- handled = TRUE;
- break;
- 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 (event->keyval)
- {
- case CLUTTER_KEY_Left:
- case CLUTTER_KEY_KP_Left:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
- handled = TRUE;
- break;
- 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 (event->keyval)
- {
- case CLUTTER_KEY_Left:
- case CLUTTER_KEY_KP_Left:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
- handled = TRUE;
- break;
- 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 (event->keyval)
- {
- case CLUTTER_KEY_Up:
- case CLUTTER_KEY_KP_Up:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
- handled = TRUE;
- break;
- 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 (event->keyval)
- {
- case CLUTTER_KEY_Up:
- case CLUTTER_KEY_KP_Up:
- display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
- handled = TRUE;
- break;
- 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_SE:
- case META_GRAB_OP_KEYBOARD_RESIZING_NE:
- case META_GRAB_OP_KEYBOARD_RESIZING_SW:
- case META_GRAB_OP_KEYBOARD_RESIZING_NW:
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
-
- if (handled)
- {
- meta_window_update_keyboard_resize (window, TRUE);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-process_keyboard_resize_grab (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event)
-{
- MetaRectangle frame_rect;
- gboolean handled;
- int height_inc;
- int width_inc;
- int width, height;
- MetaEdgeResistanceFlags flags;
- MetaGravity gravity;
-
- handled = FALSE;
-
- /* don't care about releases, but eat them, don't end grab */
- if (event->type == CLUTTER_KEY_RELEASE)
- return TRUE;
-
- /* don't end grab on modifier key presses */
- if (is_modifier (event->keyval))
- return TRUE;
-
- if (event->keyval == CLUTTER_KEY_Escape)
- {
- /* End resize and restore to original state. */
- 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, window, event))
- return TRUE;
-
- width = window->rect.width;
- height = window->rect.height;
-
- meta_window_get_frame_rect (window, &frame_rect);
- width = frame_rect.width;
- height = frame_rect.height;
-
- gravity = meta_resize_gravity_from_grab_op (display->grab_op);
-
- flags = META_EDGE_RESISTANCE_KEYBOARD_OP;
-
- if ((event->modifier_state & CLUTTER_SHIFT_MASK) != 0)
- flags |= META_EDGE_RESISTANCE_SNAP;
-
-#define SMALL_INCREMENT 1
-#define NORMAL_INCREMENT 10
-
- if (flags & META_EDGE_RESISTANCE_SNAP)
- {
- height_inc = 1;
- width_inc = 1;
- }
- else if (event->modifier_state & CLUTTER_CONTROL_MASK)
- {
- width_inc = SMALL_INCREMENT;
- height_inc = SMALL_INCREMENT;
- }
- else
- {
- width_inc = NORMAL_INCREMENT;
- height_inc = NORMAL_INCREMENT;
- }
-
- /* If this is a resize increment window, make the amount we resize
- * the window by match that amount (well, unless snap resizing...)
- */
- if (window->size_hints.width_inc > 1)
- width_inc = window->size_hints.width_inc;
- if (window->size_hints.height_inc > 1)
- height_inc = window->size_hints.height_inc;
-
- switch (event->keyval)
- {
- case CLUTTER_KEY_Up:
- case CLUTTER_KEY_KP_Up:
- switch (gravity)
- {
- case META_GRAVITY_NORTH:
- case META_GRAVITY_NORTH_WEST:
- case META_GRAVITY_NORTH_EAST:
- /* Move bottom edge up */
- height -= height_inc;
- break;
-
- case META_GRAVITY_SOUTH:
- case META_GRAVITY_SOUTH_WEST:
- case META_GRAVITY_SOUTH_EAST:
- /* Move top edge up */
- height += height_inc;
- break;
-
- 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;
- }
-
- handled = TRUE;
- break;
-
- case CLUTTER_KEY_Down:
- case CLUTTER_KEY_KP_Down:
- switch (gravity)
- {
- case META_GRAVITY_NORTH:
- case META_GRAVITY_NORTH_WEST:
- case META_GRAVITY_NORTH_EAST:
- /* Move bottom edge down */
- height += height_inc;
- break;
-
- case META_GRAVITY_SOUTH:
- case META_GRAVITY_SOUTH_WEST:
- case META_GRAVITY_SOUTH_EAST:
- /* Move top edge down */
- height -= height_inc;
- break;
-
- 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;
- }
-
- handled = TRUE;
- break;
-
- case CLUTTER_KEY_Left:
- case CLUTTER_KEY_KP_Left:
- switch (gravity)
- {
- case META_GRAVITY_EAST:
- case META_GRAVITY_SOUTH_EAST:
- case META_GRAVITY_NORTH_EAST:
- /* Move left edge left */
- width += width_inc;
- break;
-
- case META_GRAVITY_WEST:
- case META_GRAVITY_SOUTH_WEST:
- case META_GRAVITY_NORTH_WEST:
- /* Move right edge left */
- width -= width_inc;
- break;
-
- 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;
- }
-
- handled = TRUE;
- break;
-
- case CLUTTER_KEY_Right:
- case CLUTTER_KEY_KP_Right:
- switch (gravity)
- {
- case META_GRAVITY_EAST:
- case META_GRAVITY_SOUTH_EAST:
- case META_GRAVITY_NORTH_EAST:
- /* Move left edge right */
- width -= width_inc;
- break;
-
- case META_GRAVITY_WEST:
- case META_GRAVITY_SOUTH_WEST:
- case META_GRAVITY_NORTH_WEST:
- /* Move right edge right */
- width += width_inc;
- break;
-
- 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;
- }
-
- handled = TRUE;
- break;
-
- default:
- break;
- }
-
- /* fixup hack (just paranoia, not sure it's required) */
- if (height < 1)
- height = 1;
- if (width < 1)
- width = 1;
-
- if (handled)
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Computed new window size due to keypress: "
- "%dx%d, gravity %s",
- width, height, meta_gravity_to_string (gravity));
-
- /* Do any edge resistance/snapping */
- meta_window_edge_resistance_for_resize (window,
- &width,
- &height,
- gravity,
- NULL,
- flags);
-
- meta_window_resize_frame_with_gravity (window,
- TRUE,
- width,
- height,
- gravity);
-
- meta_window_update_keyboard_resize (window, FALSE);
- }
-
- return handled;
-}
-
-static void
-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;
-
- 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->time);
- }
- else
- {
- /* We could offer to create it I suppose */
- }
-}
-
-
-static void
-handle_maximize_vertically (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- if (window->has_resize_func)
- {
- if (window->maximized_vertically)
- meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL);
- else
- meta_window_maximize (window, META_MAXIMIZE_VERTICAL);
- }
-}
-
-static void
-handle_maximize_horizontally (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- if (window->has_resize_func)
- {
- if (window->maximized_horizontally)
- meta_window_unmaximize (window, META_MAXIMIZE_HORIZONTAL);
- else
- meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL);
- }
-}
-
-static void
-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_current_monitor (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)
-{
- MetaWorkspaceManager *workspace_manager = display->workspace_manager;
-
- 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_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;
-
- 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;
- }
-
- 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;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Sending panel message with timestamp %u, and turning mouse_mode "
- "off due to keybinding press", event->time);
- display->mouse_mode = FALSE;
-
- meta_x11_error_trap_push (x11_display);
-
- /* Release the grab for the panel before sending the event */
- XUngrabKeyboard (x11_display->xdisplay, event->time);
-
- XSendEvent (x11_display->xdisplay,
- x11_display->xroot,
- False,
- StructureNotifyMask,
- (XEvent*) &ev);
-
- meta_x11_error_trap_pop (x11_display);
-}
-
-static void
-handle_activate_window_menu (MetaDisplay *display,
- MetaWindow *event_window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- if (display->focus_window)
- {
- int x, y;
- MetaRectangle frame_rect;
- cairo_rectangle_int_t child_rect;
-
- meta_window_get_frame_rect (display->focus_window, &frame_rect);
- meta_window_get_client_area_rect (display->focus_window, &child_rect);
-
- x = frame_rect.x + child_rect.x;
- if (meta_get_locale_direction () == META_LOCALE_DIRECTION_RTL)
- x += child_rect.width;
-
- y = frame_rect.y + child_rect.y;
- meta_window_show_menu (display->focus_window, META_WINDOW_MENU_WM, x, y);
- }
-}
-
-static void
-do_choose_window (MetaDisplay *display,
- MetaWindow *event_window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gboolean backward)
-{
- MetaWorkspaceManager *workspace_manager = display->workspace_manager;
- MetaTabList type = binding->handler->data;
- MetaWindow *window;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Tab list = %u", 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_switch (MetaDisplay *display,
- MetaWindow *event_window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- gboolean backwards = meta_key_binding_is_reversed (binding);
- do_choose_window (display, event_window, event, binding, backwards);
-}
-
-static void
-handle_cycle (MetaDisplay *display,
- MetaWindow *event_window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- gboolean backwards = meta_key_binding_is_reversed (binding);
- do_choose_window (display, event_window, event, binding, backwards);
-}
-
-static void
-handle_toggle_fullscreen (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- if (window->fullscreen)
- meta_window_unmake_fullscreen (window);
- else if (window->has_fullscreen_func)
- meta_window_make_fullscreen (window);
-}
-
-static void
-handle_toggle_above (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- if (window->wm_state_above)
- meta_window_unmake_above (window);
- else
- meta_window_make_above (window);
-}
-
-static void
-handle_toggle_tiled (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- MetaTileMode mode = binding->handler->data;
-
- if ((META_WINDOW_TILED_LEFT (window) && mode == META_TILE_LEFT) ||
- (META_WINDOW_TILED_RIGHT (window) && mode == META_TILE_RIGHT))
- {
- meta_window_untile (window);
- }
- else if (meta_window_can_tile_side_by_side (window))
- {
- 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,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- if (META_WINDOW_MAXIMIZED (window))
- meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
- else if (window->has_maximize_func)
- meta_window_maximize (window, META_MAXIMIZE_BOTH);
-}
-
-static void
-handle_maximize (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- if (window->has_maximize_func)
- meta_window_maximize (window, META_MAXIMIZE_BOTH);
-}
-
-static void
-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_BOTH);
-}
-
-static void
-handle_toggle_shaded (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- if (window->shaded)
- meta_window_unshade (window, event->time);
- else if (window->has_shade_func)
- meta_window_shade (window, event->time);
-}
-
-static void
-handle_close (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- if (window->has_close_func)
- meta_window_delete (window, event->time);
-}
-
-static void
-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,
- 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->time);
- }
-}
-
-static void
-handle_begin_resize (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- if (window->has_resize_func)
- {
- meta_window_begin_grab_op (window,
- META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN,
- FALSE,
- event->time);
- }
-}
-
-static void
-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);
- else
- meta_window_stick (window);
-}
-
-static void
-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);
- MetaWorkspace *workspace;
-
- /* If which is zero or positive, it's a workspace number, and the window
- * should move to the workspace with that number.
- *
- * However, if it's negative, it's a direction with respect to the current
- * position; it's expressed as a member of the MetaMotionDirection enum,
- * all of whose members are negative. Such a change is called a flip.
- */
-
- if (window->always_sticky)
- return;
-
- workspace = NULL;
- 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)
- {
- /* Activate second, so the window is never unmapped */
- meta_window_change_workspace (window, workspace);
- if (flip)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Resetting mouse_mode to FALSE due to "
- "handle_move_to_workspace() call with flip set.");
- meta_display_clear_mouse_mode (workspace->display);
- meta_workspace_activate_with_focus (workspace,
- window,
- event->time);
- }
- }
- else
- {
- /* We could offer to create it I suppose */
- }
-}
-
-static void
-handle_move_to_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);
- gint which = binding->handler->data;
- MetaLogicalMonitor *current, *new;
-
- current = window->monitor;
- new = meta_monitor_manager_get_logical_monitor_neighbor (monitor_manager,
- current, which);
-
- if (new == NULL)
- return;
-
- meta_window_move_to_monitor (window, new->number);
-}
-
-static void
-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->display->stack) == window)
- {
- meta_window_lower (window);
- return;
- }
-
- /* else check if windows in same layer are intersecting it */
-
- 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))
- {
- 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))
- {
- meta_window_raise (window);
- return;
- }
- }
-
- above = meta_stack_get_above (window->display->stack, above, TRUE);
- }
-
- /* window is not obscured */
- meta_window_lower (window);
-}
-
-static void
-handle_raise (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- meta_window_raise (window);
-}
-
-static void
-handle_lower (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- meta_window_lower (window);
-}
-
-static void
-handle_set_spew_mark (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- meta_verbose ("-- MARK MARK MARK MARK --");
-}
-
-#ifdef HAVE_NATIVE_BACKEND
-static void
-handle_switch_vt (MetaDisplay *display,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer dummy)
-{
- 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");
-
- 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,
- gpointer user_data,
- GDestroyNotify free_data)
-{
- MetaKeyHandler *key_handler = HANDLER (name);
-
- if (!key_handler)
- return FALSE;
-
- if (key_handler->user_data_free_func && key_handler->user_data)
- key_handler->user_data_free_func (key_handler->user_data);
-
- key_handler->func = handler;
- key_handler->user_data = user_data;
- key_handler->user_data_free_func = free_data;
-
- return TRUE;
-}
-
-static void
-init_builtin_key_bindings (MetaDisplay *display)
-{
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- common_keybindings,
- META_KEY_BINDING_NONE |
- META_KEY_BINDING_IGNORE_AUTOREPEAT,
- META_KEYBINDING_ACTION_WORKSPACE_12,
- handle_switch_to_workspace, 11);
-
- add_builtin_keybinding (display,
- "switch-to-workspace-left",
- common_keybindings,
- META_KEY_BINDING_NONE,
- META_KEYBINDING_ACTION_WORKSPACE_LEFT,
- handle_switch_to_workspace, META_MOTION_LEFT);
-
- add_builtin_keybinding (display,
- "switch-to-workspace-right",
- common_keybindings,
- META_KEY_BINDING_NONE,
- META_KEYBINDING_ACTION_WORKSPACE_RIGHT,
- handle_switch_to_workspace, META_MOTION_RIGHT);
-
- add_builtin_keybinding (display,
- "switch-to-workspace-up",
- common_keybindings,
- META_KEY_BINDING_NONE,
- META_KEYBINDING_ACTION_WORKSPACE_UP,
- handle_switch_to_workspace, META_MOTION_UP);
-
- add_builtin_keybinding (display,
- "switch-to-workspace-down",
- common_keybindings,
- META_KEY_BINDING_NONE,
- META_KEYBINDING_ACTION_WORKSPACE_DOWN,
- handle_switch_to_workspace, META_MOTION_DOWN);
-
- add_builtin_keybinding (display,
- "switch-to-workspace-last",
- common_keybindings,
- META_KEY_BINDING_NONE,
- META_KEYBINDING_ACTION_WORKSPACE_LAST,
- handle_switch_to_last_workspace, 0);
-
-
-
- /* The ones which have inverses. These can't be bound to any keystroke
- * containing Shift because Shift will invert their "backward" state.
- *
- * TODO: "NORMAL" and "DOCKS" should be renamed to the same name as their
- * action, for obviousness.
- *
- * TODO: handle_switch and handle_cycle should probably really be the
- * same function checking a bit in the parameter for difference.
- */
-
- add_builtin_keybinding (display,
- "switch-group",
- common_keybindings,
- META_KEY_BINDING_NONE,
- META_KEYBINDING_ACTION_SWITCH_GROUP,
- handle_switch, META_TAB_LIST_GROUP);
-
- add_builtin_keybinding (display,
- "switch-group-backward",
- common_keybindings,
- META_KEY_BINDING_IS_REVERSED,
- META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD,
- 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",
- common_keybindings,
- META_KEY_BINDING_NONE,
- META_KEYBINDING_ACTION_SWITCH_WINDOWS,
- handle_switch, META_TAB_LIST_NORMAL);
-
- add_builtin_keybinding (display,
- "switch-windows-backward",
- common_keybindings,
- META_KEY_BINDING_IS_REVERSED,
- META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD,
- handle_switch, META_TAB_LIST_NORMAL);
-
- add_builtin_keybinding (display,
- "switch-panels",
- common_keybindings,
- META_KEY_BINDING_NONE,
- META_KEYBINDING_ACTION_SWITCH_PANELS,
- handle_switch, META_TAB_LIST_DOCKS);
-
- add_builtin_keybinding (display,
- "switch-panels-backward",
- common_keybindings,
- META_KEY_BINDING_IS_REVERSED,
- META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD,
- 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",
- 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",
- common_keybindings,
- META_KEY_BINDING_NONE,
- META_KEYBINDING_ACTION_PANEL_RUN_DIALOG,
- handle_panel, META_KEYBINDING_ACTION_PANEL_RUN_DIALOG);
-
- add_builtin_keybinding (display,
- "set-spew-mark",
- common_keybindings,
- META_KEY_BINDING_NONE,
- META_KEYBINDING_ACTION_SET_SPEW_MARK,
- handle_set_spew_mark, 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 ************************/
-
- /* These take a window as an extra parameter; they have no effect
- * if no window is active.
- */
-
- add_builtin_keybinding (display,
- "activate-window-menu",
- 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",
- 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",
- 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,
- "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,
- "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",
- 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",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW |
- META_KEY_BINDING_IGNORE_AUTOREPEAT,
- META_KEYBINDING_ACTION_MAXIMIZE,
- handle_maximize, 0);
-
- add_builtin_keybinding (display,
- "unmaximize",
- 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",
- 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",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW |
- META_KEY_BINDING_IGNORE_AUTOREPEAT,
- META_KEYBINDING_ACTION_MINIMIZE,
- handle_minimize, 0);
-
- add_builtin_keybinding (display,
- "close",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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-last",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW |
- META_KEY_BINDING_IGNORE_AUTOREPEAT,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LAST,
- handle_move_to_workspace_last, 0);
-
- add_builtin_keybinding (display,
- "move-to-workspace-left",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LEFT,
- handle_move_to_workspace, META_MOTION_LEFT);
-
- add_builtin_keybinding (display,
- "move-to-workspace-right",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_RIGHT,
- handle_move_to_workspace, META_MOTION_RIGHT);
-
- add_builtin_keybinding (display,
- "move-to-workspace-up",
- 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",
- 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-monitor-left",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW,
- META_KEYBINDING_ACTION_MOVE_TO_MONITOR_LEFT,
- handle_move_to_monitor, META_DISPLAY_LEFT);
-
- add_builtin_keybinding (display,
- "move-to-monitor-right",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW,
- META_KEYBINDING_ACTION_MOVE_TO_MONITOR_RIGHT,
- handle_move_to_monitor, META_DISPLAY_RIGHT);
-
- add_builtin_keybinding (display,
- "move-to-monitor-down",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW,
- META_KEYBINDING_ACTION_MOVE_TO_MONITOR_DOWN,
- handle_move_to_monitor, META_DISPLAY_DOWN);
-
- add_builtin_keybinding (display,
- "move-to-monitor-up",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW,
- META_KEYBINDING_ACTION_MOVE_TO_MONITOR_UP,
- handle_move_to_monitor, META_DISPLAY_UP);
-
- add_builtin_keybinding (display,
- "raise-or-lower",
- 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",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW |
- META_KEY_BINDING_IGNORE_AUTOREPEAT,
- META_KEYBINDING_ACTION_RAISE,
- handle_raise, 0);
-
- add_builtin_keybinding (display,
- "lower",
- 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",
- 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",
- 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",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW |
- META_KEY_BINDING_IGNORE_AUTOREPEAT,
- META_KEYBINDING_ACTION_MOVE_TO_CORNER_NW,
- handle_move_to_corner_nw, 0);
-
- add_builtin_keybinding (display,
- "move-to-corner-ne",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW |
- META_KEY_BINDING_IGNORE_AUTOREPEAT,
- META_KEYBINDING_ACTION_MOVE_TO_CORNER_NE,
- handle_move_to_corner_ne, 0);
-
- add_builtin_keybinding (display,
- "move-to-corner-sw",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW |
- META_KEY_BINDING_IGNORE_AUTOREPEAT,
- META_KEYBINDING_ACTION_MOVE_TO_CORNER_SW,
- handle_move_to_corner_sw, 0);
-
- add_builtin_keybinding (display,
- "move-to-corner-se",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW |
- META_KEY_BINDING_IGNORE_AUTOREPEAT,
- META_KEYBINDING_ACTION_MOVE_TO_CORNER_SE,
- handle_move_to_corner_se, 0);
-
- add_builtin_keybinding (display,
- "move-to-side-n",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW |
- META_KEY_BINDING_IGNORE_AUTOREPEAT,
- META_KEYBINDING_ACTION_MOVE_TO_SIDE_N,
- handle_move_to_side_n, 0);
-
- add_builtin_keybinding (display,
- "move-to-side-s",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW |
- META_KEY_BINDING_IGNORE_AUTOREPEAT,
- META_KEYBINDING_ACTION_MOVE_TO_SIDE_S,
- handle_move_to_side_s, 0);
-
- add_builtin_keybinding (display,
- "move-to-side-e",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW |
- META_KEY_BINDING_IGNORE_AUTOREPEAT,
- META_KEYBINDING_ACTION_MOVE_TO_SIDE_E,
- handle_move_to_side_e, 0);
-
- add_builtin_keybinding (display,
- "move-to-side-w",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW |
- META_KEY_BINDING_IGNORE_AUTOREPEAT,
- META_KEYBINDING_ACTION_MOVE_TO_SIDE_W,
- handle_move_to_side_w, 0);
-
- add_builtin_keybinding (display,
- "move-to-center",
- common_keybindings,
- META_KEY_BINDING_PER_WINDOW |
- META_KEY_BINDING_IGNORE_AUTOREPEAT,
- META_KEYBINDING_ACTION_MOVE_TO_CENTER,
- handle_move_to_center, 0);
-
- g_object_unref (common_keybindings);
- g_object_unref (mutter_keybindings);
- g_object_unref (mutter_wayland_keybindings);
-}
-
-void
-meta_display_init_keys (MetaDisplay *display)
-{
- MetaKeyBindingManager *keys = &display->key_binding_manager;
- MetaBackend *backend = meta_get_backend ();
- MetaKeyHandler *handler;
-
- keys->backend = backend;
-
- /* Keybindings */
- keys->ignored_modifier_mask = 0;
- keys->hyper_mask = 0;
- keys->super_mask = 0;
- keys->meta_mask = 0;
-
- 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_modmap (keys);
-
- 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 (keys);
- rebuild_special_bindings (keys);
-
- reload_combos (keys);
-
- update_window_grab_modifiers (display);
-
- /* Keys are actually grabbed in meta_screen_grab_keys() */
-
- meta_prefs_add_listener (prefs_changed_callback, display);
-
- 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/meta-accel-parse.c b/src/core/meta-accel-parse.c
deleted file mode 100644
index 0d34251af..000000000
--- a/src/core/meta-accel-parse.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 12cf3f982..000000000
--- a/src/core/meta-accel-parse.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- 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-anonymous-file.c b/src/core/meta-anonymous-file.c
deleted file mode 100644
index 95b63c9f0..000000000
--- a/src/core/meta-anonymous-file.c
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Copyright (C) 2020 Sebastian Wick
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public 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: Sebastian Wick <sebastian@sebastianwick.net>
- */
-
-#include "config.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-
-#include "core/meta-anonymous-file.h"
-
-struct _MetaAnonymousFile
-{
- int fd;
- size_t size;
-};
-
-#define READONLY_SEALS (F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE)
-
-static int
-create_tmpfile_cloexec (char *tmpname)
-{
- int fd;
-
-#if defined(HAVE_MKOSTEMP)
- fd = mkostemp (tmpname, O_CLOEXEC);
- if (fd >= 0)
- unlink (tmpname);
-#else
- fd = mkstemp (tmpname);
- if (fd >= 0)
- {
- long flags;
-
- unlink (tmpname);
-
- flags = fcntl (fd, F_GETFD);
- if (flags == -1 ||
- fcntl (fd, F_SETFD, flags | FD_CLOEXEC) == -1)
- {
- close (fd);
- return -1;
- }
- }
-#endif
-
- return fd;
-}
-
-/*
- * Create a new, unique, anonymous file of the given size, and
- * return the file descriptor for it. The file descriptor is set
- * CLOEXEC. The file is immediately suitable for mmap()'ing
- * the given size at offset zero.
- *
- * The file should not have a permanent backing store like a disk,
- * but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
- *
- * The file name is deleted from the file system.
- *
- * The file is suitable for buffer sharing between processes by
- * transmitting the file descriptor over Unix sockets using the
- * SCM_RIGHTS methods.
- *
- * If the C library implements posix_fallocate(), it is used to
- * guarantee that disk space is available for the file at the
- * given size. If disk space is insufficient, errno is set to ENOSPC.
- * If posix_fallocate() is not supported, program may receive
- * SIGBUS on accessing mmap()'ed file contents instead.
- *
- * If the C library implements memfd_create(), it is used to create the
- * file purely in memory, without any backing file name on the file
- * system, and then sealing off the possibility of shrinking it. This
- * can then be checked before accessing mmap()'ed file contents, to make
- * sure SIGBUS can't happen. It also avoids requiring XDG_RUNTIME_DIR.
- */
-static int
-create_anonymous_file (off_t size)
-{
- int fd, ret;
-
-#if defined(HAVE_MEMFD_CREATE)
- fd = memfd_create ("mutter-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);
- if (fd >= 0)
- {
- /* We can add this seal before calling posix_fallocate(), as
- * the file is currently zero-sized anyway.
- *
- * There is also no need to check for the return value, we
- * couldn't do anything with it anyway.
- */
- fcntl (fd, F_ADD_SEALS, F_SEAL_SHRINK);
- }
- else
-#endif
- {
- static const char template[] = "/mutter-shared-XXXXXX";
- const char *path;
- char *name;
-
- path = getenv ("XDG_RUNTIME_DIR");
- if (!path)
- {
- errno = ENOENT;
- return -1;
- }
-
- name = g_malloc (strlen (path) + sizeof (template));
- if (!name)
- return -1;
-
- strcpy (name, path);
- strcat (name, template);
-
- fd = create_tmpfile_cloexec (name);
-
- g_free (name);
-
- if (fd < 0)
- return -1;
- }
-
-#if defined(HAVE_POSIX_FALLOCATE)
- do
- {
- ret = posix_fallocate (fd, 0, size);
- }
- while (ret == EINTR);
-
- if (ret != 0)
- {
- close (fd);
- errno = ret;
- return -1;
- }
-#else
- do
- {
- ret = ftruncate (fd, size);
- }
- while (ret < 0 && errno == EINTR);
-
- if (ret < 0)
- {
- close (fd);
- return -1;
- }
-#endif
-
- return fd;
-}
-
-/**
- * meta_anonymous_file_new: (skip)
- * @size: The size of @data
- * @data: The data of the file with the size @size
- *
- * Create a new anonymous read-only file of the given size and the given data
- * The intended use-case is for sending mid-sized data from the compositor
- * to clients.
- *
- * When done, free the data using meta_anonymous_file_free().
- *
- * If this function fails errno is set.
- *
- * Returns: The newly created #MetaAnonymousFile, or NULL on failure. Use
- * meta_anonymous_file_free() to free the resources when done.
- */
-MetaAnonymousFile *
-meta_anonymous_file_new (size_t size,
- const uint8_t *data)
-{
- MetaAnonymousFile *file;
- void *map;
-
- file = g_malloc0 (sizeof *file);
- if (!file)
- {
- errno = ENOMEM;
- return NULL;
- }
-
- file->size = size;
- file->fd = create_anonymous_file (size);
- if (file->fd == -1)
- goto err_free;
-
- map = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, file->fd, 0);
- if (map == MAP_FAILED)
- goto err_close;
-
- memcpy (map, data, size);
-
- munmap (map, size);
-
-#if defined(HAVE_MEMFD_CREATE)
- /* try to put seals on the file to make it read-only so that we can
- * return the fd later directly when MAPMODE_SHARED is not set.
- * meta_anonymous_file_open_fd can handle the fd even if it is not
- * sealed read-only and will instead create a new anonymous file on
- * each invocation.
- */
- fcntl (file->fd, F_ADD_SEALS, READONLY_SEALS);
-#endif
-
- return file;
-
-err_close:
- close (file->fd);
-err_free:
- g_free (file);
- return NULL;
-}
-
-
-/**
- * meta_anonymous_file_free: (skip)
- * @file: the #MetaAnonymousFile
- *
- * Free the resources used by an anonymous read-only file.
- */
-void
-meta_anonymous_file_free (MetaAnonymousFile *file)
-{
- close (file->fd);
- g_free (file);
-}
-
-/**
- * meta_anonymous_file_size: (skip)
- * @file: the #MetaAnonymousFile
- *
- * Get the size of an anonymous read-only file.
- *
- * Returns: The size of the anonymous read-only file.
- */
-size_t
-meta_anonymous_file_size (MetaAnonymousFile *file)
-{
- return file->size;
-}
-
-/**
- * meta_anonymous_file_open_fd: (skip)
- * @file: the #MetaAnonymousFile to get a file descriptor for
- * @mapmode: describes the ways in which the returned file descriptor can
- * be used with mmap
- *
- * Returns a file descriptor for the given file, ready to be sent to a client.
- * The returned file descriptor must not be shared between multiple clients.
- * If @mapmode is %META_ANONYMOUS_FILE_MAPMODE_PRIVATE the file descriptor is
- * only guaranteed to be mmapable with MAP_PRIVATE. If @mapmode is
- * %META_ANONYMOUS_FILE_MAPMODE_SHARED the file descriptor can be mmaped with
- * either MAP_PRIVATE or MAP_SHARED.
- *
- * In case %META_ANONYMOUS_FILE_MAPMODE_PRIVATE is used, it is important to
- * only read the returned fd using mmap() since using read() will move the
- * read cursor of the fd and thus may cause read() calls on other returned
- * fds to fail.
- *
- * When done using the fd, it is required to call meta_anonymous_file_close_fd()
- * instead of close().
- *
- * If this function fails errno is set.
- *
- * Returns: A file descriptor for the given file that can be sent to a client
- * or -1 on failure. Use meta_anonymous_file_close_fd() to release the fd
- * when done.
- */
-int
-meta_anonymous_file_open_fd (MetaAnonymousFile *file,
- MetaAnonymousFileMapmode mapmode)
-{
- void *src, *dst;
- int fd;
-
-#if defined(HAVE_MEMFD_CREATE)
- int seals;
-
- seals = fcntl (file->fd, F_GET_SEALS);
-
- /* file was sealed for read-only and we don't have to support MAP_SHARED
- * so we can simply pass the memfd fd
- */
- if (seals != -1 && mapmode == META_ANONYMOUS_FILE_MAPMODE_PRIVATE &&
- (seals & READONLY_SEALS) == READONLY_SEALS)
- return file->fd;
-#endif
-
- /* for all other cases we create a new anonymous file that can be mapped
- * with MAP_SHARED and copy the contents to it and return that instead
- */
- fd = create_anonymous_file (file->size);
- if (fd == -1)
- return fd;
-
- src = mmap (NULL, file->size, PROT_READ, MAP_PRIVATE, file->fd, 0);
- if (src == MAP_FAILED)
- {
- close (fd);
- return -1;
- }
-
- dst = mmap (NULL, file->size, PROT_WRITE, MAP_SHARED, fd, 0);
- if (dst == MAP_FAILED)
- {
- close (fd);
- munmap (src, file->size);
- return -1;
- }
-
- memcpy (dst, src, file->size);
- munmap (src, file->size);
- munmap (dst, file->size);
-
- return fd;
-}
-
-/**
- * meta_anonymous_file_close_fd: (skip)
- * @fd: A file descriptor obtained using meta_anonymous_file_open_fd()
- *
- * Release a file descriptor returned by meta_anonymous_file_open_fd().
- * This function must be called for every file descriptor created with
- * meta_anonymous_file_open_fd() to not leak any resources.
- *
- * If this function fails errno is set.
- */
-void
-meta_anonymous_file_close_fd (int fd)
-{
-#if defined(HAVE_MEMFD_CREATE)
- int seals;
-
- seals = fcntl (fd, F_GET_SEALS);
- if (seals == -1 && errno != EINVAL)
- {
- g_warning ("Reading seals of anonymous file %d failed", fd);
- return;
- }
-
- /* The only case in which we do NOT have to close the file is when the file
- * was sealed for read-only
- */
- if (seals != -1 && (seals & READONLY_SEALS) == READONLY_SEALS)
- return;
-#endif
-
- close (fd);
-}
diff --git a/src/core/meta-anonymous-file.h b/src/core/meta-anonymous-file.h
deleted file mode 100644
index 5289c7193..000000000
--- a/src/core/meta-anonymous-file.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2020 Sebastian Wick
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public 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: Sebastian Wick <sebastian@sebastianwick.net>
- */
-
-#ifndef META_ANONYMOUS_FILE_H
-#define META_ANONYMOUS_FILE_H
-
-#include "meta/common.h"
-#include "core/util-private.h"
-
-typedef struct _MetaAnonymousFile MetaAnonymousFile;
-
-typedef enum _MetaAnonymousFileMapmode
-{
- META_ANONYMOUS_FILE_MAPMODE_PRIVATE,
- META_ANONYMOUS_FILE_MAPMODE_SHARED,
-} MetaAnonymousFileMapmode;
-
-META_EXPORT_TEST
-MetaAnonymousFile * meta_anonymous_file_new (size_t size,
- const uint8_t *data);
-
-META_EXPORT_TEST
-void meta_anonymous_file_free (MetaAnonymousFile *file);
-
-META_EXPORT_TEST
-size_t meta_anonymous_file_size (MetaAnonymousFile *file);
-
-META_EXPORT_TEST
-int meta_anonymous_file_open_fd (MetaAnonymousFile *file,
- MetaAnonymousFileMapmode mapmode);
-
-META_EXPORT_TEST
-void meta_anonymous_file_close_fd (int fd);
-
-#endif /* META_ANONYMOUS_FILE_H */
diff --git a/src/core/meta-border.c b/src/core/meta-border.c
deleted file mode 100644
index 3c926c419..000000000
--- a/src/core/meta-border.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/* -*- 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
deleted file mode 100644
index dd76db5c9..000000000
--- a/src/core/meta-border.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 794195f41..000000000
--- a/src/core/meta-clipboard-manager.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 2ba130f9b..000000000
--- a/src/core/meta-clipboard-manager.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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
deleted file mode 100644
index f149d3686..000000000
--- a/src/core/meta-close-dialog-default-private.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 544a5b62d..000000000
--- a/src/core/meta-close-dialog-default.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* -*- 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",
- 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
deleted file mode 100644
index 6d24fa570..000000000
--- a/src/core/meta-close-dialog.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/* -*- 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-context-main.c b/src/core/meta-context-main.c
deleted file mode 100644
index 8f669151a..000000000
--- a/src/core/meta-context-main.c
+++ /dev/null
@@ -1,702 +0,0 @@
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2006 Elijah Newren
- * Copyright (C) 2021 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 "core/meta-context-main.h"
-
-#include <glib.h>
-#include <gio/gio.h>
-
-#if defined(HAVE_NATIVE_BACKEND) && defined(HAVE_WAYLAND)
-#include <systemd/sd-login.h>
-#endif /* HAVE_WAYLAND && HAVE_NATIVE_BACKEND */
-
-#include "backends/meta-monitor-manager-private.h"
-#include "backends/meta-virtual-monitor.h"
-#include "backends/x11/cm/meta-backend-x11-cm.h"
-#include "meta/meta-backend.h"
-#include "wayland/meta-wayland.h"
-#include "x11/session.h"
-
-#ifdef HAVE_NATIVE_BACKEND
-#include "backends/native/meta-backend-native.h"
-#endif
-
-#ifdef HAVE_WAYLAND
-#include "backends/x11/nested/meta-backend-x11-nested.h"
-#endif
-
-typedef struct _MetaContextMainOptions
-{
- struct {
- char *display_name;
- gboolean replace;
- gboolean sync;
- gboolean force;
- } x11;
- struct {
- char *save_file;
- char *client_id;
- gboolean disable;
- } sm;
-#ifdef HAVE_WAYLAND
- gboolean wayland;
- gboolean nested;
- gboolean no_x11;
- char *wayland_display;
-#endif
-#ifdef HAVE_NATIVE_BACKEND
- gboolean display_server;
- gboolean headless;
-#endif
-#ifdef HAVE_NATIVE_BACKEND
- GList *virtual_monitor_infos;
-#endif
-} MetaContextMainOptions;
-
-struct _MetaContextMain
-{
- GObject parent;
-
- MetaContextMainOptions options;
-
- MetaCompositorType compositor_type;
-
- GList *persistent_virtual_monitors;
-};
-
-G_DEFINE_TYPE (MetaContextMain, meta_context_main, META_TYPE_CONTEXT)
-
-static gboolean
-check_configuration (MetaContextMain *context_main,
- GError **error)
-{
-#ifdef HAVE_WAYLAND
- if (context_main->options.x11.force && context_main->options.no_x11)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Can't run in X11 mode with no X11");
- return FALSE;
- }
- if (context_main->options.x11.force && context_main->options.wayland)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Can't run in X11 mode with Wayland enabled");
- return FALSE;
- }
- if (context_main->options.x11.force && context_main->options.nested)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Can't run in X11 mode nested");
- return FALSE;
- }
-#endif /* HAVE_WAYLAND */
-
-#ifdef HAVE_NATIVE_BACKEND
- if (context_main->options.x11.force && context_main->options.display_server)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Can't run in X11 mode as a display server");
- return FALSE;
- }
-
- if (context_main->options.x11.force && context_main->options.headless)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Can't run in X11 mode headlessly");
- return FALSE;
- }
-
- if (context_main->options.display_server && context_main->options.headless)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Can't run in display server mode headlessly");
- return FALSE;
- }
-#endif /* HAVE_NATIVE_BACKEND */
-
- if (context_main->options.sm.save_file &&
- context_main->options.sm.client_id)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Can't specify both SM save file and SM client id");
- return FALSE;
- }
-
- return TRUE;
-}
-
-#if defined(HAVE_WAYLAND) && defined(HAVE_NATIVE_BACKEND)
-static gboolean
-session_type_is_supported (const char *session_type)
-{
- return (g_strcmp0 (session_type, "x11") == 0) ||
- (g_strcmp0 (session_type, "wayland") == 0);
-}
-
-static char *
-find_session_type (GError **error)
-{
- 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)
- {
- ret = sd_session_get_type (session_id, &session_type);
- free (session_id);
-
- if (ret == 0)
- {
- if (session_type_is_supported (session_type))
- goto out;
- else
- is_tty = g_strcmp0 (session_type, "tty") == 0;
- free (session_type);
- }
- }
- 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")))
- {
- session_type = strdup ("x11");
- goto out;
- }
-
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Unsupported session type");
- return NULL;
-
-out:
- return session_type;
-}
-#else /* defined(HAVE_WAYLAND) && defined(HAVE_NATIVE_BACKEND) */
-static char *
-find_session_type (GError **error)
-{
- return g_strdup ("x11");
-}
-#endif /* defined(HAVE_WAYLAND) && defined(HAVE_NATIVE_BACKEND) */
-
-static MetaCompositorType
-determine_compositor_type (MetaContextMain *context_main,
- GError **error)
-{
- g_autofree char *session_type = NULL;
-
-#ifdef HAVE_WAYLAND
- if (context_main->options.wayland ||
-#ifdef HAVE_NATIVE_BACKEND
- context_main->options.display_server ||
- context_main->options.headless ||
-#endif /* HAVE_NATIVE_BACKEND */
- context_main->options.nested)
- return META_COMPOSITOR_TYPE_WAYLAND;
-#endif /* HAVE_WAYLAND */
-
- if (context_main->options.x11.force)
- return META_COMPOSITOR_TYPE_X11;
-
- session_type = find_session_type (error);
- if (!session_type)
- return -1;
-
- if (strcmp (session_type, "x11") == 0)
- return META_COMPOSITOR_TYPE_X11;
-#ifdef HAVE_WAYLAND
- else if (strcmp (session_type, "wayland") == 0)
- return META_COMPOSITOR_TYPE_WAYLAND;
-#endif
- else
- g_assert_not_reached ();
-}
-
-static gboolean
-meta_context_main_configure (MetaContext *context,
- int *argc,
- char ***argv,
- GError **error)
-{
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
- MetaContextClass *context_class =
- META_CONTEXT_CLASS (meta_context_main_parent_class);
-
- if (!context_class->configure (context, argc, argv, error))
- return FALSE;
-
- if (!check_configuration (context_main, error))
- return FALSE;
-
- context_main->compositor_type = determine_compositor_type (context_main,
- error);
- if (context_main->compositor_type == -1)
- return FALSE;
-
-#ifdef HAVE_WAYLAND
- if (context_main->options.wayland_display)
- meta_wayland_override_display_name (context_main->options.wayland_display);
-#endif
-
- return TRUE;
-}
-
-static MetaCompositorType
-meta_context_main_get_compositor_type (MetaContext *context)
-{
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
-
- return context_main->compositor_type;
-}
-
-static MetaX11DisplayPolicy
-meta_context_main_get_x11_display_policy (MetaContext *context)
-{
- MetaCompositorType compositor_type;
-#ifdef HAVE_WAYLAND
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
- char *unit;
-#endif
-
- compositor_type = meta_context_get_compositor_type (context);
- switch (compositor_type)
- {
- case META_COMPOSITOR_TYPE_X11:
- return META_X11_DISPLAY_POLICY_MANDATORY;
- case META_COMPOSITOR_TYPE_WAYLAND:
-#ifdef HAVE_WAYLAND
- if (context_main->options.no_x11)
- return META_X11_DISPLAY_POLICY_DISABLED;
- else if (sd_pid_get_user_unit (0, &unit) < 0)
- return META_X11_DISPLAY_POLICY_MANDATORY;
- else
- return META_X11_DISPLAY_POLICY_ON_DEMAND;
-#else /* HAVE_WAYLAND */
- g_assert_not_reached ();
-#endif /* HAVE_WAYLAND */
- }
-
- g_assert_not_reached ();
-}
-
-static gboolean
-meta_context_main_is_replacing (MetaContext *context)
-{
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
-
- return context_main->options.x11.replace;
-}
-
-#ifdef HAVE_NATIVE_BACKEND
-static gboolean
-add_persistent_virtual_monitors (MetaContextMain *context_main,
- GError **error)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- GList *l;
-
- for (l = context_main->options.virtual_monitor_infos; l; l = l->next)
- {
- MetaVirtualMonitorInfo *info = l->data;
- MetaVirtualMonitor *virtual_monitor;
-
- virtual_monitor =
- meta_monitor_manager_create_virtual_monitor (monitor_manager,
- info,
- error);
- if (!virtual_monitor)
- {
- g_prefix_error (error, "Failed to add virtual monitor: ");
- return FALSE;
- }
-
- context_main->persistent_virtual_monitors =
- g_list_append (context_main->persistent_virtual_monitors, virtual_monitor);
- }
-
- if (context_main->options.virtual_monitor_infos)
- {
- g_list_free_full (context_main->options.virtual_monitor_infos,
- (GDestroyNotify) meta_virtual_monitor_info_free);
- context_main->options.virtual_monitor_infos = NULL;
-
- meta_monitor_manager_reload (monitor_manager);
- }
-
- return TRUE;
-}
-#endif
-
-static gboolean
-meta_context_main_setup (MetaContext *context,
- GError **error)
-{
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
-
- if (!META_CONTEXT_CLASS (meta_context_main_parent_class)->setup (context,
- error))
- return FALSE;
-
- meta_set_syncing (context_main->options.x11.sync || g_getenv ("MUTTER_SYNC"));
-
-#ifdef HAVE_NATIVE_BACKEND
- if (!add_persistent_virtual_monitors (context_main, error))
- return FALSE;
-#endif
-
- return TRUE;
-}
-
-static MetaBackend *
-create_x11_cm_backend (MetaContext *context,
- GError **error)
-{
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
-
-#ifdef HAVE_NATIVE_BACKEND
- if (context_main->options.virtual_monitor_infos)
- g_warning ("Ignoring added virtual monitors in X11 session");
-#endif
-
- return g_initable_new (META_TYPE_BACKEND_X11_CM,
- NULL, error,
- "context", context,
- "display-name", context_main->options.x11.display_name,
- NULL);
-}
-
-#ifdef HAVE_WAYLAND
-static MetaBackend *
-create_nested_backend (MetaContext *context,
- GError **error)
-{
- return g_initable_new (META_TYPE_BACKEND_X11_NESTED,
- NULL, error,
- "context", context,
- NULL);
-}
-
-#ifdef HAVE_NATIVE_BACKEND
-static MetaBackend *
-create_headless_backend (MetaContext *context,
- GError **error)
-{
- return g_initable_new (META_TYPE_BACKEND_NATIVE,
- NULL, error,
- "context", context,
- "headless", TRUE,
- NULL);
-}
-
-static MetaBackend *
-create_native_backend (MetaContext *context,
- GError **error)
-{
- return g_initable_new (META_TYPE_BACKEND_NATIVE,
- NULL, error,
- "context", context,
- NULL);
-}
-#endif /* HAVE_NATIVE_BACKEND */
-#endif /* HAVE_WAYLAND */
-
-static MetaBackend *
-meta_context_main_create_backend (MetaContext *context,
- GError **error)
-{
-#ifdef HAVE_WAYLAND
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
-#endif
- MetaCompositorType compositor_type;
-
- compositor_type = meta_context_get_compositor_type (context);
- switch (compositor_type)
- {
- case META_COMPOSITOR_TYPE_X11:
- return create_x11_cm_backend (context, error);
- case META_COMPOSITOR_TYPE_WAYLAND:
-#ifdef HAVE_WAYLAND
- if (context_main->options.nested)
- return create_nested_backend (context, error);
-#ifdef HAVE_NATIVE_BACKEND
- else if (context_main->options.headless)
- return create_headless_backend (context, error);
- else
- return create_native_backend (context, error);
-#endif /* HAVE_NATIVE_BACKEND */
-#else /* HAVE_WAYLAND */
- g_assert_not_reached ();
-#endif /* HAVE_WAYLAND */
- }
-
- g_assert_not_reached ();
-}
-
-static void
-meta_context_main_notify_ready (MetaContext *context)
-{
- MetaContextMain *context_main = META_CONTEXT_MAIN (context);
-
- if (!context_main->options.sm.disable)
- {
- meta_session_init (context,
- context_main->options.sm.client_id,
- context_main->options.sm.save_file);
- }
- g_clear_pointer (&context_main->options.sm.client_id, g_free);
- g_clear_pointer (&context_main->options.sm.save_file, g_free);
-}
-
-#ifdef HAVE_NATIVE_BACKEND
-static gboolean
-add_virtual_monitor_cb (const char *option_name,
- const char *value,
- gpointer user_data,
- GError **error)
-{
- MetaContextMain *context_main = user_data;
- int width, height;
- float refresh_rate = 60.0;
-
- if (sscanf (value, "%dx%d@%f",
- &width, &height, &refresh_rate) == 3 ||
- sscanf (value, "%dx%d",
- &width, &height) == 2)
- {
- g_autofree char *serial = NULL;
- MetaVirtualMonitorInfo *virtual_monitor;
- int n_existing_virtual_monitor_infos;
-
- n_existing_virtual_monitor_infos =
- g_list_length (context_main->options.virtual_monitor_infos);
- serial = g_strdup_printf ("0x%.2x", n_existing_virtual_monitor_infos);
- virtual_monitor = meta_virtual_monitor_info_new (width,
- height,
- refresh_rate,
- "MetaVendor",
- "MetaVirtualMonitor",
- serial);
- context_main->options.virtual_monitor_infos =
- g_list_append (context_main->options.virtual_monitor_infos,
- virtual_monitor);
- return TRUE;
- }
- else
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "Unrecognizable virtual monitor spec '%s'", value);
- return FALSE;
- }
-}
-#endif /* HAVE_NATIVE_BACKEND */
-
-static void
-meta_context_main_add_option_entries (MetaContextMain *context_main)
-{
- MetaContext *context = META_CONTEXT (context_main);
- GOptionEntry options[] = {
- {
- "replace", 'r', 0, G_OPTION_ARG_NONE,
- &context_main->options.x11.replace,
- N_("Replace the running window manager"),
- NULL
- },
- {
- "display", 'd', 0, G_OPTION_ARG_STRING,
- &context_main->options.x11.display_name,
- N_("X Display to use"),
- "DISPLAY"
- },
- {
- "sm-disable", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.sm.disable,
- N_("Disable connection to session manager"),
- NULL
- },
- {
- "sm-client-id", 0, 0, G_OPTION_ARG_STRING,
- &context_main->options.sm.client_id,
- N_("Specify session management ID"),
- "ID"
- },
- {
- "sm-save-file", 0, 0, G_OPTION_ARG_FILENAME,
- &context_main->options.sm.save_file,
- N_("Initialize session from savefile"),
- "FILE"
- },
- {
- "sync", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.x11.sync,
- N_("Make X calls synchronous"),
- NULL
- },
-#ifdef HAVE_WAYLAND
- {
- "wayland", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.wayland,
- N_("Run as a wayland compositor"),
- NULL
- },
- {
- "nested", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.nested,
- N_("Run as a nested compositor"),
- NULL
- },
- {
- "no-x11", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.no_x11,
- N_("Run wayland compositor without starting Xwayland"),
- NULL
- },
- {
- "wayland-display", 0, 0, G_OPTION_ARG_STRING,
- &context_main->options.wayland_display,
- N_("Specify Wayland display name to use"),
- NULL
- },
-#endif
-#ifdef HAVE_NATIVE_BACKEND
- {
- "display-server", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.display_server,
- N_("Run as a full display server, rather than nested")
- },
- {
- "headless", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.headless,
- N_("Run as a headless display server")
- },
- {
- "virtual-monitor", 0, 0, G_OPTION_ARG_CALLBACK,
- add_virtual_monitor_cb,
- N_("Add persistent virtual monitor (WxH or WxH@R)")
- },
-#endif
- {
- "x11", 0, 0, G_OPTION_ARG_NONE,
- &context_main->options.x11.force,
- N_("Run with X11 backend")
- },
- { NULL }
- };
-
- meta_context_add_option_entries (context, options, GETTEXT_PACKAGE);
-}
-
-/**
- * meta_create_context:
- * @name: Human readable name of display server or window manager
- *
- * Create a context.
- *
- * Returns: (transfer full): A new context instance.
- */
-MetaContext *
-meta_create_context (const char *name)
-{
- return g_object_new (META_TYPE_CONTEXT_MAIN,
- "name", name,
- NULL);
-}
-
-static void
-meta_context_main_finalize (GObject *object)
-{
-#ifdef HAVE_NATIVE_BACKEND
- MetaContextMain *context_main = META_CONTEXT_MAIN (object);
-
- g_list_free_full (context_main->persistent_virtual_monitors, g_object_unref);
- context_main->persistent_virtual_monitors = NULL;
-#endif
-
- G_OBJECT_CLASS (meta_context_main_parent_class)->finalize (object);
-}
-
-static void
-meta_context_main_constructed (GObject *object)
-{
- MetaContextMain *context_main = META_CONTEXT_MAIN (object);
-
- G_OBJECT_CLASS (meta_context_main_parent_class)->constructed (object);
-
- meta_context_main_add_option_entries (context_main);
-}
-
-static void
-meta_context_main_class_init (MetaContextMainClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- MetaContextClass *context_class = META_CONTEXT_CLASS (klass);
-
- object_class->finalize = meta_context_main_finalize;
- object_class->constructed = meta_context_main_constructed;
-
- context_class->configure = meta_context_main_configure;
- context_class->get_compositor_type = meta_context_main_get_compositor_type;
- context_class->get_x11_display_policy =
- meta_context_main_get_x11_display_policy;
- context_class->is_replacing = meta_context_main_is_replacing;
- context_class->setup = meta_context_main_setup;
- context_class->create_backend = meta_context_main_create_backend;
- context_class->notify_ready = meta_context_main_notify_ready;
-}
-
-static void
-meta_context_main_init (MetaContextMain *context_main)
-{
- context_main->compositor_type = -1;
-}
diff --git a/src/core/meta-context-main.h b/src/core/meta-context-main.h
deleted file mode 100644
index 9a8ce902b..000000000
--- a/src/core/meta-context-main.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2021 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_CONTEXT_MAIN_H
-#define META_CONTEXT_MAIN_H
-
-#include "core/meta-context-private.h"
-
-#define META_TYPE_CONTEXT_MAIN (meta_context_main_get_type ())
-G_DECLARE_FINAL_TYPE (MetaContextMain, meta_context_main,
- META, CONTEXT_MAIN,
- MetaContext)
-
-#endif /* META_CONTEXT_MAIN_H */
diff --git a/src/core/meta-context-private.h b/src/core/meta-context-private.h
deleted file mode 100644
index a3b7f9b4b..000000000
--- a/src/core/meta-context-private.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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_CONTEXT_PRIVATE_H
-#define META_CONTEXT_PRIVATE_H
-
-#include "core/meta-private-enums.h"
-#include "core/util-private.h"
-#include "meta/meta-backend.h"
-#include "meta/meta-context.h"
-#include "wayland/meta-wayland-types.h"
-
-struct _MetaContextClass
-{
- GObjectClass parent_class;
-
- gboolean (* configure) (MetaContext *context,
- int *argc,
- char ***argv,
- GError **error);
-
- MetaCompositorType (* get_compositor_type) (MetaContext *context);
-
- MetaX11DisplayPolicy (* get_x11_display_policy) (MetaContext *context);
-
- gboolean (* is_replacing) (MetaContext *context);
-
- gboolean (* setup) (MetaContext *context,
- GError **error);
-
- MetaBackend * (* create_backend) (MetaContext *context,
- GError **error);
-
- void (* notify_ready) (MetaContext *context);
-};
-
-const char * meta_context_get_name (MetaContext *context);
-
-const char * meta_context_get_gnome_wm_keybindings (MetaContext *context);
-
-META_EXPORT_TEST
-MetaWaylandCompositor * meta_context_get_wayland_compositor (MetaContext *context);
-
-MetaX11DisplayPolicy meta_context_get_x11_display_policy (MetaContext *context);
-
-#endif /* META_CONTEXT_PRIVATE_H */
diff --git a/src/core/meta-context.c b/src/core/meta-context.c
deleted file mode 100644
index 7bb0e5f46..000000000
--- a/src/core/meta-context.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * 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 "core/meta-context-private.h"
-
-#include <locale.h>
-
-#include "backends/meta-backend-private.h"
-#include "compositor/meta-plugin-manager.h"
-#include "core/display-private.h"
-#include "core/prefs-private.h"
-#include "core/util-private.h"
-
-#ifdef HAVE_WAYLAND
-#include "wayland/meta-wayland.h"
-#endif
-
-enum
-{
- PROP_0,
-
- PROP_NAME,
-
- N_PROPS
-};
-
-static GParamSpec *obj_props[N_PROPS];
-
-typedef enum _MetaContextState
-{
- META_CONTEXT_STATE_INIT,
- META_CONTEXT_STATE_CONFIGURED,
- META_CONTEXT_STATE_SETUP,
- META_CONTEXT_STATE_STARTED,
- META_CONTEXT_STATE_RUNNING,
- META_CONTEXT_STATE_TERMINATED,
-} MetaContextState;
-
-typedef struct _MetaContextPrivate
-{
- char *name;
- char *plugin_name;
- GType plugin_gtype;
- char *gnome_wm_keybindings;
-
- MetaContextState state;
-
- GOptionContext *option_context;
-
- MetaBackend *backend;
- MetaDisplay *display;
-#ifdef HAVE_WAYLAND
- MetaWaylandCompositor *wayland_compositor;
-#endif
-
- GMainLoop *main_loop;
- GError *termination_error;
-} MetaContextPrivate;
-
-G_DEFINE_TYPE_WITH_PRIVATE (MetaContext, meta_context, G_TYPE_OBJECT)
-
-void
-meta_context_add_option_entries (MetaContext *context,
- const GOptionEntry *entries,
- const char *translation_domain)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- g_warn_if_fail (priv->state == META_CONTEXT_STATE_INIT);
-
- g_option_context_add_main_entries (priv->option_context,
- entries,
- translation_domain);
-}
-
-void
-meta_context_add_option_group (MetaContext *context,
- GOptionGroup *group)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- g_warn_if_fail (priv->state == META_CONTEXT_STATE_INIT);
- g_return_if_fail (priv->option_context);
-
- g_option_context_add_group (priv->option_context, group);
-}
-
-void
-meta_context_set_plugin_gtype (MetaContext *context,
- GType plugin_gtype)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- g_return_if_fail (priv->state <= META_CONTEXT_STATE_CONFIGURED);
- g_return_if_fail (!priv->plugin_name);
-
- priv->plugin_gtype = plugin_gtype;
-}
-
-void
-meta_context_set_plugin_name (MetaContext *context,
- const char *plugin_name)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- g_return_if_fail (priv->state <= META_CONTEXT_STATE_CONFIGURED);
- g_return_if_fail (priv->plugin_gtype == G_TYPE_NONE);
-
- priv->plugin_name = g_strdup (plugin_name);
-}
-
-void
-meta_context_set_gnome_wm_keybindings (MetaContext *context,
- const char *wm_keybindings)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- g_return_if_fail (priv->state <= META_CONTEXT_STATE_CONFIGURED);
-
- g_clear_pointer (&priv->gnome_wm_keybindings, g_free);
- priv->gnome_wm_keybindings = g_strdup (wm_keybindings);
-}
-
-const char *
-meta_context_get_gnome_wm_keybindings (MetaContext *context)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- return priv->gnome_wm_keybindings;
-}
-
-void
-meta_context_notify_ready (MetaContext *context)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- g_return_if_fail (priv->state == META_CONTEXT_STATE_STARTED ||
- priv->state == META_CONTEXT_STATE_RUNNING);
-
- META_CONTEXT_GET_CLASS (context)->notify_ready (context);
-}
-
-const char *
-meta_context_get_name (MetaContext *context)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- return priv->name;
-}
-
-/**
- * meta_context_get_backend:
- * @context: The #MetaContext
- *
- * Returns: (transfer none): the #MetaBackend
- */
-MetaBackend *
-meta_context_get_backend (MetaContext *context)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- return priv->backend;
-}
-
-/**
- * meta_context_get_display:
- * @context: The #MetaContext
- *
- * Returns: (transfer none): the #MetaDisplay
- */
-MetaDisplay *
-meta_context_get_display (MetaContext *context)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- return priv->display;
-}
-
-#ifdef HAVE_WAYLAND
-MetaWaylandCompositor *
-meta_context_get_wayland_compositor (MetaContext *context)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- return priv->wayland_compositor;
-}
-#endif
-
-MetaCompositorType
-meta_context_get_compositor_type (MetaContext *context)
-{
- return META_CONTEXT_GET_CLASS (context)->get_compositor_type (context);
-}
-
-gboolean
-meta_context_is_replacing (MetaContext *context)
-{
- return META_CONTEXT_GET_CLASS (context)->is_replacing (context);
-}
-
-MetaX11DisplayPolicy
-meta_context_get_x11_display_policy (MetaContext *context)
-{
- return META_CONTEXT_GET_CLASS (context)->get_x11_display_policy (context);
-}
-
-static gboolean
-meta_context_real_configure (MetaContext *context,
- int *argc,
- char ***argv,
- GError **error)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
- g_autoptr (GOptionContext) option_context = NULL;
-
- if (!priv->option_context)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Tried to configure multiple times");
- return FALSE;
- }
-
- option_context = g_steal_pointer (&priv->option_context);
- return g_option_context_parse (option_context, argc, argv, error);
-}
-
-gboolean
-meta_context_configure (MetaContext *context,
- int *argc,
- char ***argv,
- GError **error)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
- MetaCompositorType compositor_type;
-
- g_warn_if_fail (priv->state == META_CONTEXT_STATE_INIT);
-
- if (!META_CONTEXT_GET_CLASS (context)->configure (context, argc, argv, error))
- {
- priv->state = META_CONTEXT_STATE_TERMINATED;
- return FALSE;
- }
-
- compositor_type = meta_context_get_compositor_type (context);
- switch (compositor_type)
- {
- case META_COMPOSITOR_TYPE_WAYLAND:
- meta_set_is_wayland_compositor (TRUE);
- break;
- case META_COMPOSITOR_TYPE_X11:
- meta_set_is_wayland_compositor (FALSE);
- break;
- }
-
- priv->state = META_CONTEXT_STATE_CONFIGURED;
-
- return TRUE;
-}
-
-static const char *
-compositor_type_to_description (MetaCompositorType compositor_type)
-{
- switch (compositor_type)
- {
- case META_COMPOSITOR_TYPE_WAYLAND:
- return "Wayland display server";
- case META_COMPOSITOR_TYPE_X11:
- return "X11 window and compositing manager";
- }
-
- g_assert_not_reached ();
-}
-
-static void
-init_introspection (MetaContext *context)
-{
-#ifdef HAVE_INTROSPECTION
- g_irepository_prepend_search_path (MUTTER_PKGLIBDIR);
-#endif
-}
-
-static gboolean
-meta_context_real_setup (MetaContext *context,
- GError **error)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
- MetaBackend *backend;
-
- backend = META_CONTEXT_GET_CLASS (context)->create_backend (context, error);
- if (!backend)
- return FALSE;
-
- priv->backend = backend;
- return TRUE;
-}
-
-gboolean
-meta_context_setup (MetaContext *context,
- GError **error)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
- MetaCompositorType compositor_type;
-
- g_warn_if_fail (priv->state == META_CONTEXT_STATE_CONFIGURED);
-
- if (!priv->plugin_name && priv->plugin_gtype == G_TYPE_NONE)
- {
- priv->state = META_CONTEXT_STATE_TERMINATED;
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "No compositor plugin set");
- return FALSE;
- }
-
- meta_init_debug_utils ();
-
- compositor_type = meta_context_get_compositor_type (context);
- g_message ("Running %s (using mutter %s) as a %s",
- priv->name, VERSION,
- compositor_type_to_description (compositor_type));
-
- if (priv->plugin_name)
- meta_plugin_manager_load (priv->plugin_name);
- else
- meta_plugin_manager_set_plugin_type (priv->plugin_gtype);
-
- init_introspection (context);
-
- if (!META_CONTEXT_GET_CLASS (context)->setup (context, error))
- {
- priv->state = META_CONTEXT_STATE_TERMINATED;
- return FALSE;
- }
-
- priv->state = META_CONTEXT_STATE_SETUP;
- return TRUE;
-}
-
-gboolean
-meta_context_start (MetaContext *context,
- GError **error)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- g_warn_if_fail (priv->state == META_CONTEXT_STATE_SETUP);
-
- meta_prefs_init ();
-
-#ifdef HAVE_WAYLAND
- if (meta_context_get_compositor_type (context) ==
- META_COMPOSITOR_TYPE_WAYLAND)
- priv->wayland_compositor = meta_wayland_compositor_new (context);
-#endif
-
- priv->display = meta_display_new (context, error);
- if (!priv->display)
- {
- priv->state = META_CONTEXT_STATE_TERMINATED;
- return FALSE;
- }
-
- priv->main_loop = g_main_loop_new (NULL, FALSE);
-
- priv->state = META_CONTEXT_STATE_STARTED;
-
- return TRUE;
-}
-
-gboolean
-meta_context_run_main_loop (MetaContext *context,
- GError **error)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- g_warn_if_fail (priv->state == META_CONTEXT_STATE_STARTED);
- if (!priv->main_loop)
- {
- priv->state = META_CONTEXT_STATE_TERMINATED;
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Tried to run main loop without having started");
- return FALSE;
- }
-
- priv->state = META_CONTEXT_STATE_RUNNING;
- g_main_loop_run (priv->main_loop);
- priv->state = META_CONTEXT_STATE_TERMINATED;
- g_clear_pointer (&priv->main_loop, g_main_loop_unref);
-
- if (priv->termination_error)
- {
- g_propagate_error (error, g_steal_pointer (&priv->termination_error));
- return FALSE;
- }
-
- return TRUE;
-}
-
-void
-meta_context_terminate (MetaContext *context)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- g_warn_if_fail (priv->state == META_CONTEXT_STATE_RUNNING);
- g_warn_if_fail (g_main_loop_is_running (priv->main_loop));
-
- g_main_loop_quit (priv->main_loop);
-}
-
-void
-meta_context_terminate_with_error (MetaContext *context,
- GError *error)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- priv->termination_error = g_steal_pointer (&error);
- meta_context_terminate (context);
-}
-
-void
-meta_context_destroy (MetaContext *context)
-{
- g_object_run_dispose (G_OBJECT (context));
- g_object_unref (context);
-}
-
-static void
-meta_context_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaContext *context = META_CONTEXT (object);
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- switch (prop_id)
- {
- case PROP_NAME:
- g_value_set_string (value, priv->name);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_context_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaContext *context = META_CONTEXT (object);
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- switch (prop_id)
- {
- case PROP_NAME:
- priv->name = g_value_dup_string (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_context_dispose (GObject *object)
-{
- MetaContext *context = META_CONTEXT (object);
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- if (priv->backend)
- meta_backend_prepare_shutdown (priv->backend);
-
-#ifdef HAVE_WAYLAND
- if (priv->wayland_compositor)
- meta_wayland_compositor_prepare_shutdown (priv->wayland_compositor);
-#endif
-
- if (priv->display)
- meta_display_close (priv->display, META_CURRENT_TIME);
- g_clear_object (&priv->display);
-
-#ifdef HAVE_WAYLAND
- g_clear_object (&priv->wayland_compositor);
-#endif
-
- g_clear_pointer (&priv->backend, meta_backend_destroy);
-
- g_clear_pointer (&priv->option_context, g_option_context_free);
- g_clear_pointer (&priv->main_loop, g_main_loop_unref);
-
- G_OBJECT_CLASS (meta_context_parent_class)->dispose (object);
-}
-
-static void
-meta_context_finalize (GObject *object)
-{
- MetaContext *context = META_CONTEXT (object);
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- g_clear_pointer (&priv->gnome_wm_keybindings, g_free);
- g_clear_pointer (&priv->plugin_name, g_free);
- g_clear_pointer (&priv->name, g_free);
-
- G_OBJECT_CLASS (meta_context_parent_class)->finalize (object);
-}
-
-static void
-meta_context_class_init (MetaContextClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->get_property = meta_context_get_property;
- object_class->set_property = meta_context_set_property;
- object_class->dispose = meta_context_dispose;
- object_class->finalize = meta_context_finalize;
-
- klass->configure = meta_context_real_configure;
- klass->setup = meta_context_real_setup;
-
- obj_props[PROP_NAME] =
- g_param_spec_string ("name",
- "name",
- "Human readable name",
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, N_PROPS, obj_props);
-}
-
-static void
-meta_context_init (MetaContext *context)
-{
- MetaContextPrivate *priv = meta_context_get_instance_private (context);
-
- priv->plugin_gtype = G_TYPE_NONE;
- priv->gnome_wm_keybindings = g_strdup ("Mutter");
-
- if (!setlocale (LC_ALL, ""))
- g_warning ("Locale not understood by C library");
- bindtextdomain (GETTEXT_PACKAGE, MUTTER_LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-
- priv->option_context = g_option_context_new (NULL);
- g_option_context_set_main_group (priv->option_context,
- g_option_group_new (NULL, NULL, NULL,
- context, NULL));
-}
diff --git a/src/core/meta-fraction.c b/src/core/meta-fraction.c
deleted file mode 100644
index 8090aa411..000000000
--- a/src/core/meta-fraction.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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
deleted file mode 100644
index f7ab294cd..000000000
--- a/src/core/meta-fraction.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- 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
deleted file mode 100644
index e7bfc5472..000000000
--- a/src/core/meta-gesture-tracker-private.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 2badf8b82..000000000
--- a/src/core/meta-gesture-tracker.c
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * 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_new0 (MetaSequenceInfo, 1);
- 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_free (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
deleted file mode 100644
index 7f65494ef..000000000
--- a/src/core/meta-inhibit-shortcuts-dialog-default-private.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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
deleted file mode 100644
index d90234d6a..000000000
--- a/src/core/meta-inhibit-shortcuts-dialog-default.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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
deleted file mode 100644
index d5b4e5a05..000000000
--- a/src/core/meta-inhibit-shortcuts-dialog.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 984338c1b..000000000
--- a/src/core/meta-launch-context.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * 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-pad-action-mapper.c b/src/core/meta-pad-action-mapper.c
deleted file mode 100644
index 7c78c4014..000000000
--- a/src/core/meta-pad-action-mapper.c
+++ /dev/null
@@ -1,860 +0,0 @@
-/*
- * Copyright (C) 2014-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>
- */
-
-#include "config.h"
-
-#include <glib/gi18n-lib.h>
-#include <gsettings-desktop-schemas/gdesktop-enums.h>
-
-#ifdef HAVE_LIBWACOM
-#include <libwacom/libwacom.h>
-#endif
-
-#include "core/meta-pad-action-mapper.h"
-#include "backends/meta-input-device-private.h"
-#include "backends/meta-logical-monitor.h"
-#include "backends/meta-monitor.h"
-#include "core/display-private.h"
-
-typedef struct _PadMappingInfo PadMappingInfo;
-
-struct _PadMappingInfo
-{
- ClutterInputDevice *device;
- GSettings *settings;
- guint *group_modes;
-};
-
-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;
-
-struct _MetaPadActionMapper
-{
- GObject parent_class;
-
- GHashTable *pads;
- ClutterSeat *seat;
- ClutterVirtualInputDevice *virtual_pad_keyboard;
- MetaMonitorManager *monitor_manager;
-
- /* Pad ring/strip emission */
- struct {
- ClutterInputDevice *pad;
- MetaPadActionType action;
- guint number;
- double value;
- } last_pad_action_info;
-};
-
-G_DEFINE_TYPE (MetaPadActionMapper, meta_pad_action_mapper, G_TYPE_OBJECT)
-
-static void
-meta_pad_action_mapper_finalize (GObject *object)
-{
- MetaPadActionMapper *mapper = META_PAD_ACTION_MAPPER (object);
-
- g_hash_table_unref (mapper->pads);
- g_object_unref (mapper->monitor_manager);
- g_clear_object (&mapper->virtual_pad_keyboard);
-
- G_OBJECT_CLASS (meta_pad_action_mapper_parent_class)->finalize (object);
-}
-
-static void
-meta_pad_action_mapper_class_init (MetaPadActionMapperClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = meta_pad_action_mapper_finalize;
-}
-
-static GSettings *
-lookup_device_settings (ClutterInputDevice *device)
-{
- const char *vendor, *product;
- GSettings *settings;
- char *path;
-
- vendor = clutter_input_device_get_vendor_id (device);
- product = clutter_input_device_get_product_id (device);
- path = g_strdup_printf ("/org/gnome/desktop/peripherals/tablets/%s:%s/",
- vendor, product);
-
- settings = g_settings_new_with_path ("org.gnome.desktop.peripherals.tablet",
- path);
- g_free (path);
-
- return settings;
-}
-
-static PadMappingInfo *
-pad_mapping_info_new (ClutterInputDevice *pad)
-{
- PadMappingInfo *info;
-
- info = g_new0 (PadMappingInfo, 1);
- info->device = pad;
- info->settings = lookup_device_settings (pad);
- info->group_modes =
- g_new0 (guint, clutter_input_device_get_n_mode_groups (pad));
-
- return info;
-}
-
-static void
-pad_mapping_info_free (PadMappingInfo *info)
-{
- g_object_unref (info->settings);
- g_free (info->group_modes);
- g_free (info);
-}
-
-static void
-device_added (ClutterSeat *seat,
- ClutterInputDevice *device,
- MetaPadActionMapper *mapper)
-{
- PadMappingInfo *info;
-
- if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE)
- {
- info = pad_mapping_info_new (device);
- g_hash_table_insert (mapper->pads, device, info);
- }
-}
-
-static void
-device_removed (ClutterSeat *seat,
- ClutterInputDevice *device,
- MetaPadActionMapper *mapper)
-{
- g_hash_table_remove (mapper->pads, device);
-}
-
-static void
-meta_pad_action_mapper_init (MetaPadActionMapper *mapper)
-{
- mapper->pads = g_hash_table_new_full (NULL, NULL, NULL,
- (GDestroyNotify) pad_mapping_info_free);
-
- mapper->seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
- g_signal_connect (mapper->seat, "device-added",
- G_CALLBACK (device_added), mapper);
- g_signal_connect (mapper->seat, "device-removed",
- G_CALLBACK (device_removed), mapper);
-}
-
-MetaPadActionMapper *
-meta_pad_action_mapper_new (MetaMonitorManager *monitor_manager)
-{
- MetaPadActionMapper *action_mapper;
-
- action_mapper = g_object_new (META_TYPE_PAD_ACTION_MAPPER, NULL);
- g_set_object (&action_mapper->monitor_manager, monitor_manager);
-
- return action_mapper;
-}
-
-static GSettings *
-lookup_pad_action_settings (ClutterInputDevice *device,
- MetaPadActionType action,
- guint number,
- MetaPadDirection direction,
- int mode)
-{
- const char *vendor, *product, *action_type, *detail_type = NULL;
- GSettings *settings;
- GString *path;
- char 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/gnome/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.gnome.desktop.peripherals.tablet.pad-button",
- path->str);
- g_string_free (path, TRUE);
-
- return settings;
-}
-
-static GDesktopPadButtonAction
-meta_pad_action_mapper_get_button_action (MetaPadActionMapper *mapper,
- ClutterInputDevice *pad,
- guint button)
-{
- GDesktopPadButtonAction action;
- GSettings *settings;
-
- g_return_val_if_fail (META_IS_PAD_ACTION_MAPPER (mapper),
- G_DESKTOP_PAD_BUTTON_ACTION_NONE);
- g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad),
- G_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 (MetaPadActionMapper *mapper,
- gboolean skip_all_monitors,
- MetaLogicalMonitor *current_logical_monitor,
- MetaLogicalMonitor **next_logical_monitor)
-{
- MetaMonitorManager *monitor_manager = mapper->monitor_manager;
- GList *logical_monitors;
-
- /* We cycle between:
- * - the span of all monitors (current_output = NULL), only for
- * non-integrated devices.
- * - 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 if (skip_all_monitors)
- *next_logical_monitor = logical_monitors->data;
- else
- *next_logical_monitor = NULL;
- }
-
- return TRUE;
-}
-
-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_pad_action_mapper_find_monitor (MetaPadActionMapper *mapper,
- GSettings *settings,
- ClutterInputDevice *device,
- MetaMonitor **out_monitor,
- MetaLogicalMonitor **out_logical_monitor)
-{
- MetaMonitorManager *monitor_manager;
- MetaMonitor *monitor;
- guint n_values;
- GList *logical_monitors;
- GList *l;
- char **edid;
-
- 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 = mapper->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 void
-meta_pad_action_mapper_cycle_tablet_output (MetaPadActionMapper *mapper,
- ClutterInputDevice *device)
-{
- PadMappingInfo *info;
- MetaLogicalMonitor *logical_monitor = NULL;
- const char *edid[4] = { 0 }, *pretty_name = NULL;
- gboolean is_integrated_device = FALSE;
-#ifdef HAVE_LIBWACOM
- WacomDevice *wacom_device;
-#endif
-
- g_return_if_fail (META_IS_PAD_ACTION_MAPPER (mapper));
- 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);
-
- info = g_hash_table_lookup (mapper->pads, 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)
- {
- pretty_name = libwacom_get_name (wacom_device);
- is_integrated_device =
- libwacom_get_integration_flags (wacom_device) != WACOM_DEVICE_INTEGRATED_NONE;
- }
-#endif
-
- meta_pad_action_mapper_find_monitor (mapper, info->settings, device,
- NULL, &logical_monitor);
-
- if (!cycle_logical_monitors (mapper,
- is_integrated_device,
- 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);
-}
-
-gboolean
-meta_pad_action_mapper_is_button_grabbed (MetaPadActionMapper *mapper,
- ClutterInputDevice *pad,
- guint button)
-{
- g_return_val_if_fail (META_IS_PAD_ACTION_MAPPER (mapper), 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_pad_action_mapper_get_button_action (mapper, pad, button) !=
- G_DESKTOP_PAD_BUTTON_ACTION_NONE);
-}
-
-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_pad_action_mapper_emulate_keybinding (MetaPadActionMapper *mapper,
- const char *accel,
- gboolean is_press)
-{
- ClutterKeyState state;
- guint key, mods;
-
- if (!accel || !*accel)
- return;
-
- /* FIXME: This is appalling */
- gtk_accelerator_parse (accel, &key, &mods);
-
- if (!mapper->virtual_pad_keyboard)
- {
- ClutterBackend *backend;
- ClutterSeat *seat;
-
- backend = clutter_get_default_backend ();
- seat = clutter_backend_get_default_seat (backend);
-
- mapper->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 (mapper->virtual_pad_keyboard, mods, state);
-
- clutter_virtual_input_device_notify_keyval (mapper->virtual_pad_keyboard,
- clutter_get_current_event_time (),
- key, state);
- if (!is_press)
- emulate_modifiers (mapper->virtual_pad_keyboard, mods, state);
-}
-
-static gboolean
-meta_pad_action_mapper_handle_button (MetaPadActionMapper *mapper,
- ClutterInputDevice *pad,
- const ClutterPadButtonEvent *event)
-{
- GDesktopPadButtonAction action;
- int button, group, mode, n_modes = 0;
- gboolean is_press;
- GSettings *settings;
- char *accel;
-
- g_return_val_if_fail (META_IS_PAD_ACTION_MAPPER (mapper), 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 (group >= 0)
- n_modes = clutter_input_device_get_group_n_modes (pad, group);
-
- if (is_press && n_modes > 0)
- {
- const char *pretty_name = NULL;
- PadMappingInfo *info;
-#ifdef HAVE_LIBWACOM
- WacomDevice *wacom_device;
-#endif
-
- info = g_hash_table_lookup (mapper->pads, 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_pad_action_mapper_get_button_action (mapper, pad, button);
-
- switch (action)
- {
- case G_DESKTOP_PAD_BUTTON_ACTION_SWITCH_MONITOR:
- if (is_press)
- meta_pad_action_mapper_cycle_tablet_output (mapper, pad);
- return TRUE;
- case G_DESKTOP_PAD_BUTTON_ACTION_HELP:
- if (is_press)
- meta_display_request_pad_osd (meta_get_display (), pad, FALSE);
- return TRUE;
- case G_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_pad_action_mapper_emulate_keybinding (mapper, accel, is_press);
- g_object_unref (settings);
- g_free (accel);
- return TRUE;
- case G_DESKTOP_PAD_BUTTON_ACTION_NONE:
- default:
- return FALSE;
- }
-}
-
-static gboolean
-meta_pad_action_mapper_handle_action (MetaPadActionMapper *mapper,
- ClutterInputDevice *pad,
- MetaPadActionType action,
- guint number,
- MetaPadDirection direction,
- guint mode)
-{
- GSettings *settings;
- gboolean handled = FALSE;
- char *accel;
-
- settings = lookup_pad_action_settings (pad, action, number, direction, mode);
- accel = g_settings_get_string (settings, "keybinding");
-
- if (accel && *accel)
- {
- meta_pad_action_mapper_emulate_keybinding (mapper, accel, TRUE);
- meta_pad_action_mapper_emulate_keybinding (mapper, accel, FALSE);
- handled = TRUE;
- }
-
- g_object_unref (settings);
- g_free (accel);
-
- return handled;
-}
-
-static gboolean
-meta_pad_action_mapper_get_action_direction (MetaPadActionMapper *mapper,
- const ClutterEvent *event,
- MetaPadDirection *direction)
-{
- ClutterInputDevice *pad = clutter_event_get_device (event);
- MetaPadActionType pad_action;
- gboolean has_direction = FALSE;
- MetaPadDirection inc_dir, dec_dir;
- guint number;
- double value;
-
- *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 (mapper->last_pad_action_info.pad == pad &&
- mapper->last_pad_action_info.action == pad_action &&
- mapper->last_pad_action_info.number == number &&
- value >= 0 && mapper->last_pad_action_info.value >= 0)
- {
- *direction = (value - mapper->last_pad_action_info.value) > 0 ?
- inc_dir : dec_dir;
- has_direction = TRUE;
- }
-
- mapper->last_pad_action_info.pad = pad;
- mapper->last_pad_action_info.action = pad_action;
- mapper->last_pad_action_info.number = number;
- mapper->last_pad_action_info.value = value;
- return has_direction;
-}
-
-gboolean
-meta_pad_action_mapper_handle_event (MetaPadActionMapper *mapper,
- 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_pad_action_mapper_handle_button (mapper, pad,
- &event->pad_button);
- case CLUTTER_PAD_RING:
- if (!meta_pad_action_mapper_get_action_direction (mapper,
- event, &direction))
- return FALSE;
- return meta_pad_action_mapper_handle_action (mapper, pad,
- META_PAD_ACTION_RING,
- event->pad_ring.ring_number,
- direction,
- event->pad_ring.mode);
- case CLUTTER_PAD_STRIP:
- if (!meta_pad_action_mapper_get_action_direction (mapper,
- event, &direction))
- return FALSE;
- return meta_pad_action_mapper_handle_action (mapper, pad,
- META_PAD_ACTION_STRIP,
- event->pad_strip.strip_number,
- direction,
- event->pad_strip.mode);
- default:
- return FALSE;
- }
-}
-
-
-static char *
-compose_directional_action_label (GSettings *direction1,
- GSettings *direction2)
-{
- char *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 char *
-meta_pad_action_mapper_get_ring_label (MetaPadActionMapper *mapper,
- ClutterInputDevice *pad,
- guint number,
- guint mode)
-{
- GSettings *settings1, *settings2;
- char *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 char *
-meta_pad_action_mapper_get_strip_label (MetaPadActionMapper *mapper,
- ClutterInputDevice *pad,
- guint number,
- guint mode)
-{
- GSettings *settings1, *settings2;
- char *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 char *
-meta_pad_action_mapper_get_button_label (MetaPadActionMapper *mapper,
- ClutterInputDevice *pad,
- guint button)
-{
- GDesktopPadButtonAction action;
- int group;
-
- g_return_val_if_fail (META_IS_PAD_ACTION_MAPPER (mapper), 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_pad_action_mapper_get_button_action (mapper, pad, button);
-
- switch (action)
- {
- case G_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING:
- {
- GSettings *settings;
- char *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 G_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 G_DESKTOP_PAD_BUTTON_ACTION_HELP:
- return g_strdup (_("Show on-screen help"));
- case G_DESKTOP_PAD_BUTTON_ACTION_NONE:
- default:
- return NULL;
- }
-}
-
-static guint
-get_current_pad_mode (MetaPadActionMapper *mapper,
- ClutterInputDevice *pad,
- MetaPadActionType action_type,
- guint number)
-{
- PadMappingInfo *info;
- guint group = 0, n_groups;
-
- info = g_hash_table_lookup (mapper->pads, 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];
-}
-
-char *
-meta_pad_action_mapper_get_action_label (MetaPadActionMapper *mapper,
- ClutterInputDevice *pad,
- MetaPadActionType action_type,
- guint number)
-{
- guint mode;
-
- switch (action_type)
- {
- case META_PAD_ACTION_BUTTON:
- return meta_pad_action_mapper_get_button_label (mapper, pad, number);
- case META_PAD_ACTION_RING:
- mode = get_current_pad_mode (mapper, pad, action_type, number);
- return meta_pad_action_mapper_get_ring_label (mapper, pad, number, mode);
- case META_PAD_ACTION_STRIP:
- mode = get_current_pad_mode (mapper, pad, action_type, number);
- return meta_pad_action_mapper_get_strip_label (mapper, pad, number, mode);
- }
-
- return NULL;
-}
diff --git a/src/core/meta-pad-action-mapper.h b/src/core/meta-pad-action-mapper.h
deleted file mode 100644
index 63fc2261b..000000000
--- a/src/core/meta-pad-action-mapper.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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_PAD_ACTION_MAPPER_H
-#define META_PAD_ACTION_MAPPER_H
-
-#include "clutter/clutter.h"
-#include "meta/display.h"
-#include "meta/meta-monitor-manager.h"
-
-#define META_TYPE_PAD_ACTION_MAPPER (meta_pad_action_mapper_get_type ())
-G_DECLARE_FINAL_TYPE (MetaPadActionMapper, meta_pad_action_mapper,
- META, PAD_ACTION_MAPPER, GObject)
-
-MetaPadActionMapper * meta_pad_action_mapper_new (MetaMonitorManager *monitor_manager);
-
-gboolean meta_pad_action_mapper_is_button_grabbed (MetaPadActionMapper *mapper,
- ClutterInputDevice *pad,
- guint button);
-gboolean meta_pad_action_mapper_handle_event (MetaPadActionMapper *mapper,
- const ClutterEvent *event);
-gchar * meta_pad_action_mapper_get_action_label (MetaPadActionMapper *mapper,
- ClutterInputDevice *pad,
- MetaPadActionType action,
- guint number);
-
-#endif /* META_PAD_ACTION_MAPPER_H */
diff --git a/src/core/meta-private-enums.h b/src/core/meta-private-enums.h
deleted file mode 100644
index 1a361c782..000000000
--- a/src/core/meta-private-enums.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2019-2021 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_PRIVATE_ENUMS_H
-#define META_PRIVATE_ENUMS_H
-
-typedef enum _MetaX11DisplayPolicy
-{
- META_X11_DISPLAY_POLICY_MANDATORY,
- META_X11_DISPLAY_POLICY_ON_DEMAND,
- META_X11_DISPLAY_POLICY_DISABLED,
-} MetaX11DisplayPolicy;
-
-#endif /* META_PRIVATE_ENUMS_H */
diff --git a/src/core/meta-selection-private.h b/src/core/meta-selection-private.h
deleted file mode 100644
index de9caf9bf..000000000
--- a/src/core/meta-selection-private.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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
deleted file mode 100644
index a52f50861..000000000
--- a/src/core/meta-selection-source-memory.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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-remote.c b/src/core/meta-selection-source-remote.c
deleted file mode 100644
index aa9f9e60a..000000000
--- a/src/core/meta-selection-source-remote.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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.
- *
- */
-
-#include "config.h"
-
-#include "core/meta-selection-source-remote.h"
-
-#include <gio/gunixinputstream.h>
-
-#include "backends/meta-remote-desktop-session.h"
-
-struct _MetaSelectionSourceRemote
-{
- MetaSelectionSource parent;
-
- MetaRemoteDesktopSession *session;
- GList *mime_types;
-};
-
-G_DEFINE_TYPE (MetaSelectionSourceRemote,
- meta_selection_source_remote,
- META_TYPE_SELECTION_SOURCE)
-
-MetaSelectionSourceRemote *
-meta_selection_source_remote_new (MetaRemoteDesktopSession *session,
- GList *mime_types)
-{
- MetaSelectionSourceRemote *source_remote;
-
- source_remote = g_object_new (META_TYPE_SELECTION_SOURCE_REMOTE, NULL);
- source_remote->session = session;
- source_remote->mime_types = mime_types;
-
- return source_remote;
-}
-
-static void
-meta_selection_source_remote_read_async (MetaSelectionSource *source,
- const char *mimetype,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- MetaSelectionSourceRemote *source_remote =
- META_SELECTION_SOURCE_REMOTE (source);
- GTask *task;
-
- task = g_task_new (source, cancellable, callback, user_data);
- g_task_set_source_tag (task, meta_selection_source_remote_read_async);
-
- meta_remote_desktop_session_request_transfer (source_remote->session,
- mimetype,
- task);
-}
-
-static GInputStream *
-meta_selection_source_remote_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_remote_read_async, FALSE);
-
- return g_task_propagate_pointer (G_TASK (result), error);
-}
-
-void
-meta_selection_source_remote_complete_transfer (MetaSelectionSourceRemote *source_remote,
- int fd,
- GTask *task)
-{
- GInputStream *stream;
-
- stream = g_unix_input_stream_new (fd, TRUE);
- g_task_return_pointer (task, stream, g_object_unref);
- g_object_unref (task);
-}
-
-void
-meta_selection_source_remote_cancel_transfer (MetaSelectionSourceRemote *source_remote,
- GTask *task)
-{
- g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_CANCELLED,
- "Remote selection transfer was cancelled");
- g_object_unref (task);
-}
-
-static GList *
-meta_selection_source_remote_get_mimetypes (MetaSelectionSource *source)
-{
- MetaSelectionSourceRemote *source_remote =
- META_SELECTION_SOURCE_REMOTE (source);
-
- return g_list_copy_deep (source_remote->mime_types,
- (GCopyFunc) g_strdup,
- NULL);
-}
-
-static void
-meta_selection_source_remote_finalize (GObject *object)
-{
- MetaSelectionSourceRemote *source_remote =
- META_SELECTION_SOURCE_REMOTE (object);
-
- g_list_free_full (source_remote->mime_types, g_free);
-
- G_OBJECT_CLASS (meta_selection_source_remote_parent_class)->finalize (object);
-}
-
-static void
-meta_selection_source_remote_init (MetaSelectionSourceRemote *source_remote)
-{
-}
-
-static void
-meta_selection_source_remote_class_init (MetaSelectionSourceRemoteClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- MetaSelectionSourceClass *source_class = META_SELECTION_SOURCE_CLASS (klass);
-
- object_class->finalize = meta_selection_source_remote_finalize;
-
- source_class->read_async = meta_selection_source_remote_read_async;
- source_class->read_finish = meta_selection_source_remote_read_finish;
- source_class->get_mimetypes = meta_selection_source_remote_get_mimetypes;
-}
diff --git a/src/core/meta-selection-source-remote.h b/src/core/meta-selection-source-remote.h
deleted file mode 100644
index 51e66957b..000000000
--- a/src/core/meta-selection-source-remote.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.
- *
- */
-
-#ifndef META_SELECTION_SOURCE_REMOTE_H
-#define META_SELECTION_SOURCE_REMOTE_H
-
-#include "backends/meta-remote-desktop.h"
-#include "meta/meta-selection-source.h"
-
-#define META_TYPE_SELECTION_SOURCE_REMOTE (meta_selection_source_remote_get_type ())
-G_DECLARE_FINAL_TYPE (MetaSelectionSourceRemote,
- meta_selection_source_remote,
- META, SELECTION_SOURCE_REMOTE,
- MetaSelectionSource)
-
-void meta_selection_source_remote_complete_transfer (MetaSelectionSourceRemote *source_remote,
- int fd,
- GTask *task);
-
-void meta_selection_source_remote_cancel_transfer (MetaSelectionSourceRemote *source_remote,
- GTask *task);
-
-MetaSelectionSourceRemote * meta_selection_source_remote_new (MetaRemoteDesktopSession *session,
- GList *mime_types);
-
-#endif /* META_SELECTION_SOURCE_REMOTE_H */
diff --git a/src/core/meta-selection-source.c b/src/core/meta-selection-source.c
deleted file mode 100644
index b076391ce..000000000
--- a/src/core/meta-selection-source.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 4e42e59a9..000000000
--- a/src/core/meta-selection.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * 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
deleted file mode 100644
index e2d103893..000000000
--- a/src/core/meta-sound-player.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * 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_allow_list[] = {
- "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 (GSettings *settings)
-{
- ca_context *context;
- ca_proplist *props;
- gboolean enabled;
- char *theme_name;
-
- 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, "Mutter");
-
- enabled = g_settings_get_boolean (settings, EVENT_SOUNDS_KEY);
- ca_proplist_sets (props, CA_PROP_CANBERRA_ENABLE, enabled ? "1" : "0");
-
- theme_name = g_settings_get_string (settings, THEME_NAME_KEY);
- ca_proplist_sets (props, CA_PROP_CANBERRA_XDG_THEME_NAME, theme_name);
- g_free (theme_name);
-
- 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.gnome.desktop.sound");
- player->context = create_context (player->settings);
-
- 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_allow_list, 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
deleted file mode 100644
index 261c4d47c..000000000
--- a/src/core/meta-workspace-manager-private.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 61fbc0090..000000000
--- a/src/core/meta-workspace-manager.c
+++ /dev/null
@@ -1,1060 +0,0 @@
-/* -*- 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 overridden 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 emitted.
- * 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",
- 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",
- 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)",
- 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_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/mutter.c b/src/core/mutter.c
deleted file mode 100644
index 9d716014a..000000000
--- a/src/core/mutter.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright 2011 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 <glib/gi18n-lib.h>
-#include <stdlib.h>
-
-#include "compositor/meta-plugin-manager.h"
-#include "meta/main.h"
-#include "meta/meta-context.h"
-#include "meta/util.h"
-
-static gboolean
-print_version (const gchar *option_name,
- const gchar *value,
- gpointer data,
- GError **error)
-{
- g_print ("mutter %s\n", VERSION);
- exit (0);
-}
-
-static const char *plugin = "libdefault";
-
-GOptionEntry mutter_options[] = {
- {
- "version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
- print_version,
- N_("Print version"),
- NULL
- },
- {
- "mutter-plugin", 0, 0, G_OPTION_ARG_STRING,
- &plugin,
- N_("Mutter plugin to use"),
- "PLUGIN",
- },
- { NULL }
-};
-
-int
-main (int argc, char **argv)
-{
- g_autoptr (MetaContext) context = NULL;
- g_autoptr (GError) error = NULL;
-
- context = meta_create_context ("Mutter");
-
- meta_context_add_option_entries (context, mutter_options, GETTEXT_PACKAGE);
- if (!meta_context_configure (context, &argc, &argv, &error))
- {
- g_printerr ("Failed to configure: %s", error->message);
- return EXIT_FAILURE;
- }
-
- meta_context_set_plugin_name (context, plugin);
-
- if (!meta_context_setup (context, &error))
- {
- g_printerr ("Failed to setup: %s", error->message);
- return EXIT_FAILURE;
- }
-
- if (!meta_context_start (context, &error))
- {
- g_printerr ("Failed to start: %s", error->message);
- return EXIT_FAILURE;
- }
-
- meta_context_notify_ready (context);
-
- if (!meta_context_run_main_loop (context, &error))
- {
- g_printerr ("Mutter terminated with a failure: %s", error->message);
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
diff --git a/src/core/place.c b/src/core/place.c
deleted file mode 100644
index 1075fe20d..000000000
--- a/src/core/place.c
+++ /dev/null
@@ -1,942 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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/place.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,
- META_RIGHT,
- META_TOP,
- META_BOTTOM
-} MetaWindowDirection;
-
-static gint
-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;
-
- 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;
-
- /* 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)
- return 1;
- else
- return 0;
-}
-
-static void
-find_next_cascade (MetaWindow *window,
- /* visible windows on relevant workspaces */
- GList *windows,
- int x,
- int y,
- 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;
- MetaLogicalMonitor *current;
-
- sorted = g_list_copy (windows);
- sorted = g_list_sort (sorted, northwestcmp);
-
- /* 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);
-
- /* Find furthest-SE origin of all workspaces.
- * cascade_x, cascade_y are the target position
- * of NW corner of window frame.
- */
-
- 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. */
-
- 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 */
- 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)
- {
- 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) >
- (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);
-
-#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
- * we are out of space
- */
- if ((cascade_x + window_width) <
- (work_area.x + work_area.width))
- {
- tmp = sorted;
- continue;
- }
- else
- {
- /* All out of space, this cascade_x won't work */
- 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);
-
- *new_x = cascade_x;
- *new_y = cascade_y;
-}
-
-static void
-find_most_freespace (MetaWindow *window,
- /* visible windows on relevant workspaces */
- MetaWindow *focus_window,
- int x,
- int y,
- int *new_x,
- int *new_y)
-{
- MetaWindowDirection side;
- int max_area;
- int max_width, max_height, left, right, top, bottom;
- int left_space, right_space, top_space, bottom_space;
- MetaRectangle work_area;
- MetaRectangle avoid;
- MetaRectangle frame_rect;
-
- meta_window_get_work_area_current_monitor (focus_window, &work_area);
- 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, 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, 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;
- max_area = left*max_height;
- if (right*max_height > max_area)
- {
- side = META_RIGHT;
- max_area = right*max_height;
- }
- if (top*max_width > max_area)
- {
- side = META_TOP;
- max_area = top*max_width;
- }
- if (bottom*max_width > max_area)
- {
- side = META_BOTTOM;
- max_area = bottom*max_width;
- }
-
- /* Give up if there's no where to put it (i.e. focus window is maximized) */
- if (max_area == 0)
- return;
-
- /* Place the window on the relevant side; if the whole window fits,
- * make it adjacent to the focus window; if not, make sure the
- * window doesn't go off the edge of the screen.
- */
- switch (side)
- {
- case META_LEFT:
- *new_y = avoid.y;
- if (left_space > frame_rect.width)
- *new_x = avoid.x - frame_rect.width;
- else
- *new_x = work_area.x;
- break;
- case META_RIGHT:
- *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 - frame_rect.width;
- break;
- case META_TOP:
- *new_x = avoid.x;
- if (top_space > frame_rect.height)
- *new_y = avoid.y - frame_rect.height;
- else
- *new_y = work_area.y;
- break;
- case META_BOTTOM:
- *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 - 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,
- int *x,
- int *y)
-{
- /* We can't center this dialog if it was denied focus and it
- * overlaps with the focus window and this dialog is modal and this
- * dialog is in the same app as the focus window (*phew*...please
- * don't make me say that ten times fast). See bug 307875 comment 11
- * and 12 for details, but basically it means this is probably a
- * second modal dialog for some app while the focus window is the
- * first modal dialog. We should probably make them simultaneously
- * visible in general, but it becomes mandatory to do so due to
- * buggy apps (e.g. those using gtk+ *sigh*) because in those cases
- * this second modal dialog also happens to be modal to the first
- * dialog in addition to the main window, while it has only let us
- * know about the modal-to-the-main-window part.
- */
-
- MetaWindow *focus_window;
-
- 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->type == META_WINDOW_MODAL_DIALOG &&
- meta_window_same_application (window, focus_window) &&
- window_overlaps_focus_window (window))
- {
- 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 "
- "focus window",
- window->desc);
- }
-}
-
-static gboolean
-rectangle_overlaps_some_window (MetaRectangle *rect,
- GList *windows)
-{
- GList *tmp;
- MetaRectangle dest;
-
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *other = tmp->data;
- MetaRectangle other_rect;
-
- switch (other->type)
- {
- case META_WINDOW_DOCK:
- case META_WINDOW_SPLASHSCREEN:
- 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:
- break;
-
- case META_WINDOW_NORMAL:
- case META_WINDOW_UTILITY:
- case META_WINDOW_TOOLBAR:
- case META_WINDOW_MENU:
- meta_window_get_frame_rect (other, &other_rect);
-
- if (meta_rectangle_intersect (rect, &other_rect, &dest))
- return TRUE;
- break;
- }
-
- tmp = tmp->next;
- }
-
- return FALSE;
-}
-
-static gint
-leftmost_cmp (gconstpointer a, gconstpointer b)
-{
- MetaWindow *aw = (gpointer) a;
- MetaWindow *bw = (gpointer) b;
- MetaRectangle a_frame;
- MetaRectangle b_frame;
- int ax, bx;
-
- 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;
- else if (ax > bx)
- return 1;
- else
- return 0;
-}
-
-static gint
-topmost_cmp (gconstpointer a, gconstpointer b)
-{
- MetaWindow *aw = (gpointer) a;
- MetaWindow *bw = (gpointer) b;
- MetaRectangle a_frame;
- MetaRectangle b_frame;
- int ay, by;
-
- 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;
- else if (ay > by)
- return 1;
- else
- return 0;
-}
-
-static void
-center_tile_rect_in_area (MetaRectangle *rect,
- MetaRectangle *work_area)
-{
- int fluff;
-
- /* The point here is to tile a window such that "extra"
- * space is equal on either side (i.e. so a full screen
- * of windows tiled this way would center the windows
- * as a group)
- */
-
- fluff = (work_area->width % (rect->width+1)) / 2;
- rect->x = work_area->x + fluff;
- fluff = (work_area->height % (rect->height+1)) / 3;
- rect->y = work_area->y + fluff;
-}
-
-/* Find the leftmost, then topmost, empty area on the workspace
- * that can contain the new window.
- *
- * Cool feature to have: if we can't fit the current window size,
- * try shrinking the window (within geometry constraints). But
- * beware windows such as Emacs with no sane minimum size, we
- * don't want to create a 1x1 Emacs.
- */
-static gboolean
-find_first_fit (MetaWindow *window,
- /* visible windows on relevant workspaces */
- 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
- * with existing windows. It tries to place the window on
- * 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);
-
- /* 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);
-
- 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_PLACEMENT,
- "Natural monitor is %s",
- 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))
- {
- *new_x = rect.x;
- *new_y = rect.y;
-
- retval = TRUE;
-
- goto out;
- }
-
- /* try below each window */
- tmp = below_sorted;
- while (tmp != NULL)
- {
- 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;
- }
-
- /* try to the right of each window */
- tmp = right_sorted;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
- MetaRectangle frame_rect;
-
- meta_window_get_frame_rect (w, &frame_rect);
-
- rect.x = frame_rect.x + frame_rect.width;
- rect.y = frame_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;
-
- retval = TRUE;
-
- goto out;
- }
-
- tmp = tmp->next;
- }
-
- out:
- g_list_free (below_sorted);
- g_list_free (right_sorted);
- return retval;
-}
-
-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,
- int x,
- int y,
- int *new_x,
- int *new_y)
-{
- MetaBackend *backend = meta_get_backend ();
- GList *windows = NULL;
- MetaLogicalMonitor *logical_monitor;
-
- meta_topic (META_DEBUG_PLACEMENT, "Placing window %s", window->desc);
-
- g_return_if_fail (!window->placement.rule);
-
- switch (window->type)
- {
- /* Run placement algorithm on these. */
- case META_WINDOW_NORMAL:
- case META_WINDOW_DIALOG:
- 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")
- */
- 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:
- goto done;
- }
-
- if (meta_prefs_get_disable_workarounds ())
- {
- switch (window->type)
- {
- /* Only accept USPosition on normal windows because the app is full
- * of shit claiming the user set -geometry for a dialog or dock
- */
- case META_WINDOW_NORMAL:
- if (window->size_hints.flags & USPosition)
- {
- /* don't constrain with placement algorithm */
- meta_topic (META_DEBUG_PLACEMENT,
- "Honoring USPosition for %s instead of using placement algorithm",
- window->desc);
-
- goto done;
- }
- break;
-
- /* Ignore even USPosition on dialogs, splashscreen */
- case META_WINDOW_DIALOG:
- 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:
- if (window->size_hints.flags & PPosition)
- {
- meta_topic (META_DEBUG_PLACEMENT,
- "Not placing non-normal non-dialog window with PPosition set");
- goto done;
- }
- break;
- }
- }
- 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");
- avoid_being_obscured_as_second_modal_dialog (window, &x, &y);
- goto done;
- }
- }
-
- if (window->type == META_WINDOW_DIALOG ||
- window->type == META_WINDOW_MODAL_DIALOG)
- {
- MetaWindow *parent = meta_window_get_transient_for (window);
-
- if (parent)
- {
- 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 = parent_frame_rect.x + parent_frame_rect.width / 2;
- /* center of child over center of parent */
- x -= frame_rect.width / 2;
-
- /* "visually" center window over parent, leaving twice as
- * much space below as on top.
- */
- y += (parent_frame_rect.height - frame_rect.height)/3;
-
- meta_topic (META_DEBUG_PLACEMENT,
- "Centered window %s over transient parent",
- window->desc);
-
- 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_place_centered (window))
- {
- /* Center on current monitor */
- MetaRectangle work_area;
- MetaRectangle frame_rect;
-
- /* Warning, this function is a round trip! */
- logical_monitor = meta_backend_get_current_logical_monitor (backend);
-
- meta_window_get_work_area_for_logical_monitor (window,
- logical_monitor,
- &work_area);
- meta_window_get_frame_rect (window, &frame_rect);
-
- x = work_area.x + (work_area.width - frame_rect.width) / 2;
- y = work_area.y + (work_area.height - frame_rect.height) / 2;
-
- meta_topic (META_DEBUG_PLACEMENT, "Centered window %s on monitor %d",
- 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)
- */
- {
- GSList *all_windows;
- GSList *tmp;
-
- all_windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
-
- tmp = all_windows;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- 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;
- }
-
- g_slist_free (all_windows);
- }
-
- /* 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.
- */
- if (window->has_maximize_func && window->decorated &&
- !window->fullscreen)
- {
- MetaRectangle workarea;
- MetaRectangle frame_rect;
-
- meta_window_get_work_area_for_logical_monitor (window,
- logical_monitor,
- &workarea);
- meta_window_get_frame_rect (window, &frame_rect);
-
- /* If the window is bigger than the screen, then automaximize. Do NOT
- * auto-maximize the directions independently. See #419810.
- */
- if (frame_rect.width >= workarea.width && frame_rect.height >= workarea.height)
- {
- window->maximize_horizontally_after_placement = TRUE;
- window->maximize_vertically_after_placement = TRUE;
- }
- }
-
- /* "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
- * focus window, we do NOT want it to overlap with the focus window
- * if at all possible. This is guaranteed to only be called if the
- * focus_window is non-NULL, and we try to avoid that window.
- */
- if (window->denied_focus_and_not_transient)
- {
- MetaWindow *focus_window;
- 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 = !window_overlaps_focus_window (window);
-
- /* Try to do a first fit again, this time only taking into account the
- * focus window.
- */
- if (!found_fit)
- {
- GList *focus_window_list;
- focus_window_list = g_list_prepend (NULL, focus_window);
-
- /* Reset x and y ("origin" placement algorithm) */
- x = logical_monitor->rect.x;
- y = logical_monitor->rect.y;
-
- 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, focus_window, x, y, &x, &y);
- }
-
- done:
- if (windows)
- g_list_free (windows);
-
- *new_x = x;
- *new_y = y;
-}
diff --git a/src/core/place.h b/src/core/place.h
deleted file mode 100644
index 2e2c81141..000000000
--- a/src/core/place.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_PLACE_H
-#define META_PLACE_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,
- int x,
- int y,
- int *new_x,
- int *new_y);
-
-#endif
diff --git a/src/core/prefs-private.h b/src/core/prefs-private.h
deleted file mode 100644
index e587bfaa1..000000000
--- a/src/core/prefs-private.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2021 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 PREFS_PRIVATE_H
-#define PREFS_PRIVATE_H
-
-void meta_prefs_init (void);
-
-#endif /* PREFS_PRIVATE_H */
diff --git a/src/core/prefs.c b/src/core/prefs.c
deleted file mode 100644
index 536d9dd57..000000000
--- a/src/core/prefs.c
+++ /dev/null
@@ -1,2229 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2001 Havoc Pennington, Copyright (C) 2002 Red Hat Inc.
- * Copyright (C) 2006 Elijah Newren
- * Copyright (C) 2008 Thomas Thurman
- * Copyright (C) 2010 Milan Bouchet-Valat, Copyright (C) 2011 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:prefs
- * @title: Preferences
- * @short_description: Mutter preferences
- */
-
-#include "config.h"
-
-#include <glib.h>
-#include <gio/gio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "compositor/meta-plugin-manager.h"
-#include "core/keybindings-private.h"
-#include "core/meta-accel-parse.h"
-#include "core/prefs-private.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.
- *
- * Keys which are handled by one of the unified handlers below are
- * not given a name here, because the purpose of the unified handlers
- * is that keys should be referred to exactly once.
- */
-#define KEY_TITLEBAR_FONT "titlebar-font"
-#define KEY_NUM_WORKSPACES "num-workspaces"
-#define KEY_WORKSPACE_NAMES "workspace-names"
-
-/* 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_OVERLAY_KEY "overlay-key"
-#define KEY_WORKSPACES_ONLY_ON_PRIMARY "workspaces-only-on-primary"
-#define KEY_LOCATE_POINTER "locate-pointer"
-
-/* These are the different schemas we are keeping
- * a GSettings instance for */
-#define SCHEMA_GENERAL "org.gnome.desktop.wm.preferences"
-#define SCHEMA_MUTTER "org.gnome.mutter"
-#define SCHEMA_INTERFACE "org.gnome.desktop.interface"
-#define SCHEMA_INPUT_SOURCES "org.gnome.desktop.input-sources"
-#define SCHEMA_MOUSE "org.gnome.desktop.peripherals.mouse"
-
-#define SETTINGS(s) g_hash_table_lookup (settings_schemas, (s))
-
-static GList *changes = NULL;
-static guint changed_idle;
-static GList *listeners = NULL;
-static GHashTable *settings_schemas;
-
-static gboolean use_system_font = FALSE;
-static PangoFontDescription *titlebar_font = NULL;
-static MetaVirtualModifier mouse_button_mods = Mod1Mask;
-static MetaKeyCombo overlay_key_combo = { 0, 0, 0 };
-static MetaKeyCombo locate_pointer_key_combo = { 0, 0, 0 };
-static GDesktopFocusMode focus_mode = G_DESKTOP_FOCUS_MODE_CLICK;
-static GDesktopFocusNewWindows focus_new_windows = G_DESKTOP_FOCUS_NEW_WINDOWS_SMART;
-static gboolean raise_on_click = TRUE;
-static gboolean center_new_windows = FALSE;
-static gboolean attach_modal_dialogs = FALSE;
-static int num_workspaces = 4;
-static GDesktopTitlebarAction action_double_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE;
-static GDesktopTitlebarAction action_middle_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_LOWER;
-static GDesktopTitlebarAction action_right_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_MENU;
-static gboolean dynamic_workspaces = 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 drag_threshold;
-static gboolean resize_with_right_button = FALSE;
-static gboolean edge_tiling = FALSE;
-static gboolean force_fullscreen = TRUE;
-static gboolean auto_maximize = TRUE;
-static gboolean show_fallback_app_menu = TRUE;
-
-static GDesktopVisualBellType visual_bell_type = G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH;
-static MetaButtonLayout button_layout;
-
-/* NULL-terminated array */
-static char **workspace_names = NULL;
-
-static gboolean workspaces_only_on_primary = FALSE;
-
-static char *iso_next_group_option = NULL;
-
-static void handle_preference_update_enum (GSettings *settings,
- gchar *key);
-static gboolean update_binding (MetaKeyPref *binding,
- gchar **strokes);
-static gboolean update_key_binding (const char *key,
- gchar **strokes);
-
-static void settings_changed (GSettings *settings,
- gchar *key,
- gpointer data);
-static void bindings_changed (GSettings *settings,
- gchar *key,
- gpointer data);
-
-static void queue_changed (MetaPreference pref);
-
-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 button_layout_handler (GVariant*, gpointer*, gpointer);
-static gboolean overlay_key_handler (GVariant*, gpointer*, gpointer);
-static gboolean locate_pointer_key_handler (GVariant*, gpointer*, gpointer);
-
-static gboolean iso_next_group_handler (GVariant*, gpointer*, gpointer);
-
-static void init_bindings (void);
-
-typedef struct
-{
- MetaPrefsChangedFunc func;
- gpointer data;
-} MetaPrefsListener;
-
-typedef struct
-{
- const char *key;
- const char *schema;
- MetaPreference pref;
-} MetaBasePreference;
-
-typedef struct
-{
- MetaBasePreference base;
- gpointer target;
-} MetaEnumPreference;
-
-typedef struct
-{
- MetaBasePreference base;
- 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;
- GSettingsGetMapping handler;
- 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.
- */
-
-/* FIXMEs: */
-/* @@@ Don't use NULL lines at the end; glib can tell you how big it is */
-
-static MetaEnumPreference preferences_enum[] =
- {
- {
- { "focus-new-windows",
- SCHEMA_GENERAL,
- META_PREF_FOCUS_NEW_WINDOWS,
- },
- &focus_new_windows,
- },
- {
- { "focus-mode",
- SCHEMA_GENERAL,
- META_PREF_FOCUS_MODE,
- },
- &focus_mode,
- },
- {
- { "visual-bell-type",
- SCHEMA_GENERAL,
- META_PREF_VISUAL_BELL_TYPE,
- },
- &visual_bell_type,
- },
- {
- { "action-double-click-titlebar",
- SCHEMA_GENERAL,
- META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR,
- },
- &action_double_click_titlebar,
- },
- {
- { "action-middle-click-titlebar",
- SCHEMA_GENERAL,
- META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR,
- },
- &action_middle_click_titlebar,
- },
- {
- { "action-right-click-titlebar",
- SCHEMA_GENERAL,
- META_PREF_ACTION_RIGHT_CLICK_TITLEBAR,
- },
- &action_right_click_titlebar,
- },
- { { NULL, 0, 0 }, NULL },
- };
-
-static MetaBoolPreference preferences_bool[] =
- {
- {
- { "attach-modal-dialogs",
- SCHEMA_MUTTER,
- META_PREF_ATTACH_MODAL_DIALOGS,
- },
- &attach_modal_dialogs,
- },
- {
- { "center-new-windows",
- SCHEMA_MUTTER,
- META_PREF_CENTER_NEW_WINDOWS,
- },
- &center_new_windows,
- },
- {
- { "raise-on-click",
- SCHEMA_GENERAL,
- META_PREF_RAISE_ON_CLICK,
- },
- &raise_on_click,
- },
- {
- { "titlebar-uses-system-font",
- SCHEMA_GENERAL,
- META_PREF_TITLEBAR_FONT, /* note! shares a pref */
- },
- &use_system_font,
- },
- {
- { "dynamic-workspaces",
- SCHEMA_MUTTER,
- META_PREF_DYNAMIC_WORKSPACES,
- },
- &dynamic_workspaces,
- },
- {
- { "disable-workarounds",
- SCHEMA_GENERAL,
- META_PREF_DISABLE_WORKAROUNDS,
- },
- &disable_workarounds,
- },
- {
- { "auto-raise",
- SCHEMA_GENERAL,
- META_PREF_AUTO_RAISE,
- },
- &auto_raise,
- },
- {
- { "focus-change-on-pointer-rest",
- SCHEMA_MUTTER,
- META_PREF_FOCUS_CHANGE_ON_POINTER_REST,
- },
- &focus_change_on_pointer_rest
- },
- {
- { "visual-bell",
- SCHEMA_GENERAL,
- META_PREF_VISUAL_BELL,
- },
- &bell_is_visible, /* FIXME: change the name: it's confusing */
- },
- {
- { "audible-bell",
- SCHEMA_GENERAL,
- META_PREF_AUDIBLE_BELL,
- },
- &bell_is_audible, /* FIXME: change the name: it's confusing */
- },
- {
- { KEY_GNOME_ACCESSIBILITY,
- SCHEMA_INTERFACE,
- META_PREF_GNOME_ACCESSIBILITY,
- },
- &gnome_accessibility,
- },
- {
- { KEY_GNOME_ANIMATIONS,
- SCHEMA_INTERFACE,
- META_PREF_GNOME_ANIMATIONS,
- },
- &gnome_animations,
- },
- {
- { "resize-with-right-button",
- SCHEMA_GENERAL,
- META_PREF_RESIZE_WITH_RIGHT_BUTTON,
- },
- &resize_with_right_button,
- },
- {
- { "edge-tiling",
- SCHEMA_MUTTER,
- META_PREF_EDGE_TILING,
- },
- &edge_tiling,
- },
- {
- { "workspaces-only-on-primary",
- SCHEMA_MUTTER,
- META_PREF_WORKSPACES_ONLY_ON_PRIMARY,
- },
- &workspaces_only_on_primary,
- },
- {
- { "auto-maximize",
- SCHEMA_MUTTER,
- META_PREF_AUTO_MAXIMIZE,
- },
- &auto_maximize,
- },
- {
- { KEY_LOCATE_POINTER,
- SCHEMA_INTERFACE,
- META_PREF_LOCATE_POINTER,
- },
- &locate_pointer_is_enabled,
- },
- { { NULL, 0, 0 }, NULL },
- };
-
-static MetaStringPreference preferences_string[] =
- {
- {
- { "mouse-button-modifier",
- SCHEMA_GENERAL,
- META_PREF_MOUSE_BUTTON_MODS,
- },
- mouse_button_mods_handler,
- NULL,
- },
- {
- { KEY_TITLEBAR_FONT,
- SCHEMA_GENERAL,
- META_PREF_TITLEBAR_FONT,
- },
- titlebar_handler,
- NULL,
- },
- {
- { "button-layout",
- SCHEMA_GENERAL,
- META_PREF_BUTTON_LAYOUT,
- },
- button_layout_handler,
- NULL,
- },
- {
- { "cursor-theme",
- SCHEMA_INTERFACE,
- META_PREF_CURSOR_THEME,
- },
- NULL,
- &cursor_theme,
- },
- {
- { "overlay-key",
- SCHEMA_MUTTER,
- META_PREF_KEYBINDINGS,
- },
- overlay_key_handler,
- NULL,
- },
- {
- { "locate-pointer-key",
- SCHEMA_MUTTER,
- META_PREF_KEYBINDINGS,
- },
- 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 },
- };
-
-static MetaIntPreference preferences_int[] =
- {
- {
- { KEY_NUM_WORKSPACES,
- SCHEMA_GENERAL,
- META_PREF_NUM_WORKSPACES,
- },
- &num_workspaces
- },
- {
- { "auto-raise-delay",
- SCHEMA_GENERAL,
- META_PREF_AUTO_RAISE_DELAY,
- },
- &auto_raise_delay
- },
- {
- { "draggable-border-width",
- SCHEMA_MUTTER,
- META_PREF_DRAGGABLE_BORDER_WIDTH,
- },
- &draggable_border_width
- },
- {
- { "drag-threshold",
- SCHEMA_MOUSE,
- META_PREF_DRAG_THRESHOLD,
- },
- &drag_threshold
- },
- {
- { "cursor-size",
- SCHEMA_INTERFACE,
- META_PREF_CURSOR_SIZE,
- },
- &cursor_size
- },
- { { NULL, 0, 0 }, NULL },
- };
-
-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)
-{
- MetaEnumPreference *cursor = preferences_enum;
-
- while (cursor->base.key != NULL)
- {
- if (cursor->target==NULL)
- continue;
-
- *((gint *) cursor->target) =
- g_settings_get_enum (SETTINGS (cursor->base.schema), cursor->base.key);
-
- ++cursor;
- }
-}
-
-static void
-handle_preference_init_bool (void)
-{
- MetaBoolPreference *cursor = preferences_bool;
-
- while (cursor->base.key != NULL)
- {
- if (cursor->target!=NULL)
- *cursor->target =
- g_settings_get_boolean (SETTINGS (cursor->base.schema),
- cursor->base.key);
-
- ++cursor;
- }
-
- maybe_give_disable_workarounds_warning ();
-}
-
-static void
-handle_preference_init_string (void)
-{
- MetaStringPreference *cursor = preferences_string;
-
- 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", 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", cursor->base.key);
-
- g_free (*(cursor->target));
-
- value = g_settings_get_string (SETTINGS (cursor->base.schema),
- cursor->base.key);
-
- *(cursor->target) = value;
- }
-
- ++cursor;
- }
-}
-
-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", 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", 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)
-{
- MetaIntPreference *cursor = preferences_int;
-
-
- while (cursor->base.key != NULL)
- {
- if (cursor->target)
- *cursor->target = g_settings_get_int (SETTINGS (cursor->base.schema),
- cursor->base.key);
-
- ++cursor;
- }
-}
-
-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)
-{
- MetaEnumPreference *cursor = preferences_enum;
- gint old_value;
-
- while (cursor->base.key != NULL && strcmp (key, cursor->base.key) != 0)
- ++cursor;
-
- if (cursor->base.key == NULL)
- /* Didn't recognise that key. */
- return;
-
- /* We need to know whether the value changes, so
- * store the current value away.
- */
-
- old_value = * ((gint *)cursor->target);
- *((gint *)cursor->target) =
- g_settings_get_enum (SETTINGS (cursor->base.schema), key);
-
- /* Did it change? If so, tell the listeners about it. */
- if (old_value != *((gint *)cursor->target))
- queue_changed (cursor->base.pref);
-}
-
-static void
-handle_preference_update_bool (GSettings *settings,
- gchar *key)
-{
- MetaBoolPreference *cursor = preferences_bool;
- gboolean old_value;
-
- while (cursor->base.key != NULL && strcmp (key, cursor->base.key) != 0)
- ++cursor;
-
- if (cursor->base.key == NULL || cursor->target == NULL)
- /* Unknown key or no work for us to do. */
- return;
-
- /* We need to know whether the value changes, so
- * store the current value away.
- */
- old_value = *((gboolean *) cursor->target);
-
- /* Now look it up... */
- *((gboolean *) cursor->target) =
- g_settings_get_boolean (SETTINGS (cursor->base.schema), key);
-
- /* Did it change? If so, tell the listeners about it. */
- if (old_value != *((gboolean *)cursor->target))
- queue_changed (cursor->base.pref);
-
- if (cursor->base.pref==META_PREF_DISABLE_WORKAROUNDS)
- maybe_give_disable_workarounds_warning ();
-}
-
-static void
-handle_preference_update_string (GSettings *settings,
- gchar *key)
-{
- MetaStringPreference *cursor = preferences_string;
- char *value;
- 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", 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", cursor->base.key);
-
- value = g_settings_get_string (SETTINGS (cursor->base.schema),
- cursor->base.key);
-
- inform_listeners = (g_strcmp0 (value, *(cursor->target)) != 0);
-
- g_free(*(cursor->target));
-
- *(cursor->target) = value;
- }
-
- if (inform_listeners)
- 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", 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", 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)
-{
- MetaIntPreference *cursor = preferences_int;
- gint new_value;
-
- while (cursor->base.key != NULL && strcmp (key, cursor->base.key) != 0)
- ++cursor;
-
- if (cursor->base.key == NULL || cursor->target == NULL)
- /* Unknown key or no work for us to do. */
- return;
-
- new_value = g_settings_get_int (SETTINGS (cursor->base.schema), key);
-
- /* Did it change? If so, tell the listeners about it. */
- if (*cursor->target != new_value)
- {
- *cursor->target = new_value;
- queue_changed (cursor->base.pref);
- }
-}
-
-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 user_data)
-{
- MetaPrefsListener *l;
-
- l = g_new (MetaPrefsListener, 1);
- l->func = func;
- 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 user_data)
-{
- GList *tmp;
-
- tmp = listeners;
- while (tmp != NULL)
- {
- MetaPrefsListener *l = tmp->data;
-
- if (l->func == func &&
- l->data == user_data)
- {
- g_free (l);
- listeners = g_list_delete_link (listeners, tmp);
-
- return;
- }
-
- tmp = tmp->next;
- }
-}
-
-static void
-emit_changed (MetaPreference pref)
-{
- GList *tmp;
- GList *copy;
-
- meta_topic (META_DEBUG_PREFS, "Notifying listeners that pref %s changed",
- meta_preference_to_string (pref));
-
- copy = g_list_copy (listeners);
-
- tmp = copy;
-
- while (tmp != NULL)
- {
- MetaPrefsListener *l = tmp->data;
-
- (* l->func) (pref, l->data);
-
- tmp = tmp->next;
- }
-
- g_list_free (copy);
-}
-
-static gboolean
-changed_idle_handler (gpointer data)
-{
- GList *tmp;
- GList *copy;
-
- changed_idle = 0;
-
- copy = g_list_copy (changes); /* reentrancy paranoia */
-
- g_list_free (changes);
- changes = NULL;
-
- tmp = copy;
- while (tmp != NULL)
- {
- MetaPreference pref = GPOINTER_TO_INT (tmp->data);
-
- emit_changed (pref);
-
- tmp = tmp->next;
- }
-
- g_list_free (copy);
-
- return FALSE;
-}
-
-static void
-queue_changed (MetaPreference pref)
-{
- meta_topic (META_DEBUG_PREFS, "Queueing change of pref %s",
- meta_preference_to_string (pref));
-
- if (g_list_find (changes, GINT_TO_POINTER (pref)) == NULL)
- changes = g_list_prepend (changes, GINT_TO_POINTER (pref));
- else
- meta_topic (META_DEBUG_PREFS, "Change of pref %s was already pending",
- meta_preference_to_string (pref));
-
- if (changed_idle == 0)
- {
- 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");
- }
-}
-
-
-/****************************************************************************/
-/* Initialisation. */
-/****************************************************************************/
-
-void
-meta_prefs_init (void)
-{
- GSettings *settings;
-
- settings_schemas = g_hash_table_new_full (g_str_hash, g_str_equal,
- 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_MUTTER);
- g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL);
- 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_signal_connect (settings, "changed::" KEY_LOCATE_POINTER,
- G_CALLBACK (settings_changed), NULL);
- g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INTERFACE), settings);
-
- 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_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 ();
- handle_preference_init_uint ();
-
- init_bindings ();
-}
-
-static gboolean
-find_pref (void *prefs,
- size_t pref_size,
- const char *search_key,
- MetaBasePreference **pref)
-{
- void *p = prefs;
-
- while (TRUE)
- {
- char **key = p;
- if (*key == NULL)
- break;
-
- if (strcmp (*key, search_key) == 0)
- {
- *pref = p;
- return TRUE;
- }
-
- p = (guchar *)p + pref_size;
- }
-
- return FALSE;
-}
-
-
-/****************************************************************************/
-/* Updates. */
-/****************************************************************************/
-
-
-static void
-settings_changed (GSettings *settings,
- gchar *key,
- gpointer data)
-{
- GVariant *value;
- const GVariantType *type;
- MetaEnumPreference *cursor;
- gboolean found_enum;
-
- value = g_settings_get_value (settings, key);
- type = g_variant_get_type (value);
-
- 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);
- 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;
- found_enum = FALSE;
-
- while (cursor->base.key != NULL)
- {
-
- if (strcmp (key, cursor->base.key) == 0)
- found_enum = TRUE;
-
- cursor++;
- }
-
- if (found_enum)
- handle_preference_update_enum (settings, key);
- else
- handle_preference_update_string (settings, key);
- }
- else
- {
- /* Unknown preference type. This quite likely simply isn't
- * a preference we track changes to. */
- }
-
- g_variant_unref (value);
-}
-
-static void
-bindings_changed (GSettings *settings,
- gchar *key,
- gpointer data)
-{
- gchar **strokes;
- strokes = g_settings_get_strv (settings, key);
-
- if (update_key_binding (key, strokes))
- queue_changed (META_PREF_KEYBINDINGS);
-
- g_strfreev (strokes);
-}
-
-/**
- * maybe_give_disable_workaround_warning:
- *
- * Special case: give a warning the first time disable_workarounds
- * is turned on.
- */
-static void
-maybe_give_disable_workarounds_warning (void)
-{
- static gboolean first_disable = TRUE;
-
- if (first_disable && disable_workarounds)
- {
- first_disable = FALSE;
-
- meta_warning ("Workarounds for broken applications disabled. "
- "Some applications may not behave properly.");
- }
-}
-
-MetaVirtualModifier
-meta_prefs_get_mouse_button_mods (void)
-{
- return mouse_button_mods;
-}
-
-GDesktopFocusMode
-meta_prefs_get_focus_mode (void)
-{
- return focus_mode;
-}
-
-GDesktopFocusNewWindows
-meta_prefs_get_focus_new_windows (void)
-{
- return focus_new_windows;
-}
-
-gboolean
-meta_prefs_get_center_new_windows (void)
-{
- return center_new_windows;
-}
-
-gboolean
-meta_prefs_get_attach_modal_dialogs (void)
-{
- return attach_modal_dialogs;
-}
-
-gboolean
-meta_prefs_get_raise_on_click (void)
-{
- return raise_on_click;
-}
-
-gboolean
-meta_prefs_get_show_fallback_app_menu (void)
-{
- return show_fallback_app_menu;
-}
-
-void
-meta_prefs_set_show_fallback_app_menu (gboolean whether)
-{
- gboolean changed = FALSE;
-
- changed = (show_fallback_app_menu == !whether);
-
- show_fallback_app_menu = whether;
-
- if (changed)
- queue_changed (META_PREF_BUTTON_LAYOUT);
-}
-
-const char*
-meta_prefs_get_cursor_theme (void)
-{
- return cursor_theme;
-}
-
-int
-meta_prefs_get_cursor_size (void)
-{
- return cursor_size;
-}
-
-
-/****************************************************************************/
-/* Handlers for string preferences. */
-/****************************************************************************/
-
-static gboolean
-titlebar_handler (GVariant *value,
- gpointer *result,
- gpointer data)
-{
- PangoFontDescription *desc;
- const gchar *string_value;
-
- *result = NULL; /* ignored */
- string_value = g_variant_get_string (value, NULL);
- desc = pango_font_description_from_string (string_value);
-
- if (desc == NULL)
- {
- meta_warning ("Could not parse font description "
- "\"%s\" from GSettings key %s",
- string_value ? string_value : "(null)",
- KEY_TITLEBAR_FONT);
- return FALSE;
- }
-
- /* Is the new description the same as the old? */
- if (titlebar_font &&
- pango_font_description_equal (desc, titlebar_font))
- {
- pango_font_description_free (desc);
- }
- else
- {
- if (titlebar_font)
- pango_font_description_free (titlebar_font);
-
- titlebar_font = desc;
- queue_changed (META_PREF_TITLEBAR_FONT);
- }
-
- return TRUE;
-}
-
-static gboolean
-mouse_button_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_parse_modifier (string_value, &mods))
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Failed to parse new GSettings value");
-
- meta_warning ("\"%s\" found in configuration database is "
- "not a valid value for mouse button modifier",
- string_value);
-
- return FALSE;
- }
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Mouse button modifier has new GSettings value \"%s\"",
- string_value);
-
- if (mods != mouse_button_mods)
- {
- mouse_button_mods = mods;
- queue_changed (META_PREF_MOUSE_BUTTON_MODS);
- }
-
- return TRUE;
-}
-
-static gboolean
-button_layout_equal (const MetaButtonLayout *a,
- const MetaButtonLayout *b)
-{
- int i;
-
- i = 0;
- while (i < MAX_BUTTONS_PER_CORNER)
- {
- if (a->left_buttons[i] != b->left_buttons[i])
- return FALSE;
- if (a->right_buttons[i] != b->right_buttons[i])
- return FALSE;
- if (a->left_buttons_has_spacer[i] != b->left_buttons_has_spacer[i])
- return FALSE;
- if (a->right_buttons_has_spacer[i] != b->right_buttons_has_spacer[i])
- return FALSE;
- ++i;
- }
-
- return TRUE;
-}
-
-/*
- * This conversion cannot be handled by GSettings since
- * several values are stored in the same key (as a string).
- */
-static MetaButtonFunction
-button_function_from_string (const char *str)
-{
- if (strcmp (str, "menu") == 0)
- return META_BUTTON_FUNCTION_MENU;
- else if (strcmp (str, "minimize") == 0)
- return META_BUTTON_FUNCTION_MINIMIZE;
- else if (strcmp (str, "maximize") == 0)
- return META_BUTTON_FUNCTION_MAXIMIZE;
- else if (strcmp (str, "close") == 0)
- return META_BUTTON_FUNCTION_CLOSE;
- else
- /* don't know; give up */
- return META_BUTTON_FUNCTION_LAST;
-}
-
-static gboolean
-button_layout_handler (GVariant *value,
- gpointer *result,
- gpointer data)
-{
- MetaButtonLayout new_layout;
- const gchar *string_value;
- char **sides = NULL;
- int i;
-
- /* We need to ignore unknown button functions, for
- * compat with future versions
- */
-
- *result = NULL; /* ignored */
- string_value = g_variant_get_string (value, NULL);
-
- if (string_value)
- sides = g_strsplit (string_value, ":", 2);
-
- i = 0;
- if (sides != NULL && sides[0] != NULL)
- {
- char **buttons;
- int b;
- gboolean used[META_BUTTON_FUNCTION_LAST];
-
- while (i < META_BUTTON_FUNCTION_LAST)
- {
- used[i] = FALSE;
- new_layout.left_buttons_has_spacer[i] = FALSE;
- ++i;
- }
-
- buttons = g_strsplit (sides[0], ",", -1);
- i = 0;
- b = 0;
- while (buttons[b] != NULL)
- {
- MetaButtonFunction f = button_function_from_string (buttons[b]);
- if (i > 0 && strcmp("spacer", buttons[b]) == 0)
- {
- new_layout.left_buttons_has_spacer[i-1] = TRUE;
- }
- else
- {
- if (f != META_BUTTON_FUNCTION_LAST && !used[f])
- {
- new_layout.left_buttons[i] = f;
- used[f] = TRUE;
- ++i;
- }
- else
- {
- meta_topic (META_DEBUG_PREFS,
- "Ignoring unknown or already-used button name \"%s\"",
- buttons[b]);
- }
- }
-
- ++b;
- }
-
- g_strfreev (buttons);
- }
-
- for (; i < MAX_BUTTONS_PER_CORNER; i++)
- {
- new_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
- new_layout.left_buttons_has_spacer[i] = FALSE;
- }
-
- i = 0;
- if (sides != NULL && sides[0] != NULL && sides[1] != NULL)
- {
- char **buttons;
- int b;
- gboolean used[META_BUTTON_FUNCTION_LAST];
-
- while (i < META_BUTTON_FUNCTION_LAST)
- {
- used[i] = FALSE;
- new_layout.right_buttons_has_spacer[i] = FALSE;
- ++i;
- }
-
- buttons = g_strsplit (sides[1], ",", -1);
- i = 0;
- b = 0;
- while (buttons[b] != NULL)
- {
- MetaButtonFunction f = button_function_from_string (buttons[b]);
- if (i > 0 && strcmp("spacer", buttons[b]) == 0)
- {
- new_layout.right_buttons_has_spacer[i-1] = TRUE;
- }
- else
- {
- if (f != META_BUTTON_FUNCTION_LAST && !used[f])
- {
- new_layout.right_buttons[i] = f;
- used[f] = TRUE;
- ++i;
- }
- else
- {
- meta_topic (META_DEBUG_PREFS,
- "Ignoring unknown or already-used button name \"%s\"",
- buttons[b]);
- }
- }
-
- ++b;
- }
-
- g_strfreev (buttons);
- }
-
- for (; i < MAX_BUTTONS_PER_CORNER; i++)
- {
- new_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
- new_layout.right_buttons_has_spacer[i] = FALSE;
- }
-
- g_strfreev (sides);
-
- /* Invert the button layout for RTL languages */
- 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];
- }
- 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];
- }
- 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;
- }
-
- if (!button_layout_equal (&button_layout, &new_layout))
- {
- button_layout = new_layout;
- emit_changed (META_PREF_BUTTON_LAYOUT);
- }
-
- return TRUE;
-}
-
-static gboolean
-overlay_key_handler (GVariant *value,
- gpointer *result,
- gpointer data)
-{
- 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
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Failed to parse value for overlay-key");
- return FALSE;
- }
-
- combo.modifiers = 0;
-
- if (overlay_key_combo.keysym != combo.keysym ||
- overlay_key_combo.keycode != combo.keycode)
- {
- overlay_key_combo = combo;
- queue_changed (META_PREF_KEYBINDINGS);
- }
-
- return TRUE;
-}
-
-static gboolean
-locate_pointer_key_handler (GVariant *value,
- gpointer *result,
- gpointer data)
-{
- 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))
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Failed to parse value for locate-pointer-key");
- 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;
-}
-
-static gboolean
-iso_next_group_handler (GVariant *value,
- gpointer *result,
- gpointer data)
-{
- 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;
-}
-
-const PangoFontDescription*
-meta_prefs_get_titlebar_font (void)
-{
- if (use_system_font)
- return NULL;
- else
- return titlebar_font;
-}
-
-int
-meta_prefs_get_num_workspaces (void)
-{
- return num_workspaces;
-}
-
-gboolean
-meta_prefs_get_dynamic_workspaces (void)
-{
- return dynamic_workspaces;
-}
-
-gboolean
-meta_prefs_get_disable_workarounds (void)
-{
- return disable_workarounds;
-}
-
-#ifdef WITH_VERBOSE_MODE
-const char*
-meta_preference_to_string (MetaPreference pref)
-{
- /* TODO: better handled via GLib enum nicknames */
- switch (pref)
- {
- case META_PREF_MOUSE_BUTTON_MODS:
- return "MOUSE_BUTTON_MODS";
-
- 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_TITLEBAR_FONT:
- return "TITLEBAR_FONT";
-
- case META_PREF_NUM_WORKSPACES:
- return "NUM_WORKSPACES";
-
- case META_PREF_KEYBINDINGS:
- return "KEYBINDINGS";
-
- case META_PREF_DISABLE_WORKAROUNDS:
- return "DISABLE_WORKAROUNDS";
-
- case META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR:
- return "ACTION_DOUBLE_CLICK_TITLEBAR";
-
- case META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR:
- return "ACTION_MIDDLE_CLICK_TITLEBAR";
-
- case META_PREF_ACTION_RIGHT_CLICK_TITLEBAR:
- return "ACTION_RIGHT_CLICK_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";
-
- case META_PREF_CURSOR_THEME:
- return "CURSOR_THEME";
-
- case META_PREF_CURSOR_SIZE:
- return "CURSOR_SIZE";
-
- case META_PREF_RESIZE_WITH_RIGHT_BUTTON:
- return "RESIZE_WITH_RIGHT_BUTTON";
-
- case META_PREF_EDGE_TILING:
- return "EDGE_TILING";
-
- case META_PREF_FORCE_FULLSCREEN:
- return "FORCE_FULLSCREEN";
-
- case META_PREF_WORKSPACES_ONLY_ON_PRIMARY:
- return "WORKSPACES_ONLY_ON_PRIMARY";
-
- case META_PREF_DRAGGABLE_BORDER_WIDTH:
- return "DRAGGABLE_BORDER_WIDTH";
-
- case META_PREF_DRAG_THRESHOLD:
- return "DRAG_THRESHOLD";
-
- case META_PREF_DYNAMIC_WORKSPACES:
- return "DYNAMIC_WORKSPACES";
-
- case META_PREF_AUTO_MAXIMIZE:
- return "AUTO_MAXIMIZE";
-
- case META_PREF_LOCATE_POINTER:
- return "LOCATE_POINTER";
-
- case META_PREF_CHECK_ALIVE_TIMEOUT:
- return "CHECK_ALIVE_TIMEOUT";
- }
-
- return "(unknown)";
-}
-#endif /* WITH_VERBOSE_MODE */
-
-void
-meta_prefs_set_num_workspaces (int n_workspaces)
-{
- MetaBasePreference *pref;
-
- 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;
-
-static void
-meta_key_pref_free (MetaKeyPref *pref)
-{
- update_binding (pref, NULL);
-
- g_free (pref->name);
- g_object_unref (pref->settings);
-
- g_free (pref);
-}
-
-
-static void
-init_bindings (void)
-{
- MetaKeyPref *pref;
-
- key_bindings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
- (GDestroyNotify)meta_key_pref_free);
-
- 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)
-{
- GSList *old_combos, *a, *b;
- gboolean changed;
- int i;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Binding \"%s\" has new GSettings value",
- binding->name);
-
- old_combos = binding->combos;
- binding->combos = NULL;
-
- for (i = 0; strokes && strokes[i]; i++)
- {
- MetaKeyCombo *combo;
-
- combo = g_malloc0 (sizeof (MetaKeyCombo));
-
- if (!meta_parse_accelerator (strokes[i], combo))
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Failed to parse new GSettings value");
- meta_warning ("\"%s\" found in configuration database is not a valid value for keybinding \"%s\"",
- 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;
- }
-
- binding->combos = g_slist_prepend (binding->combos, combo);
- }
-
- binding->combos = g_slist_reverse (binding->combos);
-
- 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;
- }
- }
-
- g_slist_free_full (old_combos, g_free);
-
- return changed;
-}
-
-static gboolean
-update_key_binding (const char *key,
- gchar **strokes)
-{
- MetaKeyPref *pref = g_hash_table_lookup (key_bindings, key);
-
- if (pref)
- return update_binding (pref, strokes);
- else
- return FALSE;
-}
-
-const char*
-meta_prefs_get_workspace_name (int i)
-{
- const char *name;
-
- if (!workspace_names ||
- g_strv_length (workspace_names) < (guint)i + 1 ||
- !*workspace_names[i])
- {
- char *generated_name = g_strdup_printf (_("Workspace %d"), i + 1);
- name = g_intern_string (generated_name);
- g_free (generated_name);
- }
- else
- name = workspace_names[i];
-
- meta_topic (META_DEBUG_PREFS,
- "Getting name of workspace %d: \"%s\"", i, name);
-
- return name;
-}
-
-void
-meta_prefs_change_workspace_name (int num,
- const char *name)
-{
- GVariantBuilder builder;
- int n_workspace_names, i;
-
- g_return_if_fail (num >= 0);
-
- meta_topic (META_DEBUG_PREFS,
- "Changing name of workspace %d to %s",
- num, name ? name : "none");
-
- /* NULL and empty string both mean "default" here,
- * and we also need to match the name against its default value
- * to avoid saving it literally. */
- if (g_strcmp0 (name, meta_prefs_get_workspace_name (num)) == 0)
- {
- if (!name || !*name)
- meta_topic (META_DEBUG_PREFS,
- "Workspace %d already uses default name", num);
- else
- meta_topic (META_DEBUG_PREFS,
- "Workspace %d already has name %s", num, name);
- return;
- }
-
- g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY);
- n_workspace_names = workspace_names ? g_strv_length (workspace_names) : 0;
-
- for (i = 0; i < MAX (num + 1, n_workspace_names); i++)
- {
- const char *value;
-
- if (i == num)
- value = name ? name : "";
- else if (i < n_workspace_names)
- value = workspace_names[i] ? workspace_names[i] : "";
- else
- value = "";
-
- g_variant_builder_add (&builder, "s", value);
- }
-
- g_settings_set_value (SETTINGS (SCHEMA_GENERAL), KEY_WORKSPACE_NAMES,
- g_variant_builder_end (&builder));
-}
-
-/**
- * meta_prefs_get_button_layout:
- * @button_layout: (out):
- */
-void
-meta_prefs_get_button_layout (MetaButtonLayout *button_layout_p)
-{
- *button_layout_p = button_layout;
-}
-
-gboolean
-meta_prefs_get_visual_bell (void)
-{
- return bell_is_visible;
-}
-
-gboolean
-meta_prefs_bell_is_audible (void)
-{
- return bell_is_audible;
-}
-
-GDesktopVisualBellType
-meta_prefs_get_visual_bell_type (void)
-{
- return visual_bell_type;
-}
-
-gboolean
-meta_prefs_add_keybinding (const char *name,
- GSettings *settings,
- MetaKeyBindingAction action,
- MetaKeyBindingFlags flags)
-{
- MetaKeyPref *pref;
- char **strokes;
- guint id;
-
- if (g_hash_table_lookup (key_bindings, name))
- {
- meta_warning ("Trying to re-add keybinding \"%s\".", name);
- return FALSE;
- }
-
- pref = g_new0 (MetaKeyPref, 1);
- pref->name = g_strdup (name);
- pref->settings = g_object_ref (settings);
- pref->action = action;
- pref->combos = NULL;
- pref->builtin = (flags & META_KEY_BINDING_BUILTIN) != 0;
-
- 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
- {
- 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));
-
- 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;
-}
-
-gboolean
-meta_prefs_remove_keybinding (const char *name)
-{
- MetaKeyPref *pref;
- gulong id;
-
- pref = g_hash_table_lookup (key_bindings, name);
- if (!pref)
- {
- meta_warning ("Trying to remove non-existent keybinding \"%s\".", name);
- return FALSE;
- }
-
- if (pref->builtin)
- {
- meta_warning ("Trying to remove builtin keybinding \"%s\".", name);
- return FALSE;
- }
-
- 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);
-
- queue_changed (META_PREF_KEYBINDINGS);
-
- return TRUE;
-}
-
-GList *
-meta_prefs_get_keybindings (void)
-{
- return g_hash_table_get_values (key_bindings);
-}
-
-void
-meta_prefs_get_overlay_binding (MetaKeyCombo *combo)
-{
- *combo = overlay_key_combo;
-}
-
-void
-meta_prefs_get_locate_pointer_binding (MetaKeyCombo *combo)
-{
- *combo = locate_pointer_key_combo;
-}
-
-gboolean
-meta_prefs_is_locate_pointer_enabled (void)
-{
- return locate_pointer_is_enabled;
-}
-
-unsigned int
-meta_prefs_get_check_alive_timeout (void)
-{
- return check_alive_timeout;
-}
-
-const char *
-meta_prefs_get_iso_next_group_option (void)
-{
- return iso_next_group_option;
-}
-
-GDesktopTitlebarAction
-meta_prefs_get_action_double_click_titlebar (void)
-{
- return action_double_click_titlebar;
-}
-
-GDesktopTitlebarAction
-meta_prefs_get_action_middle_click_titlebar (void)
-{
- return action_middle_click_titlebar;
-}
-
-GDesktopTitlebarAction
-meta_prefs_get_action_right_click_titlebar (void)
-{
- return action_right_click_titlebar;
-}
-
-gboolean
-meta_prefs_get_auto_raise (void)
-{
- return auto_raise;
-}
-
-int
-meta_prefs_get_auto_raise_delay (void)
-{
- return auto_raise_delay;
-}
-
-gboolean
-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 (void)
-{
- return edge_tiling;
-}
-
-gboolean
-meta_prefs_get_auto_maximize (void)
-{
- return auto_maximize;
-}
-
-MetaKeyBindingAction
-meta_prefs_get_keybinding_action (const char *name)
-{
- MetaKeyPref *pref = g_hash_table_lookup (key_bindings, name);
-
- return pref ? pref->action
- : META_KEYBINDING_ACTION_NONE;
-}
-
-gint
-meta_prefs_get_mouse_button_resize (void)
-{
- return resize_with_right_button ? 3: 2;
-}
-
-gint
-meta_prefs_get_mouse_button_menu (void)
-{
- return resize_with_right_button ? 2: 3;
-}
-
-gboolean
-meta_prefs_get_force_fullscreen (void)
-{
- return force_fullscreen;
-}
-
-gboolean
-meta_prefs_get_workspaces_only_on_primary (void)
-{
- return workspaces_only_on_primary;
-}
-
-int
-meta_prefs_get_draggable_border_width (void)
-{
- return draggable_border_width;
-}
-
-int
-meta_prefs_get_drag_threshold (void)
-{
- return drag_threshold;
-}
-
-void
-meta_prefs_set_force_fullscreen (gboolean whether)
-{
- force_fullscreen = whether;
-}
diff --git a/src/core/restart-helper.c b/src/core/restart-helper.c
deleted file mode 100644
index 68ede2671..000000000
--- a/src/core/restart-helper.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * SECTION:restart-helper
- * @short_description: helper program during a restart
- *
- * 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 Mutter picks it back up.
- */
-
-/*
- * 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 <stdlib.h>
-#include <stdio.h>
-#include <X11/Xlib.h>
-#include <X11/extensions/Xcomposite.h>
-
-int
-main (int argc,
- char **argv)
-{
- Display *display = XOpenDisplay (NULL);
- Window selection_window;
- XSetWindowAttributes xwa;
- unsigned long mask = 0;
-
- xwa.override_redirect = True;
- mask |= CWOverrideRedirect;
-
-
- XCompositeGetOverlayWindow (display, DefaultRootWindow (display));
-
- selection_window = XCreateWindow (display,
- DefaultRootWindow (display),
- -100, -100, 1, 1, 0,
- 0,
- InputOnly,
- DefaultVisual (display, DefaultScreen (display)),
- mask, &xwa);
-
- XSetSelectionOwner (display,
- XInternAtom (display, "_MUTTER_RESTART_HELPER", False),
- selection_window,
- CurrentTime);
-
- /* 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 Mutter starts restarting.
- */
- XSync (display, False);
-
- printf ("STARTED\n");
- fflush (stdout);
-
- while (True)
- {
- XEvent xev;
-
- XNextEvent (display, &xev);
- /* 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
deleted file mode 100644
index e9a5bfd27..000000000
--- a/src/core/restart.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/* -*- 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/>.
- */
-
-/*
- * SECTION:restart
- * @short_description: Smoothly restart the compositor
- *
- * 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:
- *
- * - Display a message to the user and make sure that it is
- * actually painted before we exit.
- * - Use a helper program so that the Composite Overlay Window
- * isn't unmapped and mapped.
- *
- * This handles both of these.
- */
-
-#include "config.h"
-
-#include <gio/gunixinputstream.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_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_message_shown)
- {
- MetaDisplay *display = meta_get_display ();
-
- if (!meta_display_request_restart (display))
- meta_display_show_restart_message (display, NULL);
- }
-}
-
-static void
-restart_helper_read_line_callback (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GError *error = NULL;
- gsize length;
- char *line = g_data_input_stream_read_line_finish_utf8 (G_DATA_INPUT_STREAM (source_object),
- res,
- &length, &error);
- if (line == NULL)
- {
- meta_warning ("Failed to read output from restart helper%s%s",
- error ? ": " : NULL,
- error ? error->message : NULL);
- }
- else
- g_free (line); /* We don't actually care what the restart helper outputs */
-
- g_object_unref (source_object);
-
- restart_helper_started = TRUE;
- restart_check_ready ();
-}
-
-static gboolean
-restart_message_painted (gpointer data)
-{
- restart_message_shown = TRUE;
- restart_check_ready ();
-
- return FALSE;
-}
-
-/**
- * meta_restart:
- * @message: (allow-none): message to display to the user, or %NULL
- *
- * 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 (const char *message)
-{
- MetaDisplay *display = meta_get_display();
- GInputStream *unix_stream;
- GDataInputStream *data_stream;
- GError *error = NULL;
- int helper_out_fd;
-
- static const char * const helper_argv[] = {
- MUTTER_LIBEXECDIR "/mutter-restart-helper", 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.
- */
- if (!g_spawn_async_with_pipes (NULL, /* working directory */
- (char **)helper_argv,
- NULL, /* envp */
- G_SPAWN_DEFAULT,
- NULL, NULL, /* child_setup */
- NULL, /* child_pid */
- NULL, /* standard_input */
- &helper_out_fd,
- NULL, /* standard_error */
- &error))
- {
- meta_warning ("Failed to start restart helper: %s", error->message);
- goto error;
- }
-
- unix_stream = g_unix_input_stream_new (helper_out_fd, TRUE);
- data_stream = g_data_input_stream_new (unix_stream);
- g_object_unref (unix_stream);
-
- g_data_input_stream_read_line_async (data_stream, G_PRIORITY_DEFAULT,
- NULL, restart_helper_read_line_callback,
- &error);
- if (error != NULL)
- {
- meta_warning ("Failed to read from restart helper: %s", error->message);
- g_object_unref (data_stream);
- goto error;
- }
-
- return;
-
- error:
- /* If starting the restart helper fails, then we just go ahead and restart
- * immediately. We won't get a smooth transition, since the overlay window
- * will be destroyed and recreated, but otherwise it will work fine.
- */
- restart_helper_started = TRUE;
- restart_check_ready ();
-
- return;
-}
-
-/**
- * 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/stack-tracker.c b/src/core/stack-tracker.c
deleted file mode 100644
index fbfef6465..000000000
--- a/src/core/stack-tracker.c
+++ /dev/null
@@ -1,1293 +0,0 @@
-/* -*- 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.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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/stack-tracker.h"
-
-#include <string.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:
- *
- * - We need to have a view of the stacking order that takes into
- * account everything we have done without waiting for events
- * back from the X server; we don't want to draw intermediate
- * partially-stacked stack states just because we haven't received
- * some notification yet.
- *
- * - Only the X server has an accurate view of the complete stacking;
- * when we make a request to restack windows, we don't know how
- * it will affect override-redirect windows, because at any point
- * applications may restack these windows without our involvement.
- *
- * The technique we use is that we keep three sets of information:
- *
- * - The stacking order on the server as known from the last
- * event we received.
- * - A queue of stacking requests that *we* made subsequent to
- * that last event.
- * - A predicted stacking order, derived from applying the queued
- * requests to the last state from the server.
- *
- * When we receive a new event: a) we compare the serial in the event to
- * the serial of the queued requests and remove any that are now
- * no longer pending b) if necessary, drop the predicted stacking
- * order to recompute it at the next opportunity.
- *
- * Possible optimizations:
- * Keep the stacks as an array + reverse-mapping hash table to avoid
- * linear lookups.
- * Keep the stacks as a GList + reverse-mapping hash table to avoid
- * linear lookups and to make restacking constant-time.
- */
-
-typedef union _MetaStackOp MetaStackOp;
-
-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
- * notification event we received from the X server.
- */
-union _MetaStackOp
-{
- struct {
- MetaStackOpType type;
- gulong serial;
- guint64 window;
- } any;
- struct {
- MetaStackOpType type;
- gulong serial;
- guint64 window;
- } add;
- struct {
- MetaStackOpType type;
- gulong serial;
- guint64 window;
- } remove;
- struct {
- MetaStackOpType type;
- gulong serial;
- guint64 window;
- guint64 sibling;
- } raise_above;
- struct {
- MetaStackOpType type;
- gulong serial;
- guint64 window;
- guint64 sibling;
- } lower_below;
-};
-
-struct _MetaStackTracker
-{
- MetaDisplay *display;
-
- /* This is the serial of the last request we made that was reflected
- * in xserver_stack
- */
- 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 *unverified_predictions;
-
- /* 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;
-
- /* Idle function used to sync the compositor's view of the window
- * stack up with our best guess before a frame is drawn.
- */
- guint sync_stack_later;
-};
-
-static void
-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(%s; %ld)%s",
- prefix, window_desc, op->any.serial, suffix);
- break;
- case STACK_OP_REMOVE:
- 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(%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(%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
-stack_dump (MetaStackTracker *tracker,
- GArray *stack)
-{
- guint i;
-
- meta_push_no_msg_prefix ();
- for (i = 0; i < stack->len; i++)
- {
- guint64 window = g_array_index (stack, guint64, i);
- meta_topic (META_DEBUG_STACK, " %s", get_window_desc (tracker, window));
- }
- 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");
- meta_push_no_msg_prefix ();
- meta_topic (META_DEBUG_STACK, " xserver_serial: %ld", 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 (tracker, op, "", l->next ? ", " : "");
- }
- meta_topic (META_DEBUG_STACK, "]");
- if (tracker->predicted_stack)
- {
- meta_topic (META_DEBUG_STACK, " predicted_stack: ");
- stack_dump (tracker, tracker->predicted_stack);
- }
- meta_pop_no_msg_prefix ();
-#endif /* WITH_VERBOSE_MODE */
-}
-
-static void
-meta_stack_op_free (MetaStackOp *op)
-{
- g_free (op);
-}
-
-static int
-find_window (GArray *window_stack,
- guint64 window)
-{
- guint 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,
- 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++)
- {
- 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, guint64, i) = window;
-
- 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--)
- {
- 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, guint64, i) = window;
-
- return i != old_pos;
- }
- else
- return FALSE;
-}
-
-/* Returns TRUE if stack was changed */
-static gboolean
-meta_stack_op_apply (MetaStackTracker *tracker,
- MetaStackOp *op,
- GArray *stack,
- ApplyFlags apply_flags)
-{
- switch (op->any.type)
- {
- case STACK_OP_ADD:
- {
- int old_pos;
-
- if (META_STACK_ID_IS_X11 (op->add.window) &&
- (apply_flags & NO_RESTACK_X_WINDOWS) != 0)
- return FALSE;
-
- old_pos = find_window (stack, op->add.window);
- if (old_pos >= 0)
- {
- meta_topic (META_DEBUG_STACK,
- "STACK_OP_ADD: window %s already in stack",
- get_window_desc (tracker, op->add.window));
- return FALSE;
- }
-
- g_array_append_val (stack, op->add.window);
- return TRUE;
- }
- case STACK_OP_REMOVE:
- {
- int old_pos;
-
- if (META_STACK_ID_IS_X11 (op->remove.window) &&
- (apply_flags & NO_RESTACK_X_WINDOWS) != 0)
- return FALSE;
-
- old_pos = find_window (stack, op->remove.window);
- if (old_pos < 0)
- {
- meta_topic (META_DEBUG_STACK,
- "STACK_OP_REMOVE: window %s not in stack",
- get_window_desc (tracker, op->remove.window));
- return FALSE;
- }
-
- g_array_remove_index (stack, old_pos);
- return TRUE;
- }
- case STACK_OP_RAISE_ABOVE:
- {
- int old_pos;
- int above_pos;
-
- old_pos = find_window (stack, op->raise_above.window);
- if (old_pos < 0)
- {
- meta_topic (META_DEBUG_STACK,
- "STACK_OP_RAISE_ABOVE: window %s not in stack",
- get_window_desc (tracker, op->raise_above.window));
- return FALSE;
- }
-
- if (op->raise_above.sibling)
- {
- above_pos = find_window (stack, op->raise_above.sibling);
- if (above_pos < 0)
- {
- meta_topic (META_DEBUG_STACK,
- "STACK_OP_RAISE_ABOVE: sibling window %s not in stack",
- get_window_desc (tracker, op->raise_above.sibling));
- return FALSE;
- }
- }
- else
- {
- above_pos = -1;
- }
-
- return move_window_above (stack, op->raise_above.window, old_pos, above_pos,
- apply_flags);
- }
- case STACK_OP_LOWER_BELOW:
- {
- int old_pos;
- int above_pos;
-
- old_pos = find_window (stack, op->raise_above.window);
- if (old_pos < 0)
- {
- meta_topic (META_DEBUG_STACK,
- "STACK_OP_LOWER_BELOW: window %s not in stack",
- get_window_desc (tracker, op->lower_below.window));
- return FALSE;
- }
-
- if (op->lower_below.sibling)
- {
- int below_pos;
-
- below_pos = find_window (stack, op->lower_below.sibling);
- if (below_pos < 0)
- {
- meta_topic (META_DEBUG_STACK,
- "STACK_OP_LOWER_BELOW: sibling window %s not in stack",
- get_window_desc (tracker, op->lower_below.sibling));
- return FALSE;
- }
-
- above_pos = below_pos - 1;
- }
- else
- {
- above_pos = stack->len - 1;
- }
-
- return move_window_above (stack, op->lower_below.window, old_pos, above_pos,
- apply_flags);
- }
- }
-
- g_assert_not_reached ();
- return FALSE;
-}
-
-static GArray *
-copy_stack (GArray *stack)
-{
- GArray *copy = g_array_sized_new (FALSE, FALSE, sizeof (guint64), stack->len);
-
- g_array_set_size (copy, stack->len);
-
- memcpy (copy->data, stack->data, sizeof (guint64) * stack->len);
-
- return copy;
-}
-
-static void
-query_xserver_stack (MetaDisplay *display,
- MetaStackTracker *tracker)
-{
- MetaX11Display *x11_display = display->x11_display;
- Window ignored1, ignored2;
- Window *children;
- guint n_children;
- guint i, old_len;
-
- tracker->xserver_serial = XNextRequest (x11_display->xdisplay);
-
- XQueryTree (x11_display->xdisplay,
- x11_display->xroot,
- &ignored1, &ignored2, &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);
-
- 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;
-}
-
-void
-meta_stack_tracker_free (MetaStackTracker *tracker)
-{
- if (tracker->sync_stack_later)
- meta_later_remove (tracker->sync_stack_later);
-
- g_array_free (tracker->verified_stack, TRUE);
- if (tracker->predicted_stack)
- g_array_free (tracker->predicted_stack, TRUE);
-
- 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);
-
- g_free (tracker);
-}
-
-static void
-stack_tracker_apply_prediction (MetaStackTracker *tracker,
- MetaStackOp *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: ", "");
- g_queue_push_tail (tracker->unverified_predictions, op);
- }
-
- if (!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);
-}
-
-void
-meta_stack_tracker_record_add (MetaStackTracker *tracker,
- guint64 window,
- gulong serial)
-{
- MetaStackOp *op = g_new0 (MetaStackOp, 1);
-
- op->any.type = STACK_OP_ADD;
- op->any.serial = serial;
- op->any.window = window;
-
- stack_tracker_apply_prediction (tracker, op);
-}
-
-void
-meta_stack_tracker_record_remove (MetaStackTracker *tracker,
- guint64 window,
- gulong serial)
-{
- MetaStackOp *op = g_new0 (MetaStackOp, 1);
-
- op->any.type = STACK_OP_REMOVE;
- op->any.serial = serial;
- op->any.window = window;
-
- stack_tracker_apply_prediction (tracker, op);
-}
-
-static void
-meta_stack_tracker_record_raise_above (MetaStackTracker *tracker,
- guint64 window,
- guint64 sibling,
- gulong serial)
-{
- MetaStackOp *op = g_new0 (MetaStackOp, 1);
-
- op->any.type = STACK_OP_RAISE_ABOVE;
- op->any.serial = serial;
- op->any.window = window;
- op->raise_above.sibling = sibling;
-
- stack_tracker_apply_prediction (tracker, op);
-}
-
-static void
-meta_stack_tracker_record_lower_below (MetaStackTracker *tracker,
- guint64 window,
- guint64 sibling,
- gulong serial)
-{
- MetaStackOp *op = g_new0 (MetaStackOp, 1);
-
- op->any.type = STACK_OP_LOWER_BELOW;
- op->any.serial = serial;
- op->any.window = window;
- op->lower_below.sibling = sibling;
-
- stack_tracker_apply_prediction (tracker, op);
-}
-
-static void
-stack_tracker_event_received (MetaStackTracker *tracker,
- MetaStackOp *op)
-{
- gboolean need_sync = FALSE;
-
- /* 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;
-
- meta_stack_op_dump (tracker, op, "Stack op event received: ", "");
-
- /* 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;
- }
-
- /* 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;
-
- /* 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->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 (need_sync)
- {
- if (tracker->predicted_stack)
- {
- g_array_free (tracker->predicted_stack, TRUE);
- tracker->predicted_stack = NULL;
- }
-
- meta_stack_tracker_queue_sync_stack (tracker);
- }
-
- meta_stack_tracker_dump (tracker);
-}
-
-void
-meta_stack_tracker_create_event (MetaStackTracker *tracker,
- XCreateWindowEvent *event)
-{
- MetaStackOp op;
-
- op.any.type = STACK_OP_ADD;
- op.any.serial = event->serial;
- op.add.window = event->window;
-
- stack_tracker_event_received (tracker, &op);
-}
-
-void
-meta_stack_tracker_destroy_event (MetaStackTracker *tracker,
- XDestroyWindowEvent *event)
-{
- MetaStackOp op;
-
- op.any.type = STACK_OP_REMOVE;
- op.any.serial = event->serial;
- op.remove.window = event->window;
-
- stack_tracker_event_received (tracker, &op);
-}
-
-void
-meta_stack_tracker_reparent_event (MetaStackTracker *tracker,
- XReparentEvent *event)
-{
- if (event->parent == event->event)
- {
- MetaStackOp op;
-
- op.any.type = STACK_OP_ADD;
- op.any.serial = event->serial;
- op.add.window = event->window;
-
- stack_tracker_event_received (tracker, &op);
- }
- else
- {
- MetaStackOp op;
-
- op.any.type = STACK_OP_REMOVE;
- op.any.serial = event->serial;
- op.remove.window = event->window;
-
- stack_tracker_event_received (tracker, &op);
- }
-}
-
-void
-meta_stack_tracker_configure_event (MetaStackTracker *tracker,
- XConfigureEvent *event)
-{
- MetaStackOp op;
-
- op.any.type = STACK_OP_RAISE_ABOVE;
- op.any.serial = event->serial;
- op.raise_above.window = event->window;
- op.raise_above.sibling = event->above;
-
- 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
- *
- * @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
- * objects, others won't.
- *
- * Assuming that no other clients have made requests that change
- * the stacking order since we last received a notification, the
- * returned list of windows is exactly that you'd get as the
- * children when calling XQueryTree() on the root window.
- */
-void
-meta_stack_tracker_get_stack (MetaStackTracker *tracker,
- guint64 **windows,
- int *n_windows)
-{
- GArray *stack;
-
- if (tracker->unverified_predictions->length == 0)
- {
- stack = tracker->verified_stack;
- }
- else
- {
- if (tracker->predicted_stack == NULL)
- {
- GList *l;
-
- 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 (tracker, op, tracker->predicted_stack, APPLY_DEFAULT);
- }
- }
-
- stack = tracker->predicted_stack;
- }
-
- if (windows)
- *windows = (guint64 *)stack->data;
- if (n_windows)
- *n_windows = stack->len;
-}
-
-/**
- * meta_stack_tracker_sync_stack:
- * @tracker: a #MetaStackTracker
- *
- * Informs the compositor of the current stacking order of windows,
- * based on the predicted view maintained by the #MetaStackTracker.
- */
-void
-meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
-{
- guint64 *windows;
- GList *meta_windows;
- int n_windows;
- int i;
-
- if (tracker->sync_stack_later)
- {
- meta_later_remove (tracker->sync_stack_later);
- 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++)
- {
- 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_display_restacked (tracker->display);
-}
-
-static gboolean
-stack_tracker_sync_stack_later (gpointer data)
-{
- meta_stack_tracker_sync_stack (data);
-
- return FALSE;
-}
-
-/**
- * meta_stack_tracker_queue_sync_stack:
- * @tracker: a #MetaStackTracker
- *
- * Queue informing the compositor of the new stacking order before the
- * next redraw. (See meta_stack_tracker_sync_stack()). This is called
- * internally when the stack of X windows changes, but also needs be
- * called directly when we an undecorated window is first shown or
- * withdrawn since the compositor's stacking order (which contains only
- * the windows that have a corresponding MetaWindow) will change without
- * any change to the stacking order of the X windows, if we are creating
- * or destroying MetaWindows.
- */
-void
-meta_stack_tracker_queue_sync_stack (MetaStackTracker *tracker)
-{
- if (tracker->sync_stack_later == 0)
- {
- tracker->sync_stack_later = meta_later_add (META_LATER_SYNC_STACK,
- stack_tracker_sync_stack_later,
- tracker, NULL);
- }
-}
-
-/* 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;
-
- COGL_TRACE_BEGIN_SCOPED (StackTrackerRestackManaged,
- "StackTracker: Restack Managed");
- if (n_managed == 0)
- return;
-
- COGL_TRACE_BEGIN (StackTrackerRestackManagedGet,
- "StackTracker: Restack Managed (get)");
- 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);
- COGL_TRACE_END (StackTrackerRestackManagedGet);
-
- COGL_TRACE_BEGIN (StackTrackerRestackManagedRaise,
- "StackTracker: Restack Managed (raise)");
- 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 */
- }
- COGL_TRACE_END (StackTrackerRestackManagedRaise);
-
- old_pos--;
- new_pos--;
-
- COGL_TRACE_BEGIN (StackTrackerRestackManagedRestack,
- "StackTracker: Restack Managed (restack)");
- 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--;
- }
- COGL_TRACE_END (StackTrackerRestackManagedRestack);
-
- COGL_TRACE_BEGIN (StackTrackerRestackManagedLower,
- "StackTracker: Restack Managed (lower)");
- while (new_pos > 0)
- {
- meta_stack_tracker_lower_below (tracker, managed[new_pos], managed[new_pos - 1]);
- new_pos--;
- }
- COGL_TRACE_END (StackTrackerRestackManagedLower);
-}
-
-void
-meta_stack_tracker_restack_at_bottom (MetaStackTracker *tracker,
- const guint64 *new_order,
- int n_new_order)
-{
- guint64 *windows;
- int n_windows;
- int pos;
-
- COGL_TRACE_BEGIN_SCOPED (StackTrackerRestackAtBottom,
- "Stack tracker: Restack at bottom");
- 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
deleted file mode 100644
index dbffb0e5e..000000000
--- a/src/core/stack-tracker.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file stack-tracker.h 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.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_STACK_TRACKER_H
-#define META_STACK_TRACKER_H
-
-#include "core/util-private.h"
-#include "meta/display.h"
-#include "meta/window.h"
-
-typedef struct _MetaStackTracker MetaStackTracker;
-
-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,
- guint64 window,
- gulong serial);
-void meta_stack_tracker_record_remove (MetaStackTracker *tracker,
- 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,
- XCreateWindowEvent *event);
-void meta_stack_tracker_destroy_event (MetaStackTracker *tracker,
- XDestroyWindowEvent *event);
-void meta_stack_tracker_reparent_event (MetaStackTracker *tracker,
- XReparentEvent *event);
-void meta_stack_tracker_configure_event (MetaStackTracker *tracker,
- XConfigureEvent *event);
-
-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);
-
-#endif /* META_STACK_TRACKER_H */
diff --git a/src/core/stack.c b/src/core/stack.c
deleted file mode 100644
index 62b8954e8..000000000
--- a/src/core/stack.c
+++ /dev/null
@@ -1,1340 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * SECTION:stack
- * @short_description: Which windows cover which other windows
- */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2002, 2003 Red Hat, Inc.
- * Copyright (C) 2004 Rob Adams
- * 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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/stack.h"
-
-#include "backends/meta-logical-monitor.h"
-#include "cogl/cogl.h"
-#include "core/frame.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) \
- (meta_window_has_transient_type (w) && w->transient_for == NULL)
-
-static void meta_window_set_stack_position_no_sync (MetaWindow *window,
- int position);
-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);
-
-enum
-{
- PROP_DISPLAY = 1,
- N_PROPS
-};
-
-enum
-{
- CHANGED,
- WINDOW_ADDED,
- WINDOW_REMOVED,
- N_SIGNALS
-};
-
-static GParamSpec *pspecs[N_PROPS] = { 0 };
-static guint signals[N_SIGNALS] = { 0 };
-
-G_DEFINE_TYPE (MetaStack, meta_stack, G_TYPE_OBJECT)
-
-static void
-on_stack_changed (MetaStack *stack)
-{
- MetaDisplay *display = stack->display;
- GArray *all_root_children_stacked;
- GList *l;
- GArray *hidden_stack_ids;
- GList *sorted;
-
- COGL_TRACE_BEGIN_SCOPED (StackChanged, "Stack changed");
-
- meta_topic (META_DEBUG_STACK, "Syncing window stack to server");
-
- 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_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 */
-
- meta_topic (META_DEBUG_STACK, "Restacking %u windows",
- 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);
-}
-
-static void
-meta_stack_init (MetaStack *stack)
-{
- 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_OBJECT_CLASS (meta_stack_parent_class)->finalize (object);
-}
-
-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);
- }
-}
-
-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;
-
- COGL_TRACE_BEGIN_SCOPED (MetaStackChangedSort, "Stack: Changed");
-
- 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", window->desc);
-
- if (meta_window_is_in_stack (window))
- meta_bug ("Window %s had stack position already", window->desc);
-
- 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;
- meta_topic (META_DEBUG_STACK,
- "Window %s has stack_position initialized to %d",
- window->desc, window->stack_position);
-
- meta_stack_changed (stack);
- meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace);
-}
-
-void
-meta_stack_remove (MetaStack *stack,
- MetaWindow *window)
-{
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
-
- COGL_TRACE_BEGIN_SCOPED (MetaStackRemove,
- "Stack (remove window)");
-
- meta_topic (META_DEBUG_STACK, "Removing window %s from the stack", window->desc);
-
- /* Set window to top position, so removing it will not leave gaps
- * in the set of positions
- */
- meta_window_set_stack_position_no_sync (window,
- stack->n_positions - 1);
- window->stack_position = -1;
- stack->n_positions -= 1;
-
- stack->sorted = g_list_remove (stack->sorted, window);
-
- g_signal_emit (stack, signals[WINDOW_REMOVED], 0, window);
-
- meta_stack_changed (stack);
- meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace);
-}
-
-void
-meta_stack_update_layer (MetaStack *stack,
- MetaWindow *window)
-{
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
- stack->need_relayer = TRUE;
-
- meta_stack_changed (stack);
- meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace);
-}
-
-void
-meta_stack_update_transient (MetaStack *stack,
- MetaWindow *window)
-{
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
- stack->need_constrain = TRUE;
-
- meta_stack_changed (stack);
- meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace);
-}
-
-/* raise/lower within a layer */
-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;
-
- stack_ensure_sorted (stack);
-
- workspace = meta_window_get_workspace (window);
- for (l = stack->sorted; l; l = l->next)
- {
- MetaWindow *w = (MetaWindow *) l->data;
- if (meta_window_located_on_workspace (w, workspace) &&
- w->stack_position > max_stack_position)
- max_stack_position = w->stack_position;
- }
-
- if (max_stack_position == window->stack_position)
- return;
-
- meta_window_set_stack_position_no_sync (window, max_stack_position);
-
- meta_stack_changed (stack);
- meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace);
-}
-
-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;
-
- stack_ensure_sorted (stack);
-
- workspace = meta_window_get_workspace (window);
- for (l = stack->sorted; l; l = l->next)
- {
- MetaWindow *w = (MetaWindow *) l->data;
- if (meta_window_located_on_workspace (w, workspace) &&
- w->stack_position < min_stack_position)
- min_stack_position = w->stack_position;
- }
-
- if (min_stack_position == window->stack_position)
- return;
-
- meta_window_set_stack_position_no_sync (window, min_stack_position);
-
- meta_stack_changed (stack);
- meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace);
-}
-
-void
-meta_stack_freeze (MetaStack *stack)
-{
- stack->freeze_count += 1;
-}
-
-void
-meta_stack_thaw (MetaStack *stack)
-{
- g_return_if_fail (stack->freeze_count > 0);
-
- stack->freeze_count -= 1;
- meta_stack_changed (stack);
- meta_stack_update_window_tile_matches (stack, NULL);
-}
-
-void
-meta_stack_update_window_tile_matches (MetaStack *stack,
- MetaWorkspace *workspace)
-{
- GList *windows, *tmp;
-
- if (stack->freeze_count > 0)
- return;
-
- windows = meta_stack_list_windows (stack, workspace);
- tmp = windows;
- while (tmp)
- {
- meta_window_compute_tile_match ((MetaWindow *) tmp->data);
- tmp = tmp->next;
- }
-
- g_list_free (windows);
-}
-
-/* Front of the layer list is the topmost window,
- * so the lower stack position is later in the list
- */
-static int
-compare_window_position (void *a,
- void *b)
-{
- MetaWindow *window_a = a;
- MetaWindow *window_b = b;
-
- /* Go by layer, then stack_position */
- if (window_a->layer < window_b->layer)
- return 1; /* move window_a later in list */
- else if (window_a->layer > window_b->layer)
- return -1;
- else if (window_a->stack_position < window_b->stack_position)
- return 1; /* move window_a later in list */
- else if (window_a->stack_position > window_b->stack_position)
- return -1;
- else
- return 0; /* not reached */
-}
-
-/*
- * Stacking constraints
- *
- * Assume constraints of the form "AB" meaning "window A must be
- * below window B"
- *
- * If we have windows stacked from bottom to top
- * "ABC" then raise A we get "BCA". Say C is
- * transient for B is transient for A. So
- * we have constraints AB and BC.
- *
- * After raising A, we need to reapply the constraints.
- * If we do this by raising one window at a time -
- *
- * start: BCA
- * apply AB: CAB
- * apply BC: ABC
- *
- * but apply constraints in the wrong order and it breaks:
- *
- * start: BCA
- * apply BC: BCA
- * apply AB: CAB
- *
- * We make a directed graph of the constraints by linking
- * from "above windows" to "below windows as follows:
- *
- * AB -> BC -> CD
- * \
- * CE
- *
- * If we then walk that graph and apply the constraints in the order
- * that they appear, we will apply them correctly. Note that the
- * graph MAY have cycles, so we have to guard against that.
- *
- */
-
-typedef struct Constraint Constraint;
-
-struct Constraint
-{
- MetaWindow *above;
- MetaWindow *below;
-
- /* used to keep the constraint in the
- * list of constraints for window "below"
- */
- Constraint *next;
-
- /* used to create the graph. */
- GSList *next_nodes;
-
- /* constraint has been applied, used
- * to detect cycles.
- */
- unsigned int applied : 1;
-
- /* constraint has a previous node in the graph,
- * used to find places to start in the graph.
- * (I think this also has the side effect
- * of preventing cycles, since cycles will
- * have no starting point - so maybe
- * the "applied" flag isn't needed.)
- */
- unsigned int has_prev : 1;
-};
-
-/* We index the array of constraints by window
- * stack positions, just because the stack
- * positions are a convenient index.
- */
-static void
-add_constraint (Constraint **constraints,
- MetaWindow *above,
- MetaWindow *below)
-{
- Constraint *c;
-
- /* check if constraint is a duplicate */
- c = constraints[below->stack_position];
- while (c != NULL)
- {
- if (c->above == above)
- return;
- c = c->next;
- }
-
- /* if not, add the constraint */
- c = g_new (Constraint, 1);
- c->above = above;
- c->below = below;
- c->next = constraints[below->stack_position];
- c->next_nodes = NULL;
- c->applied = FALSE;
- c->has_prev = FALSE;
-
- constraints[below->stack_position] = c;
-}
-
-static void
-create_constraints (Constraint **constraints,
- GList *windows)
-{
- GList *tmp;
-
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- if (!meta_window_is_in_stack (w))
- {
- meta_topic (META_DEBUG_STACK, "Window %s not in the stack, not constraining it",
- w->desc);
- tmp = tmp->next;
- continue;
- }
-
- if (WINDOW_TRANSIENT_FOR_WHOLE_GROUP (w))
- {
- GSList *group_windows;
- GSList *tmp2;
- MetaGroup *group;
-
- group = meta_window_get_group (w);
-
- if (group != NULL)
- group_windows = meta_group_list_windows (group);
- else
- group_windows = NULL;
-
- tmp2 = group_windows;
-
- while (tmp2 != NULL)
- {
- MetaWindow *group_window = tmp2->data;
-
- if (!meta_window_is_in_stack (group_window) ||
- group_window->override_redirect)
- {
- tmp2 = tmp2->next;
- continue;
- }
-
-#if 0
- /* old way of doing it */
- if (!(meta_window_is_ancestor_of_transient (w, group_window)) &&
- !WINDOW_TRANSIENT_FOR_WHOLE_GROUP (group_window)) /* note */;/*note*/
-#else
- /* better way I think, so transient-for-group are constrained
- * only above non-transient-type windows in their group
- */
- 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",
- w->desc, group_window->desc);
- add_constraint (constraints, w, group_window);
- }
-
- tmp2 = tmp2->next;
- }
-
- g_slist_free (group_windows);
- }
- else if (w->transient_for != NULL)
- {
- MetaWindow *parent;
-
- parent = w->transient_for;
-
- if (parent && meta_window_is_in_stack (parent))
- {
- meta_topic (META_DEBUG_STACK,
- "Constraining %s above %s due to transiency",
- w->desc, parent->desc);
- add_constraint (constraints, w, parent);
- }
- }
-
- tmp = tmp->next;
- }
-}
-
-static void
-graph_constraints (Constraint **constraints,
- int n_constraints)
-{
- int i;
-
- i = 0;
- while (i < n_constraints)
- {
- Constraint *c;
-
- /* If we have "A below B" and "B below C" then AB -> BC so we
- * add BC to next_nodes in AB.
- */
-
- c = constraints[i];
- while (c != NULL)
- {
- Constraint *n;
-
- g_assert (c->below->stack_position == i);
-
- /* Constraints where ->above is below are our
- * next_nodes and we are their previous
- */
- n = constraints[c->above->stack_position];
- while (n != NULL)
- {
- c->next_nodes = g_slist_prepend (c->next_nodes,
- n);
- /* c is a previous node of n */
- n->has_prev = TRUE;
-
- n = n->next;
- }
-
- c = c->next;
- }
-
- ++i;
- }
-}
-
-static void
-free_constraints (Constraint **constraints,
- int n_constraints)
-{
- int i;
-
- i = 0;
- while (i < n_constraints)
- {
- Constraint *c;
-
- c = constraints[i];
- while (c != NULL)
- {
- Constraint *next = c->next;
-
- g_slist_free (c->next_nodes);
-
- g_free (c);
-
- c = next;
- }
-
- ++i;
- }
-}
-
-static void
-ensure_above (MetaWindow *above,
- MetaWindow *below)
-{
- 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 constraint",
- above->desc, above->layer, below->layer);
- above->layer = below->layer;
- }
-
- if (above->stack_position < below->stack_position)
- {
- /* move above to below->stack_position bumping below down the stack */
- meta_window_set_stack_position_no_sync (above, below->stack_position);
- g_assert (below->stack_position + 1 == above->stack_position);
- }
- meta_topic (META_DEBUG_STACK, "%s above at %d > %s below at %d",
- above->desc, above->stack_position,
- below->desc, below->stack_position);
-}
-
-static void
-traverse_constraint (Constraint *c)
-{
- GSList *tmp;
-
- if (c->applied)
- return;
-
- ensure_above (c->above, c->below);
- c->applied = TRUE;
-
- tmp = c->next_nodes;
- while (tmp != NULL)
- {
- traverse_constraint (tmp->data);
-
- tmp = tmp->next;
- }
-}
-
-static void
-apply_constraints (Constraint **constraints,
- int n_constraints)
-{
- GSList *heads;
- GSList *tmp;
- int i;
-
- /* List all heads in an ordered constraint chain */
- heads = NULL;
- i = 0;
- while (i < n_constraints)
- {
- Constraint *c;
-
- c = constraints[i];
- while (c != NULL)
- {
- if (!c->has_prev)
- heads = g_slist_prepend (heads, c);
-
- c = c->next;
- }
-
- ++i;
- }
-
- /* Now traverse the chain and apply constraints */
- tmp = heads;
- while (tmp != NULL)
- {
- Constraint *c = tmp->data;
-
- traverse_constraint (c);
-
- tmp = tmp->next;
- }
-
- g_slist_free (heads);
-}
-
-/**
- * stack_do_relayer:
- *
- * Update the layers that windows are in
- */
-static void
-stack_do_relayer (MetaStack *stack)
-{
- GList *tmp;
-
- if (!stack->need_relayer)
- return;
-
- meta_topic (META_DEBUG_STACK,
- "Recomputing layers");
-
- tmp = stack->sorted;
-
- while (tmp != NULL)
- {
- MetaWindow *w;
- MetaStackLayer old_layer;
-
- w = tmp->data;
- old_layer = w->layer;
-
- w->layer = meta_window_calculate_layer (w);
-
- if (w->layer != old_layer)
- {
- meta_topic (META_DEBUG_STACK,
- "Window %s moved from layer %u to %u",
- w->desc, old_layer, w->layer);
- stack->need_resort = TRUE;
- stack->need_constrain = TRUE;
- /* don't need to constrain as constraining
- * purely operates in terms of stack_position
- * not layer
- */
- }
-
- tmp = tmp->next;
- }
-
- stack->need_relayer = FALSE;
-}
-
-/**
- * stack_do_constrain:
- *
- * Update stack_position and layer to reflect transiency
- * constraints
- */
-static void
-stack_do_constrain (MetaStack *stack)
-{
- Constraint **constraints;
-
- /* It'd be nice if this were all faster, probably */
-
- if (!stack->need_constrain)
- return;
-
- meta_topic (META_DEBUG_STACK,
- "Reapplying constraints");
-
- constraints = g_new0 (Constraint*,
- stack->n_positions);
-
- create_constraints (constraints, stack->sorted);
-
- graph_constraints (constraints, stack->n_positions);
-
- apply_constraints (constraints, stack->n_positions);
-
- free_constraints (constraints, stack->n_positions);
- g_free (constraints);
-
- stack->need_constrain = FALSE;
-}
-
-/**
- * stack_do_resort:
- *
- * Sort stack->sorted with layers having priority over stack_position.
- */
-static void
-stack_do_resort (MetaStack *stack)
-{
- if (!stack->need_resort)
- return;
-
- meta_topic (META_DEBUG_STACK,
- "Sorting stack list");
-
- stack->sorted = g_list_sort (stack->sorted,
- (GCompareFunc) compare_window_position);
-
- 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
- * all the layers (if the flag is set), re-run all the constraint calculations
- * (if the flag is set), and finally re-sort the stack (if the flag is set,
- * and if it wasn't already it might have become so during all the previous
- * activity).
- */
-static void
-stack_ensure_sorted (MetaStack *stack)
-{
- stack_do_relayer (stack);
- stack_do_constrain (stack);
- stack_do_resort (stack);
-}
-
-MetaWindow *
-meta_stack_get_top (MetaStack *stack)
-{
- stack_ensure_sorted (stack);
-
- if (stack->sorted)
- return stack->sorted->data;
- else
- return NULL;
-}
-
-MetaWindow *
-meta_stack_get_bottom (MetaStack *stack)
-{
- GList *link;
-
- stack_ensure_sorted (stack);
-
- link = g_list_last (stack->sorted);
- if (link != NULL)
- return link->data;
- else
- return NULL;
-}
-
-MetaWindow *
-meta_stack_get_above (MetaStack *stack,
- MetaWindow *window,
- gboolean only_within_layer)
-{
- GList *link;
- MetaWindow *above;
-
- stack_ensure_sorted (stack);
-
- link = g_list_find (stack->sorted, window);
- if (link == NULL)
- return NULL;
- if (link->prev == NULL)
- return NULL;
-
- above = link->prev->data;
-
- if (only_within_layer &&
- above->layer != window->layer)
- return NULL;
- else
- return above;
-}
-
-MetaWindow *
-meta_stack_get_below (MetaStack *stack,
- MetaWindow *window,
- gboolean only_within_layer)
-{
- GList *link;
- MetaWindow *below;
-
- stack_ensure_sorted (stack);
-
- link = g_list_find (stack->sorted, window);
-
- if (link == NULL)
- return NULL;
- if (link->next == NULL)
- return NULL;
-
- below = link->next->data;
-
- if (only_within_layer &&
- below->layer != window->layer)
- return NULL;
- else
- return below;
-}
-
-static gboolean
-window_contains_point (MetaWindow *window,
- int root_x,
- int root_y)
-{
- MetaRectangle rect;
-
- meta_window_get_frame_rect (window, &rect);
-
- return META_POINT_IN_RECT (root_x, root_y, rect);
-}
-
-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,
- gboolean must_be_at_point,
- int root_x,
- int root_y)
-{
- /* Find the topmost, focusable, mapped, window.
- * not_this_one is being unfocused or going away, so exclude it.
- */
-
- GList *l;
-
- stack_ensure_sorted (stack);
-
- /* top of this layer is at the front of the list */
- for (l = stack->sorted; l != NULL; l = l->next)
- {
- MetaWindow *window = l->data;
-
- if (!window)
- continue;
-
- if (window == not_this_one)
- continue;
-
- if (!window_can_get_default_focus (window))
- continue;
-
- if (must_be_at_point && !window_contains_point (window, root_x, root_y))
- continue;
-
- return window;
- }
-
- return NULL;
-}
-
-MetaWindow *
-meta_stack_get_default_focus_window_at_point (MetaStack *stack,
- MetaWorkspace *workspace,
- MetaWindow *not_this_one,
- int root_x,
- int root_y)
-{
- return get_default_focus_window (stack, workspace, not_this_one,
- TRUE, root_x, root_y);
-}
-
-MetaWindow *
-meta_stack_get_default_focus_window (MetaStack *stack,
- MetaWorkspace *workspace,
- MetaWindow *not_this_one)
-{
- return get_default_focus_window (stack, workspace, not_this_one,
- FALSE, 0, 0);
-}
-
-GList *
-meta_stack_list_windows (MetaStack *stack,
- MetaWorkspace *workspace)
-{
- GList *workspace_windows = NULL;
- GList *link;
-
- stack_ensure_sorted (stack); /* do adds/removes */
-
- link = stack->sorted;
-
- while (link)
- {
- MetaWindow *window = link->data;
-
- if (window &&
- (workspace == NULL || meta_window_located_on_workspace (window, workspace)))
- {
- workspace_windows = g_list_prepend (workspace_windows,
- window);
- }
-
- link = link->next;
- }
-
- return workspace_windows;
-}
-
-GList *
-meta_stack_get_default_focus_candidates (MetaStack *stack,
- MetaWorkspace *workspace)
-{
- 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 */
-
- if (window_a->layer < window_b->layer)
- return -1;
- else if (window_a->layer > window_b->layer)
- return 1;
- else if (window_a->stack_position < window_b->stack_position)
- return -1;
- else if (window_a->stack_position > window_b->stack_position)
- return 1;
- else
- return 0; /* not reached */
-}
-
-static int
-compare_just_window_stack_position (void *a,
- void *b)
-{
- MetaWindow *window_a = a;
- MetaWindow *window_b = b;
-
- if (window_a->stack_position < window_b->stack_position)
- return -1; /* move window_a earlier in list */
- else if (window_a->stack_position > window_b->stack_position)
- return 1;
- else
- return 0; /* not reached */
-}
-
-GList *
-meta_stack_get_positions (MetaStack *stack)
-{
- GList *tmp;
-
- /* Make sure to handle any adds or removes */
- stack_ensure_sorted (stack);
-
- tmp = g_list_copy (stack->sorted);
- tmp = g_list_sort (tmp, (GCompareFunc) compare_just_window_stack_position);
-
- return tmp;
-}
-
-static gint
-compare_pointers (gconstpointer a,
- gconstpointer b)
-{
- if (a > b)
- return 1;
- else if (a < b)
- return -1;
- else
- return 0;
-}
-
-static gboolean
-lists_contain_same_windows (GList *a,
- GList *b)
-{
- GList *copy1, *copy2;
- GList *tmp1, *tmp2;
-
- if (g_list_length (a) != g_list_length (b))
- return FALSE;
-
- tmp1 = copy1 = g_list_sort (g_list_copy (a), compare_pointers);
- tmp2 = copy2 = g_list_sort (g_list_copy (b), compare_pointers);
-
- while (tmp1 && tmp1->data == tmp2->data) /* tmp2 is non-NULL if tmp1 is */
- {
- tmp1 = tmp1->next;
- tmp2 = tmp2->next;
- }
-
- g_list_free (copy1);
- g_list_free (copy2);
-
- return (tmp1 == NULL); /* tmp2 is non-NULL if tmp1 is */
-}
-
-void
-meta_stack_set_positions (MetaStack *stack,
- GList *windows)
-{
- int i;
- GList *tmp;
-
- /* Make sure any adds or removes aren't in limbo -- is this needed? */
- stack_ensure_sorted (stack);
-
- if (!lists_contain_same_windows (windows, stack->sorted))
- {
- meta_warning ("This list of windows has somehow changed; not resetting "
- "positions of the windows.");
- return;
- }
-
- g_list_free (stack->sorted);
- stack->sorted = g_list_copy (windows);
-
- stack->need_resort = TRUE;
- stack->need_constrain = TRUE;
-
- i = 0;
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
- w->stack_position = i++;
- tmp = tmp->next;
- }
-
- meta_topic (META_DEBUG_STACK,
- "Reset the stack positions of (nearly) all windows");
-
- meta_stack_changed (stack);
- meta_stack_update_window_tile_matches (stack, NULL);
-}
-
-void
-meta_window_set_stack_position_no_sync (MetaWindow *window,
- int position)
-{
- int low, high, delta;
- GList *tmp;
-
- 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->display->stack->n_positions);
-
- if (position == window->stack_position)
- {
- meta_topic (META_DEBUG_STACK, "Window %s already has position %d",
- window->desc, position);
- return;
- }
-
- window->display->stack->need_resort = TRUE;
- window->display->stack->need_constrain = TRUE;
-
- if (position < window->stack_position)
- {
- low = position;
- high = window->stack_position - 1;
- delta = 1;
- }
- else
- {
- low = window->stack_position + 1;
- high = position;
- delta = -1;
- }
-
- tmp = window->display->stack->sorted;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- if (w->stack_position >= low &&
- w->stack_position <= high)
- w->stack_position += delta;
-
- tmp = tmp->next;
- }
-
- window->stack_position = position;
-
- meta_topic (META_DEBUG_STACK,
- "Window %s had stack_position set to %d",
- window->desc, window->stack_position);
-}
-
-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);
- 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
deleted file mode 100644
index ec5753fe7..000000000
--- a/src/core/stack.h
+++ /dev/null
@@ -1,406 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * 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_STACK_H
-#define META_STACK_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
- * windows on the X server.
- *
- * (This is only used as a field within a MetaScreen; we treat it as a separate
- * class for simplicity.)
- */
-struct _MetaStack
-{
- GObject parent;
-
- /** The MetaDisplay containing this stack. */
- MetaDisplay *display;
-
- /** The MetaWindows of the windows we manage, sorted in order. */
- GList *sorted;
-
- /**
- * 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.
- * If it is positive, the local stack is said to be "frozen", and will need
- * to be thawed that many times before the stack can be brought up to date
- * again. You may freeze the stack with meta_stack_freeze() and thaw it
- * with meta_stack_thaw().
- */
- int freeze_count;
-
- /**
- * 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_all_root_children_stacked;
-
- /**
- * Number of stack positions; same as the length of added, but
- * kept for quick reference.
- */
- gint n_positions;
-
- /** Is the stack in need of re-sorting? */
- unsigned int need_resort : 1;
-
- /**
- * Are the windows in the stack in need of having their
- * layers recalculated?
- */
- unsigned int need_relayer : 1;
-
- /**
- * Are the windows in the stack in need of having their positions
- * recalculated with respect to transiency (parent and child windows)?
- */
- 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.
- *
- * Returns: The new stack.
- */
-MetaStack * meta_stack_new (MetaDisplay *display);
-
-/**
- * meta_stack_add:
- * @stack: The stack to add it to
- * @window: The window to add
- *
- * 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.
- */
-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.
- */
-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.
- *
- */
-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.
- *
- * FIXME: What's with the dummy parameter?
- */
-void meta_stack_update_transient (MetaStack *stack,
- MetaWindow *window);
-
-/**
- * meta_stack_raise:
- * @stack: The stack to modify.
- * @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);
-/**
- * meta_stack_lower:
- * @stack: The stack to modify.
- * @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);
-
-/**
- * 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().)
- */
-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.
- */
-void meta_stack_thaw (MetaStack *stack);
-
-/**
- * meta_stack_get_top:
- * @stack: The stack to examine.
- *
- * Finds the top window on the stack.
- *
- * 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);
-
-/**
- * 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.
- */
-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.
- *
- * Returns: %NULL if there is no such window;
- * the window above @window otherwise.
- */
-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.
- *
- *
- * Returns: %NULL if there is no such window;
- * the window below @window otherwise.
- */
-MetaWindow * meta_stack_get_below (MetaStack *stack,
- MetaWindow *window,
- gboolean only_within_layer);
-
-/**
- * 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.
- *
- * 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);
-
-/**
- * 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 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.
- *
- * 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.
- */
-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.
- *
- * 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);
-
-/**
- * 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.
- *
- * (FIXME: We could remove the stack parameter and use the stack of
- * the screen of window A, and complain if the stack of the screen of
- * window B differed; then this would be a usable general comparison function.)
- *
- * (FIXME: Apparently identical to compare_window_position(). Merge them.)
- *
- * \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);
-
-/**
- * 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).
- */
-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.
- *
- * 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);
-
-/**
- * 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().
- *
- */
-void meta_stack_set_positions (MetaStack *stack,
- GList *windows);
-
-void meta_stack_update_window_tile_matches (MetaStack *stack,
- MetaWorkspace *workspace);
-#endif
diff --git a/src/core/startup-notification-private.h b/src/core/startup-notification-private.h
deleted file mode 100644
index 5bdf2ac1a..000000000
--- a/src/core/startup-notification-private.h
+++ /dev/null
@@ -1,52 +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, 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
deleted file mode 100644
index 85a14e939..000000000
--- a/src/core/startup-notification.c
+++ /dev/null
@@ -1,696 +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, 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,
- SEQ_TIMEOUT,
- 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");
- meta_display_set_cursor (display, META_CURSOR_BUSY);
- }
- else
- {
- meta_topic (META_DEBUG_STARTUP,
- "Setting default cursor");
- 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_signals[SEQ_TIMEOUT] =
- g_signal_new ("timeout",
- META_TYPE_STARTUP_SEQUENCE,
- G_SIGNAL_RUN_LAST,
- 0, 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",
- 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",
- meta_startup_sequence_get_id (sequence));
-
- if (!meta_startup_sequence_get_completed (sequence))
- {
- g_signal_emit (sequence, seq_signals[SEQ_TIMEOUT], 0, 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/util-private.h b/src/core/util-private.h
deleted file mode 100644
index 01b663966..000000000
--- a/src/core/util-private.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public 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_UTIL_PRIVATE_H
-#define META_UTIL_PRIVATE_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);
-
-META_EXPORT_TEST
-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);
-
-void meta_init_debug_utils (void);
-
-#define META_POINT_IN_RECT(xcoord, ycoord, rect) \
- ((xcoord) >= (rect).x && \
- (xcoord) < ((rect).x + (rect).width) && \
- (ycoord) >= (rect).y && \
- (ycoord) < ((rect).y + (rect).height))
-
-void meta_get_clutter_debug_flags (ClutterDebugFlag *debug_flags,
- ClutterDrawDebugFlag *draw_flags,
- ClutterPickDebugFlag *pick_flags);
-
-#endif
diff --git a/src/core/util.c b/src/core/util.c
deleted file mode 100644
index 74a884c80..000000000
--- a/src/core/util.c
+++ /dev/null
@@ -1,796 +0,0 @@
-/*
- * 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/>.
- */
-
-/**
- * SECTION:util
- * @title: Utility functions
- * @short_description: Miscellaneous utility functions
- */
-
-#define _POSIX_C_SOURCE 200112L /* for fdopen() */
-
-#include "config.h"
-
-#include "core/util-private.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <X11/Xlib.h> /* must explicitly be included for Solaris; #326746 */
-#include <X11/Xutil.h> /* Just for the definition of the various gravities */
-
-#ifdef HAVE_SYS_PRCTL
-#include <sys/prctl.h>
-#endif
-
-#include "clutter/clutter-mutter.h"
-#include "cogl/cogl.h"
-#include "meta/common.h"
-#include "meta/main.h"
-
-static const GDebugKey meta_debug_keys[] = {
- { "focus", META_DEBUG_FOCUS },
- { "workarea", META_DEBUG_WORKAREA },
- { "stack", META_DEBUG_STACK },
- { "sm", META_DEBUG_SM },
- { "events", META_DEBUG_EVENTS },
- { "window-state", META_DEBUG_WINDOW_STATE },
- { "window-ops", META_DEBUG_WINDOW_OPS },
- { "geometry", META_DEBUG_GEOMETRY },
- { "placement", META_DEBUG_PLACEMENT },
- { "ping", META_DEBUG_PING },
- { "keybindings", META_DEBUG_KEYBINDINGS },
- { "sync", META_DEBUG_SYNC },
- { "startup", META_DEBUG_STARTUP },
- { "prefs", META_DEBUG_PREFS },
- { "groups", META_DEBUG_GROUPS },
- { "resizing", META_DEBUG_RESIZING },
- { "shapes", META_DEBUG_SHAPES },
- { "edge-resistance", META_DEBUG_EDGE_RESISTANCE },
- { "dbus", META_DEBUG_DBUS },
- { "input", META_DEBUG_INPUT },
- { "wayland", META_DEBUG_WAYLAND },
- { "kms", META_DEBUG_KMS },
- { "screen-cast", META_DEBUG_SCREEN_CAST },
- { "remote-desktop", META_DEBUG_REMOTE_DESKTOP },
- { "backend", META_DEBUG_BACKEND },
-};
-
-#ifdef WITH_VERBOSE_MODE
-static void
-meta_topic_real_valist (MetaDebugTopic topic,
- const char *format,
- va_list args) G_GNUC_PRINTF(2, 0);
-#endif
-
-static gint verbose_topics = 0;
-static int no_prefix = 0;
-static gboolean is_wayland_compositor = FALSE;
-static int debug_paint_flags = 0;
-
-#ifdef WITH_VERBOSE_MODE
-static FILE* logfile = NULL;
-
-static void
-ensure_logfile (void)
-{
- if (logfile == NULL && g_getenv ("MUTTER_USE_LOGFILE"))
- {
- char *filename = NULL;
- char *tmpl;
- int fd;
- GError *err;
-
- tmpl = g_strdup_printf ("mutter-%d-debug-log-XXXXXX",
- (int) getpid ());
-
- err = NULL;
- fd = g_file_open_tmp (tmpl,
- &filename,
- &err);
-
- g_free (tmpl);
-
- if (err != NULL)
- {
- meta_warning ("Failed to open debug log: %s",
- err->message);
- g_error_free (err);
- return;
- }
-
- logfile = fdopen (fd, "w");
-
- if (logfile == NULL)
- {
- meta_warning ("Failed to fdopen() log file %s: %s",
- filename, strerror (errno));
- close (fd);
- }
- else
- {
- g_printerr ("Opened log file %s", filename);
- }
-
- g_free (filename);
- }
-}
-#endif
-
-gboolean
-meta_is_verbose (void)
-{
- return verbose_topics != 0;
-}
-
-void
-meta_set_verbose (gboolean setting)
-{
-#ifndef WITH_VERBOSE_MODE
- if (setting)
- meta_fatal (_("Mutter was compiled without support for verbose mode"));
-#endif
-
- if (setting)
- meta_add_verbose_topic (META_DEBUG_VERBOSE);
- else
- meta_remove_verbose_topic (META_DEBUG_VERBOSE);
-}
-
-/**
- * meta_add_verbose_topic:
- * @topic: Topic for which logging will be started
- *
- * Ensure log messages for the given topic @topic
- * will be printed.
- */
-void
-meta_add_verbose_topic (MetaDebugTopic topic)
-{
- if (verbose_topics == META_DEBUG_VERBOSE)
- return;
-
- ensure_logfile ();
-
- if (topic == META_DEBUG_VERBOSE)
- verbose_topics = META_DEBUG_VERBOSE;
- else
- verbose_topics |= topic;
-}
-
-/**
- * meta_remove_verbose_topic:
- * @topic: Topic for which logging will be stopped
- *
- * Stop printing log messages for the given topic @topic. Note
- * that this method does not stack with meta_add_verbose_topic();
- * i.e. if two calls to meta_add_verbose_topic() for the same
- * topic are made, one call to meta_remove_verbose_topic() will
- * remove it.
- */
-void
-meta_remove_verbose_topic (MetaDebugTopic topic)
-{
- if (topic == META_DEBUG_VERBOSE)
- verbose_topics = 0;
- else
- verbose_topics &= ~topic;
-}
-
-void
-meta_init_debug_utils (void)
-{
- const char *debug_env;
-
-#ifdef HAVE_SYS_PRCTL
- prctl (PR_SET_DUMPABLE, 1);
-#endif
-
- if (g_getenv ("MUTTER_VERBOSE"))
- meta_set_verbose (TRUE);
-
- debug_env = g_getenv ("MUTTER_DEBUG");
- if (debug_env)
- {
- MetaDebugTopic topics;
-
- topics = g_parse_debug_string (debug_env,
- meta_debug_keys,
- G_N_ELEMENTS (meta_debug_keys));
- meta_add_verbose_topic (topics);
- }
-}
-
-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)
-{
- const gchar *s = src;
- while (n && *s)
- {
- s = g_utf8_next_char (s);
- n--;
- }
-
- return g_strndup (src, s - src);
-}
-
-static int
-utf8_fputs (const char *str,
- FILE *f)
-{
- char *l;
- int retval;
-
- l = g_locale_from_utf8 (str, -1, NULL, NULL, NULL);
-
- if (l == NULL)
- retval = fputs (str, f); /* just print it anyway, better than nothing */
- else
- retval = fputs (l, f);
-
- g_free (l);
-
- return retval;
-}
-
-#ifdef WITH_VERBOSE_MODE
-void
-meta_verbose_real (const char *format, ...)
-{
- va_list args;
-
- va_start (args, format);
- meta_topic_real_valist (META_DEBUG_VERBOSE, format, args);
- va_end (args);
-}
-
-static const char*
-topic_name (MetaDebugTopic topic)
-{
- switch (topic)
- {
- case META_DEBUG_FOCUS:
- return "FOCUS";
- case META_DEBUG_WORKAREA:
- return "WORKAREA";
- case META_DEBUG_STACK:
- return "STACK";
- case META_DEBUG_SM:
- return "SM";
- case META_DEBUG_EVENTS:
- return "EVENTS";
- case META_DEBUG_WINDOW_STATE:
- return "WINDOW_STATE";
- case META_DEBUG_WINDOW_OPS:
- return "WINDOW_OPS";
- case META_DEBUG_PLACEMENT:
- return "PLACEMENT";
- case META_DEBUG_GEOMETRY:
- return "GEOMETRY";
- case META_DEBUG_PING:
- return "PING";
- case META_DEBUG_KEYBINDINGS:
- return "KEYBINDINGS";
- case META_DEBUG_SYNC:
- return "SYNC";
- case META_DEBUG_STARTUP:
- return "STARTUP";
- case META_DEBUG_PREFS:
- return "PREFS";
- case META_DEBUG_GROUPS:
- return "GROUPS";
- case META_DEBUG_RESIZING:
- return "RESIZING";
- case META_DEBUG_SHAPES:
- return "SHAPES";
- case META_DEBUG_EDGE_RESISTANCE:
- return "EDGE_RESISTANCE";
- case META_DEBUG_DBUS:
- return "DBUS";
- case META_DEBUG_INPUT:
- return "INPUT";
- case META_DEBUG_KMS:
- return "KMS";
- case META_DEBUG_SCREEN_CAST:
- return "SCREEN_CAST";
- case META_DEBUG_REMOTE_DESKTOP:
- return "REMOTE_DESKTOP";
- case META_DEBUG_BACKEND:
- return "BACKEND";
- case META_DEBUG_VERBOSE:
- return "VERBOSE";
- case META_DEBUG_WAYLAND:
- return "WAYLAND";
- }
-
- return "WM";
-}
-
-static int sync_count = 0;
-
-gboolean
-meta_is_topic_enabled (MetaDebugTopic topic)
-{
- if (verbose_topics == 0)
- return FALSE;
-
- if (topic == META_DEBUG_VERBOSE && verbose_topics != META_DEBUG_VERBOSE)
- return FALSE;
-
- return !!(verbose_topics & topic);
-}
-
-static void
-meta_topic_real_valist (MetaDebugTopic topic,
- const char *format,
- va_list args)
-{
- gchar *str;
- FILE *out;
-
- g_return_if_fail (format != NULL);
-
- if (!meta_is_topic_enabled (topic))
- return;
-
- str = g_strdup_vprintf (format, args);
-
- out = logfile ? logfile : stderr;
-
- if (no_prefix == 0)
- fprintf (out, "%s: ", topic_name (topic));
-
- if (topic == META_DEBUG_SYNC)
- {
- ++sync_count;
- fprintf (out, "%d: ", sync_count);
- }
-
- utf8_fputs (str, out);
- utf8_fputs ("\n", out);
-
- fflush (out);
-
- g_free (str);
-}
-
-void
-meta_topic_real (MetaDebugTopic topic,
- const char *format,
- ...)
-{
- va_list args;
-
- va_start (args, format);
- meta_topic_real_valist (topic, format, args);
- va_end (args);
-}
-#endif /* WITH_VERBOSE_MODE */
-
-void
-meta_bug (const char *format, ...)
-{
- va_list args;
- gchar *str;
- FILE *out;
-
- g_return_if_fail (format != NULL);
-
- va_start (args, format);
- str = g_strdup_vprintf (format, args);
- va_end (args);
-
-#ifdef WITH_VERBOSE_MODE
- out = logfile ? logfile : stderr;
-#else
- out = stderr;
-#endif
-
- if (no_prefix == 0)
- utf8_fputs ("Bug in window manager: ", out);
- utf8_fputs (str, out);
- utf8_fputs ("\n", out);
-
- fflush (out);
-
- g_free (str);
-
- /* stop us in a debugger */
- abort ();
-}
-
-void
-meta_warning (const char *format, ...)
-{
- va_list args;
- gchar *str;
- FILE *out;
-
- g_return_if_fail (format != NULL);
-
- va_start (args, format);
- str = g_strdup_vprintf (format, args);
- va_end (args);
-
-#ifdef WITH_VERBOSE_MODE
- out = logfile ? logfile : stderr;
-#else
- out = stderr;
-#endif
-
- if (no_prefix == 0)
- utf8_fputs ("Window manager warning: ", out);
- utf8_fputs (str, out);
- utf8_fputs ("\n", out);
-
- fflush (out);
-
- g_free (str);
-}
-
-void
-meta_fatal (const char *format, ...)
-{
- va_list args;
- gchar *str;
- FILE *out;
-
- g_warn_if_fail (format);
- if (!format)
- meta_exit (META_EXIT_ERROR);
-
- va_start (args, format);
- str = g_strdup_vprintf (format, args);
- va_end (args);
-
-#ifdef WITH_VERBOSE_MODE
- out = logfile ? logfile : stderr;
-#else
- out = stderr;
-#endif
-
- if (no_prefix == 0)
- utf8_fputs ("Window manager error: ", out);
- utf8_fputs (str, out);
- utf8_fputs ("\n", out);
-
- fflush (out);
-
- g_free (str);
-
- meta_exit (META_EXIT_ERROR);
-}
-
-void
-meta_push_no_msg_prefix (void)
-{
- ++no_prefix;
-}
-
-void
-meta_pop_no_msg_prefix (void)
-{
- g_return_if_fail (no_prefix > 0);
-
- --no_prefix;
-}
-
-void
-meta_exit (MetaExitCode code)
-{
-
- exit (code);
-}
-
-gint
-meta_unsigned_long_equal (gconstpointer v1,
- gconstpointer v2)
-{
- return *((const gulong*) v1) == *((const gulong*) v2);
-}
-
-guint
-meta_unsigned_long_hash (gconstpointer v)
-{
- gulong val = * (const gulong *) v;
-
- /* I'm not sure this works so well. */
-#if GLIB_SIZEOF_LONG > 4
- return (guint) (val ^ (val >> 32));
-#else
- return val;
-#endif
-}
-
-const char*
-meta_gravity_to_string (MetaGravity gravity)
-{
- switch (gravity)
- {
- case META_GRAVITY_NORTH_WEST:
- return "META_GRAVITY_NORTH_WEST";
- break;
- case META_GRAVITY_NORTH:
- return "META_GRAVITY_NORTH";
- break;
- case META_GRAVITY_NORTH_EAST:
- return "META_GRAVITY_NORTH_EAST";
- break;
- case META_GRAVITY_WEST:
- return "META_GRAVITY_WEST";
- break;
- case META_GRAVITY_CENTER:
- return "META_GRAVITY_CENTER";
- break;
- case META_GRAVITY_EAST:
- return "META_GRAVITY_EAST";
- break;
- case META_GRAVITY_SOUTH_WEST:
- return "META_GRAVITY_SOUTH_WEST";
- break;
- case META_GRAVITY_SOUTH:
- return "META_GRAVITY_SOUTH";
- break;
- case META_GRAVITY_SOUTH_EAST:
- return "META_GRAVITY_SOUTH_EAST";
- break;
- case META_GRAVITY_STATIC:
- return "META_GRAVITY_STATIC";
- break;
- default:
- 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
- * representable in the locale encoding.
- */
-static void
-append_argument (GPtrArray *args,
- const char *arg)
-{
- char *locale_arg = g_locale_from_utf8 (arg, -1, NULL, NULL, NULL);
-
- /* This is cheesy, but it's better to have a few ???'s in the dialog
- * for an unresponsive application than no dialog at all appear */
- if (!locale_arg)
- locale_arg = g_strdup ("???");
-
- g_ptr_array_add (args, locale_arg);
-}
-
-/**
- * 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
-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)
-{
- GError *error = NULL;
- GSList *tmp;
- GPid child_pid;
- GPtrArray *args;
-
- args = g_ptr_array_new ();
-
- append_argument (args, "zenity");
- append_argument (args, type);
-
- if (display)
- {
- append_argument (args, "--display");
- append_argument (args, display);
- }
-
- append_argument (args, "--class");
- append_argument (args, "mutter-dialog");
- append_argument (args, "--title");
- append_argument (args, "");
- append_argument (args, "--text");
- append_argument (args, message);
-
- if (timeout)
- {
- append_argument (args, "--timeout");
- append_argument (args, timeout);
- }
-
- if (ok_text)
- {
- append_argument (args, "--ok-label");
- append_argument (args, ok_text);
- }
-
- if (cancel_text)
- {
- append_argument (args, "--cancel-label");
- append_argument (args, cancel_text);
- }
-
- if (icon_name)
- {
- append_argument (args, "--icon-name");
- append_argument (args, icon_name);
- }
-
- tmp = columns;
- while (tmp)
- {
- append_argument (args, "--column");
- append_argument (args, tmp->data);
- tmp = tmp->next;
- }
-
- tmp = entries;
- while (tmp)
- {
- append_argument (args, tmp->data);
- tmp = tmp->next;
- }
-
- if (transient_for)
- {
- gchar *env = g_strdup_printf("%d", transient_for);
- setenv ("WINDOWID", env, 1);
- g_free (env);
-
- append_argument (args, "--modal");
- }
-
- g_ptr_array_add (args, NULL); /* NULL-terminate */
-
- g_spawn_async (
- "/",
- (gchar**) args->pdata,
- NULL,
- G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
- NULL, NULL,
- &child_pid,
- &error
- );
-
- if (transient_for)
- unsetenv ("WINDOWID");
-
- g_ptr_array_free (args, TRUE);
-
- if (error)
- {
- meta_warning ("%s", error->message);
- g_error_free (error);
- }
-
- return child_pid;
-}
-
-MetaLocaleDirection
-meta_get_locale_direction (void)
-{
- 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;
- }
-}
-
-char *
-meta_generate_random_id (GRand *rand,
- int length)
-{
- char *id;
- int i;
-
- /* Generate a random string of printable ASCII characters. */
-
- id = g_new0 (char, length + 1);
- for (i = 0; i < length; i++)
- id[i] = (char) g_rand_int_range (rand, 32, 127);
-
- return id;
-}
-
-
-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);
-}
-
-void
-meta_remove_clutter_debug_flags (ClutterDebugFlag debug_flags,
- ClutterDrawDebugFlag draw_flags,
- ClutterPickDebugFlag pick_flags)
-{
- clutter_remove_debug_flags (debug_flags, draw_flags, pick_flags);
-}
-
-void
-meta_get_clutter_debug_flags (ClutterDebugFlag *debug_flags,
- ClutterDrawDebugFlag *draw_flags,
- ClutterPickDebugFlag *pick_flags)
-{
- clutter_get_debug_flags (debug_flags, draw_flags, pick_flags);
-}
-
-void
-meta_add_debug_paint_flag (MetaDebugPaintFlag flag)
-{
- debug_paint_flags |= flag;
-}
-
-void
-meta_remove_debug_paint_flag (MetaDebugPaintFlag flag)
-{
- debug_paint_flags &= ~flag;
-}
-
-MetaDebugPaintFlag
-meta_get_debug_paint_flags (void)
-{
- return debug_paint_flags;
-}
diff --git a/src/core/window-private.h b/src/core/window-private.h
deleted file mode 100644
index d1730c988..000000000
--- a/src/core/window-private.h
+++ /dev/null
@@ -1,888 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file window-private.h Windows which Mutter manages
- *
- * Managing X windows.
- * This file contains methods on this class which are available to
- * routines in core but not outside it. (See window.h for the routines
- * 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_PRIVATE_H
-#define META_WINDOW_PRIVATE_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
-{
- META_CLIENT_TYPE_UNKNOWN = 0,
- META_CLIENT_TYPE_APPLICATION = 1,
- META_CLIENT_TYPE_PAGER = 2,
- META_CLIENT_TYPE_MAX_RECOGNIZED = 2
-} MetaClientType;
-
-typedef enum
-{
- META_QUEUE_CALC_SHOWING = 1 << 0,
- META_QUEUE_MOVE_RESIZE = 1 << 1,
- META_QUEUE_UPDATE_ICON = 1 << 2,
-} MetaQueueType;
-
-#define NUMBER_OF_QUEUES 3
-
-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,
- META_EDGE_CONSTRAINT_WINDOW = 1,
- META_EDGE_CONSTRAINT_MONITOR = 2,
-} MetaEdgeConstraint;
-
-typedef enum
-{
- META_EDGE_RESISTANCE_DEFAULT = 0,
- META_EDGE_RESISTANCE_SNAP = 1 << 0,
- META_EDGE_RESISTANCE_KEYBOARD_OP = 1 << 1,
- META_EDGE_RESISTANCE_WINDOWS = 1 << 2,
-} MetaEdgeResistanceFlags;
-
-struct _MetaWindow
-{
- GObject parent_instance;
-
- MetaDisplay *display;
- 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;
- char *desc; /* used in debug spew */
- char *title;
-
- cairo_surface_t *icon;
- cairo_surface_t *mini_icon;
-
- MetaWindowType type;
-
- /* NOTE these five are not in UTF-8, we just treat them as random
- * binary data
- */
- char *res_class;
- char *res_name;
- char *role;
- char *sm_client_id;
- char *wm_client_machine;
-
- char *startup_id;
- char *mutter_hints;
- char *sandboxed_app_id;
- char *gtk_theme_variant;
- char *gtk_application_id;
- char *gtk_unique_bus_name;
- char *gtk_application_object_path;
- char *gtk_window_object_path;
- char *gtk_app_menu_object_path;
- char *gtk_menubar_object_path;
-
- Window xtransient_for;
- Window xgroup_leader;
- Window xclient_leader;
- MetaWindow *transient_for;
-
- /* Initial workspace property */
- int initial_workspace;
-
- /* Initial timestamp property */
- guint32 initial_timestamp;
-
- /* Whether this is an override redirect window or not */
- guint override_redirect : 1;
-
- /* Whether we're maximized */
- guint maximized_horizontally : 1;
- guint maximized_vertically : 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;
-
- /* 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;
-
- 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;
-
- /* Whether we're fullscreen */
- guint fullscreen : 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. */
- 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;
-
- /* Whether we're trying to constrain the window to be on a single monitor */
- guint require_on_single_monitor : 1;
-
- /* Whether we're trying to constrain the window's titlebar to be onscreen */
- guint require_titlebar_visible : 1;
-
- /* Whether we're sticky in the multi-workspace sense
- * (vs. the not-scroll-with-viewport sense, we don't
- * have no stupid viewports)
- */
- guint on_all_workspaces : 1;
-
- /* This is true if the client requested sticky, and implies on_all_workspaces == TRUE,
- * however on_all_workspaces can be set TRUE for other internal reasons too, such as
- * being override_redirect or being on the non-primary monitor. */
- guint on_all_workspaces_requested : 1;
-
- /* Minimize is the state controlled by the minimize button */
- guint minimized : 1;
- guint tab_unminimized : 1;
-
- /* Whether the window is mapped; actual server-side state
- * 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.
- * 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.
- */
- guint pending_compositor_effect : 4; /* MetaCompEffect */
-
- /* Iconic is the state in WM_STATE; happens for workspaces/shading
- * in addition to minimize
- */
- guint iconic : 1;
- /* initially_iconic is the WM_HINTS setting when we first manage
- * the window. It's taken to mean initially minimized.
- */
- guint initially_iconic : 1;
-
- /* 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;
-
- /* Globally active / No input */
- guint input : 1;
-
- /* MWM hints about features of window */
- guint mwm_decorated : 1;
- guint mwm_border_only : 1;
- guint mwm_has_close_func : 1;
- guint mwm_has_minimize_func : 1;
- 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;
- guint always_sticky : 1;
- guint has_close_func : 1;
- guint has_minimize_func : 1;
- guint has_maximize_func : 1;
- guint has_shade_func : 1;
- guint has_move_func : 1;
- guint has_resize_func : 1;
- guint has_fullscreen_func : 1;
-
- /* Computed whether to skip taskbar or not */
- guint skip_taskbar : 1;
- guint skip_pager : 1;
- guint skip_from_window_list : 1;
-
- /* TRUE if client set these */
- guint wm_state_above : 1;
- guint wm_state_below : 1;
-
- /* EWHH demands attention flag */
- guint wm_state_demands_attention : 1;
-
- /* TRUE iff window == window->display->focus_window */
- guint has_focus : 1;
-
- /* Have we placed this window? */
- guint placed : 1;
-
- /* Is this not a transient of the focus window which is being denied focus? */
- guint denied_focus_and_not_transient : 1;
-
- /* Has this window not ever been shown yet? */
- guint showing_for_first_time : 1;
-
- /* Are we in meta_window_unmanage()? */
- guint unmanaging : 1;
-
- /* 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
- */
- guint withdrawn : 1;
-
- /* TRUE if constrain_position should calc placement.
- * only relevant if !window->placed
- */
- guint calc_placement : 1;
-
- /* if TRUE, window was maximized at start of current grab op */
- guint shaken_loose : 1;
-
- /* if TRUE we have a grab on the focus click buttons */
- guint have_focus_click_grab : 1;
-
- /* if TRUE, application is buggy and SYNC resizing is turned off */
- guint disable_sync : 1;
-
- /* 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;
-
- /* Note: can be NULL */
- GSList *struts;
-
- /* XSync update counter */
- XSyncCounter sync_request_counter;
- gint64 sync_request_serial;
- gint64 sync_request_wait_serial;
- guint sync_request_timeout_id;
- /* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
- XSyncAlarm sync_request_alarm;
-
- /* 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;
-
- /* set to the most recent user-interaction event timestamp that we
- know about for this window */
- guint32 net_wm_user_time;
-
- /* window that gets updated net_wm_user_time values */
- Window user_time_window;
-
- gboolean has_custom_frame_extents;
- GtkBorder custom_frame_extents;
-
- /* 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;
-
- /* The geometry to restore when we unfullscreen. */
- MetaRectangle saved_rect_fullscreen;
-
- /* 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.
- *
- * For X11 windows, this matches XGetGeometry of the toplevel.
- *
- * 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 buffer_rect;
-
- /* Cached net_wm_icon_geometry */
- MetaRectangle icon_geometry;
-
- /* 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 */
-
- /* Managed by delete.c */
- MetaCloseDialog *close_dialog;
-
- /* maintained by group.c */
- MetaGroup *group;
-
- GObject *compositor_private;
-
- /* 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;
-
- 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;
-
- pid_t client_pid;
-};
-
-struct _MetaWindowClass
-{
- GObjectClass parent_class;
-
- 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);
- pid_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
- * the dynamic window state such as "maximized", not just the
- * window's type
- */
-#define META_WINDOW_MAXIMIZED(w) ((w)->maximized_horizontally && \
- (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) && \
- (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(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)
-#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);
-META_EXPORT_TEST
-void meta_window_untile (MetaWindow *window);
-
-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_make_fullscreen_internal (MetaWindow *window);
-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);
-
-void meta_window_update_struts (MetaWindow *window);
-
-/* 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,
- 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_session_geometry (MetaWindow *window,
- int *x,
- int *y,
- int *width,
- int *height);
-
-void meta_window_update_unfocused_button_grabs (MetaWindow *window);
-
-void meta_window_set_focused_internal (MetaWindow *window,
- gboolean focused);
-
-gboolean meta_window_is_focusable (MetaWindow *window);
-
-gboolean meta_window_can_ping (MetaWindow *window);
-
-MetaStackLayer meta_window_calculate_layer (MetaWindow *window);
-
-void meta_window_current_workspace_changed (MetaWindow *window);
-
-void meta_window_show_menu (MetaWindow *window,
- MetaWindowMenuType menu,
- int x,
- int y);
-
-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);
-
-
-gboolean meta_window_same_application (MetaWindow *window,
- MetaWindow *other_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) \
- (meta_window_is_focusable (w) && META_WINDOW_IN_NORMAL_TAB_CHAIN_TYPE (w) && (!(w)->skip_taskbar))
-#define META_WINDOW_IN_DOCK_TAB_CHAIN(w) \
- (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) \
- (meta_window_is_focusable (w) && (!g || meta_window_get_group(w)==g))
-
-void meta_window_free_delete_dialog (MetaWindow *window);
-
-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_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);
-
-void meta_window_stack_just_above (MetaWindow *window,
- MetaWindow *above_this_one);
-
-void meta_window_set_user_time (MetaWindow *window,
- guint32 timestamp);
-
-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);
-
-void meta_window_compute_tile_match (MetaWindow *window);
-
-gboolean meta_window_updates_are_frozen (MetaWindow *window);
-
-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);
-
-gboolean meta_window_has_transient_type (MetaWindow *window);
-
-void meta_window_set_transient_for (MetaWindow *window,
- MetaWindow *parent);
-
-void meta_window_set_opacity (MetaWindow *window,
- guint8 opacity);
-
-void meta_window_handle_enter (MetaWindow *window,
- guint32 timestamp,
- guint root_x,
- guint root_y);
-void meta_window_handle_leave (MetaWindow *window);
-
-gboolean meta_window_handle_ui_frame_event (MetaWindow *window,
- const ClutterEvent *event);
-
-void meta_window_handle_ungrabbed_event (MetaWindow *window,
- const ClutterEvent *event);
-
-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);
-
-META_EXPORT_TEST
-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,
- MetaEdgeResistanceFlags flags,
- 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);
-
-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.c b/src/core/window.c
deleted file mode 100644
index ea56f3328..000000000
--- a/src/core/window.c
+++ /dev/null
@@ -1,8665 +0,0 @@
-/* -*- 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/>.
- */
-
-/**
- * SECTION:meta-window
- * @title: MetaWindow
- * @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 "core/window-private.h"
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <X11/Xatom.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
-
-/* 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 invalidate_work_areas (MetaWindow *window);
-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 meta_window_show (MetaWindow *window);
-static void meta_window_hide (MetaWindow *window);
-
-static void meta_window_save_rect (MetaWindow *window);
-
-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,
- MetaEdgeResistanceFlags flags,
- int x,
- int y);
-static gboolean update_move_timeout (gpointer data);
-static void update_resize (MetaWindow *window,
- MetaEdgeResistanceFlags flags,
- int x,
- int y,
- gboolean force);
-static gboolean update_resize_timeout (gpointer data);
-static gboolean should_be_on_all_workspaces (MetaWindow *window);
-
-static void meta_window_flush_calc_showing (MetaWindow *window);
-
-static gboolean queue_calc_showing_func (MetaWindow *window,
- void *data);
-
-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_propagate_focus_appearance (MetaWindow *window,
- gboolean focused);
-static void meta_window_update_icon_now (MetaWindow *window,
- gboolean force);
-
-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);
-
-/* 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
- * index into the queue arrays to use.
- *
- * TODO: Possibly there is still some code duplication among these, which we
- * need to sort out at some point.
- */
-static gboolean idle_calc_showing (gpointer data);
-static gboolean idle_move_resize (gpointer data);
-static gboolean idle_update_icon (gpointer data);
-
-G_DEFINE_ABSTRACT_TYPE (MetaWindow, meta_window, G_TYPE_OBJECT);
-
-enum
-{
- PROP_0,
-
- PROP_TITLE,
- PROP_ICON,
- PROP_MINI_ICON,
- PROP_DECORATED,
- PROP_FULLSCREEN,
- PROP_MAXIMIZED_HORIZONTALLY,
- PROP_MAXIMIZED_VERTICALLY,
- PROP_MINIMIZED,
- PROP_WINDOW_TYPE,
- PROP_USER_TIME,
- PROP_DEMANDS_ATTENTION,
- PROP_URGENT,
- PROP_SKIP_TASKBAR,
- PROP_MUTTER_HINTS,
- PROP_APPEARS_FOCUSED,
- PROP_RESIZEABLE,
- PROP_ABOVE,
- PROP_WM_CLASS,
- PROP_GTK_APPLICATION_ID,
- PROP_GTK_UNIQUE_BUS_NAME,
- PROP_GTK_APPLICATION_OBJECT_PATH,
- PROP_GTK_WINDOW_OBJECT_PATH,
- PROP_GTK_APP_MENU_OBJECT_PATH,
- PROP_GTK_MENUBAR_OBJECT_PATH,
- PROP_ON_ALL_WORKSPACES,
-
- PROP_LAST,
-};
-
-static GParamSpec *obj_props[PROP_LAST];
-
-enum
-{
- WORKSPACE_CHANGED,
- FOCUS,
- RAISED,
- UNMANAGING,
- UNMANAGED,
- SIZE_CHANGED,
- POSITION_CHANGED,
- SHOWN,
-
- LAST_SIGNAL
-};
-
-static guint window_signals[LAST_SIGNAL] = { 0 };
-
-static void
-prefs_changed_callback (MetaPreference pref,
- gpointer data)
-{
- MetaWindow *window = data;
-
- 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);
- }
-}
-
-static void
-meta_window_real_grab_op_began (MetaWindow *window,
- MetaGrabOp op)
-{
-}
-
-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 pid_t
-meta_window_real_get_client_pid (MetaWindow *window)
-{
- return 0;
-}
-
-static void
-meta_window_finalize (GObject *object)
-{
- MetaWindow *window = META_WINDOW (object);
-
- if (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);
-
- 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);
-}
-
-static void
-meta_window_get_property(GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaWindow *win = META_WINDOW (object);
-
- switch (prop_id)
- {
- 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;
- case PROP_FULLSCREEN:
- g_value_set_boolean (value, win->fullscreen);
- break;
- case PROP_MAXIMIZED_HORIZONTALLY:
- g_value_set_boolean (value, win->maximized_horizontally);
- break;
- case PROP_MAXIMIZED_VERTICALLY:
- g_value_set_boolean (value, win->maximized_vertically);
- break;
- case PROP_MINIMIZED:
- g_value_set_boolean (value, win->minimized);
- break;
- case PROP_WINDOW_TYPE:
- g_value_set_enum (value, win->type);
- break;
- case PROP_USER_TIME:
- g_value_set_uint (value, win->net_wm_user_time);
- break;
- case PROP_DEMANDS_ATTENTION:
- g_value_set_boolean (value, win->wm_state_demands_attention);
- break;
- case PROP_URGENT:
- g_value_set_boolean (value, win->urgent);
- break;
- case PROP_SKIP_TASKBAR:
- g_value_set_boolean (value, win->skip_taskbar);
- break;
- 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));
- break;
- case PROP_WM_CLASS:
- g_value_set_string (value, win->res_class);
- break;
- case PROP_RESIZEABLE:
- g_value_set_boolean (value, win->has_resize_func);
- break;
- case PROP_ABOVE:
- g_value_set_boolean (value, win->wm_state_above);
- break;
- case PROP_GTK_APPLICATION_ID:
- g_value_set_string (value, win->gtk_application_id);
- break;
- case PROP_GTK_UNIQUE_BUS_NAME:
- g_value_set_string (value, win->gtk_unique_bus_name);
- break;
- case PROP_GTK_APPLICATION_OBJECT_PATH:
- g_value_set_string (value, win->gtk_application_object_path);
- break;
- case PROP_GTK_WINDOW_OBJECT_PATH:
- g_value_set_string (value, win->gtk_window_object_path);
- break;
- case PROP_GTK_APP_MENU_OBJECT_PATH:
- g_value_set_string (value, win->gtk_app_menu_object_path);
- break;
- case PROP_GTK_MENUBAR_OBJECT_PATH:
- g_value_set_string (value, win->gtk_menubar_object_path);
- break;
- 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);
- break;
- }
-}
-
-static void
-meta_window_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_window_class_init (MetaWindowClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = meta_window_finalize;
-
- object_class->get_property = meta_window_get_property;
- object_class->set_property = meta_window_set_property;
-
- 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,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
- window_signals[FOCUS] =
- g_signal_new ("focus",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
- window_signals[RAISED] =
- g_signal_new ("raised",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 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);
-
- window_signals[UNMANAGED] =
- g_signal_new ("unmanaged",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 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),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-
- /**
- * 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);
-
- /**
- * 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,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
-}
-
-static void
-meta_window_init (MetaWindow *self)
-{
- self->stamp = next_window_stamp++;
- meta_prefs_add_listener (prefs_changed_callback, self);
-}
-
-static gboolean
-is_desktop_or_dock_foreach (MetaWindow *window,
- void *data)
-{
- gboolean *result = data;
-
- *result =
- window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK ||
- window->skip_from_window_list;
- if (*result)
- return FALSE; /* stop as soon as we find one */
- else
- return TRUE;
-}
-
-/* window is the window that's newly mapped provoking
- * the possible change
- */
-static void
-maybe_leave_show_desktop_mode (MetaWindow *window)
-{
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
- gboolean is_desktop_or_dock;
-
- if (!workspace_manager->active_workspace->showing_desktop)
- return;
-
- /* If the window is a transient for the dock or desktop, don't
- * leave show desktop mode when the window opens. That's
- * so you can e.g. hide all windows, manipulate a file on
- * the desktop via a dialog, then unshow windows again.
- */
- is_desktop_or_dock = FALSE;
- is_desktop_or_dock_foreach (window,
- &is_desktop_or_dock);
-
- meta_window_foreach_ancestor (window, is_desktop_or_dock_foreach,
- &is_desktop_or_dock);
-
- if (!is_desktop_or_dock)
- {
- 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 = client_window_should_be_mapped (window);
-
- g_return_if_fail (!window->override_redirect);
-
- if (window->mapped == should_be_mapped)
- return;
-
- window->mapped = should_be_mapped;
-
- if (window->mapped)
- META_WINDOW_GET_CLASS (window)->map (window);
- else
- META_WINDOW_GET_CLASS (window)->unmap (window);
-}
-
-static gboolean
-meta_window_update_flatpak_id (MetaWindow *window,
- uint32_t pid)
-{
- g_autoptr(GKeyFile) key_file = NULL;
- g_autofree char *info_filename = NULL;
-
- g_return_val_if_fail (pid != 0, FALSE);
- g_return_val_if_fail (window->sandboxed_app_id == NULL, FALSE);
-
- key_file = g_key_file_new ();
- info_filename = g_strdup_printf ("/proc/%u/root/.flatpak-info", pid);
-
- if (!g_key_file_load_from_file (key_file, info_filename, G_KEY_FILE_NONE, NULL))
- return FALSE;
-
- window->sandboxed_app_id = g_key_file_get_string (key_file, "Application", "name", NULL);
-
- return TRUE;
-}
-
-static gboolean
-meta_window_update_snap_id (MetaWindow *window,
- uint32_t pid)
-{
- 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;
-
- 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);
-
- if (!g_file_get_contents (security_label_filename,
- &security_label_contents,
- &security_label_contents_size,
- NULL))
- return FALSE;
-
- if (!g_str_has_prefix (security_label_contents, SNAP_SECURITY_LABEL_PREFIX))
- return FALSE;
-
- /* 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;
-
- for (i = 0; i < security_label_contents_size; ++i)
- {
- if (contents_start[i] == '.')
- contents_start[i] = '_';
- }
-
- sandboxed_app_id = g_malloc0 (security_label_contents_size + 1);
- memcpy (sandboxed_app_id, contents_start, security_label_contents_size);
-
- window->sandboxed_app_id = sandboxed_app_id;
-
- return TRUE;
-}
-
-static void
-meta_window_update_sandboxed_app_id (MetaWindow *window)
-{
- pid_t pid;
-
- g_clear_pointer (&window->sandboxed_app_id, g_free);
-
- pid = meta_window_get_pid (window);
-
- if (pid < 1)
- return;
-
- if (meta_window_update_flatpak_id (window, pid))
- return;
-
- if (meta_window_update_snap_id (window, pid))
- return;
-}
-
-static void
-meta_window_update_desc (MetaWindow *window)
-{
- g_clear_pointer (&window->desc, g_free);
-
- if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
- window->desc = g_strdup_printf ("0x%lx", window->xwindow);
- else
- {
- guint64 small_stamp = window->stamp - G_GUINT64_CONSTANT(0x100000000);
-
- window->desc = g_strdup_printf ("W%" G_GUINT64_FORMAT , small_stamp);
- }
-}
-
-static void
-meta_window_main_monitor_changed (MetaWindow *window,
- const MetaLogicalMonitor *old)
-{
- META_WINDOW_GET_CLASS (window)->main_monitor_changed (window, old);
-
- 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);
-}
-
-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;
-
- meta_window_get_frame_rect (window, &window_rect);
- return meta_monitor_manager_get_logical_monitor_from_rect (monitor_manager,
- &window_rect);
-}
-
-static void
-meta_window_manage (MetaWindow *window)
-{
- COGL_TRACE_BEGIN_SCOPED (MetaWindowManage,
- "Window (manage)");
-
- META_WINDOW_GET_CLASS (window)->manage (window);
-}
-
-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;
-
- COGL_TRACE_BEGIN_SCOPED (MetaWindowSharedNew,
- "Window (new)");
-
- g_assert (attrs != NULL);
-
- meta_verbose ("attrs->map_state = %d (%s)",
- attrs->map_state,
- (attrs->map_state == IsUnmapped) ?
- "IsUnmapped" :
- (attrs->map_state == IsViewable) ?
- "IsViewable" :
- (attrs->map_state == IsUnviewable) ?
- "IsUnviewable" :
- "(unknown)");
-
- 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 ();
-
- window->constructing = TRUE;
-
- window->client_type = client_type;
- window->surface = surface;
- window->xwindow = xwindow;
-
- window->display = display;
- meta_display_register_stamp (window->display, &window->stamp, window);
-
- window->workspace = NULL;
-
- window->sync_request_counter = None;
- window->sync_request_serial = 0;
- window->sync_request_timeout_id = 0;
- window->sync_request_alarm = None;
-
- meta_window_update_sandboxed_app_id (window);
- meta_window_update_desc (window);
-
- window->override_redirect = attrs->override_redirect;
-
- /* 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;
-
- /* size_hints are the "request" */
- window->size_hints.x = attrs->x;
- window->size_hints.y = attrs->y;
- window->size_hints.width = attrs->width;
- window->size_hints.height = attrs->height;
- /* initialize the remaining size_hints as if size_hints.flags were zero */
- meta_set_normal_hints (window, NULL);
-
- /* And this is our unmaximized size */
- window->saved_rect = window->rect;
- window->unconstrained_rect = window->rect;
-
- window->depth = attrs->depth;
- window->xvisual = attrs->visual;
-
- window->title = NULL;
- window->icon = NULL;
- window->mini_icon = NULL;
-
- window->frame = NULL;
- window->has_focus = FALSE;
- window->attached_focus_window = NULL;
-
- window->maximized_horizontally = FALSE;
- window->maximized_vertically = FALSE;
- window->maximize_horizontally_after_placement = FALSE;
- window->maximize_vertically_after_placement = FALSE;
- window->minimize_after_placement = FALSE;
- window->fullscreen = FALSE;
- 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->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->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 */
- window->showing_for_first_time = !window->mapped;
- /* 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);
- window->denied_focus_and_not_transient = FALSE;
- window->unmanaging = FALSE;
- window->is_in_queues = 0;
- window->keys_grabbed = FALSE;
- window->grab_on_frame = FALSE;
- window->all_keys_grabbed = FALSE;
- window->withdrawn = FALSE;
- window->initial_workspace_set = FALSE;
- window->initial_timestamp_set = FALSE;
- window->net_wm_user_time_set = FALSE;
- window->user_time_window = None;
- window->input = TRUE;
- window->calc_placement = FALSE;
- window->shaken_loose = FALSE;
- window->have_focus_click_grab = FALSE;
- window->disable_sync = FALSE;
-
- window->unmaps_pending = 0;
- window->reparents_pending = 0;
-
- window->mwm_decorated = TRUE;
- window->mwm_border_only = FALSE;
- window->mwm_has_close_func = TRUE;
- window->mwm_has_minimize_func = TRUE;
- window->mwm_has_maximize_func = TRUE;
- window->mwm_has_move_func = TRUE;
- window->mwm_has_resize_func = 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;
- window->has_move_func = TRUE;
- window->has_resize_func = TRUE;
-
- window->has_shade_func = TRUE;
-
- window->has_fullscreen_func = TRUE;
-
- window->always_sticky = FALSE;
-
- window->skip_taskbar = FALSE;
- window->skip_pager = FALSE;
- window->skip_from_window_list = FALSE;
- window->wm_state_above = FALSE;
- window->wm_state_below = FALSE;
- window->wm_state_demands_attention = FALSE;
-
- window->res_class = NULL;
- window->res_name = NULL;
- window->role = NULL;
- window->sm_client_id = NULL;
- window->wm_client_machine = NULL;
- window->is_remote = FALSE;
- window->startup_id = NULL;
-
- window->client_pid = 0;
-
- window->xtransient_for = None;
- window->xclient_leader = None;
-
- window->type = META_WINDOW_NORMAL;
-
- window->struts = NULL;
-
- window->layer = META_LAYER_LAST; /* invalid value */
- window->stack_position = -1;
- window->initial_workspace = 0; /* not used */
- window->initial_timestamp = 0; /* not used */
-
- window->compositor_private = NULL;
-
- 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;
- window->always_sticky = TRUE;
- window->has_close_func = FALSE;
- window->has_shade_func = FALSE;
- window->has_move_func = FALSE;
- window->has_resize_func = FALSE;
- }
-
- window->id = meta_display_generate_window_id (display);
-
- meta_window_manage (window);
-
- if (!window->override_redirect)
- meta_window_update_icon_now (window, TRUE);
-
- if (window->initially_iconic)
- {
- /* WM_HINTS said minimized */
- window->minimized = TRUE;
- meta_verbose ("Window %s asked to start out minimized", window->desc);
- }
-
- if (existing_wm_state == IconicState)
- {
- /* WM_STATE said minimized */
- window->minimized = TRUE;
- meta_verbose ("Window %s had preexisting WM_STATE = IconicState, minimizing",
- window->desc);
-
- /* Assume window was previously placed, though perhaps it's
- * been iconic its whole life, we have no way of knowing.
- */
- window->placed = TRUE;
- }
-
- /* Apply any window attributes such as initial workspace
- * based on startup notification
- */
- 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
- * from the parent window. If the window has no parent, there isn't
- * much we can do...except record the current time so that any children
- * can use this time as a fallback.
- */
- if (!window->override_redirect && !window->net_wm_user_time_set) {
- /* First, maybe the app was launched with startup notification using an
- * obsolete version of the spec; use that timestamp if it exists.
- */
- if (window->initial_timestamp_set)
- /* NOTE: Do NOT toggle net_wm_user_time_set to true; this is just
- * being recorded as a fallback for potential transients
- */
- window->net_wm_user_time = window->initial_timestamp;
- 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
- */
- window->net_wm_user_time =
- meta_display_get_current_time_roundtrip (window->display);
- }
-
- window->attached = meta_window_should_attach_to_parent (window);
- if (window->attached)
- meta_window_recalc_features (window);
-
- if (window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK)
- {
- /* Change the default, but don't enforce this if the user
- * focuses the dock/desktop and unsticks it using key shortcuts.
- * Need to set this before adding to the workspaces so the MRU
- * lists will be updated.
- */
- window->on_all_workspaces_requested = TRUE;
- }
-
- window->on_all_workspaces = should_be_on_all_workspaces (window);
-
- /* For the workspace, first honor hints,
- * if that fails put transients with parents,
- * otherwise put window on active space
- */
-
- 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,
- "Window %s is initially on all spaces",
- window->desc);
-
- /* need to set on_all_workspaces first so that it will be
- * added to all the MRU lists
- */
- window->on_all_workspaces_requested = TRUE;
-
- on_all_workspaces = TRUE;
- }
- else if (!on_all_workspaces)
- {
- meta_topic (META_DEBUG_PLACEMENT,
- "Window %s is initially on space %d",
- window->desc, window->initial_workspace);
-
- 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
- * with window->on_all_workspaces == TRUE. Other windows are part of
- * some workspace (so they can return to that if the flag is turned off),
- * but appear on other workspaces. override-redirect windows are part
- * of no workspace.
- */
- if (!window->override_redirect && window->workspace == NULL)
- {
- if (window->transient_for != NULL)
- {
- meta_topic (META_DEBUG_PLACEMENT,
- "Putting window %s on same workspace as parent %s",
- window->desc, window->transient_for->desc);
-
- 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",
- window->desc);
-
- set_workspace_state (window, TRUE, NULL);
- }
- else
- {
- meta_topic (META_DEBUG_PLACEMENT,
- "Putting window %s on active workspace",
- window->desc);
-
- set_workspace_state (window, FALSE, workspace_manager->active_workspace);
- }
-
- meta_window_update_struts (window);
- }
-
- 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
- * fullscreen'd; acrobat is one such braindead case; it withdraws
- * and remaps its window whenever trying to become fullscreen...)
- * and thus constraints may try to auto-fullscreen it which also
- * means restacking it.
- */
- if (meta_window_is_stackable (window))
- meta_stack_add (window->display->stack,
- window);
- else if (window->override_redirect)
- window->layer = META_LAYER_OVERRIDE_REDIRECT; /* otherwise set by MetaStack */
-
- if (!window->override_redirect)
- {
- /* FIXME we have a tendency to set this then immediately
- * change it again.
- */
- set_wm_state (window);
- set_net_wm_state (window);
- }
-
- meta_compositor_add_window (window->display->compositor, window);
- window->known_to_compositor = TRUE;
-
- /* Sync stack changes */
- 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->display->stack_tracker);
-
- /* disable show desktop mode unless we're a desktop component */
- maybe_leave_show_desktop_mode (window);
-
- meta_window_queue (window, META_QUEUE_CALC_SHOWING);
- /* See bug 303284; a transient of the given window can already exist, in which
- * case we think it should probably be shown.
- */
- meta_window_foreach_transient (window,
- queue_calc_showing_func,
- NULL);
- /* See bug 334899; the window may have minimized ancestors
- * which need to be shown.
- *
- * However, we shouldn't unminimize windows here when opening
- * a new display because that breaks passing _NET_WM_STATE_HIDDEN
- * between window managers when replacing them; see bug 358042.
- *
- * And we shouldn't unminimize windows if they were initially
- * iconic.
- */
- if (!window->override_redirect &&
- !display->display_opening &&
- !window->initially_iconic)
- unminimize_window_and_all_transient_parents (window);
-
- window->constructing = FALSE;
-
- meta_display_notify_window_created (display, window);
-
- if (window->wm_state_demands_attention)
- g_signal_emit_by_name (window->display, "window-demands-attention", window);
-
- return window;
-}
-
-static gboolean
-detach_foreach_func (MetaWindow *window,
- void *data)
-{
- GList **children = data;
- MetaWindow *parent;
-
- if (window->attached)
- {
- /* Only return the immediate children of the window being unmanaged */
- parent = meta_window_get_transient_for (window);
- if (parent->unmanaging)
- *children = g_list_prepend (*children, window);
- }
-
- return TRUE;
-}
-
-void
-meta_window_unmanage (MetaWindow *window,
- guint32 timestamp)
-{
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
- GList *tmp;
-
- meta_verbose ("Unmanaging %s", window->desc);
- window->unmanaging = TRUE;
-
- g_clear_handle_id (&window->unmanage_idle_id, g_source_remove);
-
- g_signal_emit (window, window_signals[UNMANAGING], 0);
-
- meta_window_free_delete_dialog (window);
-
- if (window->visible_to_compositor)
- {
- 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",
- window->desc);
-
- meta_display_unregister_stamp (window->display, window->stamp);
-
- if (meta_prefs_get_attach_modal_dialogs ())
- {
- GList *attached_children = NULL, *iter;
-
- /* Detach any attached dialogs by unmapping and letting them
- * be remapped after @window is destroyed.
- */
- meta_window_foreach_transient (window,
- detach_foreach_func,
- &attached_children);
- for (iter = attached_children; iter; iter = iter->next)
- meta_window_unmanage (iter->data, timestamp);
- 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;
-
- /* If the window is fullscreen, it may be forcing
- * other windows in its group to a higher layer
- */
-
- meta_stack_freeze (window->display->stack);
- group = meta_window_get_group (window);
- if (group)
- meta_group_update_layers (group);
- meta_stack_thaw (window->display->stack);
- }
-
- 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
- * an EnterNotify the EnterNotify will have final say
- * on what gets focused, maintaining sloppy focus
- * invariants.
- */
- if (meta_window_appears_focused (window))
- meta_window_propagate_focus_appearance (window, FALSE);
- if (window->has_focus)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing default window since we're unmanaging %s",
- window->desc);
- meta_workspace_focus_default_window (workspace_manager->active_workspace,
- window,
- timestamp);
- }
- else
- {
- meta_topic (META_DEBUG_FOCUS,
- "Unmanaging window %s which doesn't currently have focus",
- window->desc);
- }
-
- g_assert (window->display->focus_window != window);
-
- if (window->struts)
- {
- g_slist_free_full (window->struts, g_free);
- window->struts = NULL;
-
- meta_topic (META_DEBUG_WORKAREA,
- "Unmanaging window %s which has struts, so invalidating work areas",
- window->desc);
- invalidate_work_areas (window);
- }
-
- 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->maximized_horizontally || window->maximized_vertically)
- unmaximize_window_before_freeing (window);
-
- meta_window_unqueue (window, META_QUEUE_CALC_SHOWING |
- META_QUEUE_MOVE_RESIZE |
- META_QUEUE_UPDATE_ICON);
-
- set_workspace_state (window, FALSE, NULL);
-
- g_assert (window->workspace == NULL);
-
-#ifndef G_DISABLE_CHECKS
- tmp = workspace_manager->workspaces;
- while (tmp != NULL)
- {
- MetaWorkspace *workspace = tmp->data;
-
- g_assert (g_list_find (workspace->windows, window) == NULL);
- g_assert (g_list_find (workspace->mru_list, window) == NULL);
-
- tmp = tmp->next;
- }
-#endif
-
- if (window->monitor)
- {
- const MetaLogicalMonitor *old = window->monitor;
-
- window->monitor = NULL;
- meta_window_main_monitor_changed (window, old);
- }
-
- 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->display->stack_tracker);
-
- if (window->display->autoraise_window == window)
- meta_display_remove_autoraise_callback (window->display);
-
- META_WINDOW_GET_CLASS (window)->unmanage (window);
-
- meta_prefs_remove_listener (prefs_changed_callback, window);
- meta_display_queue_check_fullscreen (window->display);
-
- g_signal_emit (window, window_signals[UNMANAGED], 0);
-
- g_object_unref (window);
-}
-
-static void
-set_wm_state (MetaWindow *window)
-{
- if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
- meta_window_x11_set_wm_state (window);
-}
-
-static void
-set_net_wm_state (MetaWindow *window)
-{
- if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
- meta_window_x11_set_net_wm_state (window);
-}
-
-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);
-}
-
-/**
- * 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,
- void *data)
-{
- gboolean *result = data;
-
- *result = window->minimized;
- if (*result)
- return FALSE; /* stop as soon as we find one */
- else
- return TRUE;
-}
-
-static gboolean
-ancestor_is_minimized (MetaWindow *window)
-{
- gboolean is_minimized;
-
- is_minimized = FALSE;
-
- meta_window_foreach_ancestor (window, is_minimized_foreach, &is_minimized);
-
- return is_minimized;
-}
-
-/**
- * meta_window_showing_on_its_workspace:
- * @window: A #MetaWindow
- *
- * Returns: %TRUE if window would be visible, if its workspace was current
- */
-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)
- showing = FALSE;
-
- /* 2. See if we're in "show desktop" mode */
- is_desktop_or_dock = FALSE;
- is_desktop_or_dock_foreach (window,
- &is_desktop_or_dock);
-
- meta_window_foreach_ancestor (window, is_desktop_or_dock_foreach,
- &is_desktop_or_dock);
-
- if (window->on_all_workspaces)
- 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 (showing &&
- workspace_of_window && workspace_of_window->showing_desktop &&
- !is_desktop_or_dock)
- {
- meta_verbose ("We're showing the desktop on the workspace(s) that window %s is on",
- 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 (showing)
- {
- if (ancestor_is_minimized (window))
- showing = FALSE;
- }
-
- return showing;
-}
-
-gboolean
-meta_window_should_be_showing (MetaWindow *window)
-{
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
-
-#ifdef HAVE_WAYLAND
- if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND &&
- !meta_wayland_surface_get_buffer (window->surface))
- return FALSE;
-#endif
-
- /* 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
-implement_showing (MetaWindow *window,
- gboolean showing)
-{
- /* Actually show/hide the window */
- meta_verbose ("Implement showing = %d for window %s",
- 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
- * until it is is first shown, but if we're previewing hidden
- * 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 && client_window_should_be_mapped (window))
- meta_window_force_placement (window, FALSE);
-
- meta_window_hide (window);
- }
- else
- meta_window_show (window);
-
- if (!window->override_redirect)
- sync_client_window_mapped (window);
-}
-
-static void
-meta_window_calc_showing (MetaWindow *window)
-{
- implement_showing (window, meta_window_should_be_showing (window));
-}
-
-static guint queue_later[NUMBER_OF_QUEUES] = {0, 0, 0};
-static GSList *queue_pending[NUMBER_OF_QUEUES] = {NULL, NULL, NULL};
-
-static int
-stackcmp (gconstpointer a, gconstpointer b)
-{
- MetaWindow *aw = (gpointer) a;
- MetaWindow *bw = (gpointer) b;
-
- 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;
- guint queue_index = GPOINTER_TO_INT (data);
-
- COGL_TRACE_BEGIN_SCOPED (MetaWindowCalcShowing, "Window: Calc showing");
-
- g_return_val_if_fail (queue_pending[queue_index] != NULL, FALSE);
-
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Clearing the calc_showing queue");
-
- /* 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 calc_showings.
- */
- 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;
-
- destroying_windows_disallowed += 1;
-
- /* We map windows from top to bottom and unmap from bottom to
- * top, to avoid extra expose events. The exception is
- * for unplaced windows, which have to be mapped from bottom to
- * top so placement works.
- */
- should_show = NULL;
- should_hide = NULL;
- unplaced = NULL;
- displays = NULL;
-
- COGL_TRACE_BEGIN (MetaWindowCalcShowingCalc, "Window: Calc showing (calc)");
-
- tmp = copy;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- if (!window->placed)
- unplaced = g_slist_prepend (unplaced, window);
- else if (meta_window_should_be_showing (window))
- should_show = g_slist_prepend (should_show, window);
- else
- should_hide = g_slist_prepend (should_hide, window);
-
- tmp = tmp->next;
- }
-
- /* bottom to top */
- unplaced = g_slist_sort (unplaced, stackcmp);
- should_hide = g_slist_sort (should_hide, stackcmp);
- /* top to bottom */
- should_show = g_slist_sort (should_show, stackcmp);
- should_show = g_slist_reverse (should_show);
-
- COGL_TRACE_END (MetaWindowCalcShowingCalc);
-
- COGL_TRACE_BEGIN (MetaWindowCalcShowingUnplaced,
- "Window: Calc showing (calc unplaced)");
-
- tmp = unplaced;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- meta_window_calc_showing (window);
-
- tmp = tmp->next;
- }
-
- COGL_TRACE_END (MetaWindowCalcShowingUnplaced);
-
- meta_stack_freeze (display->stack);
-
- COGL_TRACE_BEGIN (MetaWindowCalcShowingShow, "Window: Calc showing (show)");
- tmp = should_show;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- implement_showing (window, TRUE);
-
- tmp = tmp->next;
- }
- COGL_TRACE_END (MetaWindowCalcShowingShow);
-
- COGL_TRACE_BEGIN (MetaWindowCalcShowingHide, "Window: Calc showing (hide)");
- tmp = should_hide;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- implement_showing (window, FALSE);
-
- tmp = tmp->next;
- }
- COGL_TRACE_END (MetaWindowCalcShowingHide);
-
- COGL_TRACE_BEGIN (MetaWindowCalcShowingSync,
- "Window: Calc showing (sync stack)");
- meta_stack_thaw (display->stack);
- COGL_TRACE_END (MetaWindowCalcShowingSync);
-
- tmp = copy;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- /* important to set this here for reentrancy -
- * if we queue a window again while it's in "copy",
- * then queue_calc_showing will just return since
- * we are still in the calc_showing queue
- */
- window->is_in_queues &= ~META_QUEUE_CALC_SHOWING;
-
- tmp = tmp->next;
- }
-
- if (meta_prefs_get_focus_mode () != G_DESKTOP_FOCUS_MODE_CLICK)
- {
- /* When display->mouse_mode is false, we want to ignore
- * EnterNotify events unless they come from mouse motion. To do
- * that, we set a sentinel property on the root window if we're
- * not in mouse_mode.
- */
- tmp = should_show;
- while (tmp != NULL)
- {
- MetaWindow *window = tmp->data;
- MetaDisplay *display = window->display;
-
- if (display->x11_display && !display->mouse_mode)
- meta_x11_display_increment_focus_sentinel (display->x11_display);
-
- tmp = tmp->next;
- }
- }
-
- g_slist_free (copy);
-
- g_slist_free (unplaced);
- g_slist_free (should_show);
- g_slist_free (should_hide);
- g_slist_free (displays);
-
- destroying_windows_disallowed -= 1;
-
- return FALSE;
-}
-
-#ifdef WITH_VERBOSE_MODE
-static const gchar* meta_window_queue_names[NUMBER_OF_QUEUES] =
- {"calc_showing", "move_resize", "update_icon"};
-#endif
-
-static void
-meta_window_unqueue (MetaWindow *window, guint queuebits)
-{
- gint queuenum;
-
- for (queuenum=0; queuenum<NUMBER_OF_QUEUES; queuenum++)
- {
- if ((queuebits & 1<<queuenum) /* they have asked to unqueue */
- &&
- (window->is_in_queues & 1<<queuenum)) /* it's in the queue */
- {
-
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Removing %s from the %s queue",
- window->desc,
- meta_window_queue_names[queuenum]);
-
- /* Note that window may not actually be in the queue
- * because it may have been in "copy" inside the idle handler
- */
- queue_pending[queuenum] = g_slist_remove (queue_pending[queuenum], window);
- window->is_in_queues &= ~(1<<queuenum);
-
- /* Okay, so maybe we've used up all the entries in the queue.
- * In that case, we should kill the function that deals with
- * the queue, because there's nothing left for it to do.
- */
- if (queue_pending[queuenum] == NULL && queue_later[queuenum] != 0)
- {
- meta_later_remove (queue_later[queuenum]);
- queue_later[queuenum] = 0;
- }
- }
- }
-}
-
-static void
-meta_window_flush_calc_showing (MetaWindow *window)
-{
- if (window->is_in_queues & META_QUEUE_CALC_SHOWING)
- {
- meta_window_unqueue (window, META_QUEUE_CALC_SHOWING);
- meta_window_calc_showing (window);
- }
-}
-
-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 (queuenum=0; queuenum<NUMBER_OF_QUEUES; queuenum++)
- {
- if (queuebits & 1<<queuenum)
- {
- /* Data which varies between queues.
- * Yes, these do look a lot like associative arrays:
- * I seem to be turning into a Perl programmer.
- */
-
- const MetaLaterType window_queue_later_when[NUMBER_OF_QUEUES] =
- {
- 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_update_icon,
- };
-
- /* If we're about to drop the window, there's no point in putting
- * it on a queue.
- */
- if (window->unmanaging)
- break;
-
- /* If the window already claims to be in that queue, there's no
- * point putting it in the queue.
- */
- if (window->is_in_queues & 1<<queuenum)
- break;
-
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Putting %s in the %s queue",
- window->desc,
- meta_window_queue_names[queuenum]);
-
- /* So, mark it as being in this queue. */
- window->is_in_queues |= 1<<queuenum;
-
- /* There's not a lot of point putting things into a queue if
- * nobody's on the other end pulling them out. Therefore,
- * let's check to see whether an idle handler exists to do
- * that. If not, we'll create one.
- */
-
- if (queue_later[queuenum] == 0)
- queue_later[queuenum] = meta_later_add
- (
- window_queue_later_when[queuenum],
- window_queue_later_handler[queuenum],
- GUINT_TO_POINTER(queuenum),
- NULL
- );
-
- /* And now we actually put it on the queue. */
- queue_pending[queuenum] = g_slist_prepend (queue_pending[queuenum],
- window);
- }
- }
-}
-
-static gboolean
-intervening_user_event_occurred (MetaWindow *window)
-{
- guint32 compare;
- MetaWindow *focus_window;
-
- focus_window = window->display->focus_window;
-
- meta_topic (META_DEBUG_STARTUP,
- "COMPARISON:\n"
- " net_wm_user_time_set : %d\n"
- " net_wm_user_time : %u\n"
- " initial_timestamp_set: %d\n"
- " initial_timestamp : %u",
- window->net_wm_user_time_set,
- window->net_wm_user_time,
- window->initial_timestamp_set,
- window->initial_timestamp);
- if (focus_window != NULL)
- {
- meta_topic (META_DEBUG_STARTUP,
- "COMPARISON (continued):\n"
- " focus_window : %s\n"
- " fw->net_wm_user_time_set : %d\n"
- " fw->net_wm_user_time : %u",
- focus_window->desc,
- focus_window->net_wm_user_time_set,
- focus_window->net_wm_user_time);
- }
-
- /* 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
- * merely a preliminary optimization. :)
- */
- if ( ((window->net_wm_user_time_set == TRUE) &&
- (window->net_wm_user_time == 0))
- ||
- ((window->initial_timestamp_set == TRUE) &&
- (window->initial_timestamp == 0)))
- {
- meta_topic (META_DEBUG_STARTUP,
- "window %s explicitly requested no focus",
- window->desc);
- return TRUE;
- }
-
- if (!(window->net_wm_user_time_set) && !(window->initial_timestamp_set))
- {
- meta_topic (META_DEBUG_STARTUP,
- "no information about window %s found",
- window->desc);
- return FALSE;
- }
-
- if (focus_window != NULL &&
- !focus_window->net_wm_user_time_set)
- {
- meta_topic (META_DEBUG_STARTUP,
- "focus window, %s, doesn't have a user time set yet!",
- window->desc);
- return FALSE;
- }
-
- /* To determine the "launch" time of an application,
- * startup-notification can set the TIMESTAMP and the
- * application (usually via its toolkit such as gtk or qt) can
- * set the _NET_WM_USER_TIME. If both are set, we need to be
- * using the newer of the two values.
- *
- * See http://bugzilla.gnome.org/show_bug.cgi?id=573922
- */
- compare = 0;
- if (window->net_wm_user_time_set &&
- window->initial_timestamp_set)
- compare =
- XSERVER_TIME_IS_BEFORE (window->net_wm_user_time,
- window->initial_timestamp) ?
- window->initial_timestamp : window->net_wm_user_time;
- else if (window->net_wm_user_time_set)
- compare = window->net_wm_user_time;
- else if (window->initial_timestamp_set)
- compare = window->initial_timestamp;
-
- if ((focus_window != NULL) &&
- XSERVER_TIME_IS_BEFORE (compare, focus_window->net_wm_user_time))
- {
- meta_topic (META_DEBUG_STARTUP,
- "window %s focus prevented by other activity; %u < %u",
- window->desc,
- compare,
- focus_window->net_wm_user_time);
- return TRUE;
- }
- else
- {
- meta_topic (META_DEBUG_STARTUP,
- "new window %s with no intervening events",
- window->desc);
- return FALSE;
- }
-}
-
-/* This function is an ugly hack. It's experimental in nature and ought to be
- * replaced by a real hint from the app to the WM if we decide the experimental
- * 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.
- */
-static gboolean
-window_is_terminal (MetaWindow *window)
-{
- if (window == NULL || window->res_class == NULL)
- return FALSE;
-
- /*
- * Compare res_class, which is not user-settable, and thus theoretically
- * a more-reliable indication of term-ness.
- */
-
- /* gnome-terminal -- if you couldn't guess */
- if (strcmp (window->res_class, "Gnome-terminal") == 0)
- return TRUE;
- /* xterm, rxvt, aterm */
- else if (strcmp (window->res_class, "XTerm") == 0)
- return TRUE;
- /* konsole, KDE's terminal program */
- else if (strcmp (window->res_class, "Konsole") == 0)
- return TRUE;
- /* rxvt-unicode */
- else if (strcmp (window->res_class, "URxvt") == 0)
- return TRUE;
- /* eterm */
- else if (strcmp (window->res_class, "Eterm") == 0)
- return TRUE;
- /* KTerm -- some terminal not KDE based; so not like Konsole */
- else if (strcmp (window->res_class, "KTerm") == 0)
- return TRUE;
- /* Multi-gnome-terminal */
- else if (strcmp (window->res_class, "Multi-gnome-terminal") == 0)
- return TRUE;
- /* mlterm ("multi lingual terminal emulator on X") */
- else if (strcmp (window->res_class, "mlterm") == 0)
- return TRUE;
- /* Terminal -- XFCE Terminal */
- else if (strcmp (window->res_class, "Terminal") == 0)
- return TRUE;
-
- return FALSE;
-}
-
-/* This function determines what state the window should have assuming that it
- * and the focus_window have no relation
- */
-static void
-window_state_on_map (MetaWindow *window,
- gboolean *takes_focus,
- gboolean *places_on_top)
-{
- gboolean intervening_events;
-
- intervening_events = intervening_user_event_occurred (window);
-
- *takes_focus = !intervening_events;
- *places_on_top = *takes_focus;
-
- /* don't initially focus windows that are intended to not accept
- * focus
- */
- if (!meta_window_is_focusable (window))
- {
- *takes_focus = FALSE;
- return;
- }
-
- /* Terminal usage may be different; some users intend to launch
- * many apps in quick succession or to just view things in the new
- * window while still interacting with the terminal. In that case,
- * apps launched from the terminal should not take focus. This
- * isn't quite the same as not allowing focus to transfer from
- * terminals due to new window map, but the latter is a much easier
- * approximation to enforce so we do that.
- */
- if (*takes_focus &&
- meta_prefs_get_focus_new_windows () == G_DESKTOP_FOCUS_NEW_WINDOWS_STRICT &&
- !window->display->allow_terminal_deactivation &&
- window_is_terminal (window->display->focus_window) &&
- !meta_window_is_ancestor_of_transient (window->display->focus_window,
- window))
- {
- meta_topic (META_DEBUG_FOCUS,
- "focus_window is terminal; not focusing new window.");
- *takes_focus = FALSE;
- *places_on_top = FALSE;
- }
-
- switch (window->type)
- {
- case META_WINDOW_UTILITY:
- case META_WINDOW_TOOLBAR:
- *takes_focus = FALSE;
- *places_on_top = FALSE;
- break;
- case META_WINDOW_DOCK:
- case META_WINDOW_DESKTOP:
- case META_WINDOW_SPLASHSCREEN:
- case META_WINDOW_MENU:
- /* 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:
- case META_WINDOW_OVERRIDE_OTHER:
- /* don't focus any of these; places_on_top may be irrelevant for some of
- * these (e.g. dock)--but you never know--the focus window might also be
- * of the same type in some weird situation...
- */
- *takes_focus = FALSE;
- break;
- case META_WINDOW_NORMAL:
- case META_WINDOW_DIALOG:
- case META_WINDOW_MODAL_DIALOG:
- /* The default is correct for these */
- break;
- }
-}
-
-static gboolean
-windows_overlap (const MetaWindow *w1, const MetaWindow *w2)
-{
- MetaRectangle w1rect, w2rect;
- meta_window_get_frame_rect (w1, &w1rect);
- meta_window_get_frame_rect (w2, &w2rect);
- return meta_rectangle_overlap (&w1rect, &w2rect);
-}
-
-/* Returns whether a new window would be covered by any
- * existing window on the same workspace that is set
- * to be "above" ("always on top"). A window that is not
- * set "above" would be underneath the new window anyway.
- *
- * We take "covered" to mean even partially covered, but
- * some people might prefer entirely covered. I think it
- * is more useful to behave this way if any part of the
- * window is covered, because a partial coverage could be
- * (say) ninety per cent and almost indistinguishable from total.
- */
-static gboolean
-window_would_be_covered (const MetaWindow *newbie)
-{
- MetaWorkspace *workspace = meta_window_get_workspace ((MetaWindow *)newbie);
- GList *tmp, *windows;
-
- windows = meta_workspace_list_windows (workspace);
-
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- if (w->wm_state_above && w != newbie)
- {
- /* We have found a window that is "above". Perhaps it overlaps. */
- if (windows_overlap (w, newbie))
- {
- g_list_free (windows); /* clean up... */
- return TRUE; /* yes, it does */
- }
- }
-
- tmp = tmp->next;
- }
-
- g_list_free (windows);
- return FALSE; /* none found */
-}
-
-void
-meta_window_force_placement (MetaWindow *window,
- gboolean force_move)
-{
- MetaMoveResizeFlags flags;
-
- if (window->placed)
- return;
-
- /* We have to recalc the placement here since other windows may
- * have been mapped/placed since we last did constrain_position
- */
-
- /* calc_placement is an efficiency hack to avoid
- * multiple placement calculations before we finally
- * show the window.
- */
- window->calc_placement = TRUE;
-
- 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.
- * This is toggled here so that initially-iconified windows
- * still get placed when they are ultimately shown.
- */
- window->placed = TRUE;
-
- /* Don't want to accidentally reuse the fact that we had been denied
- * focus in any future constraints unless we're denied focus again.
- */
- window->denied_focus_and_not_transient = FALSE;
-}
-
-static void
-meta_window_show (MetaWindow *window)
-{
- gboolean did_show;
- gboolean takes_focus_on_map;
- gboolean place_on_top_on_map;
- 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",
- window->desc, window->shaded, window->iconic, window->placed);
-
- focus_window = window->display->focus_window; /* May be NULL! */
- did_show = FALSE;
- window_state_on_map (window, &takes_focus_on_map, &place_on_top_on_map);
- needs_stacking_adjustment = FALSE;
-
- meta_topic (META_DEBUG_WINDOW_STATE,
- "Window %s %s focus on map, and %s place on top on map.",
- window->desc,
- takes_focus_on_map ? "does" : "does not",
- place_on_top_on_map ? "does" : "does not");
-
- /* Now, in some rare cases we should *not* put a new window on top.
- * These cases include certain types of windows showing for the first
- * time, and any window which would be covered because of another window
- * being set "above" ("always on top").
- *
- * FIXME: Although "place_on_top_on_map" and "takes_focus_on_map" are
- * generally based on the window type, there is a special case when the
- * focus window is a terminal for them both to be false; this should
- * probably rather be a term in the "if" condition below.
- */
-
- if ( focus_window != NULL && window->showing_for_first_time &&
- ( (!place_on_top_on_map && !takes_focus_on_map) ||
- window_would_be_covered (window) )
- ) {
- if (!meta_window_is_ancestor_of_transient (focus_window, window))
- {
- needs_stacking_adjustment = TRUE;
- if (!window->placed)
- window->denied_focus_and_not_transient = TRUE;
- }
- }
-
- if (!window->placed)
- {
- 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)
- {
- gboolean overlap;
-
- /* This window isn't getting focus on map. We may need to do some
- * special handing with it in regards to
- * - the stacking of the window
- * - the MRU position of the window
- * - the demands attention setting of the window
- *
- * Firstly, set the flag so we don't give the window focus anyway
- * and confuse people.
- */
-
- takes_focus_on_map = FALSE;
-
- overlap = windows_overlap (window, focus_window);
-
- /* We want alt tab to go to the denied-focus window */
- ensure_mru_position_after (window, focus_window);
-
- /* We don't want the denied-focus window to obscure the focus
- * window, and if we're in both click-to-focus mode and
- * raise-on-click mode then we want to maintain the invariant
- * that MRU order == stacking order. The need for this if
- * comes from the fact that in sloppy/mouse focus the focus
- * window may not overlap other windows and also can be
- * considered "below" them; this combination means that
- * placing the denied-focus window "below" the focus window
- * in the stack when it doesn't overlap it confusingly places
- * that new window below a lot of other windows.
- */
- if (overlap ||
- (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK &&
- meta_prefs_get_raise_on_click ()))
- meta_window_stack_just_below (window, focus_window);
-
- /* If the window will be obscured by the focus window, then the
- * user might not notice the window appearing so set the
- * demands attention hint.
- *
- * We set the hint ourselves rather than calling
- * meta_window_set_demands_attention() because that would cause
- * a recalculation of overlap, and a call to set_net_wm_state()
- * which we are going to call ourselves here a few lines down.
- */
- if (overlap)
- {
- if (!window->wm_state_demands_attention)
- {
- window->wm_state_demands_attention = TRUE;
- notify_demands_attention = TRUE;
- }
- }
- }
-
- if (window->hidden)
- {
- meta_stack_freeze (window->display->stack);
- window->hidden = FALSE;
- meta_stack_thaw (window->display->stack);
- did_show = TRUE;
- }
-
- if (window->iconic)
- {
- window->iconic = FALSE;
- set_wm_state (window);
- }
-
- if (!window->visible_to_compositor)
- {
- MetaCompEffect effect = META_COMP_EFFECT_NONE;
-
- window->visible_to_compositor = TRUE;
-
- switch (window->pending_compositor_effect)
- {
- case META_COMP_EFFECT_CREATE:
- case META_COMP_EFFECT_UNMINIMIZE:
- effect = window->pending_compositor_effect;
- break;
- case META_COMP_EFFECT_NONE:
- case META_COMP_EFFECT_DESTROY:
- case META_COMP_EFFECT_MINIMIZE:
- break;
- }
-
- 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
- * implement_showing(); we only want to worry about focus if this
- * window has not been shown before.
- */
- if (window->showing_for_first_time)
- {
- window->showing_for_first_time = FALSE;
- if (takes_focus_on_map)
- {
- guint32 timestamp;
-
- timestamp = meta_display_get_current_time_roundtrip (window->display);
-
- meta_window_focus (window, timestamp);
- }
- else if (display->x11_display)
- {
- /* Prevent EnterNotify events in sloppy/mouse focus from
- * erroneously focusing the window that had been denied
- * focus. FIXME: This introduces a race; I have a couple
- * ideas for a better way to accomplish the same thing, but
- * they're more involved so do it this way for now.
- */
- meta_x11_display_increment_focus_sentinel (display->x11_display);
- }
- }
-
- set_net_wm_state (window);
-
- if (did_show && window->struts)
- {
- meta_topic (META_DEBUG_WORKAREA,
- "Mapped window %s with struts, so invalidating work areas",
- window->desc);
- invalidate_work_areas (window);
- }
-
- if (did_show)
- meta_display_queue_check_fullscreen (window->display);
-
- /*
- * Now that we have shown the window, we no longer want to consider the
- * initial timestamp in any subsequent deliberations whether to focus this
- * window or not, so clear the flag.
- *
- * See http://bugzilla.gnome.org/show_bug.cgi?id=573922
- */
- window->initial_timestamp_set = FALSE;
-
- if (notify_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,
- "Hiding window %s", window->desc);
-
- if (window->visible_to_compositor)
- {
- MetaCompEffect effect = META_COMP_EFFECT_NONE;
-
- window->visible_to_compositor = FALSE;
-
- switch (window->pending_compositor_effect)
- {
- case META_COMP_EFFECT_CREATE:
- case META_COMP_EFFECT_UNMINIMIZE:
- case META_COMP_EFFECT_NONE:
- break;
- case META_COMP_EFFECT_DESTROY:
- case META_COMP_EFFECT_MINIMIZE:
- effect = window->pending_compositor_effect;
- break;
- }
-
- 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->display->stack);
- window->hidden = TRUE;
- meta_stack_thaw (window->display->stack);
-
- did_hide = TRUE;
- }
-
- if (!window->iconic)
- {
- window->iconic = TRUE;
- set_wm_state (window);
- }
-
- set_net_wm_state (window);
-
- if (did_hide && window->struts)
- {
- meta_topic (META_DEBUG_WORKAREA,
- "Unmapped window %s with struts, so invalidating work areas",
- window->desc);
- invalidate_work_areas (window);
- }
-
- if (window->has_focus)
- {
- MetaWindow *not_this_one = NULL;
- MetaWorkspace *my_workspace = meta_window_get_workspace (window);
- guint32 timestamp = meta_display_get_current_time_roundtrip (window->display);
-
- /*
- * If this window is modal, passing the not_this_one window to
- * _focus_default_window() makes the focus to be given to this window's
- * ancestor. This can only be the case if the window is on the currently
- * 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 (my_workspace == workspace_manager->active_workspace &&
- !my_workspace->showing_desktop)
- not_this_one = window;
-
- meta_workspace_focus_default_window (workspace_manager->active_workspace,
- not_this_one,
- timestamp);
- }
-
- if (did_hide)
- meta_display_queue_check_fullscreen (window->display);
-}
-
-static gboolean
-queue_calc_showing_func (MetaWindow *window,
- void *data)
-{
- meta_window_queue(window, META_QUEUE_CALC_SHOWING);
- return TRUE;
-}
-
-void
-meta_window_minimize (MetaWindow *window)
-{
- g_return_if_fail (!window->override_redirect);
-
- if (!window->minimized)
- {
- window->minimized = TRUE;
- window->pending_compositor_effect = META_COMP_EFFECT_MINIMIZE;
- meta_window_queue(window, META_QUEUE_CALC_SHOWING);
-
- meta_window_foreach_transient (window,
- queue_calc_showing_func,
- NULL);
-
- if (window->has_focus)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing default window due to minimization of focus window %s",
- window->desc);
- }
- else
- {
- meta_topic (META_DEBUG_FOCUS,
- "Minimizing window %s which doesn't have the focus",
- window->desc);
- }
-
- g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_MINIMIZED]);
- }
-}
-
-void
-meta_window_unminimize (MetaWindow *window)
-{
- g_return_if_fail (!window->override_redirect);
-
- if (window->minimized)
- {
- window->minimized = FALSE;
- window->pending_compositor_effect = META_COMP_EFFECT_UNMINIMIZE;
- meta_window_queue(window, META_QUEUE_CALC_SHOWING);
-
- meta_window_foreach_transient (window,
- queue_calc_showing_func,
- NULL);
-
- g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_MINIMIZED]);
- }
-}
-
-static void
-ensure_size_hints_satisfied (MetaRectangle *rect,
- const XSizeHints *size_hints)
-{
- int minw, minh, maxw, maxh; /* min/max width/height */
- int basew, baseh, winc, hinc; /* base width/height, width/height increment */
- int extra_width, extra_height;
-
- minw = size_hints->min_width; minh = size_hints->min_height;
- maxw = size_hints->max_width; maxh = size_hints->max_height;
- basew = size_hints->base_width; baseh = size_hints->base_height;
- winc = size_hints->width_inc; hinc = size_hints->height_inc;
-
- /* First, enforce min/max size constraints */
- rect->width = CLAMP (rect->width, minw, maxw);
- rect->height = CLAMP (rect->height, minh, maxh);
-
- /* Now, verify size increment constraints are satisfied, or make them be */
- extra_width = (rect->width - basew) % winc;
- extra_height = (rect->height - baseh) % hinc;
-
- rect->width -= extra_width;
- rect->height -= extra_height;
-
- /* Adjusting width/height down, as done above, may violate minimum size
- * constraints, so one last fix.
- */
- if (rect->width < minw)
- rect->width += ((minw - rect->width)/winc + 1)*winc;
- if (rect->height < minh)
- rect->height += ((minh - rect->height)/hinc + 1)*hinc;
-}
-
-static void
-meta_window_save_rect (MetaWindow *window)
-{
- 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->maximized_vertically)
- {
- window->saved_rect.y = window->rect.y;
- window->saved_rect.height = window->rect.height;
- }
- }
-}
-
-void
-meta_window_maximize_internal (MetaWindow *window,
- MetaMaximizeFlags directions,
- MetaRectangle *saved_rect)
-{
- /* At least one of the two directions ought to be set */
- gboolean maximize_horizontally, maximize_vertically;
- maximize_horizontally = directions & META_MAXIMIZE_HORIZONTAL;
- maximize_vertically = directions & META_MAXIMIZE_VERTICAL;
- g_assert (maximize_horizontally || maximize_vertically);
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Maximizing %s%s",
- window->desc,
- maximize_horizontally && maximize_vertically ? "" :
- maximize_horizontally ? " horizontally" :
- maximize_vertically ? " vertically" : "BUGGGGG");
-
- if (saved_rect != NULL)
- window->saved_rect = *saved_rect;
- else
- meta_window_save_rect (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;
-
- /* Update the edge constraints */
- update_edge_constraints (window);
-
- meta_window_recalc_features (window);
- set_net_wm_state (window);
-
- if (window->monitor && window->monitor->in_fullscreen)
- meta_display_queue_check_fullscreen (window->display);
-
- 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_maximize (MetaWindow *window,
- MetaMaximizeFlags directions)
-{
- MetaRectangle *saved_rect = NULL;
- gboolean maximize_horizontally, maximize_vertically;
-
- g_return_if_fail (!window->override_redirect);
-
- /* At least one of the two directions ought to be set */
- maximize_horizontally = directions & META_MAXIMIZE_HORIZONTAL;
- maximize_vertically = directions & META_MAXIMIZE_VERTICAL;
- g_assert (maximize_horizontally || maximize_vertically);
-
- /* Only do something if the window isn't already maximized in the
- * given direction(s).
- */
- if ((maximize_horizontally && !window->maximized_horizontally) ||
- (maximize_vertically && !window->maximized_vertically))
- {
- if (window->shaded && maximize_vertically)
- {
- /* Shading sucks anyway; I'm not adding a timestamp argument
- * to this function just for this niche usage & corner case.
- */
- guint32 timestamp =
- meta_display_get_current_time_roundtrip (window->display);
- meta_window_unshade (window, timestamp);
- }
-
- /* if the window hasn't been placed yet, we'll maximize it then
- */
- if (!window->placed)
- {
- window->maximize_horizontally_after_placement =
- window->maximize_horizontally_after_placement ||
- maximize_horizontally;
- window->maximize_vertically_after_placement =
- window->maximize_vertically_after_placement ||
- maximize_vertically;
- return;
- }
-
- if (window->tile_mode != META_TILE_NONE)
- {
- saved_rect = &window->saved_rect;
-
- window->maximized_vertically = FALSE;
- window->tile_mode = META_TILE_NONE;
- }
-
- meta_window_maximize_internal (window,
- directions,
- saved_rect);
-
- 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_MAXIMIZE,
- &old_frame_rect, &old_buffer_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_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;
- *
- * Return value: current maximization state
- */
-MetaMaximizeFlags
-meta_window_get_maximized (MetaWindow *window)
-{
- return ((window->maximized_horizontally ? META_MAXIMIZE_HORIZONTAL : 0) |
- (window->maximized_vertically ? META_MAXIMIZE_VERTICAL : 0));
-}
-
-/**
- * meta_window_is_fullscreen:
- * @window: a #MetaWindow
- *
- * Return value: %TRUE if the window is currently fullscreen
- */
-gboolean
-meta_window_is_fullscreen (MetaWindow *window)
-{
- return window->fullscreen;
-}
-
-/**
- * meta_window_is_screen_sized:
- * @window: A #MetaWindow
- *
- * Return value: %TRUE if the window is occupies the
- * the whole screen (all monitors).
- */
-gboolean
-meta_window_is_screen_sized (MetaWindow *window)
-{
- MetaRectangle window_rect;
- int screen_width, screen_height;
-
- meta_display_get_size (window->display, &screen_width, &screen_height);
- meta_window_get_frame_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;
-
- return FALSE;
-}
-
-/**
- * meta_window_is_monitor_sized:
- * @window: a #MetaWindow
- *
- * Return value: %TRUE if the window is occupies an entire monitor or
- * the whole screen.
- */
-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;
-
- 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;
- }
-
- return FALSE;
-}
-
-/**
- * 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;
-}
-
-static void
-meta_window_get_tile_fraction (MetaWindow *window,
- MetaTileMode tile_mode,
- double *fraction)
-{
- MetaWindow *tile_match;
-
- /* 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;
-}
-
-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 (!META_WINDOW_TILED_SIDE_BY_SIDE (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;
-
- if (tile_match && window->display->grab_window == window)
- meta_window_tile (tile_match, tile_match->tile_mode);
-}
-
-static void
-update_edge_constraints (MetaWindow *window)
-{
- switch (window->tile_mode)
- {
- 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;
-
- 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;
-
- case META_TILE_LEFT:
- window->edge_constraints.top = META_EDGE_CONSTRAINT_MONITOR;
-
- if (window->tile_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_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;
- }
-
- /* h/vmaximize also modify the edge constraints */
- if (window->maximized_vertically)
- {
- window->edge_constraints.top = META_EDGE_CONSTRAINT_MONITOR;
- window->edge_constraints.bottom = META_EDGE_CONSTRAINT_MONITOR;
- }
-
- if (window->maximized_horizontally)
- {
- window->edge_constraints.right = META_EDGE_CONSTRAINT_MONITOR;
- window->edge_constraints.left = META_EDGE_CONSTRAINT_MONITOR;
- }
-}
-
-void
-meta_window_untile (MetaWindow *window)
-{
- 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);
-}
-
-void
-meta_window_tile (MetaWindow *window,
- MetaTileMode tile_mode)
-{
- MetaMaximizeFlags directions;
- MetaRectangle old_frame_rect, old_buffer_rect;
-
- meta_window_get_tile_fraction (window, tile_mode, &window->tile_hfraction);
- window->tile_mode = tile_mode;
-
- /* Don't do anything if no tiling is requested */
- if (window->tile_mode == META_TILE_NONE)
- {
- window->tile_monitor_number = -1;
- return;
- }
- else if (window->tile_monitor_number < 0)
- {
- window->tile_monitor_number = window->monitor->number;
- }
-
- if (window->tile_mode == META_TILE_MAXIMIZED)
- directions = META_MAXIMIZE_BOTH;
- else
- directions = META_MAXIMIZE_VERTICAL;
-
- meta_window_maximize_internal (window, directions, NULL);
- meta_display_update_tile_preview (window->display, FALSE);
-
- /* Setup the edge constraints */
- update_edge_constraints (window);
-
- 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_MAXIMIZE,
- &old_frame_rect, &old_buffer_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);
-
- if (window->frame)
- meta_frame_queue_draw (window->frame);
-}
-
-MetaTileMode
-meta_window_get_tile_mode (MetaWindow *window)
-{
- return window->tile_mode;
-}
-
-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);
-}
-
-static gboolean
-meta_window_can_tile_maximized (MetaWindow *window)
-{
- return window->has_maximize_func;
-}
-
-gboolean
-meta_window_can_tile_side_by_side (MetaWindow *window)
-{
- int monitor;
- MetaRectangle tile_area;
- MetaRectangle client_rect;
-
- if (!meta_window_can_tile_maximized (window))
- return FALSE;
-
- 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;
-
- meta_window_frame_rect_to_client_rect (window, &tile_area, &client_rect);
-
- return client_rect.width >= window->size_hints.min_width &&
- client_rect.height >= window->size_hints.min_height;
-}
-
-static void
-unmaximize_window_before_freeing (MetaWindow *window)
-{
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Unmaximizing %s just before freeing",
- window->desc);
-
- window->maximized_horizontally = FALSE;
- window->maximized_vertically = FALSE;
-
- if (window->withdrawn) /* See bug #137185 */
- {
- window->rect = window->saved_rect;
- set_net_wm_state (window);
- }
-#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
- * that will need the current _NET_WM_STATE atoms.
- * 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_frame (window,
- FALSE,
- window->saved_rect.x,
- window->saved_rect.y,
- window->saved_rect.width,
- window->saved_rect.height);
- }
-#endif
-}
-
-static void
-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 isn't already maximized in the
- * given direction(s).
- */
- if ((unmaximize_horizontally && window->maximized_horizontally) ||
- (unmaximize_vertically && window->maximized_vertically))
- {
- MetaRectangle *desired_rect;
- MetaRectangle target_rect;
- MetaRectangle work_area;
- MetaRectangle old_frame_rect, old_buffer_rect;
- gboolean has_target_size;
-
- 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",
- window->desc,
- unmaximize_horizontally && unmaximize_vertically ? "" :
- unmaximize_horizontally ? " horizontally" :
- unmaximize_vertically ? " vertically" : "BUGGGGG");
-
- window->maximized_horizontally =
- window->maximized_horizontally && !unmaximize_horizontally;
- window->maximized_vertically =
- window->maximized_vertically && !unmaximize_vertically;
-
- /* Update the edge constraints */
- update_edge_constraints (window);
-
- /* recalc_features() will eventually clear the cached frame
- * extents, but we need the correct frame extents in the code below,
- * so invalidate the old frame extents manually up front.
- */
- meta_window_frame_size_changed (window);
-
- desired_rect = &window->saved_rect;
-
- /* Unmaximize to the saved_rect position in the direction(s)
- * being unmaximized.
- */
- 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)
- {
- target_rect.x = desired_rect->x;
- target_rect.width = desired_rect->width;
- }
- if (unmaximize_vertically)
- {
- target_rect.y = desired_rect->y;
- target_rect.height = desired_rect->height;
- }
-
- /* Window's size hints may have changed while maximized, making
- * saved_rect invalid. #329152
- * Do not enforce limits, if no previous 'saved_rect' has been stored.
- */
- has_target_size = (target_rect.width > 0 && target_rect.height > 0);
- if (has_target_size)
- meta_window_maybe_apply_size_hints (window, &target_rect);
-
- meta_compositor_size_change_window (window->display->compositor, window,
- META_SIZE_CHANGE_UNMAXIMIZE,
- &old_frame_rect, &old_buffer_rect);
-
- 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 anchor position.
- */
- if (meta_grab_op_is_moving (window->display->grab_op) &&
- window->display->grab_window == window)
- {
- window->display->grab_anchor_window_pos = target_rect;
- }
-
- meta_window_recalc_features (window);
- set_net_wm_state (window);
- if (!window->monitor->in_fullscreen)
- meta_display_queue_check_fullscreen (window->display);
- }
-
- 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_make_above (MetaWindow *window)
-{
- g_return_if_fail (!window->override_redirect);
-
- meta_window_set_above (window, TRUE);
- meta_window_raise (window);
-}
-
-void
-meta_window_unmake_above (MetaWindow *window)
-{
- g_return_if_fail (!window->override_redirect);
-
- meta_window_set_above (window, FALSE);
- meta_window_raise (window);
-}
-
-static void
-meta_window_set_above (MetaWindow *window,
- gboolean new_value)
-{
- new_value = new_value != FALSE;
- if (new_value == window->wm_state_above)
- return;
-
- window->wm_state_above = new_value;
- meta_window_update_layer (window);
- set_net_wm_state (window);
- meta_window_frame_size_changed (window);
- g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_ABOVE]);
-}
-
-void
-meta_window_make_fullscreen_internal (MetaWindow *window)
-{
- if (!window->fullscreen)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Fullscreening %s", window->desc);
-
- if (window->shaded)
- {
- /* Shading sucks anyway; I'm not adding a timestamp argument
- * to this function just for this niche usage & corner case.
- */
- guint32 timestamp =
- meta_display_get_current_time_roundtrip (window->display);
- meta_window_unshade (window, timestamp);
- }
-
- window->saved_rect_fullscreen = window->rect;
-
- window->fullscreen = TRUE;
-
- meta_stack_freeze (window->display->stack);
-
- meta_window_raise (window);
- meta_stack_thaw (window->display->stack);
-
- meta_window_recalc_features (window);
- set_net_wm_state (window);
-
- /* For the auto-minimize feature, if we fail to get focus */
- meta_display_queue_check_fullscreen (window->display);
-
- g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_FULLSCREEN]);
- }
-}
-
-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);
- 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);
- }
-}
-
-void
-meta_window_unmake_fullscreen (MetaWindow *window)
-{
- g_return_if_fail (!window->override_redirect);
-
- if (window->fullscreen)
- {
- MetaRectangle old_frame_rect, old_buffer_rect, target_rect;
- gboolean has_target_size;
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Unfullscreening %s", window->desc);
-
- window->fullscreen = FALSE;
- target_rect = window->saved_rect_fullscreen;
-
- 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
- * Do not enforce limits, if no previous 'saved_rect' has been stored.
- */
- has_target_size = (target_rect.width > 0 && target_rect.height > 0);
- if (has_target_size)
- meta_window_maybe_apply_size_hints (window, &target_rect);
-
- /* Need to update window->has_resize_func before we move_resize()
- */
- meta_window_recalc_features (window);
- set_net_wm_state (window);
-
- meta_compositor_size_change_window (window->display->compositor,
- window, META_SIZE_CHANGE_UNFULLSCREEN,
- &old_frame_rect, &old_buffer_rect);
-
- 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_display_queue_check_fullscreen (window->display);
-
- g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_FULLSCREEN]);
- }
-}
-
-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 (top && bottom && left && right)
- {
- window->fullscreen_monitors.top = top;
- window->fullscreen_monitors.bottom = bottom;
- window->fullscreen_monitors.left = left;
- window->fullscreen_monitors.right = right;
- }
- else
- {
- meta_window_clear_fullscreen_monitors (window);
- }
-
- if (window->fullscreen)
- {
- meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
- }
-}
-
-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)
-{
- g_return_if_fail (!window->override_redirect);
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Shading %s", window->desc);
- if (!window->shaded)
- {
- window->shaded = TRUE;
-
- meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING);
- meta_window_frame_size_changed (window);
-
- /* After queuing the calc showing, since _focus flushes it,
- * and we need to focus the frame
- */
- meta_topic (META_DEBUG_FOCUS,
- "Re-focusing window %s after shading it",
- window->desc);
- meta_window_focus (window, timestamp);
-
- set_net_wm_state (window);
- }
-}
-
-void
-meta_window_unshade (MetaWindow *window,
- guint32 timestamp)
-{
- g_return_if_fail (!window->override_redirect);
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Unshading %s", window->desc);
- if (window->shaded)
- {
- window->shaded = FALSE;
- meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING);
- meta_window_frame_size_changed (window);
-
- /* focus the window */
- meta_topic (META_DEBUG_FOCUS,
- "Focusing window %s after unshading it",
- window->desc);
- meta_window_focus (window, timestamp);
-
- set_net_wm_state (window);
- }
-}
-
-static gboolean
-unminimize_func (MetaWindow *window,
- void *data)
-{
- meta_window_unminimize (window);
- return TRUE;
-}
-
-static void
-unminimize_window_and_all_transient_parents (MetaWindow *window)
-{
- meta_window_unminimize (window);
- meta_window_foreach_ancestor (window, unminimize_func, NULL);
-}
-
-void
-meta_window_activate_full (MetaWindow *window,
- guint32 timestamp,
- MetaClientType source_indication,
- MetaWorkspace *workspace)
-{
- 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.",
- window->desc, timestamp, source_indication);
-
- 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 "
- " _NET_ACTIVE_WINDOW message.",
- window->display->last_user_time);
- meta_window_set_demands_attention(window);
- return;
- }
-
- if (timestamp == 0)
- timestamp = meta_display_get_current_time_roundtrip (window->display);
-
- meta_window_set_user_time (window, timestamp);
-
- /* disable show desktop mode unless we're a desktop component */
- maybe_leave_show_desktop_mode (window);
-
- /* Get window on current or given workspace */
- if (workspace == NULL)
- 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->transient_for == NULL &&
- !allow_workspace_switch &&
- !meta_window_located_on_workspace (window, workspace))
- {
- meta_window_set_demands_attention (window);
- /* We've marked it as demanding, don't need to do anything else. */
- return;
- }
- 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);
- }
-
- if (window->shaded)
- meta_window_unshade (window, timestamp);
-
- unminimize_window_and_all_transient_parents (window);
-
- if (meta_prefs_get_raise_on_click () ||
- source_indication == META_CLIENT_TYPE_PAGER)
- meta_window_raise (window);
-
- meta_topic (META_DEBUG_FOCUS,
- "Focusing window %s due to activation",
- window->desc);
-
- 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 Mutter, but Mutter shouldn't need to specify a client
- * type for itself. ;-)
- */
-void
-meta_window_activate (MetaWindow *window,
- guint32 timestamp)
-{
- 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.
- */
- meta_window_activate_full (window, timestamp, META_CLIENT_TYPE_PAGER, NULL);
-}
-
-void
-meta_window_activate_with_workspace (MetaWindow *window,
- guint32 timestamp,
- MetaWorkspace *workspace)
-{
- g_return_if_fail (!window->override_redirect);
-
- meta_window_activate_full (window, timestamp, META_CLIENT_TYPE_APPLICATION, workspace);
-}
-
-/**
- * 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
-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);
-}
-
-static gboolean
-maybe_move_attached_window (MetaWindow *window,
- void *data)
-{
- if (window->hidden)
- return G_SOURCE_CONTINUE;
-
- if (meta_window_is_attached_dialog (window) ||
- meta_window_get_placement_rule (window))
- meta_window_reposition (window);
-
- return G_SOURCE_CONTINUE;
-}
-
-/**
- * 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, or -1
- * if the window has been recently unmanaged and does not have a monitor.
- */
-int
-meta_window_get_monitor (MetaWindow *window)
-{
- if (!window->monitor)
- return -1;
-
- return window->monitor->number;
-}
-
-MetaLogicalMonitor *
-meta_window_get_main_logical_monitor (MetaWindow *window)
-{
- return window->monitor;
-}
-
-static MetaLogicalMonitor *
-find_monitor_by_winsys_id (MetaWindow *window,
- uint64_t winsys_id)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- GList *logical_monitors, *l;
-
- logical_monitors =
- meta_monitor_manager_get_logical_monitors (monitor_manager);
-
- 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 */
-void
-meta_window_update_for_monitors_changed (MetaWindow *window)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- const MetaLogicalMonitor *old, *new;
-
- 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,
- META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE);
- goto out;
- }
-
- old = window->monitor;
-
- /* Try the preferred output first */
- new = find_monitor_by_winsys_id (window, window->preferred_output_winsys_id);
-
- /* Otherwise, try to find the old output on a new monitor */
- if (old && !new)
- new = find_monitor_by_winsys_id (window, old->winsys_id);
-
- /* 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)
- {
- 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);
- }
-
-out:
- g_assert (!window->monitor ||
- g_list_find (meta_monitor_manager_get_logical_monitors (monitor_manager),
- window->monitor));
-}
-
-void
-meta_window_update_monitor (MetaWindow *window,
- MetaWindowUpdateMonitorFlags flags)
-{
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
- const MetaLogicalMonitor *old;
-
- old = window->monitor;
- META_WINDOW_GET_CLASS (window)->update_main_monitor (window, flags);
- if (old != window->monitor)
- {
- meta_window_on_all_workspaces_changed (window);
-
- /* 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.
- */
- if (meta_prefs_get_workspaces_only_on_primary () &&
- flags & META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP &&
- meta_window_is_on_primary_monitor (window) &&
- workspace_manager->active_workspace != window->workspace)
- meta_window_change_workspace (window, workspace_manager->active_workspace);
-
- 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. */
- meta_window_recalc_features (window);
- }
-}
-
-void
-meta_window_move_resize_internal (MetaWindow *window,
- MetaMoveResizeFlags flags,
- 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.
- *
- * For an X11 unframed window, the rectangle here directly matches
- * the server's rectangle, since the visible and invisible borders
- * are both 0.
- *
- * For an X11 CSD window, the client window's server rectangle is
- * outset from this rectagle by the client-specified frame extents.
- *
- * For a Wayland window, this rectangle can simply be sent directly
- * to the client.
- */
-
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
- gboolean did_placement;
- 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;
-
- g_return_if_fail (!window->override_redirect);
-
- /* 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));
-
- 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);
-
- 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))
- {
- /* 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,
- frame_rect.width,
- frame_rect.height);
- }
- else if ((flags & META_MOVE_RESIZE_MOVE_ACTION))
- {
- /* 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;
- }
- else if ((flags & META_MOVE_RESIZE_WAYLAND_FINISH_MOVE_RESIZE))
- {
- /* 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 ();
-
- 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) &&
- !(flags & (META_MOVE_RESIZE_UNMAXIMIZE | META_MOVE_RESIZE_UNFULLSCREEN)) &&
- window->monitor)
- {
- MetaRectangle old_rect;
- meta_window_get_frame_rect (window, &old_rect);
-
- meta_window_constrain (window,
- flags,
- gravity,
- &old_rect,
- &constrained_rect,
- &temporary_rect,
- &rel_x,
- &rel_y);
- }
- else if (window->placement.rule)
- {
- rel_x = window->placement.pending.rel_x;
- rel_y = window->placement.pending.rel_y;
- }
-
- /* 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;
- }
-
- /* 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);
-
- if (result & META_MOVE_RESIZE_RESULT_MOVED)
- {
- moved_or_resized = TRUE;
- g_signal_emit (window, window_signals[POSITION_CHANGED], 0);
- }
-
- if (result & META_MOVE_RESIZE_RESULT_RESIZED)
- {
- moved_or_resized = TRUE;
- g_signal_emit (window, window_signals[SIZE_CHANGED], 0);
- }
-
- 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);
- }
-
- 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;
-
- if (window->monitor)
- {
- uint64_t old_output_winsys_id;
-
- old_output_winsys_id = window->monitor->winsys_id;
-
- meta_window_update_monitor (window, update_monitor_flags);
-
- 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
- {
- meta_window_update_monitor (window, update_monitor_flags);
- }
-
- if ((result & META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED) && window->frame_bounds)
- {
- cairo_region_destroy (window->frame_bounds);
- window->frame_bounds = NULL;
- }
-
- meta_window_foreach_transient (window, maybe_move_attached_window, NULL);
-
- meta_stack_update_window_tile_matches (window->display->stack,
- workspace_manager->active_workspace);
-}
-
-/**
- * meta_window_move_frame:
- * @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, using the northwest edge of the frame as the reference,
- * instead of the actual window's origin, but only if a frame is present.
- * 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)
-{
- MetaMoveResizeFlags flags;
- MetaRectangle rect = { root_x_nw, root_y_nw, 0, 0 };
-
- g_return_if_fail (!window->override_redirect);
-
- 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;
-
- 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->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_internal (window,
- move_resize_flags |
- META_MOVE_RESIZE_MOVE_ACTION |
- META_MOVE_RESIZE_RESIZE_ACTION,
- META_GRAVITY_NORTH_WEST,
- window->unconstrained_rect);
-}
-
-/**
- * meta_window_move_resize_frame:
- * @window: a #MetaWindow
- * @user_op: bool to indicate whether or not this is a user operation
- * @root_x_nw: new x
- * @root_y_nw: new y
- * @w: desired width
- * @h: desired height
- *
- * Resizes the window so that its outer bounds (including frame)
- * fit within the given rect
- */
-void
-meta_window_move_resize_frame (MetaWindow *window,
- gboolean user_op,
- int root_x_nw,
- int root_y_nw,
- int w,
- int h)
-{
- MetaMoveResizeFlags flags;
- MetaRectangle rect = { root_x_nw, root_y_nw, w, h };
-
- g_return_if_fail (!window->override_redirect);
-
- 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);
-}
-
-/**
- * meta_window_move_to_monitor:
- * @window: a #MetaWindow
- * @monitor: desired monitor index
- *
- * Moves the window to the monitor with index @monitor, keeping
- * the relative position of the window's top left corner.
- */
-void
-meta_window_move_to_monitor (MetaWindow *window,
- int monitor)
-{
- MetaRectangle old_area, new_area;
-
- if (window->tile_mode != META_TILE_NONE)
- window->tile_monitor_number = monitor;
-
- meta_window_get_work_area_for_monitor (window,
- window->monitor->number,
- &old_area);
- meta_window_get_work_area_for_monitor (window,
- monitor,
- &new_area);
-
- 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;
-
- if (window->fullscreen || window->override_redirect)
- meta_display_queue_check_fullscreen (window->display);
-}
-
-static void
-adjust_size_for_tile_match (MetaWindow *window,
- int *new_w,
- int *new_h)
-{
- MetaRectangle work_area, rect;
- MetaWindow *tile_match = window->tile_match;
-
- if (!META_WINDOW_TILED_SIDE_BY_SIDE (window) || !tile_match)
- return;
-
- 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);
-}
-
-void
-meta_window_resize_frame_with_gravity (MetaWindow *window,
- gboolean user_op,
- int w,
- int h,
- MetaGravity gravity)
-{
- MetaMoveResizeFlags flags;
- MetaRectangle rect;
-
- rect.width = w;
- rect.height = 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)
-{
- 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
-idle_move_resize (gpointer data)
-{
- GSList *tmp;
- GSList *copy;
- guint queue_index = GPOINTER_TO_INT (data);
-
- meta_topic (META_DEBUG_GEOMETRY, "Clearing the move_resize queue");
-
- /* 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 move_resizes.
- */
- 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;
-
- destroying_windows_disallowed += 1;
-
- tmp = copy;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- /* As a side effect, sets window->move_resize_queued = FALSE */
- meta_window_move_resize_now (window);
-
- tmp = tmp->next;
- }
-
- g_slist_free (copy);
-
- destroying_windows_disallowed -= 1;
-
- return FALSE;
-}
-
-void
-meta_window_get_gravity_position (MetaWindow *window,
- MetaGravity gravity,
- int *root_x,
- int *root_y)
-{
- MetaRectangle frame_extents;
- int w, h;
- int x, y;
-
- w = window->rect.width;
- h = window->rect.height;
-
- if (gravity == META_GRAVITY_STATIC)
- {
- frame_extents = window->rect;
- if (window->frame)
- {
- frame_extents.x = window->frame->rect.x + window->frame->child_x;
- frame_extents.y = window->frame->rect.y + window->frame->child_y;
- }
- }
- else
- {
- if (window->frame == NULL)
- frame_extents = window->rect;
- else
- frame_extents = window->frame->rect;
- }
-
- x = frame_extents.x;
- y = frame_extents.y;
-
- switch (gravity)
- {
- 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 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. */
- x -= w;
- break;
- default:
- break;
- }
-
- switch (gravity)
- {
- 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 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 */
- y -= h;
- break;
- default:
- break;
- }
-
- if (root_x)
- *root_x = x;
- if (root_y)
- *root_y = y;
-}
-
-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,
- x, y);
-
- *width = (window->rect.width - window->size_hints.base_width) /
- window->size_hints.width_inc;
- *height = (window->rect.height - window->size_hints.base_height) /
- window->size_hints.height_inc;
-}
-
-/**
- * meta_window_get_buffer_rect:
- * @window: a #MetaWindow
- * @rect: (out): pointer to an allocated #MetaRectangle
- *
- * 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_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)
- {
- 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
- {
- 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_frame_rect_to_client_rect:
- * @window: a #MetaWindow
- * @frame_rect: desired frame bounds for the window
- * @client_rect: (out): location to store the computed corresponding client rectangle.
- *
- * Converts a desired frame bounds for a window into the bounds of the client
- * window.
- */
-void
-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;
- meta_frame_calc_borders (window->frame, &borders);
-
- 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
- {
- 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 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)
-{
- MetaFrameBorders borders;
-
- meta_frame_calc_borders (window->frame, &borders);
-
- rect->x = borders.total.left;
- rect->y = borders.total.top;
-
- rect->width = window->buffer_rect.width - borders.total.left - borders.total.right;
- if (window->shaded)
- rect->height = 0;
- else
- rect->height = window->buffer_rect.height - borders.total.top - borders.total.bottom;
-}
-
-void
-meta_window_get_titlebar_rect (MetaWindow *window,
- MetaRectangle *rect)
-{
- meta_window_get_frame_rect (window, rect);
-
- /* The returned rectangle is relative to the frame rect. */
- rect->x = 0;
- rect->y = 0;
-
- if (window->frame)
- {
- rect->height = window->frame->child_y;
- }
- else
- {
- /* Pick an arbitrary height for a titlebar. We might want to
- * eventually have CSD windows expose their borders to us. */
- rect->height = 50;
- }
-}
-
-const char*
-meta_window_get_startup_id (MetaWindow *window)
-{
- if (window->startup_id == NULL)
- {
- MetaGroup *group;
-
- group = meta_window_get_group (window);
-
- if (group != NULL)
- return meta_group_get_startup_id (group);
- }
-
- return window->startup_id;
-}
-
-static MetaWindow*
-get_modal_transient (MetaWindow *window)
-{
- GSList *windows;
- GSList *tmp;
- MetaWindow *modal_transient;
-
- /* A window can't be the transient of itself, but this is just for
- * convenience in the loop below; we manually fix things up at the
- * end if no real modal transient was found.
- */
- modal_transient = window;
-
- windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *transient = tmp->data;
-
- if (transient->transient_for == modal_transient &&
- transient->type == META_WINDOW_MODAL_DIALOG)
- {
- modal_transient = transient;
- tmp = windows;
- continue;
- }
-
- tmp = tmp->next;
- }
-
- g_slist_free (windows);
-
- if (window == modal_transient)
- modal_transient = NULL;
-
- 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 */
-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 focusable: %d",
- window->desc, window->input, meta_window_is_focusable (window));
-
- if (window->display->grab_window &&
- 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",
- window->display->grab_window->desc, window->desc);
- return;
- }
-
- modal_transient = get_modal_transient (window);
- if (modal_transient != NULL &&
- !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.",
- window->desc, modal_transient->desc);
- 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;
- }
-
- meta_window_flush_calc_showing (window);
-
- if ((!window->mapped || window->hidden) && !window->shaded)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Window %s is not showing, not focusing after all",
- window->desc);
- return;
- }
-
- META_WINDOW_GET_CLASS (window)->focus (window, timestamp);
-
- if (window->display->event_route == META_EVENT_ROUTE_NORMAL)
- {
- MetaBackend *backend = meta_get_backend ();
- ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
- clutter_stage_set_key_focus (stage, NULL);
- }
-
- 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
-set_workspace_state (MetaWindow *window,
- gboolean on_all_workspaces,
- MetaWorkspace *workspace)
-{
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
-
- /* 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 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)
- {
- GList *l;
- for (l = workspace_manager->workspaces; l != NULL; l = l->next)
- {
- MetaWorkspace *ws = l->data;
- meta_workspace_add_window (ws, window);
- }
- }
-
- /* 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)
- 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;
-
- 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)
- {
- 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
-change_workspace_foreach (MetaWindow *window,
- void *data)
-{
- meta_window_change_workspace_without_transients (window, data);
- return TRUE;
-}
-
-void
-meta_window_change_workspace (MetaWindow *window,
- MetaWorkspace *workspace)
-{
- g_return_if_fail (!window->override_redirect);
-
- meta_window_change_workspace_without_transients (window, workspace);
-
- meta_window_foreach_transient (window, change_workspace_foreach,
- workspace);
- meta_window_foreach_ancestor (window, change_workspace_foreach,
- workspace);
-}
-
-static void
-window_stick_impl (MetaWindow *window)
-{
- meta_verbose ("Sticking window %s current on_all_workspaces = %d",
- window->desc, window->on_all_workspaces);
-
- if (window->on_all_workspaces_requested)
- return;
-
- /* We don't change window->workspaces, because we revert
- * to that original workspace list if on_all_workspaces is
- * toggled back off.
- */
- window->on_all_workspaces_requested = TRUE;
- meta_window_on_all_workspaces_changed (window);
-}
-
-static void
-window_unstick_impl (MetaWindow *window)
-{
- if (!window->on_all_workspaces_requested)
- return;
-
- /* Revert to window->workspaces */
-
- window->on_all_workspaces_requested = FALSE;
- meta_window_on_all_workspaces_changed (window);
-}
-
-static gboolean
-stick_foreach_func (MetaWindow *window,
- void *data)
-{
- gboolean stick;
-
- stick = *(gboolean*)data;
- if (stick)
- window_stick_impl (window);
- else
- window_unstick_impl (window);
- return TRUE;
-}
-
-void
-meta_window_stick (MetaWindow *window)
-{
- gboolean stick = TRUE;
-
- g_return_if_fail (!window->override_redirect);
-
- window_stick_impl (window);
- meta_window_foreach_transient (window,
- stick_foreach_func,
- &stick);
-}
-
-void
-meta_window_unstick (MetaWindow *window)
-{
- gboolean stick = FALSE;
-
- g_return_if_fail (!window->override_redirect);
-
- window_unstick_impl (window);
- meta_window_foreach_transient (window,
- stick_foreach_func,
- &stick);
-}
-
-void
-meta_window_current_workspace_changed (MetaWindow *window)
-{
- META_WINDOW_GET_CLASS (window)->current_workspace_changed (window);
-}
-
-static gboolean
-find_root_ancestor (MetaWindow *window,
- void *data)
-{
- MetaWindow **ancestor = data;
-
- /* Overwrite the previously "most-root" ancestor with the new one found */
- *ancestor = window;
-
- /* We want this to continue until meta_window_foreach_ancestor quits because
- * there are no more valid ancestors.
- */
- return TRUE;
-}
-
-/**
- * meta_window_find_root_ancestor:
- * @window: a #MetaWindow
- *
- * Follow the chain of parents of @window, skipping transient windows,
- * and return the "root" window which has no non-transient parent.
- *
- * Returns: (transfer none): The root ancestor window
- */
-MetaWindow *
-meta_window_find_root_ancestor (MetaWindow *window)
-{
- MetaWindow *ancestor;
- ancestor = window;
- meta_window_foreach_ancestor (window, find_root_ancestor, &ancestor);
- return ancestor;
-}
-
-void
-meta_window_raise (MetaWindow *window)
-{
- MetaWindow *ancestor;
-
- g_return_if_fail (!window->override_redirect);
-
- ancestor = meta_window_find_root_ancestor (window);
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Raising window %s, ancestor of %s",
- ancestor->desc, window->desc);
-
- /* Raise the ancestor of the window (if the window has no ancestor,
- * then ancestor will be set to the window itself); do this because
- * it's weird to see windows from other apps stacked between a child
- * and parent window of the currently active app. The stacking
- * constraints in stack.c then magically take care of raising all
- * the child windows appropriately.
- */
- 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->display->stack != "
- "ancestor->screen->stack. window = %s, ancestor = %s.",
- window->desc, ancestor->desc);
- /* We could raise the window here, but don't want to do that twice and
- * so we let the case below handle that.
- */
- }
-
- /* Okay, so stacking constraints misses one case: If a window has
- * two children and we want to raise one of those children, then
- * raising the ancestor isn't enough; we need to also raise the
- * correct child. See bug 307875.
- */
- if (window != ancestor)
- meta_stack_raise (window->display->stack, window);
-
- g_signal_emit (window, window_signals[RAISED], 0);
-}
-
-void
-meta_window_lower (MetaWindow *window)
-{
- g_return_if_fail (!window->override_redirect);
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Lowering window %s", window->desc);
-
- meta_stack_lower (window->display->stack, window);
-}
-
-/*
- * Move window to the requested workspace; append controls whether new WS
- * should be created if one does not exist.
- */
-void
-meta_window_change_workspace_by_index (MetaWindow *window,
- gint space_index,
- gboolean append)
-{
- MetaWorkspaceManager *workspace_manager;
- MetaWorkspace *workspace;
- MetaDisplay *display;
-
- g_return_if_fail (!window->override_redirect);
-
- if (space_index == -1)
- {
- meta_window_stick (window);
- return;
- }
-
- display = window->display;
- workspace_manager = display->workspace_manager;
-
- workspace =
- meta_workspace_manager_get_workspace_by_index (workspace_manager, space_index);
-
- if (!workspace && append)
- workspace = meta_workspace_manager_append_new_workspace (workspace_manager, FALSE, META_CURRENT_TIME);
-
- if (workspace)
- meta_window_change_workspace (window, workspace);
-}
-
-static void
-meta_window_appears_focused_changed (MetaWindow *window)
-{
- set_net_wm_state (window);
- meta_window_frame_size_changed (window);
-
- g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_APPEARS_FOCUSED]);
-
- if (window->frame)
- meta_frame_queue_draw (window->frame);
-}
-
-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;
-
- /* Parents of these sorts of override-redirect windows should
- * appear focused. */
- switch (window->type)
- {
- 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;
- default:
- break;
- }
-
- return FALSE;
-}
-
-/**
- * meta_window_propagate_focus_appearance:
- * @window: the window to start propagating from
- * @focused: %TRUE if @window's ancestors should appear focused,
- * %FALSE if they should not.
- *
- * Adjusts the value of #MetaWindow:appears-focused on @window's
- * ancestors (but not @window itself). If @focused is %TRUE, each of
- * @window's ancestors will have its %attached_focus_window field set
- * to the current %focus_window. If @focused if %FALSE, each of
- * @window's ancestors will have its %attached_focus_window field
- * cleared if it is currently %focus_window.
- */
-static void
-meta_window_propagate_focus_appearance (MetaWindow *window,
- gboolean focused)
-{
- MetaWindow *child, *parent, *focus_window;
-
- focus_window = window->display->focus_window;
-
- child = window;
- parent = meta_window_get_transient_for (child);
- while (parent && (!focused || should_propagate_focus_appearance (child)))
- {
- gboolean child_focus_state_changed;
-
- if (focused)
- {
- if (parent->attached_focus_window == focus_window)
- break;
- child_focus_state_changed = (parent->attached_focus_window == NULL);
- parent->attached_focus_window = focus_window;
- }
- else
- {
- if (parent->attached_focus_window != focus_window)
- break;
- child_focus_state_changed = (parent->attached_focus_window != NULL);
- parent->attached_focus_window = NULL;
- }
-
- if (child_focus_state_changed && !parent->has_focus)
- {
- meta_window_appears_focused_changed (parent);
- }
-
- child = parent;
- parent = meta_window_get_transient_for (child);
- }
-}
-
-void
-meta_window_set_focused_internal (MetaWindow *window,
- gboolean focused)
-{
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
-
- if (focused)
- {
- window->has_focus = TRUE;
- if (window->override_redirect)
- return;
-
- /* 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))
- {
- 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_prepend (workspace_manager->active_workspace->mru_list,
- window);
- }
-
- if (window->frame)
- meta_frame_queue_draw (window->frame);
-
- /* 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 () == G_DESKTOP_FOCUS_MODE_CLICK ||
- !meta_prefs_get_raise_on_click())
- {
- 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);
- }
-
- g_signal_emit (window, window_signals[FOCUS], 0);
-
- if (!window->attached_focus_window)
- meta_window_appears_focused_changed (window);
-
- meta_window_propagate_focus_appearance (window, TRUE);
- }
- else
- {
- window->has_focus = FALSE;
- if (window->override_redirect)
- return;
-
- meta_window_propagate_focus_appearance (window, FALSE);
-
- if (!window->attached_focus_window)
- meta_window_appears_focused_changed (window);
-
- /* Re-grab for click to focus and raise-on-click, if necessary */
- if (meta_prefs_get_focus_mode () == G_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.
- *
- * Gets the location of the icon corresponding to the window. The location
- * will be provided set by the task bar or other user interface element
- * displaying the icon, and is relative to the root window.
- *
- * Return value: %TRUE if the icon geometry was successfully retrieved.
- */
-gboolean
-meta_window_get_icon_geometry (MetaWindow *window,
- MetaRectangle *rect)
-{
- g_return_val_if_fail (!window->override_redirect, FALSE);
-
- if (window->icon_geometry_set)
- {
- if (rect)
- *rect = window->icon_geometry;
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- * meta_window_set_icon_geometry:
- * @window: a #MetaWindow
- * @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
- * interface element displaying the icon, and is relative to the root window.
- */
-void
-meta_window_set_icon_geometry (MetaWindow *window,
- MetaRectangle *rect)
-{
- if (rect)
- {
- window->icon_geometry = *rect;
- window->icon_geometry_set = TRUE;
- }
- else
- {
- window->icon_geometry_set = FALSE;
- }
-}
-
-static void
-redraw_icon (MetaWindow *window)
-{
- /* We could probably be smart and just redraw the icon here,
- * instead of the whole frame.
- */
- if (window->frame)
- meta_frame_queue_draw (window->frame);
-}
-
-static void
-meta_window_update_icon_now (MetaWindow *window,
- gboolean force)
-{
- gboolean changed;
- cairo_surface_t *icon = NULL;
- cairo_surface_t *mini_icon;
-
- g_return_if_fail (!window->override_redirect);
-
- changed = META_WINDOW_GET_CLASS (window)->update_icon (window, &icon, &mini_icon);
-
- if (changed || force)
- {
- if (window->icon)
- cairo_surface_destroy (window->icon);
- window->icon = icon;
-
- if (window->mini_icon)
- cairo_surface_destroy (window->mini_icon);
- window->mini_icon = mini_icon;
-
- 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));
-
- redraw_icon (window);
- }
-}
-
-static gboolean
-idle_update_icon (gpointer data)
-{
- GSList *tmp;
- GSList *copy;
- guint queue_index = GPOINTER_TO_INT (data);
-
- meta_topic (META_DEBUG_GEOMETRY, "Clearing the update_icon queue");
-
- /* 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;
-
- destroying_windows_disallowed += 1;
-
- tmp = copy;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- meta_window_update_icon_now (window, FALSE);
- window->is_in_queues &= ~META_QUEUE_UPDATE_ICON;
-
- tmp = tmp->next;
- }
-
- g_slist_free (copy);
-
- destroying_windows_disallowed -= 1;
-
- return FALSE;
-}
-
-GList*
-meta_window_get_workspaces (MetaWindow *window)
-{
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
-
- if (window->on_all_workspaces)
- return workspace_manager->workspaces;
- else if (window->workspace != NULL)
- return window->workspace->list_containing_self;
- else if (window->constructing)
- return NULL;
- else
- g_assert_not_reached ();
- return NULL;
-}
-
-static void
-invalidate_work_areas (MetaWindow *window)
-{
- GList *tmp;
-
- tmp = meta_window_get_workspaces (window);
-
- while (tmp != NULL)
- {
- meta_workspace_invalidate_work_area (tmp->data);
- tmp = tmp->next;
- }
-}
-
-void
-meta_window_update_struts (MetaWindow *window)
-{
- if (META_WINDOW_GET_CLASS (window)->update_struts (window))
- invalidate_work_areas (window);
-}
-
-static void
-meta_window_type_changed (MetaWindow *window)
-{
- gboolean old_decorated = window->decorated;
- GObject *object = G_OBJECT (window);
-
- window->attached = meta_window_should_attach_to_parent (window);
- meta_window_recalc_features (window);
-
- if (!window->override_redirect)
- set_net_wm_state (window);
-
- /* Update frame */
- if (window->decorated)
- meta_window_ensure_frame (window);
- else
- meta_window_destroy_frame (window);
-
- /* update stacking constraints */
- meta_window_update_layer (window);
-
- meta_window_grab_keys (window);
-
- g_object_freeze_notify (object);
-
- if (old_decorated != window->decorated)
- g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_DECORATED]);
-
- g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_WINDOW_TYPE]);
-
- g_object_thaw_notify (object);
-}
-
-void
-meta_window_set_type (MetaWindow *window,
- MetaWindowType type)
-{
- if (window->type == type)
- return;
-
- window->type = type;
- meta_window_type_changed (window);
-}
-
-void
-meta_window_frame_size_changed (MetaWindow *window)
-{
- if (window->frame)
- meta_frame_clear_cached_borders (window->frame);
-}
-
-static void
-meta_window_get_default_skip_hints (MetaWindow *window,
- gboolean *skip_taskbar_out,
- gboolean *skip_pager_out)
-{
- META_WINDOW_GET_CLASS (window)->get_default_skip_hints (window, skip_taskbar_out, skip_pager_out);
-}
-
-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;
-
- 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 = window->skip_from_window_list;
- break;
-
- 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_from_window_list;
- window->skip_pager = skip_pager_hint | window->skip_from_window_list;
- }
- break;
- }
-}
-
-void
-meta_window_recalc_features (MetaWindow *window)
-{
- gboolean old_has_close_func;
- gboolean old_has_minimize_func;
- gboolean old_has_move_func;
- gboolean old_has_resize_func;
- gboolean old_has_shade_func;
- gboolean old_always_sticky;
- gboolean old_skip_taskbar;
-
- old_has_close_func = window->has_close_func;
- old_has_minimize_func = window->has_minimize_func;
- old_has_move_func = window->has_move_func;
- old_has_resize_func = window->has_resize_func;
- old_has_shade_func = window->has_shade_func;
- old_always_sticky = window->always_sticky;
- old_skip_taskbar = window->skip_taskbar;
-
- /* Use MWM hints initially */
- 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;
- window->has_maximize_func = window->mwm_has_maximize_func;
- window->has_move_func = window->mwm_has_move_func;
-
- window->has_resize_func = TRUE;
-
- /* If min_size == max_size, then don't allow resize */
- if (window->size_hints.min_width == window->size_hints.max_width &&
- window->size_hints.min_height == window->size_hints.max_height)
- window->has_resize_func = FALSE;
- else if (!window->mwm_has_resize_func)
- {
- /* 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.
- */
-
- meta_warning ("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.",
- window->desc,
- window->size_hints.min_width,
- window->size_hints.min_height,
- window->size_hints.max_width,
- window->size_hints.max_height);
- }
-
- window->has_shade_func = TRUE;
- window->has_fullscreen_func = TRUE;
-
- window->always_sticky = FALSE;
-
- /* Semantic category overrides the MWM hints */
- if (window->type == META_WINDOW_TOOLBAR)
- window->decorated = FALSE;
-
- if (window->type == META_WINDOW_DESKTOP ||
- window->type == META_WINDOW_DOCK ||
- window->override_redirect)
- window->always_sticky = TRUE;
-
- if (window->override_redirect ||
- meta_window_get_frame_type (window) == META_FRAME_TYPE_LAST)
- {
- window->decorated = FALSE;
- window->has_close_func = FALSE;
- window->has_shade_func = FALSE;
-
- /* FIXME this keeps panels and things from using
- * NET_WM_MOVERESIZE; the problem is that some
- * panels (edge panels) have fixed possible locations,
- * and others ("floating panels") do not.
- *
- * Perhaps we should require edge panels to explicitly
- * disable movement?
- */
- window->has_move_func = FALSE;
- window->has_resize_func = FALSE;
- }
-
- if (window->type != META_WINDOW_NORMAL)
- {
- window->has_minimize_func = FALSE;
- window->has_maximize_func = FALSE;
- window->has_fullscreen_func = FALSE;
- }
-
- 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 == display_rect.width &&
- window->size_hints.min_height == display_rect.height)
- ; /* leave fullscreen available */
- else
- window->has_fullscreen_func = FALSE;
- }
-
- /* We leave fullscreen windows decorated, just push the frame outside
- * the screen. This avoids flickering to unparent them.
- *
- * Note that setting has_resize_func = FALSE here must come after the
- * above code that may disable fullscreen, because if the window
- * is not resizable purely due to fullscreen, we don't want to
- * disable fullscreen mode.
- */
- if (window->fullscreen)
- {
- window->has_shade_func = FALSE;
- window->has_move_func = FALSE;
- window->has_resize_func = FALSE;
- window->has_maximize_func = FALSE;
- }
-
- if (window->has_maximize_func && window->monitor)
- {
- MetaRectangle work_area, client_rect;
-
- meta_window_get_work_area_current_monitor (window, &work_area);
- meta_window_frame_rect_to_client_rect (window, &work_area, &client_rect);
-
- if (window->size_hints.min_width >= client_rect.width ||
- window->size_hints.min_height >= client_rect.height)
- window->has_maximize_func = FALSE;
- }
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Window %s fullscreen = %d not resizable, maximizable = %d fullscreenable = %d min size %dx%d max size %dx%d",
- window->desc,
- window->fullscreen,
- window->has_maximize_func, window->has_fullscreen_func,
- window->size_hints.min_width,
- window->size_hints.min_height,
- window->size_hints.max_width,
- window->size_hints.max_height);
-
- /* no shading if not decorated */
- if (!window->decorated || window->border_only)
- window->has_shade_func = FALSE;
-
- meta_window_recalc_skip_features (window);
-
- /* 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",
- window->desc,
- window->decorated,
- window->border_only,
- window->has_close_func,
- window->has_minimize_func,
- window->has_maximize_func,
- window->has_move_func,
- window->has_shade_func,
- 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_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 ||
- old_has_minimize_func != window->has_minimize_func ||
- old_has_move_func != window->has_move_func ||
- old_has_resize_func != window->has_resize_func ||
- old_has_shade_func != window->has_shade_func ||
- old_always_sticky != window->always_sticky)
- set_allowed_actions_hint (window);
-
- if (window->has_resize_func != old_has_resize_func)
- g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_RESIZEABLE]);
-
- meta_window_frame_size_changed (window);
-
- /* FIXME perhaps should ensure if we don't have a shade func,
- * we aren't shaded, etc.
- */
-}
-
-void
-meta_window_show_menu (MetaWindow *window,
- MetaWindowMenuType menu,
- int x,
- int y)
-{
- g_return_if_fail (!window->override_redirect);
- meta_compositor_show_window_menu (window->display->compositor, window, menu, x, y);
-}
-
-void
-meta_window_show_menu_for_rect (MetaWindow *window,
- MetaWindowMenuType menu,
- MetaRectangle *rect)
-{
- g_return_if_fail (!window->override_redirect);
- meta_compositor_show_window_menu_for_rect (window->display->compositor, window, menu, rect);
-}
-
-void
-meta_window_shove_titlebar_onscreen (MetaWindow *window)
-{
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
- MetaRectangle frame_rect;
- GList *onscreen_region;
- int horiz_amount, vert_amount;
-
- g_return_if_fail (!window->override_redirect);
-
- /* If there's no titlebar, don't bother */
- if (!window->frame)
- return;
-
- /* Get the basic info we need */
- 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 = frame_rect.width;
- vert_amount = frame_rect.height;
- meta_rectangle_expand_region (onscreen_region,
- horiz_amount,
- horiz_amount,
- 0,
- vert_amount);
- meta_rectangle_shove_into_region(onscreen_region,
- FIXED_DIRECTION_X,
- &frame_rect);
- meta_rectangle_expand_region (onscreen_region,
- -horiz_amount,
- -horiz_amount,
- 0,
- -vert_amount);
-
- meta_window_move_frame (window, FALSE, frame_rect.x, frame_rect.y);
-}
-
-gboolean
-meta_window_titlebar_is_onscreen (MetaWindow *window)
-{
- 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 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 TRUE;
-
- /* Get the rectangle corresponding to the titlebar */
- 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 = workspace_manager->active_workspace->screen_region;
- while (onscreen_region)
- {
- MetaRectangle *spanning_rect = onscreen_region->data;
- MetaRectangle overlap;
-
- meta_rectangle_intersect (&titlebar_rect, spanning_rect, &overlap);
- if (overlap.height > MIN (titlebar_rect.height, min_height_needed) &&
- overlap.width > MIN (titlebar_rect.width * min_width_percent,
- min_width_absolute))
- {
- is_onscreen = TRUE;
- break;
- }
-
- onscreen_region = onscreen_region->next;
- }
-
- return is_onscreen;
-}
-
-static gboolean
-check_moveresize_frequency (MetaWindow *window,
- gdouble *remaining)
-{
- 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;
-
- current_time = g_get_real_time ();
-
- /* 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;
-
- elapsed = (current_time - window->display->grab_last_moveresize_time) / 1000;
-
- if (elapsed >= 0.0 && elapsed < ms_between_resizes)
- {
- meta_topic (META_DEBUG_RESIZING,
- "Delaying move/resize as only %g of %g ms elapsed",
- elapsed, ms_between_resizes);
-
- if (remaining)
- *remaining = (ms_between_resizes - elapsed);
-
- return FALSE;
- }
-
- meta_topic (META_DEBUG_RESIZING,
- " Checked moveresize freq, allowing move/resize now (%g of %g seconds elapsed)",
- elapsed / 1000.0, 1.0 / max_resizes_per_second);
-
- return TRUE;
-}
-
-static gboolean
-update_move_timeout (gpointer data)
-{
- MetaWindow *window = data;
-
- update_move (window,
- window->display->grab_last_edge_resistance_flags,
- window->display->grab_latest_motion_x,
- window->display->grab_latest_motion_y);
-
- return FALSE;
-}
-
-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;
-
- /* 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;
-
- meta_window_get_work_area_for_monitor (window,
- logical_monitor->number,
- &work_area);
-
- /* 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))
- 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;
-
- if (display->preview_tile_mode != META_TILE_NONE)
- window->tile_monitor_number = logical_monitor->number;
-}
-
-static void
-update_move (MetaWindow *window,
- MetaEdgeResistanceFlags flags,
- int x,
- int y)
-{
- int dx, dy;
- int new_x, new_y;
- MetaRectangle old;
- int shake_threshold;
- MetaDisplay *display = window->display;
-
- display->grab_latest_motion_x = x;
- display->grab_latest_motion_y = y;
-
- dx = x - display->grab_anchor_root_x;
- dy = y - display->grab_anchor_root_y;
-
- new_x = display->grab_anchor_window_pos.x + dx;
- new_y = display->grab_anchor_window_pos.y + dy;
-
- meta_verbose ("x,y = %d,%d anchor ptr %d,%d anchor pos %d,%d dx,dy %d,%d",
- x, y,
- display->grab_anchor_root_x,
- display->grab_anchor_root_y,
- display->grab_anchor_window_pos.x,
- display->grab_anchor_window_pos.y,
- dx, dy);
-
- /* 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.
- */
- if (dx == 0 && dy == 0)
- return;
-
- /* Originally for detaching maximized windows, but we use this
- * 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 (flags & META_EDGE_RESISTANCE_SNAP)
- {
- /* We don't want to tile while snapping. Also, clear any previous tile
- request. */
- display->preview_tile_mode = META_TILE_NONE;
- window->tile_monitor_number = -1;
- }
- 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);
- }
-
- /* 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.
- */
-
- 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;
-
- /* Shake loose, so that the window snaps back to maximized
- * when dragged near the top; do not snap back if tiling
- * is enabled, as top edge tiling can be used in that case
- */
- window->shaken_loose = !meta_prefs_get_edge_tiling ();
- window->tile_mode = META_TILE_NONE;
-
- /* move the unmaximized window to the cursor */
- prop =
- ((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;
-
- /* 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)
- {
- 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_BOTH);
- return;
- }
-
- /* remaximize window on another monitor if window has been shaken
- * 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)
- {
- 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 = window->monitor;
- n_logical_monitors =
- meta_monitor_manager_get_num_logical_monitors (monitor_manager);
-
- for (monitor = 0; monitor < n_logical_monitors; monitor++)
- {
- meta_window_get_work_area_for_monitor (window, monitor, &work_area);
-
- /* check if cursor is near the top of a monitor work area */
- if (x >= work_area.x &&
- x < (work_area.x + work_area.width) &&
- y >= work_area.y &&
- 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
- */
- if (wmonitor->number != monitor)
- {
- window->saved_rect.x = work_area.x;
- window->saved_rect.y = work_area.y;
-
- if (window->frame)
- {
- window->saved_rect.x += window->frame->child_x;
- window->saved_rect.y += window->frame->child_y;
- }
-
- window->unconstrained_rect.x = window->saved_rect.x;
- window->unconstrained_rect.y = window->saved_rect.y;
-
- 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;
-
- meta_window_maximize (window, META_MAXIMIZE_BOTH);
- }
-
- return;
- }
- }
- }
-
- /* 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_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))
- new_x = old.x;
- if (window->maximized_vertically)
- new_y = old.y;
-
- /* Do any edge resistance/snapping */
- meta_window_edge_resistance_for_move (window,
- &new_x,
- &new_y,
- update_move_timeout,
- flags);
-
- meta_window_move_frame (window, TRUE, new_x, new_y);
-}
-
-static gboolean
-update_resize_timeout (gpointer data)
-{
- MetaWindow *window = data;
-
- update_resize (window,
- window->display->grab_last_edge_resistance_flags,
- window->display->grab_latest_motion_x,
- window->display->grab_latest_motion_y,
- TRUE);
- return FALSE;
-}
-
-static void
-update_resize (MetaWindow *window,
- MetaEdgeResistanceFlags flags,
- int x,
- int y,
- gboolean force)
-{
- int dx, dy;
- 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;
-
- dx = x - window->display->grab_anchor_root_x;
- dy = y - window->display->grab_anchor_root_y;
-
- /* Attached modal dialogs are special in that size
- * changes apply to both sides, so that the dialog
- * remains centered to the parent.
- */
- if (meta_window_is_attached_dialog (window))
- {
- dx *= 2;
- dy *= 2;
- }
-
- 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)
- {
- MetaGrabOp op = META_GRAB_OP_WINDOW_BASE | META_GRAB_OP_WINDOW_FLAG_KEYBOARD;
-
- if (dx > 0)
- op |= META_GRAB_OP_WINDOW_DIR_EAST;
- else if (dx < 0)
- op |= META_GRAB_OP_WINDOW_DIR_WEST;
-
- if (dy > 0)
- op |= META_GRAB_OP_WINDOW_DIR_SOUTH;
- else if (dy < 0)
- op |= META_GRAB_OP_WINDOW_DIR_NORTH;
-
- window->display->grab_op = op;
-
- meta_window_update_keyboard_resize (window, TRUE);
- }
-
- 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;
-
- if (!check_moveresize_frequency (window, &remaining) && !force)
- {
- /* we are ignoring an event here, so we schedule a
- * compensation event when we would otherwise not ignore
- * an event. Otherwise we can become stuck if the user never
- * generates another event.
- */
- if (!window->display->grab_resize_timeout_id)
- {
- 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 */
- g_clear_handle_id (&window->display->grab_resize_timeout_id, g_source_remove);
-
- 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.
- */
-
- if ((window->display->grab_op & (META_GRAB_OP_WINDOW_DIR_WEST | META_GRAB_OP_WINDOW_DIR_EAST)) == 0)
- new_rect.width = old_rect.width;
-
- 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 */
- 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,
- &new_rect.width,
- &new_rect.height,
- gravity,
- update_resize_timeout,
- flags);
-
- meta_window_resize_frame_with_gravity (window, TRUE,
- new_rect.width, new_rect.height,
- gravity);
-
- /* Store the latest resize time, if we actually resized. */
- if (window->rect.width != old_rect.width ||
- window->rect.height != old_rect.height)
- window->display->grab_last_moveresize_time = g_get_real_time ();
-}
-
-static void
-maybe_maximize_tiled_window (MetaWindow *window)
-{
- MetaRectangle work_area;
- gint shake_threshold;
-
- if (!META_WINDOW_TILED_SIDE_BY_SIDE (window))
- return;
-
- shake_threshold = meta_prefs_get_drag_threshold ();
-
- 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);
-}
-
-void
-meta_window_update_resize (MetaWindow *window,
- MetaEdgeResistanceFlags flags,
- int x, int y,
- gboolean force)
-{
- update_resize (window, flags, x, y, force);
-}
-
-static void
-end_grab_op (MetaWindow *window,
- const ClutterEvent *event)
-{
- ClutterModifierType modifiers;
- MetaEdgeResistanceFlags last_flags;
- gfloat x, y;
-
- clutter_event_get_coords (event, &x, &y);
- modifiers = clutter_event_get_state (event);
- meta_display_check_threshold_reached (window->display, x, y);
-
- /* 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.
- */
- last_flags = window->display->grab_last_edge_resistance_flags;
- if ((last_flags & META_EDGE_RESISTANCE_SNAP) == 0)
- {
- MetaEdgeResistanceFlags flags = META_EDGE_RESISTANCE_DEFAULT;
-
- if (modifiers & CLUTTER_SHIFT_MASK)
- flags |= META_EDGE_RESISTANCE_SNAP;
-
- if (modifiers & CLUTTER_CONTROL_MASK)
- flags |= META_EDGE_RESISTANCE_WINDOWS;
-
- if (meta_grab_op_is_moving (window->display->grab_op))
- {
- if (window->display->preview_tile_mode != META_TILE_NONE)
- meta_window_tile (window, window->display->preview_tile_mode);
- else
- update_move (window, flags, x, y);
- }
- else if (meta_grab_op_is_resizing (window->display->grab_op))
- {
- if (window->tile_match != NULL)
- flags |= (META_EDGE_RESISTANCE_SNAP | META_EDGE_RESISTANCE_WINDOWS);
-
- update_resize (window, flags, x, y, TRUE);
- maybe_maximize_tiled_window (window);
- }
- }
- window->display->preview_tile_mode = META_TILE_NONE;
- meta_display_end_grab_op (window->display, clutter_event_get_time (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;
- MetaEdgeResistanceFlags flags;
- gfloat x, y;
-
- switch (event->type)
- {
- case CLUTTER_TOUCH_BEGIN:
- if (!meta_display_is_pointer_emulating_sequence (window->display, sequence))
- return FALSE;
-
- return TRUE;
-
- case CLUTTER_BUTTON_PRESS:
- {
- ClutterModifierType grab_mods = meta_display_get_compositor_modifiers (window->display);
-
- /* This is the keybinding or menu case where we've
- * been dragging around the window without the button
- * pressed. */
-
- 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))
- return FALSE;
-
- 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);
-
- return TRUE;
-
- case CLUTTER_TOUCH_UPDATE:
- if (!meta_display_is_pointer_emulating_sequence (window->display, sequence))
- return FALSE;
-
- /* Fall through */
- case CLUTTER_MOTION:
- modifier_state = clutter_event_get_state (event);
- clutter_event_get_coords (event, &x, &y);
- flags = META_EDGE_RESISTANCE_DEFAULT;
-
- if (modifier_state & CLUTTER_SHIFT_MASK)
- flags |= META_EDGE_RESISTANCE_SNAP;
-
- if (modifier_state & CLUTTER_CONTROL_MASK)
- flags |= META_EDGE_RESISTANCE_WINDOWS;
-
- meta_display_check_threshold_reached (window->display, x, y);
- if (meta_grab_op_is_moving (window->display->grab_op))
- {
- update_move (window, flags, x, y);
- }
- else if (meta_grab_op_is_resizing (window->display->grab_op))
- {
- if (window->tile_match != NULL)
- flags |= (META_EDGE_RESISTANCE_SNAP | META_EDGE_RESISTANCE_WINDOWS);
-
- update_resize (window, flags, x, y, FALSE);
- }
- return TRUE;
-
- case CLUTTER_TOUCH_CANCEL:
- end_grab_op (window, event);
- return FALSE;
-
- default:
- return FALSE;
- }
-}
-
-void
-meta_window_get_work_area_for_logical_monitor (MetaWindow *window,
- MetaLogicalMonitor *logical_monitor,
- MetaRectangle *area)
-{
- GList *tmp;
-
- g_assert (logical_monitor);
-
- /* Initialize to the whole monitor */
- *area = logical_monitor->rect;
-
- tmp = meta_window_get_workspaces (window);
- while (tmp != NULL)
- {
- MetaRectangle 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);
- tmp = tmp->next;
- }
-
- meta_topic (META_DEBUG_WORKAREA,
- "Window %s monitor %d has work area %d,%d %d x %d",
- window->desc, logical_monitor->number,
- area->x, area->y, area->width, area->height);
-}
-
-/**
- * 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)
-{
- meta_window_get_work_area_for_monitor (window,
- window->monitor->number,
- area);
-}
-
-/**
- * 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);
-
- 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);
-}
-
-/**
- * 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 };
-
- 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)
- {
- MetaRectangle workspace_work_area;
- meta_workspace_get_work_area_all_monitors (tmp->data,
- &workspace_work_area);
- meta_rectangle_intersect (area,
- &workspace_work_area,
- area);
- tmp = tmp->next;
- }
-
- meta_topic (META_DEBUG_WORKAREA,
- "Window %s has whole-screen work area %d,%d %d x %d",
- window->desc, area->x, area->y, area->width, area->height);
-}
-
-int
-meta_window_get_current_tile_monitor_number (MetaWindow *window)
-{
- int tile_monitor_number = window->tile_monitor_number;
-
- if (tile_monitor_number < 0)
- {
- meta_warning ("%s called with an invalid monitor number; using 0 instead", G_STRFUNC);
- tile_monitor_number = 0;
- }
-
- return tile_monitor_number;
-}
-
-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 (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);
-
- *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;
-}
-
-gboolean
-meta_window_same_application (MetaWindow *window,
- MetaWindow *other_window)
-{
- MetaGroup *group = meta_window_get_group (window);
- MetaGroup *other_group = meta_window_get_group (other_window);
-
- return
- group!=NULL &&
- other_group!=NULL &&
- group==other_group;
-}
-
-/**
- * meta_window_is_client_decorated:
- *
- * Check if if the window has decorations drawn by the client.
- * (window->decorated refers only to whether we should add decorations)
- */
-gboolean
-meta_window_is_client_decorated (MetaWindow *window)
-{
- if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
- {
- /* Assume all Wayland clients draw decorations - not strictly
- * true but good enough for current purposes.
- */
- return TRUE;
- }
- else
- {
- /* 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;
- }
-}
-
-/**
- * meta_window_foreach_transient:
- * @window: a #MetaWindow
- * @func: (scope call) (closure user_data): Called for each window which is a transient of @window (transitively)
- * @user_data: User data
- *
- * Call @func for every window which is either transient for @window, or is
- * a transient of a window which is in turn transient for @window.
- * The order of window enumeration is not defined.
- *
- * Iteration will stop if @func at any point returns %FALSE.
- */
-void
-meta_window_foreach_transient (MetaWindow *window,
- MetaWindowForeachFunc func,
- void *user_data)
-{
- GSList *windows;
- GSList *tmp;
-
- windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
-
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *transient = tmp->data;
-
- if (meta_window_is_ancestor_of_transient (window, transient))
- {
- if (!(* func) (transient, user_data))
- break;
- }
-
- tmp = tmp->next;
- }
-
- g_slist_free (windows);
-}
-
-/**
- * meta_window_foreach_ancestor:
- * @window: a #MetaWindow
- * @func: (scope call) (closure user_data): Called for each window which is a transient parent of @window
- * @user_data: User data
- *
- * If @window is transient, call @func with the window for which it's transient,
- * repeatedly until either we find a non-transient window, or @func returns %FALSE.
- */
-void
-meta_window_foreach_ancestor (MetaWindow *window,
- MetaWindowForeachFunc func,
- void *user_data)
-{
- MetaWindow *w;
-
- w = window;
- do
- {
- if (w->transient_for == NULL)
- break;
-
- w = w->transient_for;
- }
- while (w && (* func) (w, user_data));
-}
-
-typedef struct
-{
- MetaWindow *ancestor;
- gboolean found;
-} FindAncestorData;
-
-static gboolean
-find_ancestor_func (MetaWindow *window,
- void *data)
-{
- FindAncestorData *d = data;
-
- if (window == d->ancestor)
- {
- d->found = TRUE;
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * meta_window_is_ancestor_of_transient:
- * @window: a #MetaWindow
- * @transient: a #MetaWindow
- *
- * The function determines whether @window is an ancestor of @transient; it does
- * so by traversing the @transient's ancestors until it either locates @window
- * or reaches an ancestor that is not transient.
- *
- * Return Value: %TRUE if window is an ancestor of transient.
- */
-gboolean
-meta_window_is_ancestor_of_transient (MetaWindow *window,
- MetaWindow *transient)
-{
- FindAncestorData d;
-
- d.ancestor = window;
- d.found = FALSE;
-
- meta_window_foreach_ancestor (transient, find_ancestor_func, &d);
-
- return d.found;
-}
-
-/* Warp pointer to location appropriate for grab,
- * return root coordinates where pointer ended up.
- */
-static gboolean
-warp_grab_pointer (MetaWindow *window,
- MetaGrabOp grab_op,
- int *x,
- int *y)
-{
- MetaRectangle rect;
- MetaRectangle display_rect = { 0 };
- MetaDisplay *display;
- ClutterSeat *seat;
-
- 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_frame_rect (window, &rect);
-
- 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;
-
- 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, display_rect.width - 1);
- *y = CLAMP (*y, 0, display_rect.height - 1);
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Warping pointer to %d,%d with window at %d,%d",
- *x, *y, rect.x, rect.y);
-
- /* Need to update the grab positions so that the MotionNotify and other
- * events generated by the XWarpPointer() call below don't cause complete
- * funkiness. See bug 124582 and bug 122670.
- */
- display->grab_anchor_root_x = *x;
- display->grab_anchor_root_y = *y;
- display->grab_latest_motion_x = *x;
- display->grab_latest_motion_y = *y;
- meta_window_get_frame_rect (window,
- &display->grab_anchor_window_pos);
-
- seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
- clutter_seat_warp_pointer (seat, *x, *y);
-
- return TRUE;
-}
-
-void
-meta_window_begin_grab_op (MetaWindow *window,
- MetaGrabOp op,
- gboolean frame_action,
- guint32 timestamp)
-{
- int x, y;
-
- warp_grab_pointer (window,
- op, &x, &y);
-
- meta_display_begin_grab_op (window->display,
- window,
- op,
- FALSE,
- frame_action,
- 0 /* button */,
- 0,
- timestamp,
- x, y);
-}
-
-void
-meta_window_update_keyboard_resize (MetaWindow *window,
- gboolean update_cursor)
-{
- int x, y;
-
- warp_grab_pointer (window,
- window->display->grab_op,
- &x, &y);
-
- if (update_cursor)
- meta_display_update_cursor (window->display);
-}
-
-void
-meta_window_update_keyboard_move (MetaWindow *window)
-{
- int x, y;
-
- warp_grab_pointer (window,
- window->display->grab_op,
- &x, &y);
-}
-
-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->display->stack);
- group = meta_window_get_group (window);
- if (group)
- meta_group_update_layers (group);
- else
- meta_stack_update_layer (window->display->stack, window);
- meta_stack_thaw (window->display->stack);
-}
-
-/* ensure_mru_position_after ensures that window appears after
- * below_this_one in the active_workspace's mru_list (i.e. it treats
- * window as having been less recently used than below_this_one)
- */
-static void
-ensure_mru_position_after (MetaWindow *window,
- MetaWindow *after_this_one)
-{
- /* This is sort of slow since it runs through the entire list more
- * than once (especially considering the fact that we expect the
- * windows of interest to be the first two elements in the list),
- * but it doesn't matter while we're only using it on new window
- * map.
- */
-
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
- GList* active_mru_list;
- GList* window_position;
- GList* after_this_one_position;
-
- 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
- * that case we don't need to do any MRU shuffling so we can simply
- * return.
- */
- if (after_this_one_position == NULL)
- return;
-
- if (g_list_length (window_position) > g_list_length (after_this_one_position))
- {
- workspace_manager->active_workspace->mru_list =
- g_list_delete_link (workspace_manager->active_workspace->mru_list,
- window_position);
-
- workspace_manager->active_workspace->mru_list =
- g_list_insert_before (workspace_manager->active_workspace->mru_list,
- after_this_one_position->next,
- window);
- }
-}
-
-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)
-{
- g_return_if_fail (window != NULL);
- g_return_if_fail (below_this_one != NULL);
-
- if (window->stack_position > below_this_one->stack_position)
- {
- meta_topic (META_DEBUG_STACK,
- "Setting stack position of window %s to %d (making it below window %s).",
- window->desc,
- below_this_one->stack_position,
- below_this_one->desc);
- meta_window_set_stack_position (window, below_this_one->stack_position);
- }
- else
- {
- meta_topic (META_DEBUG_STACK,
- "Window %s was already below window %s.",
- window->desc, below_this_one->desc);
- }
-}
-
-void
-meta_window_stack_just_above (MetaWindow *window,
- MetaWindow *above_this_one)
-{
- g_return_if_fail (window != NULL);
- g_return_if_fail (above_this_one != NULL);
-
- if (window->stack_position < above_this_one->stack_position)
- {
- meta_topic (META_DEBUG_STACK,
- "Setting stack position of window %s to %d (making it above window %s).",
- window->desc,
- above_this_one->stack_position,
- above_this_one->desc);
- meta_window_set_stack_position (window, above_this_one->stack_position);
- }
- else
- {
- meta_topic (META_DEBUG_STACK,
- "Window %s was already above window %s.",
- window->desc, above_this_one->desc);
- }
-}
-
-/**
- * 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 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.
- *
- * Returns: The last time the user interacted with this window.
- */
-guint32
-meta_window_get_user_time (MetaWindow *window)
-{
- return window->net_wm_user_time;
-}
-
-void
-meta_window_set_user_time (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.
- */
-
- g_return_if_fail (!window->override_redirect);
-
- /* Only update the time if this timestamp is newer... */
- if (window->net_wm_user_time_set &&
- XSERVER_TIME_IS_BEFORE (timestamp, window->net_wm_user_time))
- {
- meta_topic (META_DEBUG_STARTUP,
- "Window %s _NET_WM_USER_TIME not updated to %u, because it "
- "is less than %u",
- window->desc, timestamp, window->net_wm_user_time);
- }
- else
- {
- meta_topic (META_DEBUG_STARTUP,
- "Window %s has _NET_WM_USER_TIME of %u",
- window->desc, timestamp);
- window->net_wm_user_time_set = TRUE;
- window->net_wm_user_time = timestamp;
- if (XSERVER_TIME_IS_BEFORE (window->display->last_user_time, timestamp))
- window->display->last_user_time = timestamp;
-
- /* 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 () == G_DESKTOP_FOCUS_NEW_WINDOWS_STRICT &&
- window_is_terminal (window))
- window->display->allow_terminal_deactivation = FALSE;
-
- g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_USER_TIME]);
- }
-}
-
-/**
- * meta_window_get_stable_sequence:
- * @window: A #MetaWindow
- *
- * The stable sequence number is a monotonicially increasing
- * unique integer assigned to each #MetaWindow upon creation.
- *
- * This number can be useful for sorting windows in a stable
- * fashion.
- *
- * Returns: Internal sequence number for this window
- */
-guint32
-meta_window_get_stable_sequence (MetaWindow *window)
-{
- g_return_val_if_fail (META_IS_WINDOW (window), 0);
-
- return window->stable_sequence;
-}
-
-/* Sets the demands_attention hint on a window, but only
- * if it's at least partially obscured (see #305882).
- */
-void
-meta_window_set_demands_attention (MetaWindow *window)
-{
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
- MetaRectangle candidate_rect, other_rect;
- GList *stack = window->display->stack->sorted;
- MetaWindow *other_window;
- gboolean obscured = FALSE;
-
- MetaWorkspace *workspace = workspace_manager->active_workspace;
-
- if (window->wm_state_demands_attention)
- return;
-
- if (!meta_window_located_on_workspace (window, workspace))
- {
- /* windows on other workspaces are necessarily obscured */
- obscured = TRUE;
- }
- else if (window->minimized)
- {
- obscured = TRUE;
- }
- else
- {
- meta_window_get_frame_rect (window, &candidate_rect);
-
- /* The stack is sorted with the top windows first. */
-
- while (stack != NULL && stack->data != window)
- {
- other_window = stack->data;
- stack = stack->next;
-
- if (meta_window_located_on_workspace (other_window, workspace))
- {
- meta_window_get_frame_rect (other_window, &other_rect);
-
- if (meta_rectangle_overlap (&candidate_rect, &other_rect))
- {
- obscured = TRUE;
- break;
- }
- }
- }
- }
-
- if (obscured)
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Marking %s as needing attention",
- window->desc);
-
- window->wm_state_demands_attention = TRUE;
- set_net_wm_state (window);
- g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_DEMANDS_ATTENTION]);
- g_signal_emit_by_name (window->display, "window-demands-attention",
- window);
- }
- else
- {
- /* If the window's in full view, there's no point setting the flag. */
-
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Not marking %s as needing attention because "
- "it's in full view",
- window->desc);
- }
-}
-
-void
-meta_window_unset_demands_attention (MetaWindow *window)
-{
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Marking %s as not needing attention", window->desc);
-
- if (window->wm_state_demands_attention)
- {
- window->wm_state_demands_attention = FALSE;
- set_net_wm_state (window);
- g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_DEMANDS_ATTENTION]);
- }
-}
-
-/**
- * meta_window_get_frame: (skip)
- * @window: a #MetaWindow
- *
- */
-MetaFrame *
-meta_window_get_frame (MetaWindow *window)
-{
- return window->frame;
-}
-
-/**
- * meta_window_appears_focused:
- * @window: a #MetaWindow
- *
- * Determines if the window should be drawn with a focused appearance. This is
- * true for focused windows but also true for windows with a focused modal
- * dialog attached.
- *
- * Return value: %TRUE if the window should be drawn with a focused frame
- */
-gboolean
-meta_window_appears_focused (MetaWindow *window)
-{
- return window->has_focus || (window->attached_focus_window != NULL);
-}
-
-gboolean
-meta_window_has_focus (MetaWindow *window)
-{
- return window->has_focus;
-}
-
-gboolean
-meta_window_is_shaded (MetaWindow *window)
-{
- return window->shaded;
-}
-
-/**
- * meta_window_is_override_redirect:
- * @window: A #MetaWindow
- *
- * 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
-meta_window_is_override_redirect (MetaWindow *window)
-{
- return window->override_redirect;
-}
-
-/**
- * meta_window_is_skip_taskbar:
- * @window: A #MetaWindow
- *
- * Gets whether this window should be ignored by task lists.
- *
- * Return value: %TRUE if the skip bar hint is set.
- */
-gboolean
-meta_window_is_skip_taskbar (MetaWindow *window)
-{
- g_return_val_if_fail (META_IS_WINDOW (window), FALSE);
-
- return window->skip_taskbar;
-}
-
-/**
- * meta_window_get_display:
- * @window: A #MetaWindow
- *
- * Returns: (transfer none): The display for @window
- */
-MetaDisplay *
-meta_window_get_display (MetaWindow *window)
-{
- return window->display;
-}
-
-/**
- * meta_window_get_xwindow: (skip)
- * @window: a #MetaWindow
- *
- */
-Window
-meta_window_get_xwindow (MetaWindow *window)
-{
- return window->xwindow;
-}
-
-MetaWindowType
-meta_window_get_window_type (MetaWindow *window)
-{
- return window->type;
-}
-
-/**
- * meta_window_get_workspace:
- * @window: a #MetaWindow
- *
- * Gets the #MetaWorkspace that the window is currently displayed on.
- * If the window is on all workspaces, returns the currently active
- * workspace.
- *
- * Return value: (transfer none): the #MetaWorkspace for the window
- */
-MetaWorkspace *
-meta_window_get_workspace (MetaWindow *window)
-{
- MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
-
- if (window->on_all_workspaces)
- return workspace_manager->active_workspace;
- else
- return window->workspace;
-}
-
-gboolean
-meta_window_is_on_all_workspaces (MetaWindow *window)
-{
- return window->on_all_workspaces;
-}
-
-gboolean
-meta_window_is_hidden (MetaWindow *window)
-{
- return window->hidden;
-}
-
-const char *
-meta_window_get_description (MetaWindow *window)
-{
- if (!window)
- return NULL;
-
- return window->desc;
-}
-
-/**
- * meta_window_get_wm_class:
- * @window: a #MetaWindow
- *
- * Return the current value of the name part of WM_CLASS X property.
- */
-const char *
-meta_window_get_wm_class (MetaWindow *window)
-{
- if (!window)
- return NULL;
-
- return window->res_class;
-}
-
-/**
- * meta_window_get_wm_class_instance:
- * @window: a #MetaWindow
- *
- * Return the current value of the instance part of WM_CLASS X property.
- */
-const char *
-meta_window_get_wm_class_instance (MetaWindow *window)
-{
- if (!window)
- return NULL;
-
- 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
- *
- * Return value: (transfer none): the application ID
- **/
-const char *
-meta_window_get_gtk_application_id (MetaWindow *window)
-{
- return window->gtk_application_id;
-}
-
-/**
- * meta_window_get_gtk_unique_bus_name:
- * @window: a #MetaWindow
- *
- * Return value: (transfer none): the unique name
- **/
-const char *
-meta_window_get_gtk_unique_bus_name (MetaWindow *window)
-{
- return window->gtk_unique_bus_name;
-}
-
-/**
- * meta_window_get_gtk_application_object_path:
- * @window: a #MetaWindow
- *
- * Return value: (transfer none): the object path
- **/
-const char *
-meta_window_get_gtk_application_object_path (MetaWindow *window)
-{
- return window->gtk_application_object_path;
-}
-
-/**
- * meta_window_get_gtk_window_object_path:
- * @window: a #MetaWindow
- *
- * Return value: (transfer none): the object path
- **/
-const char *
-meta_window_get_gtk_window_object_path (MetaWindow *window)
-{
- return window->gtk_window_object_path;
-}
-
-/**
- * meta_window_get_gtk_app_menu_object_path:
- * @window: a #MetaWindow
- *
- * Return value: (transfer none): the object path
- **/
-const char *
-meta_window_get_gtk_app_menu_object_path (MetaWindow *window)
-{
- return window->gtk_app_menu_object_path;
-}
-
-/**
- * meta_window_get_gtk_menubar_object_path:
- * @window: a #MetaWindow
- *
- * Return value: (transfer none): the object path
- **/
-const char *
-meta_window_get_gtk_menubar_object_path (MetaWindow *window)
-{
- return window->gtk_menubar_object_path;
-}
-
-/**
- * meta_window_get_compositor_private:
- * @window: a #MetaWindow
- *
- * Gets the compositor's wrapper object for @window.
- *
- * Return value: (transfer none): the wrapper object.
- **/
-GObject *
-meta_window_get_compositor_private (MetaWindow *window)
-{
- if (!window)
- return NULL;
- return window->compositor_private;
-}
-
-void
-meta_window_set_compositor_private (MetaWindow *window, GObject *priv)
-{
- if (!window)
- return;
- window->compositor_private = priv;
-}
-
-const char *
-meta_window_get_role (MetaWindow *window)
-{
- if (!window)
- return NULL;
-
- return window->role;
-}
-
-/**
- * meta_window_get_title:
- * @window: a #MetaWindow
- *
- * Returns: the current title of the window.
- */
-const char *
-meta_window_get_title (MetaWindow *window)
-{
- g_return_val_if_fail (META_IS_WINDOW (window), NULL);
-
- return window->title;
-}
-
-MetaStackLayer
-meta_window_get_layer (MetaWindow *window)
-{
- return window->layer;
-}
-
-/**
- * meta_window_get_transient_for:
- * @window: a #MetaWindow
- *
- * Returns the #MetaWindow for 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.
- *
- * Return value: (transfer none): the window this window is transient for, or
- * %NULL if the WM_TRANSIENT_FOR hint is unset or does not point to a toplevel
- * window that Metacity knows about.
- */
-MetaWindow *
-meta_window_get_transient_for (MetaWindow *window)
-{
- g_return_val_if_fail (META_IS_WINDOW (window), NULL);
-
- 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_pid:
- * @window: a #MetaWindow
- *
- * Returns the pid of the process that created this window, if available
- * to the windowing system.
- *
- * Note that the value returned by this is vulnerable to spoofing attacks
- * by the client.
- *
- * Return value: the pid, or 0 if not known.
- */
-pid_t
-meta_window_get_pid (MetaWindow *window)
-{
- g_return_val_if_fail (META_IS_WINDOW (window), 0);
-
- if (window->client_pid == 0)
- window->client_pid = META_WINDOW_GET_CLASS (window)->get_client_pid (window);
-
- return window->client_pid;
-}
-
-/**
- * meta_window_get_client_machine:
- * @window: a #MetaWindow
- *
- * Returns name of the client machine from which this windows was created,
- * if known (obtained from the WM_CLIENT_MACHINE property).
- *
- * Return value: (transfer none): the machine name, or NULL; the string is
- * owned by the window manager and should not be freed or modified by the
- * caller.
- */
-const char *
-meta_window_get_client_machine (MetaWindow *window)
-{
- g_return_val_if_fail (META_IS_WINDOW (window), NULL);
-
- return window->wm_client_machine;
-}
-
-/**
- * meta_window_is_remote:
- * @window: a #MetaWindow
- *
- * Returns: %TRUE if this window originates from a host
- * different from the one running mutter.
- */
-gboolean
-meta_window_is_remote (MetaWindow *window)
-{
- return window->is_remote;
-}
-
-/**
- * meta_window_get_mutter_hints:
- * @window: a #MetaWindow
- *
- * 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
- * hints that are plugin-specific.
- *
- * 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; 'mutter-' key prefix is reserved for internal use, and must not be used
- * by plugins.
- *
- * Return value: (transfer none): the _MUTTER_HINTS string, or %NULL if no hints
- * are set.
- */
-const char *
-meta_window_get_mutter_hints (MetaWindow *window)
-{
- g_return_val_if_fail (META_IS_WINDOW (window), NULL);
-
- return window->mutter_hints;
-}
-
-/**
- * meta_window_get_frame_type:
- * @window: a #MetaWindow
- *
- * Gets the type of window decorations that should be used for this window.
- *
- * Return value: the frame type
- */
-MetaFrameType
-meta_window_get_frame_type (MetaWindow *window)
-{
- MetaFrameType base_type = META_FRAME_TYPE_LAST;
-
- switch (window->type)
- {
- case META_WINDOW_NORMAL:
- base_type = META_FRAME_TYPE_NORMAL;
- break;
-
- case META_WINDOW_DIALOG:
- base_type = META_FRAME_TYPE_DIALOG;
- break;
-
- case META_WINDOW_MODAL_DIALOG:
- if (meta_window_is_attached_dialog (window))
- base_type = META_FRAME_TYPE_ATTACHED;
- else
- base_type = META_FRAME_TYPE_MODAL_DIALOG;
- break;
-
- case META_WINDOW_MENU:
- base_type = META_FRAME_TYPE_MENU;
- break;
-
- case META_WINDOW_UTILITY:
- base_type = META_FRAME_TYPE_UTILITY;
- break;
-
- case META_WINDOW_DESKTOP:
- case META_WINDOW_DOCK:
- case META_WINDOW_TOOLBAR:
- 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:
- /* No frame */
- base_type = META_FRAME_TYPE_LAST;
- break;
- }
-
- if (base_type == META_FRAME_TYPE_LAST)
- {
- /* can't add border if undecorated */
- return META_FRAME_TYPE_LAST;
- }
- else if (window->border_only)
- {
- /* override base frame type */
- return META_FRAME_TYPE_BORDER;
- }
- else
- {
- return base_type;
- }
-}
-
-/**
- * meta_window_get_frame_bounds:
- * @window: a #MetaWindow
- *
- * Gets a region representing the outer bounds of the window's frame.
- *
- * 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.
- */
-cairo_region_t *
-meta_window_get_frame_bounds (MetaWindow *window)
-{
- if (!window->frame_bounds)
- {
- if (window->frame)
- window->frame_bounds = meta_frame_get_frame_bounds (window->frame);
- }
-
- 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.",
- 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.", 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");
- }
- 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() == G_DESKTOP_FOCUS_MODE_MOUSE &&
- display->focus_window != NULL)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Unsetting focus from %s due to mouse entering "
- "the DESKTOP window",
- display->focus_window->desc);
- meta_display_unset_input_focus (display, timestamp);
- }
- }
-}
-
-static gboolean
-window_has_pointer_wayland (MetaWindow *window)
-{
- ClutterSeat *seat;
- ClutterInputDevice *dev;
- ClutterStage *stage;
- ClutterActor *pointer_actor, *window_actor;
-
- seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
- dev = clutter_seat_get_pointer (seat);
- stage = CLUTTER_STAGE (meta_backend_get_stage (meta_get_backend ()));
- pointer_actor = clutter_stage_get_device_actor (stage, dev, NULL);
- window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window));
-
- return pointer_actor && clutter_actor_contains (window_actor, pointer_actor);
-}
-
-static gboolean
-window_has_pointer_x11 (MetaWindow *window)
-{
- MetaX11Display *x11_display = window->display->x11_display;
- Window root, child;
- double root_x, root_y, x, y;
- XIButtonState buttons;
- XIModifierState mods;
- XIGroupState group;
-
- 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);
-
- return meta_x11_display_lookup_x_window (x11_display, child) == window;
-}
-
-gboolean
-meta_window_has_pointer (MetaWindow *window)
-{
- if (meta_is_wayland_compositor ())
- return window_has_pointer_wayland (window);
- else
- 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);
- graphene_point_t point;
- guint32 timestamp;
-
- if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
- goto out;
-
- meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
-
- if ((int) point.x != focus_data->pointer_x ||
- (int) point.y != focus_data->pointer_y)
- {
- focus_data->pointer_x = point.x;
- focus_data->pointer_y = point.y;
- return G_SOURCE_CONTINUE;
- }
-
- if (!meta_window_has_pointer (window))
- goto out;
-
- timestamp = meta_display_get_current_time_roundtrip (display);
- mouse_mode_focus (window, timestamp);
-
- out:
- display->focus_timeout_id = 0;
- return G_SOURCE_REMOVE;
-}
-
-/* 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
-
-static void
-queue_focus_callback (MetaDisplay *display,
- MetaWindow *window,
- int pointer_x,
- int pointer_y)
-{
- MetaFocusData *focus_data;
-
- 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_handle_enter (MetaWindow *window,
- guint32 timestamp,
- guint root_x,
- guint root_y)
-{
- MetaDisplay *display = window->display;
-
- switch (meta_prefs_get_focus_mode ())
- {
- case G_DESKTOP_FOCUS_MODE_SLOPPY:
- case G_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);
-
- /* stop ignoring stuff */
- reset_ignored_crossing_serials (display);
- }
- break;
- case G_DESKTOP_FOCUS_MODE_CLICK:
- break;
- }
-
- if (window->type == META_WINDOW_DOCK)
- meta_window_raise (window);
-}
-
-void
-meta_window_handle_leave (MetaWindow *window)
-{
- if (window->type == META_WINDOW_DOCK && !window->has_focus)
- meta_window_lower (window);
-}
-
-gboolean
-meta_window_handle_ui_frame_event (MetaWindow *window,
- const ClutterEvent *event)
-{
- if (!window->frame)
- return FALSE;
-
- return meta_ui_frame_handle_event (window->frame->ui_frame, event);
-}
-
-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;
-
- if (event->type != CLUTTER_BUTTON_PRESS &&
- event->type != CLUTTER_TOUCH_BEGIN)
- return;
-
- 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);
-
- 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;
-
- /* 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)",
- 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.
- */
-
- grab_mods = meta_display_get_compositor_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));
-
- clutter_event_get_coords (event, &x, &y);
-
- 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");
- }
- 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
-meta_window_can_maximize (MetaWindow *window)
-{
- return window->has_maximize_func;
-}
-
-gboolean
-meta_window_can_minimize (MetaWindow *window)
-{
- return window->has_minimize_func;
-}
-
-gboolean
-meta_window_can_shade (MetaWindow *window)
-{
- return window->has_shade_func;
-}
-
-gboolean
-meta_window_can_close (MetaWindow *window)
-{
- return window->has_close_func;
-}
-
-gboolean
-meta_window_is_always_on_all_workspaces (MetaWindow *window)
-{
- return window->always_sticky;
-}
-
-gboolean
-meta_window_is_above (MetaWindow *window)
-{
- return window->wm_state_above;
-}
-
-gboolean
-meta_window_allows_move (MetaWindow *window)
-{
- return META_WINDOW_ALLOWS_MOVE (window);
-}
-
-gboolean
-meta_window_allows_resize (MetaWindow *window)
-{
- return META_WINDOW_ALLOWS_RESIZE (window);
-}
-
-void
-meta_window_set_urgent (MetaWindow *window,
- gboolean urgent)
-{
- if (window->urgent == urgent)
- return;
-
- 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)
-{
- META_WINDOW_GET_CLASS (window)->grab_op_began (window, op);
-}
-
-void
-meta_window_grab_op_ended (MetaWindow *window,
- MetaGrabOp op)
-{
- META_WINDOW_GET_CLASS (window)->grab_op_ended (window, op);
-}
-
-void
-meta_window_emit_size_changed (MetaWindow *window)
-{
- g_signal_emit (window, window_signals[SIZE_CHANGED], 0);
-}
-
-MetaPlacementRule *
-meta_window_get_placement_rule (MetaWindow *window)
-{
- return window->placement.rule;
-}
-
-void
-meta_window_force_restore_shortcuts (MetaWindow *window,
- ClutterInputDevice *source)
-{
- META_WINDOW_GET_CLASS (window)->force_restore_shortcuts (window, source);
-}
-
-gboolean
-meta_window_shortcuts_inhibited (MetaWindow *window,
- ClutterInputDevice *source)
-{
- return META_WINDOW_GET_CLASS (window)->shortcuts_inhibited (window, source);
-}
-
-gboolean
-meta_window_is_focusable (MetaWindow *window)
-{
- g_return_val_if_fail (!window->unmanaging, FALSE);
-
- return META_WINDOW_GET_CLASS (window)->is_focusable (window);
-}
-
-gboolean
-meta_window_can_ping (MetaWindow *window)
-{
- g_return_val_if_fail (!window->unmanaging, FALSE);
-
- 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_get_id:
- * @window: a #MetaWindow
- *
- * Returns the window id associated with window.
- *
- * Returns: The window id
- */
-uint64_t
-meta_window_get_id (MetaWindow *window)
-{
- return window->id;
-}
-
-/**
- * meta_window_get_client_type:
- * @window: a #MetaWindow
- *
- * Returns the #MetaWindowClientType of the window.
- *
- * Returns: The root ancestor window
- */
-MetaWindowClientType
-meta_window_get_client_type (MetaWindow *window)
-{
- return window->client_type;
-}
diff --git a/src/core/workspace-private.h b/src/core/workspace-private.h
deleted file mode 100644
index a58b2347d..000000000
--- a/src/core/workspace-private.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file workspace.h 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.
- */
-
-/*
- * 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_PRIVATE_H
-#define META_WORKSPACE_PRIVATE_H
-
-#include "core/window-private.h"
-#include "meta/workspace.h"
-
-struct _MetaWorkspace
-{
- GObject parent_instance;
- MetaDisplay *display;
- MetaWorkspaceManager *manager;
-
- GList *windows;
-
- /* The "MRU list", or "most recently used" list, is a list of
- * MetaWindows ordered based on the time the the user interacted
- * with the window most recently.
- *
- * For historical reasons, we keep an MRU list per workspace.
- * It used to be used to calculate the default focused window,
- * but isn't anymore, as the window next in the stacking order
- * can sometimes be not the window the user interacted with last,
- */
- GList *mru_list;
-
- GList *list_containing_self;
-
- GHashTable *logical_monitor_data;
-
- MetaRectangle work_area_screen;
- GList *screen_region;
- GList *screen_edges;
- GList *monitor_edges;
- GSList *builtin_struts;
- GSList *all_struts;
- guint work_areas_invalid : 1;
-
- guint showing_desktop : 1;
-};
-
-struct _MetaWorkspaceClass
-{
- GObjectClass parent_class;
-};
-
-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_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,
- 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
deleted file mode 100644
index 321d3efb0..000000000
--- a/src/core/workspace.c
+++ /dev/null
@@ -1,1477 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2003 Rob Adams
- * 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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:workspace
- * @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,
- * 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 "config.h"
-
-#include "meta/workspace.h"
-
-#include <X11/Xatom.h>
-#include <string.h>
-
-#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);
-
-G_DEFINE_TYPE (MetaWorkspace, meta_workspace, G_TYPE_OBJECT);
-
-enum
-{
- PROP_0,
-
- PROP_N_WINDOWS,
- PROP_WORKSPACE_INDEX,
- PROP_ACTIVE,
-
- PROP_LAST,
-};
-
-static GParamSpec *obj_props[PROP_LAST];
-
-enum
-{
- WINDOW_ADDED,
- WINDOW_REMOVED,
-
- LAST_SIGNAL
-};
-
-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);
-}
-
-static void
-meta_workspace_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_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaWorkspace *ws = META_WORKSPACE (object);
-
- switch (prop_id)
- {
- case PROP_N_WINDOWS:
- /*
- * This is reliable, but not very efficient; should we store
- * the list length ?
- */
- 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;
- case PROP_ACTIVE:
- g_value_set_boolean (value, ws->manager->active_workspace == ws);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_workspace_class_init (MetaWorkspaceClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = meta_workspace_finalize;
- object_class->get_property = meta_workspace_get_property;
- object_class->set_property = meta_workspace_set_property;
-
- signals[WINDOW_ADDED] = g_signal_new ("window-added",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- 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, NULL,
- G_TYPE_NONE, 1,
- META_TYPE_WINDOW);
-
- 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);
- obj_props[PROP_ACTIVE] = g_param_spec_boolean ("active",
- "Active",
- "Whether the workspace is currently active",
- FALSE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
- g_object_class_install_properties (object_class, PROP_LAST, obj_props);
-}
-
-static void
-meta_workspace_init (MetaWorkspace *workspace)
-{
-}
-
-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->display = display;
- workspace->manager = workspace_manager;
-
- workspace_manager->workspaces =
- g_list_append (workspace_manager->workspaces, workspace);
- workspace->windows = NULL;
- workspace->mru_list = NULL;
-
- workspace->work_areas_invalid = TRUE;
- 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->screen_edges = NULL;
- workspace->monitor_edges = NULL;
- workspace->list_containing_self = g_list_prepend (NULL, workspace);
-
- workspace->builtin_struts = NULL;
- workspace->all_struts = NULL;
-
- workspace->showing_desktop = FALSE;
-
- /* 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);
-
- return workspace;
-}
-
-/**
- * workspace_free_all_struts:
- * @workspace: The workspace.
- *
- * Frees the combined struts list of a workspace.
- */
-static void
-workspace_free_all_struts (MetaWorkspace *workspace)
-{
- if (workspace->all_struts == NULL)
- return;
-
- g_slist_free_full (workspace->all_struts, g_free);
- workspace->all_struts = NULL;
-}
-
-/**
- * workspace_free_builtin_struts:
- * @workspace: The workspace.
- *
- * Frees the struts list set with meta_workspace_set_builtin_struts
- */
-static void
-workspace_free_builtin_struts (MetaWorkspace *workspace)
-{
- if (workspace->builtin_struts == NULL)
- return;
-
- g_slist_free_full (workspace->builtin_struts, g_free);
- workspace->builtin_struts = NULL;
-}
-
-/* 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 *l;
- for (l = workspace->windows; l != NULL; l = l->next)
- {
- MetaWindow *window = l->data;
- g_assert (window->on_all_workspaces);
- }
-}
-
-void
-meta_workspace_remove (MetaWorkspace *workspace)
-{
- MetaWorkspaceManager *manager = workspace->display->workspace_manager;
-
- g_return_if_fail (workspace != manager->active_workspace);
-
- assert_workspace_empty (workspace);
-
- 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);
-
- workspace_free_builtin_struts (workspace);
-
- /* screen.c:update_num_workspaces(), which calls us, removes windows from
- * workspaces first, which can cause the workareas on the workspace to be
- * invalidated (and hence for struts/regions/edges to be freed).
- * So, no point trying to double free it; that causes a crash
- * anyway. #361804.
- */
-
- if (!workspace->work_areas_invalid)
- {
- workspace_free_all_struts (workspace);
- 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);
- }
-
- g_object_unref (workspace);
-
- /* don't bother to reset names, pagers can just ignore
- * extra ones
- */
-}
-
-void
-meta_workspace_add_window (MetaWorkspace *workspace,
- MetaWindow *window)
-{
- g_return_if_fail (g_list_find (workspace->mru_list, window) == NULL);
-
- COGL_TRACE_BEGIN_SCOPED (MetaWorkspaceAddWindow,
- "Workspace (add window)");
-
- workspace->mru_list = g_list_prepend (workspace->mru_list, window);
-
- workspace->windows = g_list_prepend (workspace->windows, window);
-
- if (window->struts)
- {
- meta_topic (META_DEBUG_WORKAREA,
- "Invalidating work area of workspace %d since we're adding window %s to it",
- meta_workspace_index (workspace), window->desc);
- meta_workspace_invalidate_work_area (workspace);
- }
-
- g_signal_emit (workspace, signals[WINDOW_ADDED], 0, window);
- g_object_notify_by_pspec (G_OBJECT (workspace), obj_props[PROP_N_WINDOWS]);
-}
-
-void
-meta_workspace_remove_window (MetaWorkspace *workspace,
- MetaWindow *window)
-{
- COGL_TRACE_BEGIN_SCOPED (MetaWorkspaceRemoveWindow,
- "Workspace (remove window)");
-
- workspace->windows = g_list_remove (workspace->windows, window);
-
- workspace->mru_list = g_list_remove (workspace->mru_list, window);
- g_assert (g_list_find (workspace->mru_list, window) == NULL);
-
- if (window->struts)
- {
- meta_topic (META_DEBUG_WORKAREA,
- "Invalidating work area of workspace %d since we're removing window %s from it",
- meta_workspace_index (workspace), window->desc);
- meta_workspace_invalidate_work_area (workspace);
- }
-
- g_signal_emit (workspace, signals[WINDOW_REMOVED], 0, window);
- g_object_notify (G_OBJECT (workspace), "n-windows");
-}
-
-void
-meta_workspace_relocate_windows (MetaWorkspace *workspace,
- MetaWorkspace *new_home)
-{
- GList *copy, *l;
-
- g_return_if_fail (workspace != new_home);
-
- /* can't modify list we're iterating over */
- copy = g_list_copy (workspace->windows);
-
- for (l = copy; l != NULL; l = l->next)
- {
- MetaWindow *window = l->data;
-
- if (!window->on_all_workspaces)
- meta_window_change_workspace (window, new_home);
- }
-
- g_list_free (copy);
-
- assert_workspace_empty (workspace);
-}
-
-void
-meta_workspace_queue_calc_showing (MetaWorkspace *workspace)
-{
- GList *l;
-
- 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)
-{
- MetaSoundPlayer *player;
- MetaWorkspaceLayout layout;
- int i, nw, x, y, fi, ti;
- const char *e;
-
- nw = meta_workspace_manager_get_n_workspaces (from->manager);
- fi = meta_workspace_index(from);
- ti = meta_workspace_index(to);
-
- meta_workspace_manager_calc_workspace_layout (from->manager,
- 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");
- 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!");
- goto finish;
- }
-
- player = meta_display_get_sound_player (from->display);
- meta_sound_player_play_from_theme (player, e, "Desktop switched", NULL);
-
- finish:
- meta_workspace_manager_free_workspace_layout (&layout);
-}
-
-/**
- * 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;
- MetaCompositor *comp;
- MetaWorkspaceLayout layout1, layout2;
- gint num_workspaces, current_space, new_space;
- MetaMotionDirection direction;
-
- meta_verbose ("Activating workspace %d",
- meta_workspace_index (workspace));
-
- 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->display);
-
- if (workspace->manager->active_workspace)
- workspace_switch_sound (workspace->manager->active_workspace, workspace);
-
- /* Note that old can be NULL; e.g. when starting up */
- old = workspace->manager->active_workspace;
-
- workspace->manager->active_workspace = workspace;
-
- g_signal_emit_by_name (workspace->manager, "active-workspace-changed");
-
- g_object_notify_by_pspec (G_OBJECT (workspace), obj_props[PROP_ACTIVE]);
-
- if (old == NULL)
- return;
-
- g_object_notify_by_pspec (G_OBJECT (old), obj_props[PROP_ACTIVE]);
-
- /* 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->showing_desktop != workspace->showing_desktop)
- g_signal_emit_by_name (workspace->manager, "showing-desktop-changed");
-
- move_window = NULL;
- if (meta_grab_op_is_moving (workspace->display->grab_op))
- move_window = workspace->display->grab_window;
-
- if (move_window != NULL)
- {
- /* 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
- * on it.
- *
- * \bug This comment appears to be the reverse of what happens
- */
- 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);
-
- /*
- * Notify the compositor that the active workspace is changing.
- */
- comp = meta_display_get_compositor (workspace->display);
- direction = 0;
-
- current_space = meta_workspace_index (old);
- new_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, &layout1);
-
- 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;
- }
-
- if (layout1.current_row < layout2.current_row)
- {
- if (!direction)
- direction = META_MOTION_DOWN;
- else if (direction == META_MOTION_RIGHT)
- direction = META_MOTION_DOWN_RIGHT;
- else
- direction = META_MOTION_DOWN_LEFT;
- }
-
- if (layout1.current_row > layout2.current_row)
- {
- if (!direction)
- direction = META_MOTION_UP;
- else if (direction == META_MOTION_RIGHT)
- direction = META_MOTION_UP_RIGHT;
- else
- direction = META_MOTION_UP_LEFT;
- }
-
- meta_workspace_manager_free_workspace_layout (&layout1);
- meta_workspace_manager_free_workspace_layout (&layout2);
-
- 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
- * shown and that would confuse the compositor if it didn't know we
- * were in a workspace switch.
- */
- if (focus_this)
- {
- meta_window_activate (focus_this, timestamp);
- }
- else if (move_window)
- {
- meta_window_raise (move_window);
- }
- else
- {
- meta_topic (META_DEBUG_FOCUS, "Focusing default window on new workspace");
- meta_workspace_focus_default_window (workspace, NULL, timestamp);
- }
-
- meta_workspace_manager_workspace_switched (workspace->manager, current_space,
- new_space, direction);
-}
-
-void
-meta_workspace_activate (MetaWorkspace *workspace,
- guint32 timestamp)
-{
- meta_workspace_activate_with_focus (workspace, NULL, timestamp);
-}
-
-int
-meta_workspace_index (MetaWorkspace *workspace)
-{
- int ret;
-
- ret = g_list_index (workspace->manager->workspaces, workspace);
-
- if (ret < 0)
- meta_bug ("Workspace does not exist to index!");
-
- return ret;
-}
-
-void
-meta_workspace_index_changed (MetaWorkspace *workspace)
-{
- GList *l;
- for (l = workspace->windows; l != NULL; l = l->next)
- {
- MetaWindow *win = l->data;
- meta_window_current_workspace_changed (win);
- }
-
- g_object_notify_by_pspec (G_OBJECT (workspace), obj_props[PROP_WORKSPACE_INDEX]);
-}
-
-/**
- * meta_workspace_list_windows:
- * @workspace: a #MetaWorkspace
- *
- * Gets windows contained on the workspace, including workspace->windows
- * and also sticky windows. Override-redirect windows are not included.
- *
- * Return value: (transfer container) (element-type MetaWindow): the list of windows.
- */
-GList*
-meta_workspace_list_windows (MetaWorkspace *workspace)
-{
- GSList *display_windows, *l;
- GList *workspace_windows;
-
- display_windows = meta_display_list_windows (workspace->display,
- META_LIST_DEFAULT);
-
- workspace_windows = NULL;
- for (l = display_windows; l != NULL; l = l->next)
- {
- MetaWindow *window = l->data;
-
- if (meta_window_located_on_workspace (window, workspace))
- workspace_windows = g_list_prepend (workspace_windows,
- window);
- }
-
- g_slist_free (display_windows);
-
- return workspace_windows;
-}
-
-void
-meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
-{
- GList *windows, *l;
-
- if (workspace->work_areas_invalid)
- {
- meta_topic (META_DEBUG_WORKAREA,
- "Work area for workspace %d is already invalid",
- meta_workspace_index (workspace));
- return;
- }
-
- meta_topic (META_DEBUG_WORKAREA,
- "Invalidating work area for workspace %d",
- meta_workspace_index (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->manager->active_workspace)
- meta_display_cleanup_edges (workspace->display);
-
- meta_workspace_clear_logical_monitor_data (workspace);
-
- workspace_free_all_struts (workspace);
-
- 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->screen_region = NULL;
- workspace->screen_edges = NULL;
- workspace->monitor_edges = NULL;
-
- workspace->work_areas_invalid = TRUE;
-
- /* redo the size/position constraints on all windows */
- windows = meta_workspace_list_windows (workspace);
-
- for (l = windows; l != NULL; l = l->next)
- {
- MetaWindow *w = l->data;
- meta_window_queue (w, META_QUEUE_MOVE_RESIZE);
- }
-
- g_list_free (windows);
-
- meta_display_queue_workarea_recalc (workspace->display);
-}
-
-static MetaStrut *
-copy_strut(MetaStrut *original)
-{
- return g_memdup2 (original, sizeof (MetaStrut));
-}
-
-static GSList *
-copy_strut_list(GSList *original)
-{
- GSList *result = NULL;
-
- for (; original != NULL; original = original->next)
- result = g_slist_prepend (result, copy_strut (original->data));
-
- return g_slist_reverse (result);
-}
-
-static void
-ensure_work_areas_validated (MetaWorkspace *workspace)
-{
- 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->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);
-
- windows = meta_workspace_list_windows (workspace);
- for (tmp = windows; tmp != NULL; tmp = tmp->next)
- {
- MetaWindow *win = tmp->data;
- GSList *s_iter;
-
- for (s_iter = win->struts; s_iter != NULL; s_iter = s_iter->next) {
- workspace->all_struts = g_slist_prepend (workspace->all_struts,
- copy_strut(s_iter->data));
- }
- }
- g_list_free (windows);
-
- /* STEP 2: Get the maximal/spanning rects for the onscreen and
- * on-single-monitor regions
- */
- g_assert (workspace->screen_region == NULL);
-
- logical_monitors =
- meta_monitor_manager_get_logical_monitors (monitor_manager);
- for (l = logical_monitors; l; l = l->next)
- {
- 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 (
- &logical_monitor->rect,
- workspace->all_struts);
- }
-
- workspace->screen_region =
- meta_rectangle_get_minimal_spanning_set_for_region (
- &display_rect,
- workspace->all_struts);
-
- /* STEP 3: Get the work areas (region-to-maximize-to) for the screen and
- * monitors.
- */
- work_area = display_rect; /* start with the screen */
- if (workspace->screen_region == NULL)
- work_area = meta_rect (0, 0, -1, -1);
- else
- meta_rectangle_clip_to_region (workspace->screen_region,
- FIXED_DIRECTION_NONE,
- &work_area);
-
- /* Lots of paranoia checks, forcing work_area_screen to be sane */
-#define MIN_SANE_AREA 100
- if (work_area.width < MIN_SANE_AREA &&
- work_area.width != display_rect.width)
- {
- meta_warning ("struts occupy an unusually large percentage of the screen; "
- "available remaining width = %d < %d",
- work_area.width, MIN_SANE_AREA);
- if (work_area.width < 1)
- {
- work_area.x = (display_rect.width - MIN_SANE_AREA)/2;
- work_area.width = MIN_SANE_AREA;
- }
- else
- {
- int amount = (MIN_SANE_AREA - work_area.width)/2;
- work_area.x -= amount;
- work_area.width += 2*amount;
- }
- }
- if (work_area.height < MIN_SANE_AREA &&
- work_area.height != display_rect.height)
- {
- meta_warning ("struts occupy an unusually large percentage of the screen; "
- "available remaining height = %d < %d",
- work_area.height, MIN_SANE_AREA);
- if (work_area.height < 1)
- {
- work_area.y = (display_rect.height - MIN_SANE_AREA)/2;
- work_area.height = MIN_SANE_AREA;
- }
- else
- {
- int amount = (MIN_SANE_AREA - work_area.height)/2;
- work_area.y -= amount;
- work_area.height += 2*amount;
- }
- }
- workspace->work_area_screen = work_area;
- meta_topic (META_DEBUG_WORKAREA,
- "Computed work area for workspace %d: %d,%d %d x %d",
- meta_workspace_index (workspace),
- workspace->work_area_screen.x,
- workspace->work_area_screen.y,
- workspace->work_area_screen.width,
- workspace->work_area_screen.height);
-
- /* Now find the work areas for each monitor */
- for (l = logical_monitors; l; l = l->next)
- {
- MetaLogicalMonitor *logical_monitor = l->data;
- MetaWorkspaceLogicalMonitorData *data;
-
- 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 (data->logical_monitor_region,
- FIXED_DIRECTION_NONE,
- &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",
- meta_workspace_index (workspace),
- 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
- * since it relies on step 3).
- */
- if (workspace->screen_region == NULL)
- {
- MetaRectangle *nonempty_region;
- nonempty_region = g_new (MetaRectangle, 1);
- *nonempty_region = workspace->work_area_screen;
- workspace->screen_region = g_list_prepend (NULL, nonempty_region);
- }
-
- /* STEP 5: Cache screen and monitor edges for edge resistance and snapping */
- g_assert (workspace->screen_edges == NULL);
- g_assert (workspace->monitor_edges == NULL);
- workspace->screen_edges =
- meta_rectangle_find_onscreen_edges (&display_rect,
- workspace->all_struts);
- tmp = NULL;
- 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);
- g_list_free (tmp);
-
- /* We're all done, YAAY! Record that everything has been validated. */
- workspace->work_areas_invalid = FALSE;
-}
-
-static gboolean
-strut_lists_equal (GSList *l,
- GSList *m)
-{
- for (; l && m; l = l->next, m = m->next)
- {
- MetaStrut *a = l->data;
- MetaStrut *b = m->data;
-
- if (a->side != b->side ||
- !meta_rectangle_equal (&a->rect, &b->rect))
- return FALSE;
- }
-
- return l == NULL && m == NULL;
-}
-
-/**
- * meta_workspace_set_builtin_struts:
- * @workspace: a #MetaWorkspace
- * @struts: (element-type Meta.Strut) (transfer none): list of #MetaStrut
- *
- * Sets a list of struts that will be used in addition to the struts
- * of the windows in the workspace when computing the work area of
- * the workspace.
- */
-void
-meta_workspace_set_builtin_struts (MetaWorkspace *workspace,
- GSList *struts)
-{
- 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;
- 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_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_monitor_manager_get_logical_monitor_neighbor (monitor_manager,
- logical_monitor,
- META_DISPLAY_DOWN))
- continue;
-
- strut->rect.height = display_rect.height - strut->rect.y;
- break;
- case META_SIDE_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_monitor_manager_get_logical_monitor_neighbor (monitor_manager,
- logical_monitor,
- META_DISPLAY_RIGHT))
- continue;
-
- strut->rect.width = display_rect.width - strut->rect.x;
- break;
- }
- }
-
- /* Reordering doesn't actually matter, so we don't catch all
- * no-impact changes, but this is just a (possibly unnecessary
- * anyways) optimization */
- if (strut_lists_equal (struts, workspace->builtin_struts))
- return;
-
- workspace_free_builtin_struts (workspace);
- workspace->builtin_struts = copy_strut_list (struts);
-
- meta_workspace_invalidate_work_area (workspace);
-}
-
-void
-meta_workspace_get_work_area_for_logical_monitor (MetaWorkspace *workspace,
- MetaLogicalMonitor *logical_monitor,
- MetaRectangle *area)
-{
- meta_workspace_get_work_area_for_monitor (workspace,
- logical_monitor->number,
- area);
-}
-
-/**
- * meta_workspace_get_work_area_for_monitor:
- * @workspace: a #MetaWorkspace
- * @which_monitor: a monitor index
- * @area: (out): location to store the work area
- *
- * Stores the work area for @which_monitor on @workspace
- * in @area.
- */
-void
-meta_workspace_get_work_area_for_monitor (MetaWorkspace *workspace,
- int which_monitor,
- MetaRectangle *area)
-{
- 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);
- data = meta_workspace_get_logical_monitor_data (workspace, logical_monitor);
-
- g_return_if_fail (data != NULL);
-
- *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)
-{
- ensure_work_areas_validated (workspace);
-
- *area = workspace->work_area_screen;
-}
-
-GList*
-meta_workspace_get_onscreen_region (MetaWorkspace *workspace)
-{
- ensure_work_areas_validated (workspace);
-
- return workspace->screen_region;
-}
-
-GList *
-meta_workspace_get_onmonitor_region (MetaWorkspace *workspace,
- MetaLogicalMonitor *logical_monitor)
-{
- MetaWorkspaceLogicalMonitorData *data;
-
- ensure_work_areas_validated (workspace);
-
- data = meta_workspace_get_logical_monitor_data (workspace, logical_monitor);
-
- return data->logical_monitor_region;
-}
-
-#ifdef WITH_VERBOSE_MODE
-static const char *
-meta_motion_direction_to_string (MetaMotionDirection direction)
-{
- switch (direction)
- {
- case META_MOTION_UP:
- return "Up";
- case META_MOTION_DOWN:
- return "Down";
- case META_MOTION_LEFT:
- return "Left";
- case META_MOTION_RIGHT:
- return "Right";
- case META_MOTION_UP_RIGHT:
- return "Up-Right";
- case META_MOTION_DOWN_RIGHT:
- return "Down-Right";
- case META_MOTION_UP_LEFT:
- return "Up-Left";
- case META_MOTION_DOWN_LEFT:
- return "Down-Left";
- }
-
- return "Unknown";
-}
-#endif /* WITH_VERBOSE_MODE */
-
-/**
- * meta_workspace_get_neighbor:
- * @workspace: a #MetaWorkspace
- * @direction: a #MetaMotionDirection, relative to @workspace
- *
- * Calculate and retrieve the workspace that is next to @workspace,
- * according to @direction and the current workspace layout, as set
- * by meta_screen_override_workspace_layout().
- *
- * 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,
- MetaMotionDirection direction)
-{
- MetaWorkspaceLayout layout;
- int i, current_space, num_workspaces;
- gboolean ltr;
-
- 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);
-
- meta_verbose ("Getting neighbor of %d in direction %s",
- current_space, meta_motion_direction_to_string (direction));
-
- ltr = (meta_get_locale_direction () == META_LOCALE_DIRECTION_LTR);
-
- switch (direction)
- {
- case META_MOTION_LEFT:
- layout.current_col -= ltr ? 1 : -1;
- break;
- case META_MOTION_RIGHT:
- layout.current_col += ltr ? 1 : -1;
- break;
- case META_MOTION_UP:
- layout.current_row -= 1;
- break;
- case META_MOTION_DOWN:
- layout.current_row += 1;
- break;
- default:;
- }
-
- if (layout.current_col < 0)
- layout.current_col = 0;
- if (layout.current_col >= layout.cols)
- layout.current_col = layout.cols - 1;
- if (layout.current_row < 0)
- layout.current_row = 0;
- if (layout.current_row >= layout.rows)
- layout.current_row = layout.rows - 1;
-
- i = layout.grid[layout.current_row * layout.cols + layout.current_col];
-
- if (i < 0)
- i = current_space;
-
- if (i >= num_workspaces)
- meta_bug ("calc_workspace_layout left an invalid (too-high) workspace number %d in the grid",
- i);
-
- meta_verbose ("Neighbor workspace is %d at row %d col %d",
- i, layout.current_row, layout.current_col);
-
- meta_workspace_manager_free_workspace_layout (&layout);
-
- return meta_workspace_manager_get_workspace_by_index (workspace->manager, i);
-}
-
-const char*
-meta_workspace_get_name (MetaWorkspace *workspace)
-{
- return meta_prefs_get_workspace_name (meta_workspace_index (workspace));
-}
-
-void
-meta_workspace_focus_default_window (MetaWorkspace *workspace,
- MetaWindow *not_this_one,
- guint32 timestamp)
-{
- if (timestamp == META_CURRENT_TIME)
- meta_warning ("META_CURRENT_TIME used to choose focus window; "
- "focus window may not be correct.");
-
- if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK ||
- !workspace->display->mouse_mode)
- focus_ancestor_or_top_window (workspace, not_this_one, timestamp);
- else
- {
- MetaWindow * window;
- 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 == META_CURRENT_TIME)
- {
-
- /* We would like for this to never happen. However, if
- * 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.
- */
-
- meta_topic (META_DEBUG_FOCUS,
- "Not focusing mouse window %s because EnterNotify events should handle that",
- window->desc);
- }
- else
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing mouse window %s", window->desc);
- meta_window_focus (window, timestamp);
- }
-
- if (workspace->display->autoraise_window != window &&
- meta_prefs_get_auto_raise ())
- {
- meta_display_queue_autoraise_callback (workspace->display, window);
- }
- }
- else if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_SLOPPY)
- focus_ancestor_or_top_window (workspace, not_this_one, timestamp);
- else if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_MOUSE)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Setting focus to no_focus_window, since no valid "
- "window to focus found.");
- meta_display_unset_input_focus (workspace->display, timestamp);
- }
- }
-}
-
-static gboolean
-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)
-{
- 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);
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Focus ancestor of not_this_one if there is one */
-static void
-focus_ancestor_or_top_window (MetaWorkspace *workspace,
- MetaWindow *not_this_one,
- guint32 timestamp)
-{
- MetaWindow *window = NULL;
-
- if (not_this_one)
- meta_topic (META_DEBUG_FOCUS,
- "Focusing MRU window excluding %s", not_this_one->desc);
- else
- meta_topic (META_DEBUG_FOCUS,
- "Focusing MRU window");
-
- /* First, check to see if we need to focus an ancestor of a window */
- if (not_this_one)
- {
- MetaWindow *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",
- ancestor->desc, not_this_one->desc);
-
- 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 () == G_DESKTOP_FOCUS_MODE_CLICK)
- meta_window_raise (ancestor);
-
- return;
- }
- }
- }
-
- window = meta_stack_get_default_focus_window (workspace->display->stack,
- workspace,
- not_this_one);
-
- if (window)
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing workspace MRU window %s", 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 () == G_DESKTOP_FOCUS_MODE_CLICK)
- meta_window_raise (window);
-
- 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/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}
diff --git a/src/meson.build b/src/meson.build
deleted file mode 100644
index 8ea2df0fa..000000000
--- a/src/meson.build
+++ /dev/null
@@ -1,1102 +0,0 @@
-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,
- gsettings_desktop_schemas_dep,
- gtk3_dep,
- pango_dep,
-]
-
-mutter_pkg_private_deps = [
- gmodule_no_export_dep,
- gnome_desktop_dep,
- gnome_settings_daemon_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',
- '-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-mode.c',
- 'backends/meta-crtc-mode.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-manager.c',
- 'backends/meta-idle-manager.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-input-settings-dummy.c',
- 'backends/meta-input-settings-dummy.h',
- 'backends/meta-keymap-utils.c',
- 'backends/meta-keymap-utils.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-impl.c',
- 'backends/meta-stage-impl-private.h',
- 'backends/meta-stage-private.h',
- 'backends/meta-stage-view.c',
- 'backends/meta-stage-view-private.h',
- 'backends/meta-viewport-info.c',
- 'backends/meta-viewport-info.h',
- 'backends/meta-virtual-monitor.c',
- 'backends/meta-virtual-monitor.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-cursor-tracker-x11.c',
- 'backends/x11/meta-cursor-tracker-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-content.c',
- 'compositor/meta-background-content-private.h',
- 'compositor/meta-background.c',
- 'compositor/meta-background-group.c',
- 'compositor/meta-background-image.c',
- 'compositor/meta-background-private.h',
- 'compositor/meta-compositor-server.c',
- 'compositor/meta-compositor-server.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-later.c',
- '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/meta-accel-parse.c',
- 'core/meta-accel-parse.h',
- 'core/meta-anonymous-file.c',
- 'core/meta-anonymous-file.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-context-main.c',
- 'core/meta-context-main.h',
- 'core/meta-context-private.h',
- 'core/meta-context.c',
- '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-pad-action-mapper.c',
- 'core/meta-private-enums.h',
- '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-private.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-area-stream.c',
- 'backends/meta-screen-cast-area-stream.h',
- 'backends/meta-screen-cast-area-stream-src.c',
- 'backends/meta-screen-cast-area-stream-src.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-virtual-stream-src.c',
- 'backends/meta-screen-cast-virtual-stream-src.h',
- 'backends/meta-screen-cast-virtual-stream.c',
- 'backends/meta-screen-cast-virtual-stream.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',
- 'core/meta-selection-source-remote.c',
- 'core/meta-selection-source-remote.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',
- '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-activation.c',
- 'wayland/meta-wayland-activation.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-client.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-presentation-time.c',
- 'wayland/meta-wayland-presentation-time-private.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-cogl-utils.c',
- 'backends/native/meta-cogl-utils.h',
- 'backends/native/meta-crtc-kms.c',
- 'backends/native/meta-crtc-kms.h',
- 'backends/native/meta-crtc-native.c',
- 'backends/native/meta-crtc-native.h',
- 'backends/native/meta-crtc-mode-kms.c',
- 'backends/native/meta-crtc-mode-kms.h',
- 'backends/native/meta-crtc-mode-virtual.c',
- 'backends/native/meta-crtc-mode-virtual.h',
- 'backends/native/meta-crtc-virtual.c',
- 'backends/native/meta-crtc-virtual.h',
- 'backends/native/meta-cursor-renderer-native.c',
- 'backends/native/meta-cursor-renderer-native.h',
- 'backends/native/meta-device-pool-private.h',
- 'backends/native/meta-device-pool.c',
- 'backends/native/meta-device-pool.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-private.h',
- 'backends/native/meta-drm-buffer.c',
- 'backends/native/meta-drm-buffer.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-native.c',
- 'backends/native/meta-monitor-manager-native.h',
- 'backends/native/meta-output-kms.c',
- 'backends/native/meta-output-kms.h',
- 'backends/native/meta-output-native.c',
- 'backends/native/meta-output-native.h',
- 'backends/native/meta-output-virtual.c',
- 'backends/native/meta-output-virtual.h',
- '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-atomic.c',
- 'backends/native/meta-kms-impl-device-atomic.h',
- 'backends/native/meta-kms-impl-device-dummy.c',
- 'backends/native/meta-kms-impl-device-dummy.h',
- 'backends/native/meta-kms-impl-device-simple.c',
- 'backends/native/meta-kms-impl-device-simple.h',
- 'backends/native/meta-kms-impl-device.c',
- 'backends/native/meta-kms-impl-device.h',
- 'backends/native/meta-kms-impl.c',
- 'backends/native/meta-kms-impl.h',
- 'backends/native/meta-kms-mode.c',
- 'backends/native/meta-kms-mode.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-onscreen-native.c',
- 'backends/native/meta-onscreen-native.h',
- 'backends/native/meta-pointer-constraint-native.c',
- 'backends/native/meta-pointer-constraint-native.h',
- 'backends/native/meta-renderer-native-gles3.c',
- 'backends/native/meta-renderer-native-gles3.h',
- 'backends/native/meta-renderer-native-private.h',
- 'backends/native/meta-renderer-native.c',
- 'backends/native/meta-renderer-native.h',
- 'backends/native/meta-seat-impl.c',
- 'backends/native/meta-seat-impl.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-virtual-monitor-native.c',
- 'backends/native/meta-virtual-monitor-native.h',
- 'backends/native/meta-xkb-utils.c',
- 'backends/native/meta-xkb-utils.h',
- 'compositor/meta-compositor-native.c',
- 'compositor/meta-compositor-native.h',
- ]
-endif
-
-if have_wayland_eglstream
- mutter_sources += [
- 'wayland/meta-wayland-egl-stream.c',
- 'wayland/meta-wayland-egl-stream.h',
- ]
-endif
-
-mutter_private_enum_sources = []
-
-if have_remote_desktop
- mutter_private_enum_sources += [
- 'backends/meta-screen-cast.h',
- ]
-endif
-
-if have_native_backend
- mutter_private_enum_sources += [
- 'backends/native/meta-backend-native-types.h',
- 'backends/native/meta-kms-types.h',
- ]
-endif
-
-mutter_built_sources = []
-
-if mutter_private_enum_sources.length() > 0
- mutter_private_enum_types = gnome.mkenums('meta-private-enum-types',
- sources: mutter_private_enum_sources,
- c_template: 'meta-private-enum-types.c.in',
- h_template: 'meta-private-enum-types.h.in',
- )
-
- mutter_built_sources += mutter_private_enum_types
-endif
-
-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
-
-if have_profiler
- mutter_sources += [
- 'backends/meta-profiler.c',
- 'backends/meta-profiler.h',
- ]
-
- if sysprof_dep.type_name() == 'pkgconfig'
- sysprof_dbus_interfaces_dir = join_paths(sysprof_dep.get_pkgconfig_variable('datadir'), 'dbus-1', 'interfaces')
- else
- sysprof_dbus_interfaces_dir = join_paths(meson.source_root(), 'subprojects', 'sysprof', 'src')
- endif
-
- 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
-
- dbus_login1_built_sources = gnome.gdbus_codegen('meta-dbus-login1',
- 'org.freedesktop.login1.xml',
- interface_prefix: 'org.freedesktop.login1.',
- namespace: 'MetaDbusLogin1',
- )
- 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', ],
- ['presentation-time', 'stable', ],
- ['primary-selection', 'unstable', 'v1', ],
- ['relative-pointer', 'unstable', 'v1', ],
- ['tablet', 'unstable', 'v2', ],
- ['text-input', 'unstable', 'v3', ],
- ['viewporter', 'stable', ],
- ['xdg-activation', 'staging', 'v1', ],
- ['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 == 'staging'
- protocol_version = p.get(2)
- output_base = '@0@-@1@'.format(protocol_name, protocol_version)
- 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
-
-libmutter = shared_library(libmutter_name,
- 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,
- dependencies: [
- libmutter_cogl_dep,
- libmutter_clutter_dep,
- mutter_deps,
- ],
-)
-
-executable('mutter',
- sources: [
- files('core/mutter.c'),
- ],
- include_directories: mutter_includes,
- c_args: mutter_c_args,
- dependencies: [libmutter_dep],
- install_dir: bindir,
- install: true,
-)
-
-executable('mutter-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_enum_types[1],
- mutter_introspected_sources,
- mutter_public_header_files
- ],
- nsversion: libmutter_api_version,
- namespace: 'Meta',
- symbol_prefix: 'meta',
- includes: [
- 'GObject-2.0',
- 'GDesktopEnums-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: 'libmutter-' + libmutter_api_version,
- description: 'Mutter 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}/mutter-' + libmutter_api_version,
- 'typelibdir=${libdir}/mutter-' + libmutter_api_version,
- ],
- install_dir: pcdir,
-)
-
-subdir('compositor/plugins')
-
-if have_core_tests
- subdir('tests')
-endif
diff --git a/src/meta-private-enum-types.c.in b/src/meta-private-enum-types.c.in
deleted file mode 100644
index c2479a91a..000000000
--- a/src/meta-private-enum-types.c.in
+++ /dev/null
@@ -1,39 +0,0 @@
-/*** BEGIN file-header ***/
-#include "meta-private-enum-types.h"
-/*** END file-header ***/
-
-/*** BEGIN file-production ***/
-
-/* enumerations from "@filename@" */
-#include "@filename@"
-
-/*** END file-production ***/
-
-/*** BEGIN value-header ***/
-GType
-@enum_name@_get_type (void)
-{
- static size_t g_enum_type_id = 0;
-
- if (g_once_init_enter (&g_enum_type_id))
- {
- static const G@Type@Value values[] = {
-/*** END value-header ***/
-
-/*** BEGIN value-production ***/
- { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
-/*** END value-production ***/
-
-/*** BEGIN value-tail ***/
- { 0, NULL, NULL }
- };
- GType id;
-
- id = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
-
- g_once_init_leave (&g_enum_type_id, id);
- }
-
- return g_enum_type_id;
-}
-/*** END value-tail ***/
diff --git a/src/meta-private-enum-types.h.in b/src/meta-private-enum-types.h.in
deleted file mode 100644
index 2427a0c68..000000000
--- a/src/meta-private-enum-types.h.in
+++ /dev/null
@@ -1,25 +0,0 @@
-/*** BEGIN file-header ***/
-#ifndef META_PRIVATE_ENUM_TYPES_H
-#define META_PRIVATE_ENUM_TYPES_H
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-/*** END file-header ***/
-
-/*** BEGIN file-production ***/
-/* enumerations from "@basename@" */
-/*** END file-production ***/
-
-/*** BEGIN file-tail ***/
-G_END_DECLS
-
-#endif /* !__MUTTER_ENUM_TYPES_H__ */
-/*** END file-tail ***/
-
-/*** BEGIN value-header ***/
-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/barrier.h b/src/meta/barrier.h
deleted file mode 100644
index 72ed33cfc..000000000
--- a/src/meta/barrier.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 7585e1312..000000000
--- a/src/meta/boxes.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_BOXES_H
-#define META_BOXES_H
-
-#include <glib-object.h>
-#include <meta/common.h>
-
-#define META_TYPE_RECTANGLE (meta_rectangle_get_type ())
-
-/**
- * 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;
- int y;
- 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
-{
- MetaRectangle rect;
- 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,
- META_EDGE_MONITOR,
- 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
-{
- MetaRectangle rect; /* width or height should be 1 */
- MetaSide side_type;
- 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);
-
-/* 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);
-
-/* vert_overlap means ignore the horizontal location and ask if the
- * vertical parts overlap. An alternate way to think of it is "Does there
- * 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);
-
-#endif /* META_BOXES_H */
diff --git a/src/meta/common.h b/src/meta/common.h
deleted file mode 100644
index ab9308049..000000000
--- a/src/meta/common.h
+++ /dev/null
@@ -1,553 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_COMMON_H
-#define META_COMMON_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: Mutter common types
- */
-
-/* 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_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;
-
-/**
- * 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,
-
- /* Window grab ops. */
- META_GRAB_OP_WINDOW_BASE,
-
- /* Special grab op when the compositor asked for a grab */
- 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)
- * @META_CURSOR_BLANK: Invisible cursor
- */
-typedef enum
-{
- META_CURSOR_NONE = 0,
- META_CURSOR_DEFAULT,
- META_CURSOR_NORTH_RESIZE,
- META_CURSOR_SOUTH_RESIZE,
- META_CURSOR_WEST_RESIZE,
- META_CURSOR_EAST_RESIZE,
- META_CURSOR_SE_RESIZE,
- META_CURSOR_SW_RESIZE,
- META_CURSOR_NE_RESIZE,
- META_CURSOR_NW_RESIZE,
- META_CURSOR_MOVE_OR_RESIZE_WINDOW,
- 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_BLANK,
- 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,
- META_FRAME_TYPE_DIALOG,
- META_FRAME_TYPE_MODAL_DIALOG,
- META_FRAME_TYPE_UTILITY,
- META_FRAME_TYPE_MENU,
- META_FRAME_TYPE_BORDER,
- META_FRAME_TYPE_ATTACHED,
- 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
- * X mod bits, to be sure we find bugs
- */
- META_VIRTUAL_SHIFT_MASK = 1 << 5,
- META_VIRTUAL_CONTROL_MASK = 1 << 6,
- META_VIRTUAL_ALT_MASK = 1 << 7,
- META_VIRTUAL_META_MASK = 1 << 8,
- META_VIRTUAL_SUPER_MASK = 1 << 9,
- META_VIRTUAL_HYPER_MASK = 1 << 10,
- META_VIRTUAL_MOD2_MASK = 1 << 11,
- META_VIRTUAL_MOD3_MASK = 1 << 12,
- META_VIRTUAL_MOD4_MASK = 1 << 13,
- 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
- * display.[ch]:MetaDisplayDirection,
- * workspace.[ch]:MetaMotionDirection,
- * with the use of MetaDirection.
- */
-typedef enum
-{
- META_DIRECTION_LEFT = 1 << 0,
- META_DIRECTION_RIGHT = 1 << 1,
- META_DIRECTION_TOP = 1 << 2,
- META_DIRECTION_BOTTOM = 1 << 3,
-
- /* Some aliases for making code more readable for various circumstances. */
- META_DIRECTION_UP = META_DIRECTION_TOP,
- META_DIRECTION_DOWN = META_DIRECTION_BOTTOM,
-
- /* A few more definitions using aliases */
- META_DIRECTION_HORIZONTAL = META_DIRECTION_LEFT | META_DIRECTION_RIGHT,
- 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
- */
-typedef enum
-{
- META_MOTION_UP = -1,
- META_MOTION_DOWN = -2,
- META_MOTION_LEFT = -3,
- META_MOTION_RIGHT = -4,
- /* These are only used for effects */
- META_MOTION_UP_LEFT = -5,
- META_MOTION_UP_RIGHT = -6,
- META_MOTION_DOWN_LEFT = -7,
- 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
- * MetaDirection used to be used as a side.
- */
-typedef enum
-{
- META_SIDE_LEFT = META_DIRECTION_LEFT,
- META_SIDE_RIGHT = META_DIRECTION_RIGHT,
- META_SIDE_TOP = META_DIRECTION_TOP,
- META_SIDE_BOTTOM = META_DIRECTION_BOTTOM
-} MetaSide;
-
-/**
- * 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.
- */
-typedef enum
-{
- META_BUTTON_FUNCTION_MENU,
- META_BUTTON_FUNCTION_MINIMIZE,
- META_BUTTON_FUNCTION_MAXIMIZE,
- META_BUTTON_FUNCTION_CLOSE,
- META_BUTTON_FUNCTION_LAST
-} MetaButtonFunction;
-
-#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=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
-{
- /* buttons in the group on the left side */
- MetaButtonFunction left_buttons[MAX_BUTTONS_PER_CORNER];
- gboolean left_buttons_has_spacer[MAX_BUTTONS_PER_CORNER];
-
- /* buttons in the group on the right side */
- MetaButtonFunction right_buttons[MAX_BUTTONS_PER_CORNER];
- 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
-{
- /* The frame border is made up of two pieces - an inner visible portion
- * and an outer portion that is invisible but responds to events.
- */
- GtkBorder visible;
- GtkBorder invisible;
-
- /* For convenience, we have a "total" border which is equal to the sum
- * of the two borders above. */
- GtkBorder total;
-};
-
-/* 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
- * will take precedence over the others. Priorities are sometimes
- * used to enforce ordering: give A a higher priority than B if
- * A must occur before B. But that poses a problem since then
- * if A occurs frequently enough, B will never occur.
- *
- * Anything we want to occur more or less immediately should
- * have a priority of G_PRIORITY_DEFAULT. When we want to
- * coalesce multiple things together, the appropriate place to
- * do it is usually META_PRIORITY_BEFORE_REDRAW.
- *
- * Note that its usually better to use meta_later_add() rather
- * than calling g_idle_add() directly; this will make sure things
- * get run when added from a clutter event handler without
- * waiting for another repaint cycle.
- *
- * If something has a priority lower than the redraw priority
- * (such as a default priority idle), then it may be arbitrarily
- * delayed. This happens if the screen is updating rapidly: we
- * are spending all our time either redrawing or waiting for a
- * vblank-synced buffer swap. (When X is improved to allow
- * clutter to do the buffer-swap asynchronously, this will get
- * better.)
- */
-
-/* G_PRIORITY_DEFAULT:
- * events
- * many timeouts
- */
-
-/* GTK_PRIORITY_RESIZE: (G_PRIORITY_HIGH_IDLE + 10) */
-#define META_PRIORITY_RESIZE (G_PRIORITY_HIGH_IDLE + 15)
-/* GTK_PRIORITY_REDRAW: (G_PRIORITY_HIGH_IDLE + 20) */
-
-#define META_PRIORITY_BEFORE_REDRAW (G_PRIORITY_HIGH_IDLE + 40)
-/* calc-showing idle
- * update-icon idle
- */
-
-/* CLUTTER_PRIORITY_REDRAW: (G_PRIORITY_HIGH_IDLE + 50) */
-#define META_PRIORITY_REDRAW (G_PRIORITY_HIGH_IDLE + 50)
-
-/* ==== Anything below here can be starved arbitrarily ==== */
-
-/* G_PRIORITY_DEFAULT_IDLE:
- * Mutter plugin unloading
- */
-
-#define META_PRIORITY_PREFS_NOTIFY (G_PRIORITY_DEFAULT_IDLE + 10)
-
-/************************************************************/
-
-/**
- * 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.
- */
-typedef enum
-{
- META_LAYER_DESKTOP = 0,
- META_LAYER_BOTTOM = 1,
- META_LAYER_NORMAL = 2,
- META_LAYER_TOP = 4, /* Same as DOCK; see EWMH and bug 330717 */
- META_LAYER_DOCK = 4,
- META_LAYER_OVERRIDE_REDIRECT = 7,
- META_LAYER_LAST = 8
-} MetaStackLayer;
-
-/* MetaGravity: (skip)
- *
- * Identical to the corresponding gravity value macros from libX11.
- */
-typedef enum _MetaGravity
-{
- 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-mutter.h b/src/meta/compositor-mutter.h
deleted file mode 100644
index 0c420882f..000000000
--- a/src/meta/compositor-mutter.h
+++ /dev/null
@@ -1,60 +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, 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
deleted file mode 100644
index 1ccae70d7..000000000
--- a/src/meta/compositor.h
+++ /dev/null
@@ -1,165 +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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef META_COMPOSITOR_H
-#define META_COMPOSITOR_H
-
-#include <glib.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
- * (also used for a window that was previously on a different
- * workspace and is changed to become visible on the active
- * workspace.)
- * @META_COMP_EFFECT_UNMINIMIZE: The window should be shown
- * as unminimizing from its icon geometry.
- * @META_COMP_EFFECT_DESTROY: The window is being destroyed
- * @META_COMP_EFFECT_MINIMIZE: The window should be shown
- * as minimizing to its icon geometry.
- * @META_COMP_EFFECT_NONE: No effect, the window should be
- * shown or hidden immediately.
- *
- * Indicates the appropriate effect to show the user for
- * meta_compositor_show_window() and meta_compositor_hide_window()
- */
-typedef enum
-{
- META_COMP_EFFECT_CREATE,
- META_COMP_EFFECT_UNMINIMIZE,
- META_COMP_EFFECT_DESTROY,
- META_COMP_EFFECT_MINIMIZE,
- META_COMP_EFFECT_NONE
-} MetaCompEffect;
-
-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);
-
-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);
-
-META_EXPORT
-void meta_compositor_window_opacity_changed (MetaCompositor *compositor,
- MetaWindow *window);
-
-META_EXPORT
-gboolean meta_compositor_filter_keybinding (MetaCompositor *compositor,
- MetaKeyBinding *binding);
-
-META_EXPORT
-void meta_compositor_add_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,
- MetaWorkspace *from,
- MetaWorkspace *to,
- MetaMotionDirection direction);
-
-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);
-
-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,
- GList *stack);
-
-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
deleted file mode 100644
index 23bcbd0f5..000000000
--- a/src/meta/display.h
+++ /dev/null
@@ -1,315 +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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef META_DISPLAY_H
-#define META_DISPLAY_H
-
-#include <glib-object.h>
-#include <X11/Xlib.h>
-
-#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,
- META_TAB_LIST_DOCKS,
- META_TAB_LIST_GROUP,
- 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 ())
-#define META_DISPLAY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), META_TYPE_DISPLAY, MetaDisplay))
-#define META_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DISPLAY, MetaDisplayClass))
-#define META_IS_DISPLAY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), META_TYPE_DISPLAY))
-#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)
-
-META_EXPORT
-gboolean meta_display_supports_extended_barriers (MetaDisplay *display);
-
-META_EXPORT
-void meta_display_close (MetaDisplay *display,
- guint32 timestamp);
-
-META_EXPORT
-MetaContext * meta_display_get_context (MetaDisplay *display);
-
-META_EXPORT
-MetaCompositor *meta_display_get_compositor (MetaDisplay *display);
-
-META_EXPORT
-MetaX11Display *meta_display_get_x11_display (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);
-
-META_EXPORT
-guint32 meta_display_get_current_time_roundtrip (MetaDisplay *display);
-
-META_EXPORT
-GList* meta_display_get_tab_list (MetaDisplay *display,
- MetaTabList type,
- MetaWorkspace *workspace);
-
-META_EXPORT
-MetaWindow* meta_display_get_tab_next (MetaDisplay *display,
- MetaTabList type,
- MetaWorkspace *workspace,
- MetaWindow *window,
- gboolean backward);
-
-META_EXPORT
-MetaWindow* meta_display_get_tab_current (MetaDisplay *display,
- MetaTabList type,
- MetaWorkspace *workspace);
-
-META_EXPORT
-gboolean meta_display_begin_grab_op (MetaDisplay *display,
- MetaWindow *window,
- MetaGrabOp op,
- gboolean pointer_already_grabbed,
- gboolean frame_action,
- int button,
- gulong modmask,
- 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);
-
-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);
-
-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
-ClutterModifierType meta_display_get_compositor_modifiers (MetaDisplay *display);
-
-META_EXPORT
-GSList *meta_display_sort_windows_by_stacking (MetaDisplay *display,
- GSList *windows);
-
-META_EXPORT
-void meta_display_add_ignored_crossing_serial (MetaDisplay *display,
- unsigned long serial);
-
-META_EXPORT
-void meta_display_clear_mouse_mode (MetaDisplay *display);
-
-META_EXPORT
-void meta_display_freeze_keyboard (MetaDisplay *display,
- guint32 timestamp);
-
-META_EXPORT
-void meta_display_ungrab_keyboard (MetaDisplay *display,
- guint32 timestamp);
-
-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/group.h b/src/meta/group.h
deleted file mode 100644
index 5567cf466..000000000
--- a/src/meta/group.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_GROUP_H
-#define META_GROUP_H
-
-#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 */
-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
deleted file mode 100644
index ac1cee5b3..000000000
--- a/src/meta/keybindings.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2009 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef META_KEYBINDINGS_H
-#define META_KEYBINDINGS_H
-
-#include <meta/display.h>
-#include <meta/common.h>
-
-#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);
-#endif
diff --git a/src/meta/main.h b/src/meta/main.h
deleted file mode 100644
index 3e5db424a..000000000
--- a/src/meta/main.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Mutter 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef META_MAIN_H
-#define META_MAIN_H
-
-#include <glib.h>
-
-#include <meta/common.h>
-
-META_EXPORT
-void meta_restart (const char *message);
-
-META_EXPORT
-gboolean meta_is_restart (void);
-
-/**
- * MetaExitCode:
- * @META_EXIT_SUCCESS: Success
- * @META_EXIT_ERROR: Error
- */
-typedef enum
-{
- META_EXIT_SUCCESS,
- META_EXIT_ERROR
-} MetaExitCode;
-
-/* exit immediately */
-META_EXPORT
-void meta_exit (MetaExitCode code) G_GNUC_NORETURN;
-
-#endif
diff --git a/src/meta/meson.build b/src/meta/meson.build
deleted file mode 100644
index 3076f7532..000000000
--- a/src/meta/meson.build
+++ /dev/null
@@ -1,75 +0,0 @@
-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-content.h',
- 'meta-background-group.h',
- 'meta-background-image.h',
- 'meta-close-dialog.h',
- 'meta-cursor-tracker.h',
- 'meta-context.h',
- 'meta-dnd.h',
- 'meta-enums.h',
- 'meta-idle-monitor.h',
- 'meta-inhibit-shortcuts-dialog.h',
- 'meta-launch-context.h',
- 'meta-later.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_wayland
- mutter_public_headers += [
- 'meta-wayland-client.h',
- ]
-endif
-
-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,
-)
diff --git a/src/meta/meta-backend.h b/src/meta/meta-backend.h
deleted file mode 100644
index 63a679a1a..000000000
--- a/src/meta/meta-backend.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- 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-idle-monitor.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
-MetaContext * meta_backend_get_context (MetaBackend *backend);
-
-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
-MetaIdleMonitor * meta_backend_get_core_idle_monitor (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
deleted file mode 100644
index 3008edcfd..000000000
--- a/src/meta/meta-background-actor.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef META_BACKGROUND_ACTOR_H
-#define META_BACKGROUND_ACTOR_H
-
-#include <gdesktop-enums.h>
-
-#include "clutter/clutter.h"
-#include "meta/meta-background.h"
-
-/**
- * MetaBackgroundActor:
- *
- * 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_ACTOR (meta_background_actor_get_type ())
-
-META_EXPORT
-G_DECLARE_FINAL_TYPE (MetaBackgroundActor,
- meta_background_actor,
- META, BACKGROUND_ACTOR,
- ClutterActor)
-
-
-META_EXPORT
-ClutterActor *meta_background_actor_new (MetaDisplay *display,
- int monitor);
-
-#endif /* META_BACKGROUND_ACTOR_H */
diff --git a/src/meta/meta-background-content.h b/src/meta/meta-background-content.h
deleted file mode 100644
index a24ad809e..000000000
--- a/src/meta/meta-background-content.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * meta-background-content.h: ClutterContent for painting the wallpaper
- *
- * Copyright 2010 Red Hat, Inc.
- * Copyright 2020 Endless Foundation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_CONTENT_H
-#define META_BACKGROUND_CONTENT_H
-
-#include <gdesktop-enums.h>
-
-#include "clutter/clutter.h"
-#include "meta/meta-background.h"
-
-/**
- * MetaBackgroundContent:
- *
- * 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_CONTENT (meta_background_content_get_type ())
-
-META_EXPORT
-G_DECLARE_FINAL_TYPE (MetaBackgroundContent,
- meta_background_content,
- META, BACKGROUND_CONTENT,
- GObject)
-
-
-META_EXPORT
-ClutterContent *meta_background_content_new (MetaDisplay *display,
- int monitor);
-
-META_EXPORT
-void meta_background_content_set_background (MetaBackgroundContent *self,
- MetaBackground *background);
-
-META_EXPORT
-void meta_background_content_set_gradient (MetaBackgroundContent *self,
- gboolean enabled,
- int height,
- double tone_start);
-
-META_EXPORT
-void meta_background_content_set_vignette (MetaBackgroundContent *self,
- gboolean enabled,
- double brightness,
- double sharpness);
-
-META_EXPORT
-void meta_background_content_set_rounded_clip_radius (MetaBackgroundContent *self,
- float radius);
-
-META_EXPORT
-void meta_background_content_set_rounded_clip_bounds (MetaBackgroundContent *self,
- const graphene_rect_t *bounds);
-
-#endif /* META_BACKGROUND_CONTENT_H */
diff --git a/src/meta/meta-background-group.h b/src/meta/meta-background-group.h
deleted file mode 100644
index b43fcb94a..000000000
--- a/src/meta/meta-background-group.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 137a6ff8e..000000000
--- a/src/meta/meta-background-image.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 550b1d986..000000000
--- a/src/meta/meta-background.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- 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 <gdesktop-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,
- GDesktopBackgroundShading shading_direction,
- ClutterColor *color,
- ClutterColor *second_color);
-
-META_EXPORT
-void meta_background_set_file (MetaBackground *self,
- GFile *file,
- GDesktopBackgroundStyle style);
-
-META_EXPORT
-void meta_background_set_blend (MetaBackground *self,
- GFile *file1,
- GFile *file2,
- double blend_factor,
- GDesktopBackgroundStyle style);
-
-#endif /* META_BACKGROUND_H */
diff --git a/src/meta/meta-close-dialog.h b/src/meta/meta-close-dialog.h
deleted file mode 100644
index 281b0ee24..000000000
--- a/src/meta/meta-close-dialog.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- 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-context.h b/src/meta/meta-context.h
deleted file mode 100644
index 50b4bd5f9..000000000
--- a/src/meta/meta-context.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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_CONTEXT_H
-#define META_CONTEXT_H
-
-#include <glib-object.h>
-
-#include "meta/common.h"
-#include "meta/meta-enums.h"
-#include "meta/types.h"
-
-#define META_TYPE_CONTEXT (meta_context_get_type ())
-META_EXPORT
-G_DECLARE_DERIVABLE_TYPE (MetaContext, meta_context, META, CONTEXT, GObject)
-
-META_EXPORT
-MetaContext * meta_create_context (const char *name);
-
-META_EXPORT
-void meta_context_destroy (MetaContext *context);
-
-META_EXPORT
-void meta_context_add_option_entries (MetaContext *context,
- const GOptionEntry *entries,
- const char *translation_domain);
-
-META_EXPORT
-void meta_context_add_option_group (MetaContext *context,
- GOptionGroup *group);
-
-META_EXPORT
-void meta_context_set_plugin_gtype (MetaContext *context,
- GType plugin_gtype);
-
-META_EXPORT
-void meta_context_set_plugin_name (MetaContext *context,
- const char *plugin_name);
-
-META_EXPORT
-void meta_context_set_gnome_wm_keybindings (MetaContext *context,
- const char *wm_keybindings);
-
-META_EXPORT
-gboolean meta_context_configure (MetaContext *context,
- int *argc,
- char ***argv,
- GError **error);
-
-META_EXPORT
-gboolean meta_context_setup (MetaContext *context,
- GError **error);
-
-META_EXPORT
-gboolean meta_context_start (MetaContext *context,
- GError **error);
-
-META_EXPORT
-gboolean meta_context_run_main_loop (MetaContext *context,
- GError **error);
-
-META_EXPORT
-void meta_context_notify_ready (MetaContext *context);
-
-META_EXPORT
-void meta_context_terminate (MetaContext *context);
-
-META_EXPORT
-void meta_context_terminate_with_error (MetaContext *context,
- GError *error);
-
-META_EXPORT
-MetaCompositorType meta_context_get_compositor_type (MetaContext *context);
-
-META_EXPORT
-gboolean meta_context_is_replacing (MetaContext *context);
-
-META_EXPORT
-MetaBackend * meta_context_get_backend (MetaContext *context);
-
-META_EXPORT
-MetaDisplay * meta_context_get_display (MetaContext *context);
-
-#endif /* META_CONTEXT_H */
diff --git a/src/meta/meta-cursor-tracker.h b/src/meta/meta-cursor-tracker.h
deleted file mode 100644
index a3b71c4f6..000000000
--- a/src/meta/meta-cursor-tracker.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- 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_DERIVABLE_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,
- graphene_point_t *coords,
- 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
deleted file mode 100644
index 2b2be1029..000000000
--- a/src/meta/meta-dnd.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- 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/meta/meta-enum-types.c.in b/src/meta/meta-enum-types.c.in
deleted file mode 100644
index a5d839141..000000000
--- a/src/meta/meta-enum-types.c.in
+++ /dev/null
@@ -1,39 +0,0 @@
-/*** BEGIN file-header ***/
-#include <meta/meta-enum-types.h>
-/*** END file-header ***/
-
-/*** BEGIN file-production ***/
-
-/* enumerations from "@filename@" */
-#include "@filename@"
-
-/*** END file-production ***/
-
-/*** BEGIN value-header ***/
-GType
-@enum_name@_get_type (void)
-{
- static size_t g_enum_type_id = 0;
-
- if (g_once_init_enter (&g_enum_type_id))
- {
- static const G@Type@Value values[] = {
-/*** END value-header ***/
-
-/*** BEGIN value-production ***/
- { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
-/*** END value-production ***/
-
-/*** BEGIN value-tail ***/
- { 0, NULL, NULL }
- };
- GType id;
-
- id = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
-
- g_once_init_leave (&g_enum_type_id, id);
- }
-
- return g_enum_type_id;
-}
-/*** END value-tail ***/
diff --git a/src/meta/meta-enum-types.h.in b/src/meta/meta-enum-types.h.in
deleted file mode 100644
index bee0196de..000000000
--- a/src/meta/meta-enum-types.h.in
+++ /dev/null
@@ -1,27 +0,0 @@
-/*** BEGIN file-header ***/
-#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 "@basename@" */
-/*** END file-production ***/
-
-/*** BEGIN file-tail ***/
-G_END_DECLS
-
-#endif /* !__MUTTER_ENUM_TYPES_H__ */
-/*** END file-tail ***/
-
-/*** BEGIN value-header ***/
-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-enums.h b/src/meta/meta-enums.h
deleted file mode 100644
index 373d14451..000000000
--- a/src/meta/meta-enums.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2016-2021 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_ENUMS_H
-#define META_ENUMS_H
-
-typedef enum _MetaCompositorType
-{
- META_COMPOSITOR_TYPE_WAYLAND,
- META_COMPOSITOR_TYPE_X11,
-} MetaCompositorType;
-
-#endif /* META_ENUMS_H */
diff --git a/src/meta/meta-idle-monitor.h b/src/meta/meta-idle-monitor.h
deleted file mode 100644
index 8cc9bf2bf..000000000
--- a/src/meta/meta-idle-monitor.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- 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 ())
-META_EXPORT
-G_DECLARE_FINAL_TYPE (MetaIdleMonitor, meta_idle_monitor,
- META, IDLE_MONITOR,
- GObject)
-
-typedef void (*MetaIdleMonitorWatchFunc) (MetaIdleMonitor *monitor,
- guint watch_id,
- gpointer user_data);
-
-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
deleted file mode 100644
index 4e34f1701..000000000
--- a/src/meta/meta-inhibit-shortcuts-dialog.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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-later.h b/src/meta/meta-later.h
deleted file mode 100644
index 4464fc3bd..000000000
--- a/src/meta/meta-later.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2005 Elijah Newren
- * 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/>.
- */
-
-#ifndef META_LATER_H
-#define META_LATER_H
-
-/**
- * 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 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
-{
- META_LATER_RESIZE,
- META_LATER_CALC_SHOWING,
- META_LATER_CHECK_FULLSCREEN,
- META_LATER_SYNC_STACK,
- META_LATER_BEFORE_REDRAW,
- 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);
-
-#endif /* META_LATER_H */
diff --git a/src/meta/meta-launch-context.h b/src/meta/meta-launch-context.h
deleted file mode 100644
index b719f0e07..000000000
--- a/src/meta/meta-launch-context.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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
deleted file mode 100644
index ce57156be..000000000
--- a/src/meta/meta-monitor-manager.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- 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);
-
-META_EXPORT
-gboolean meta_monitor_manager_get_panel_orientation_managed (MetaMonitorManager *manager);
-
-#endif /* META_MONITOR_MANAGER_H */
diff --git a/src/meta/meta-plugin.h b/src/meta/meta-plugin.h
deleted file mode 100644
index 1bc19a5f0..000000000
--- a/src/meta/meta-plugin.h
+++ /dev/null
@@ -1,370 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (c) 2008 Intel Corp.
- *
- * Author: Tomas Frydrych <tf@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_PLUGIN_H_
-#define META_PLUGIN_H_
-
-#include <X11/extensions/Xfixes.h>
-#include <gmodule.h>
-
-#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/types.h"
-
-#define META_TYPE_PLUGIN (meta_plugin_get_type ())
-
-META_EXPORT
-G_DECLARE_DERIVABLE_TYPE (MetaPlugin, meta_plugin, META, PLUGIN, GObject)
-
-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);
-
- /**
- * MetaPluginClass::unminimize:
- * @actor: a #MetaWindowActor
- *
- * Virtual function called when the window represented by @actor is unminimized.
- */
- void (*unminimize) (MetaPlugin *plugin,
- MetaWindowActor *actor);
-
- void (*size_changed) (MetaPlugin *plugin,
- MetaWindowActor *actor);
-
- void (*size_change) (MetaPlugin *plugin,
- MetaWindowActor *actor,
- 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);
- void (*hide_tile_preview) (MetaPlugin *plugin);
-
- 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);
-
- /**
- * 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;
- const gchar *version;
- const gchar *author;
- const gchar *license;
- const gchar *description;
-};
-
-META_EXPORT
-const MetaPluginInfo * meta_plugin_get_info (MetaPlugin *plugin);
-
-/*
- * Convenience macro to set up the plugin type. Based on GEdit.
- */
-#define META_PLUGIN_DECLARE_WITH_CODE(ObjectName, object_name, CODE) \
- /* Prototypes */ \
- G_MODULE_EXPORT GType \
- object_name##_get_type (void); \
- \
- G_MODULE_EXPORT GType \
- meta_plugin_register_type (GTypeModule *type_module); \
- \
- \
- G_DEFINE_DYNAMIC_TYPE_EXTENDED(ObjectName, object_name, \
- META_TYPE_PLUGIN, 0, CODE) \
- \
- /* 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) \
- { \
- 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_unminimize_completed (MetaPlugin *plugin,
- MetaWindowActor *actor);
-
-META_EXPORT
-void
-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
- * grabbed by the plugin and should not be grabbed again.
- * @META_MODAL_KEYBOARD_ALREADY_GRABBED: if set the keyboard is already
- * grabbed by the plugin and should not be grabbed again.
- *
- * Options that can be provided when calling meta_plugin_begin_modal().
- */
-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,
- MetaModalOptions options,
- guint32 timestamp);
-
-META_EXPORT
-void
-meta_plugin_end_modal (MetaPlugin *plugin,
- guint32 timestamp);
-
-META_EXPORT
-MetaDisplay *meta_plugin_get_display (MetaPlugin *plugin);
-
-void _meta_plugin_set_compositor (MetaPlugin *plugin, MetaCompositor *compositor);
-
-/* 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
deleted file mode 100644
index 81b717eac..000000000
--- a/src/meta/meta-remote-access-controller.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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)
-
-META_EXPORT
-void meta_remote_access_controller_inhibit_remote_access (MetaRemoteAccessController *controller);
-
-META_EXPORT
-void meta_remote_access_controller_uninhibit_remote_access (MetaRemoteAccessController *controller);
-
-#endif /* META_REMOTE_ACCESS_CONTROLLER_H */
diff --git a/src/meta/meta-selection-source-memory.h b/src/meta/meta-selection-source-memory.h
deleted file mode 100644
index b72e12762..000000000
--- a/src/meta/meta-selection-source-memory.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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
deleted file mode 100644
index a341bede1..000000000
--- a/src/meta/meta-selection-source.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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
deleted file mode 100644
index ef86dce1d..000000000
--- a/src/meta/meta-selection.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 5683d7c1d..000000000
--- a/src/meta/meta-settings.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- 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
deleted file mode 100644
index a3aa0847c..000000000
--- a/src/meta/meta-shadow-factory.h
+++ /dev/null
@@ -1,135 +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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __META_SHADOW_FACTORY_H__
-#define __META_SHADOW_FACTORY_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:
- * @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
- * @x_offset: horizontal offset of the shadow with respect to the
- * shape being shadowed, in pixels
- * @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;
-
-struct _MetaShadowParams
-{
- int radius;
- int top_fade;
- int x_offset;
- int y_offset;
- guint8 opacity;
-};
-
-#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.
- */
-META_EXPORT
-MetaShadowFactory *meta_shadow_factory_get_default (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);
-
-/**
- * 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
deleted file mode 100644
index 2ca0e6e61..000000000
--- a/src/meta/meta-shaped-texture.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * shaped texture
- *
- * An actor to draw a texture clipped to a list of rectangles
- *
- * Authored By Neil Roberts <neil@linux.intel.com>
- *
- * Copyright (C) 2008 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __META_SHAPED_TEXTURE_H__
-#define __META_SHAPED_TEXTURE_H__
-
-#include <X11/Xlib.h>
-
-#include "clutter/clutter.h"
-#include <meta/common.h>
-
-G_BEGIN_DECLS
-
-#define META_TYPE_SHAPED_TEXTURE (meta_shaped_texture_get_type ())
-
-META_EXPORT
-G_DECLARE_FINAL_TYPE (MetaShapedTexture,
- meta_shaped_texture,
- META, SHAPED_TEXTURE,
- GObject)
-
-
-META_EXPORT
-void meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
- gboolean create_mipmaps);
-
-META_EXPORT
-CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
-
-META_EXPORT
-void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
- CoglTexture *mask_texture);
-
-META_EXPORT
-cairo_surface_t * meta_shaped_texture_get_image (MetaShapedTexture *stex,
- cairo_rectangle_int_t *clip);
-
-G_END_DECLS
-
-#endif /* __META_SHAPED_TEXTURE_H__ */
diff --git a/src/meta/meta-sound-player.h b/src/meta/meta-sound-player.h
deleted file mode 100644
index 4183689cd..000000000
--- a/src/meta/meta-sound-player.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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/meta/meta-stage.h b/src/meta/meta-stage.h
deleted file mode 100644
index afab102e5..000000000
--- a/src/meta/meta-stage.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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_H
-#define META_STAGE_H
-
-#include "clutter/clutter.h"
-
-G_BEGIN_DECLS
-
-#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_STAGE_H */
diff --git a/src/meta/meta-startup-notification.h b/src/meta/meta-startup-notification.h
deleted file mode 100644
index 11afb3e05..000000000
--- a/src/meta/meta-startup-notification.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- 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-wayland-client.h b/src/meta/meta-wayland-client.h
deleted file mode 100644
index 911048b3e..000000000
--- a/src/meta/meta-wayland-client.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright 2019 Sergio Costas (rastersoft@gmail.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public 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_CLIENT_H
-#define META_WAYLAND_CLIENT_H
-
-#include <glib-object.h>
-#include <gio/gio.h>
-
-#include "meta/display.h"
-
-G_BEGIN_DECLS
-
-#define META_TYPE_WAYLAND_CLIENT (meta_wayland_client_get_type ())
-META_EXPORT
-G_DECLARE_FINAL_TYPE (MetaWaylandClient, meta_wayland_client, META, WAYLAND_CLIENT, GObject)
-
-META_EXPORT
-MetaWaylandClient *meta_wayland_client_new (GSubprocessLauncher *launcher,
- GError **error);
-
-META_EXPORT
-GSubprocess *meta_wayland_client_spawn (MetaWaylandClient *client,
- MetaDisplay *display,
- GError **error,
- const char *argv0,
- ...) G_GNUC_NULL_TERMINATED;
-
-META_EXPORT
-GSubprocess *meta_wayland_client_spawnv (MetaWaylandClient *client,
- MetaDisplay *display,
- const char * const *argv,
- GError **error);
-
-META_EXPORT
-gboolean meta_wayland_client_owns_window (MetaWaylandClient *client,
- MetaWindow *window);
-
-META_EXPORT
-void meta_wayland_client_hide_from_window_list (MetaWaylandClient *client,
- MetaWindow *window);
-
-META_EXPORT
-void meta_wayland_client_show_in_window_list (MetaWaylandClient *client,
- MetaWindow *window);
-
-G_END_DECLS
-
-#endif /* META_WAYLAND_CLIENT_H */
diff --git a/src/meta/meta-window-actor.h b/src/meta/meta-window-actor.h
deleted file mode 100644
index 6e18683a2..000000000
--- a/src/meta/meta-window-actor.h
+++ /dev/null
@@ -1,67 +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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef META_WINDOW_ACTOR_H_
-#define META_WINDOW_ACTOR_H_
-
-#include "clutter/clutter.h"
-#include "meta/compositor.h"
-#include "meta/meta-shaped-texture.h"
-
-#define META_TYPE_WINDOW_ACTOR (meta_window_actor_get_type ())
-
-META_EXPORT
-G_DECLARE_DERIVABLE_TYPE (MetaWindowActor,
- meta_window_actor,
- META, WINDOW_ACTOR,
- ClutterActor)
-
-META_EXPORT
-MetaWindow * meta_window_actor_get_meta_window (MetaWindowActor *self);
-
-META_EXPORT
-MetaShapedTexture *meta_window_actor_get_texture (MetaWindowActor *self);
-
-META_EXPORT
-void meta_window_actor_sync_visibility (MetaWindowActor *self);
-
-META_EXPORT
-gboolean meta_window_actor_is_destroyed (MetaWindowActor *self);
-
-META_EXPORT
-cairo_surface_t * meta_window_actor_get_image (MetaWindowActor *self,
- cairo_rectangle_int_t *clip);
-
-META_EXPORT
-void meta_window_actor_freeze (MetaWindowActor *self);
-
-META_EXPORT
-void meta_window_actor_thaw (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
deleted file mode 100644
index cfc487e7c..000000000
--- a/src/meta/meta-window-group.h
+++ /dev/null
@@ -1,16 +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"
-
-#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/meta/meta-window-shape.h b/src/meta/meta-window-shape.h
deleted file mode 100644
index ec9fa7da1..000000000
--- a/src/meta/meta-window-shape.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/*
- * MetaWindowShape
- *
- * Extracted invariant window shape
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __META_WINDOW_SHAPE_H__
-#define __META_WINDOW_SHAPE_H__
-
-#include <cairo.h>
-#include <glib-object.h>
-
-#include <meta/common.h>
-
-META_EXPORT
-GType meta_window_shape_get_type (void) G_GNUC_CONST;
-
-/**
- * MetaWindowShape:
- * #MetaWindowShape represents a 9-sliced region with borders on all sides that
- * are unscaled, and a constant central region that is scaled. For example,
- * the regions representing two windows that are rounded rectangles,
- * with the same corner radius but different sizes, have the
- * same MetaWindowShape.
- *
- * #MetaWindowShape is designed to be used as part of a hash table key, so has
- * efficient hash and equal functions.
- */
-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);
-
-#endif /* __META_WINDOW_SHAPE_H __*/
-
diff --git a/src/meta/meta-workspace-manager.h b/src/meta/meta-workspace-manager.h
deleted file mode 100644
index 92cd68191..000000000
--- a/src/meta/meta-workspace-manager.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- 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
deleted file mode 100644
index eb84c2b20..000000000
--- a/src/meta/meta-x11-display.h
+++ /dev/null
@@ -1,73 +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, 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/meta-x11-errors.h b/src/meta/meta-x11-errors.h
deleted file mode 100644
index ec9fa5c71..000000000
--- a/src/meta/meta-x11-errors.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_ERRORS_H
-#define META_ERRORS_H
-
-#include <X11/Xlib.h>
-
-#include <meta/util.h>
-#include <meta/meta-x11-display.h>
-
-META_EXPORT
-void meta_x11_error_trap_push (MetaX11Display *x11_display);
-
-META_EXPORT
-void meta_x11_error_trap_pop (MetaX11Display *x11_display);
-
-/* returns X error code, or 0 for no error */
-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
deleted file mode 100644
index 7a8bfab96..000000000
--- a/src/meta/prefs.h
+++ /dev/null
@@ -1,485 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_PREFS_H
-#define META_PREFS_H
-
-/* This header is a "common" one between the UI and core side */
-#include <meta/common.h>
-#include <meta/types.h>
-#include <pango/pango-font.h>
-#include <gdesktop-enums.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
-{
- META_PREF_MOUSE_BUTTON_MODS,
- META_PREF_FOCUS_MODE,
- META_PREF_FOCUS_NEW_WINDOWS,
- META_PREF_ATTACH_MODAL_DIALOGS,
- 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_AUTO_RAISE,
- META_PREF_AUTO_RAISE_DELAY,
- META_PREF_FOCUS_CHANGE_ON_POINTER_REST,
- META_PREF_TITLEBAR_FONT,
- META_PREF_NUM_WORKSPACES,
- META_PREF_DYNAMIC_WORKSPACES,
- META_PREF_KEYBINDINGS,
- META_PREF_DISABLE_WORKAROUNDS,
- META_PREF_BUTTON_LAYOUT,
- META_PREF_WORKSPACE_NAMES,
- 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_WORKSPACES_ONLY_ON_PRIMARY,
- META_PREF_DRAGGABLE_BORDER_WIDTH,
- 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 user_data);
-
-META_EXPORT
-void meta_prefs_add_listener (MetaPrefsChangedFunc func,
- gpointer user_data);
-
-META_EXPORT
-void meta_prefs_remove_listener (MetaPrefsChangedFunc func,
- gpointer user_data);
-
-META_EXPORT
-const char* meta_preference_to_string (MetaPreference pref);
-
-META_EXPORT
-MetaVirtualModifier meta_prefs_get_mouse_button_mods (void);
-
-META_EXPORT
-gint meta_prefs_get_mouse_button_resize (void);
-
-META_EXPORT
-gint meta_prefs_get_mouse_button_menu (void);
-
-META_EXPORT
-GDesktopFocusMode meta_prefs_get_focus_mode (void);
-
-META_EXPORT
-GDesktopFocusNewWindows meta_prefs_get_focus_new_windows (void);
-
-META_EXPORT
-gboolean meta_prefs_get_attach_modal_dialogs (void);
-
-META_EXPORT
-gboolean meta_prefs_get_raise_on_click (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);
-
-META_EXPORT
-gboolean meta_prefs_get_dynamic_workspaces (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);
-
-META_EXPORT
-gboolean meta_prefs_get_auto_maximize (void);
-
-META_EXPORT
-gboolean meta_prefs_get_center_new_windows (void);
-
-META_EXPORT
-gboolean meta_prefs_get_show_fallback_app_menu (void);
-
-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
-GDesktopTitlebarAction meta_prefs_get_action_double_click_titlebar (void);
-
-META_EXPORT
-GDesktopTitlebarAction meta_prefs_get_action_middle_click_titlebar (void);
-
-META_EXPORT
-GDesktopTitlebarAction meta_prefs_get_action_right_click_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);
-
-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);
-
-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
- * evolves a little.
- */
-typedef enum _MetaKeyBindingAction
-{
- META_KEYBINDING_ACTION_NONE,
- META_KEYBINDING_ACTION_WORKSPACE_1,
- META_KEYBINDING_ACTION_WORKSPACE_2,
- META_KEYBINDING_ACTION_WORKSPACE_3,
- META_KEYBINDING_ACTION_WORKSPACE_4,
- META_KEYBINDING_ACTION_WORKSPACE_5,
- META_KEYBINDING_ACTION_WORKSPACE_6,
- META_KEYBINDING_ACTION_WORKSPACE_7,
- META_KEYBINDING_ACTION_WORKSPACE_8,
- META_KEYBINDING_ACTION_WORKSPACE_9,
- META_KEYBINDING_ACTION_WORKSPACE_10,
- META_KEYBINDING_ACTION_WORKSPACE_11,
- META_KEYBINDING_ACTION_WORKSPACE_12,
- META_KEYBINDING_ACTION_WORKSPACE_LEFT,
- 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,
- META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD,
- META_KEYBINDING_ACTION_SWITCH_PANELS,
- META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD,
- META_KEYBINDING_ACTION_CYCLE_GROUP,
- META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD,
- META_KEYBINDING_ACTION_CYCLE_WINDOWS,
- META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD,
- META_KEYBINDING_ACTION_CYCLE_PANELS,
- META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD,
- 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_TOGGLE_TILED_LEFT,
- META_KEYBINDING_ACTION_TOGGLE_TILED_RIGHT,
- META_KEYBINDING_ACTION_TOGGLE_ABOVE,
- META_KEYBINDING_ACTION_MAXIMIZE,
- META_KEYBINDING_ACTION_UNMAXIMIZE,
- META_KEYBINDING_ACTION_TOGGLE_SHADED,
- META_KEYBINDING_ACTION_MINIMIZE,
- META_KEYBINDING_ACTION_CLOSE,
- META_KEYBINDING_ACTION_BEGIN_MOVE,
- META_KEYBINDING_ACTION_BEGIN_RESIZE,
- META_KEYBINDING_ACTION_TOGGLE_ON_ALL_WORKSPACES,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_1,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_2,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_3,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_4,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_5,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_6,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_7,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_8,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_9,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_10,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_11,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_12,
- META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LEFT,
- 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_LAST,
- META_KEYBINDING_ACTION_MOVE_TO_MONITOR_LEFT,
- META_KEYBINDING_ACTION_MOVE_TO_MONITOR_RIGHT,
- 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,
- META_KEYBINDING_ACTION_MAXIMIZE_VERTICALLY,
- META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY,
- META_KEYBINDING_ACTION_MOVE_TO_CORNER_NW,
- META_KEYBINDING_ACTION_MOVE_TO_CORNER_NE,
- META_KEYBINDING_ACTION_MOVE_TO_CORNER_SW,
- META_KEYBINDING_ACTION_MOVE_TO_CORNER_SE,
- META_KEYBINDING_ACTION_MOVE_TO_SIDE_N,
- META_KEYBINDING_ACTION_MOVE_TO_SIDE_S,
- META_KEYBINDING_ACTION_MOVE_TO_SIDE_E,
- META_KEYBINDING_ACTION_MOVE_TO_SIDE_W,
- META_KEYBINDING_ACTION_MOVE_TO_CENTER,
- 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_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;
-
-/**
- * MetaKeyHandlerFunc:
- * @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,
- MetaWindow *window,
- ClutterKeyEvent *event,
- MetaKeyBinding *binding,
- gpointer user_data);
-
-META_EXPORT
-GType meta_key_binding_get_type (void);
-
-META_EXPORT
-MetaKeyBindingAction meta_prefs_get_keybinding_action (const char *name);
-
-META_EXPORT
-gboolean meta_prefs_get_visual_bell (void);
-
-META_EXPORT
-gboolean meta_prefs_bell_is_audible (void);
-
-META_EXPORT
-GDesktopVisualBellType meta_prefs_get_visual_bell_type (void);
-
-META_EXPORT
-unsigned int meta_prefs_get_check_alive_timeout (void);
-
-#endif
diff --git a/src/meta/theme.h b/src/meta/theme.h
deleted file mode 100644
index 0fbd1e5af..000000000
--- a/src/meta/theme.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_THEME_H
-#define META_THEME_H
-
-#include <glib.h>
-
-/**
- * MetaTheme:
- *
- */
-typedef struct _MetaTheme MetaTheme;
-
-META_EXPORT
-MetaTheme* meta_theme_get_default (void);
-
-META_EXPORT
-MetaTheme* meta_theme_new (void);
-
-META_EXPORT
-void meta_theme_free (MetaTheme *theme);
-#endif
diff --git a/src/meta/types.h b/src/meta/types.h
deleted file mode 100644
index 403e62b16..000000000
--- a/src/meta/types.h
+++ /dev/null
@@ -1,49 +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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef META_TYPES_H
-#define META_TYPES_H
-
-/**
- * MetaCompositor: (skip)
- *
- */
-typedef struct _MetaBackend MetaBackend;
-typedef struct _MetaContext MetaContext;
-typedef struct _MetaCompositor MetaCompositor;
-typedef struct _MetaDisplay MetaDisplay;
-typedef struct _MetaX11Display MetaX11Display;
-typedef struct _MetaFrame MetaFrame;
-typedef struct _MetaWindow MetaWindow;
-typedef struct _MetaWorkspace MetaWorkspace;
-/**
- * MetaGroup: (skip)
- *
- */
-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
deleted file mode 100644
index 834e61d49..000000000
--- a/src/meta/util.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_UTIL_H
-#define META_UTIL_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-#include <meta/common.h>
-#include <meta/meta-later.h>
-
-META_EXPORT
-gboolean meta_is_verbose (void);
-
-META_EXPORT
-gboolean meta_is_syncing (void);
-
-META_EXPORT
-gboolean meta_is_wayland_compositor (void);
-
-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_NORETURN G_ANALYZER_NORETURN;
-
-/**
- * MetaDebugTopic:
- * @META_DEBUG_VERBOSE: verbose logging
- * @META_DEBUG_FOCUS: focus
- * @META_DEBUG_WORKAREA: workarea
- * @META_DEBUG_STACK: stack
- * @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_KEYBINDINGS: keybindings
- * @META_DEBUG_SYNC: sync
- * @META_DEBUG_STARTUP: startup
- * @META_DEBUG_PREFS: preferences
- * @META_DEBUG_GROUPS: groups
- * @META_DEBUG_RESIZING: resizing
- * @META_DEBUG_SHAPES: shapes
- * @META_DEBUG_EDGE_RESISTANCE: edge resistance
- * @META_DEBUG_WAYLAND: Wayland
- * @META_DEBUG_KMS: kernel mode setting
- * @META_DEBUG_SCREEN_CAST: screencasting
- * @META_DEBUG_REMOTE_DESKTOP: remote desktop
- * @META_DEBUG_BACKEND: backend
- */
-typedef enum
-{
- META_DEBUG_VERBOSE = -1,
- META_DEBUG_FOCUS = 1 << 0,
- META_DEBUG_WORKAREA = 1 << 1,
- META_DEBUG_STACK = 1 << 2,
- META_DEBUG_SM = 1 << 3,
- META_DEBUG_EVENTS = 1 << 4,
- META_DEBUG_WINDOW_STATE = 1 << 5,
- META_DEBUG_WINDOW_OPS = 1 << 6,
- META_DEBUG_GEOMETRY = 1 << 7,
- META_DEBUG_PLACEMENT = 1 << 8,
- META_DEBUG_PING = 1 << 9,
- META_DEBUG_KEYBINDINGS = 1 << 10,
- META_DEBUG_SYNC = 1 << 11,
- META_DEBUG_STARTUP = 1 << 12,
- META_DEBUG_PREFS = 1 << 13,
- META_DEBUG_GROUPS = 1 << 14,
- META_DEBUG_RESIZING = 1 << 15,
- META_DEBUG_SHAPES = 1 << 16,
- META_DEBUG_EDGE_RESISTANCE = 1 << 17,
- META_DEBUG_DBUS = 1 << 18,
- META_DEBUG_INPUT = 1 << 19,
- META_DEBUG_WAYLAND = 1 << 20,
- META_DEBUG_KMS = 1 << 21,
- META_DEBUG_SCREEN_CAST = 1 << 22,
- META_DEBUG_REMOTE_DESKTOP = 1 << 23,
- META_DEBUG_BACKEND = 1 << 24,
-} MetaDebugTopic;
-
-/**
- * MetaDebugPaintFlag:
- * @META_DEBUG_PAINT_NONE: default
- * @META_DEBUG_PAINT_OPAQUE_REGION: paint opaque regions
- */
-typedef enum
-{
- META_DEBUG_PAINT_NONE = 0,
- META_DEBUG_PAINT_OPAQUE_REGION = 1 << 0,
-} MetaDebugPaintFlag;
-
-META_EXPORT
-gboolean meta_is_topic_enabled (MetaDebugTopic topic);
-
-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);
-
-META_EXPORT
-guint meta_unsigned_long_hash (gconstpointer v);
-
-META_EXPORT
-const char* meta_frame_type_to_string (MetaFrameType type);
-META_EXPORT
-const char* meta_gravity_to_string (MetaGravity gravity);
-
-META_EXPORT
-char* meta_external_binding_name_for_action (guint keybinding_action);
-
-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);
-
-/* To disable verbose mode, we make these functions into no-ops */
-#ifdef WITH_VERBOSE_MODE
-
-#define meta_verbose(...) \
- G_STMT_START \
- { \
- if (meta_is_topic_enabled (META_DEBUG_VERBOSE)) \
- meta_verbose_real (__VA_ARGS__); \
- } \
- G_STMT_END
-
-#define meta_topic(debug_topic,...) \
- G_STMT_START \
- { \
- if (meta_is_topic_enabled (debug_topic)) \
- meta_topic_real (debug_topic, __VA_ARGS__); \
- } \
- G_STMT_END
-
-#else
-
-# ifdef G_HAVE_ISO_VARARGS
-# define meta_verbose(...)
-# define meta_topic(...)
-# elif defined(G_HAVE_GNUC_VARARGS)
-# define meta_verbose(format...)
-# define meta_topic(format...)
-# else
-# error "This compiler does not support varargs macros and thus verbose mode can't be disabled meaningfully"
-# endif
-
-#endif /* !WITH_VERBOSE_MODE */
-
-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);
-
-META_EXPORT
-void meta_add_debug_paint_flag (MetaDebugPaintFlag flag);
-
-META_EXPORT
-void meta_remove_debug_paint_flag (MetaDebugPaintFlag flag);
-
-META_EXPORT
-MetaDebugPaintFlag meta_get_debug_paint_flags (void);
-
-#endif /* META_UTIL_H */
diff --git a/src/meta/window.h b/src/meta/window.h
deleted file mode 100644
index 3157d44ee..000000000
--- a/src/meta/window.h
+++ /dev/null
@@ -1,449 +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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef META_WINDOW_H
-#define META_WINDOW_H
-
-#include <glib-object.h>
-#include <cairo.h>
-#include <X11/Xlib.h>
-
-#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,
- META_WINDOW_DESKTOP,
- META_WINDOW_DOCK,
- META_WINDOW_DIALOG,
- META_WINDOW_MODAL_DIALOG,
- META_WINDOW_TOOLBAR,
- META_WINDOW_MENU,
- META_WINDOW_UTILITY,
- META_WINDOW_SPLASHSCREEN,
-
- /* override redirect window types: */
- META_WINDOW_DROPDOWN_MENU,
- META_WINDOW_POPUP_MENU,
- META_WINDOW_TOOLTIP,
- META_WINDOW_NOTIFICATION,
- META_WINDOW_COMBO,
- META_WINDOW_DND,
- 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_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))
-#define META_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_WINDOW))
-#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);
-
-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);
-
-META_EXPORT
-Window meta_window_get_xwindow (MetaWindow *window);
-
-META_EXPORT
-MetaWindowType meta_window_get_window_type (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);
-
-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);
-
-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);
-
-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);
-
-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 *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);
-
-META_EXPORT
-gboolean meta_window_is_on_primary_monitor (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);
-
-META_EXPORT
-const char *meta_window_get_title (MetaWindow *window);
-
-META_EXPORT
-MetaWindow *meta_window_get_transient_for (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
-pid_t meta_window_get_pid (MetaWindow *window);
-
-META_EXPORT
-const char *meta_window_get_client_machine (MetaWindow *window);
-
-META_EXPORT
-gboolean meta_window_is_remote (MetaWindow *window);
-
-META_EXPORT
-gboolean meta_window_is_attached_dialog (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);
-
-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
deleted file mode 100644
index 99aebee5d..000000000
--- a/src/meta/workspace.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_H
-#define META_WORKSPACE_H
-
-#include <meta/types.h>
-#include <meta/boxes.h>
-
-#define META_TYPE_WORKSPACE (meta_workspace_get_type ())
-#define META_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WORKSPACE, MetaWorkspace))
-#define META_WORKSPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WORKSPACE, MetaWorkspaceClass))
-#define META_IS_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_WORKSPACE))
-#define META_IS_WORKSPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WORKSPACE))
-#define META_WORKSPACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WORKSPACE, MetaWorkspaceClass))
-
-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);
-
-META_EXPORT
-void meta_workspace_set_builtin_struts (MetaWorkspace *workspace,
- GSList *struts);
-
-META_EXPORT
-MetaWorkspace* meta_workspace_get_neighbor (MetaWorkspace *workspace,
- MetaMotionDirection direction);
-
-#endif
diff --git a/src/org.freedesktop.login1.xml b/src/org.freedesktop.login1.xml
deleted file mode 100644
index 765475132..000000000
--- a/src/org.freedesktop.login1.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<!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
deleted file mode 100644
index 7522652dc..000000000
--- a/src/org.gnome.Mutter.DisplayConfig.xml
+++ /dev/null
@@ -1,473 +0,0 @@
-<!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 consistently
- 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" />
-
- <!--
- PanelOrientationManaged:
-
- Whether the built-in panel orientation is automatically managed
- by mutter.
- -->
- <property name="PanelOrientationManaged" type="b" access="read" />
-
- <!--
- 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 laid 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:
-
- * "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.
- * "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>
-
- <!--
- SetOutputCTM:
- @serial: configuration serial
- @output: API id of the output
- @ctm: 3x3 matrix in fixed-point sign-magnitude S31.32
-
- Changes the color transform matrix of @output
- -->
- <method name="SetOutputCTM">
- <arg name="serial" direction="in" type="u" />
- <arg name="output" direction="in" type="u" />
- <arg name="ctm" direction="in" type="(ttttttttt)" />
- </method>
- </interface>
-</node>
diff --git a/src/org.gnome.Mutter.IdleMonitor.xml b/src/org.gnome.Mutter.IdleMonitor.xml
deleted file mode 100644
index 374af4dc4..000000000
--- a/src/org.gnome.Mutter.IdleMonitor.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<!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
deleted file mode 100644
index 7bae10e43..000000000
--- a/src/org.gnome.Mutter.RemoteDesktop.xml
+++ /dev/null
@@ -1,351 +0,0 @@
-<!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 an evdev keycode 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. Relative motion deltas are to be
- interpreted as pixel movement of a standardized mouse.
-
- Additionally to the smooth pointer axis event notification, an emulated
- discrete pointer axis event notification is emitted based on the submitted
- accumulated smooth scrolling steps.
- The base for these emulated discrete pointer axis event is the discrete step
- with the value 10.0.
- This means that for a delta dx (or dy) with the value 10.0 one emulated
- discrete scrolling event is emitted.
- For a high resolution smooth pointer axis event, a smaller value is submitted
- for each scrolling step.
- This means: For a double resolution mouse wheel one emulated discrete event
- is emitted for 2 smooth pointer axis events with each having the value 5.0.
-
- Possible @flags:
- 1: finish - scroll motion was finished (e.g. fingers lifted)
- 2: source_wheel - The scroll event is originated by a mouse wheel.
- 4: source_finger - The scroll event is originated by one or more fingers on
- the device (eg. touchpads).
- 8: source_continuous - The scroll event is originated by the motion of some
- device (eg. a scroll button is set).
-
- Maximum one of the @flags 'source_wheel', 'source_finger',
- 'source_continuous' may be specified.
- If no source flag is specified, `source_finger` is assumed.
- -->
- <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>
-
- <!--
- EnableClipboard:
- @options: Options for the clipboard
-
- Available @options include:
-
- * "mime-types" (as): List of mime types, for which the clipboard of the
- remote desktop client has content.
- Each mime-type is in string form, e.g. "image/jpeg",
- "text/plain", etc..
- If this list is included in @options, then this call
- is equivalent to calling 'EnableClipboard' and
- 'SetSelection' atomically.
-
- Enables the clipboard for the remote desktop client which will allow it
- to call the methods 'SetSelection', 'DisableClipboard', 'SelectionWrite',
- 'SelectionWriteDone', 'SelectionRead'.
- The 'SelectionOwnerChanged' signal will also be emitted when the
- selection owner changes to inform the API user of new clipboard mime
- types, and the 'SelectionTransfer' signal will be emitted to request the
- advertised clipboard content of a mime type.
- -->
- <method name="EnableClipboard">
- <arg name="options" type="a{sv}" direction="in" />
- </method>
-
- <!--
- DisableClipboard:
-
- Unregisters all clipboard types that were advertised by the
- remote desktop client.
- The 'SelectionOwnerChanged' or 'SelectionTransfer' signals will not be
- emitted any more.
- Any 'SelectionTransfer' signals that weren't answered yet with a
- 'SelectionWriteDone' call, will be answered with a 'SelectionWriteDone'
- call where 'success' is 'false'.
- -->
- <method name="DisableClipboard" />
-
- <!--
- SetSelection:
- @options: Options for the clipboard selection
-
- Available @options include:
-
- * "mime-types" (as): List of mime types, for which the clipboard of the
- remote desktop client has content.
- Each mime-type is in string form, e.g. "image/jpeg",
- "text/plain", etc..
-
- Sets the owner of the clipboard formats in 'mime-types' in @options to
- the remote desktop client, i.e. the remote desktop client has data for
- these advertised clipboard formats.
- -->
- <method name="SetSelection">
- <arg name="options" type="a{sv}" direction="in" />
- </method>
-
- <!--
- SelectionWrite:
- @serial: The serial of the request where this answer is directed to
- @fd: The file descriptor where the data will be written to
-
- Answer to 'SelectionTransfer' signal. Contains the fd where the clipboard
- content will be written to.
- -->
- <method name="SelectionWrite">
- <arg name="serial" type="u" direction="in" />
- <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
- <arg name="fd" type="h" direction="out" />
- </method>
-
- <!--
- SelectionWriteDone:
- @serial: The serial of the request where this answer is directed to
- @success: A boolean which indicates whether the transfer of the clipboard
- data was successful ('true') or not ('false').
-
- Notifies that the transfer of the clipboard data has either completed
- successfully, or failed.
- -->
- <method name="SelectionWriteDone">
- <arg name="serial" type="u" direction="in" />
- <arg name="success" type="b" direction="in" />
- </method>
-
- <!--
- SelectionRead:
- @mime_type: The mime-type string of the requested format
- @fd: The file descriptor where the data will be written to
-
- Transfer the clipboard content given the specified mime type to the
- method caller via a file descriptor.
- It is the callee that creates the file descriptor.
- -->
- <method name="SelectionRead">
- <arg name="mime_type" type="s" direction="in" />
- <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
- <arg name="fd" type="h" direction="out" />
- </method>
-
- <!--
- SelectionOwnerChanged:
- @options: Options for the clipboard selection
-
- Available @options include:
-
- * "mime-types" (as): List of mime types, for which the clipboard of the
- remote desktop client has content.
- Each mime-type is in string form, e.g. "image/jpeg",
- "text/plain", etc..
- * "session-is-owner" (b): 'true', if the remote desktop clients clipboard
- is already owner of these types, else 'false'.
-
- Informs the remote desktop client of new clipboard formats that are
- available.
- -->
- <signal name="SelectionOwnerChanged">
- <arg name="options" type="a{sv}" direction="in" />
- </signal>
-
- <!--
- SelectionTransfer:
- @mime_type: The mime-type string of the requested format
- @serial: The serial, that the answer of this particular request, MUST use
-
- Requests the data for a clipboard format from the remote desktop client.
- MUST NOT be called when the remote desktop clients clipboard is (already)
- disabled.
- -->
- <signal name="SelectionTransfer">
- <arg name="mime_type" type="s" direction="in" />
- <arg name="serial" type="u" direction="in" />
- </signal>
-
- <property name="CapsLockState" type="b" access="read" />
- <property name="NumLockState" type="b" access="read" />
-
- </interface>
-
-</node>
diff --git a/src/org.gnome.Mutter.ScreenCast.xml b/src/org.gnome.Mutter.ScreenCast.xml
deleted file mode 100644
index d9f1f4435..000000000
--- a/src/org.gnome.Mutter.ScreenCast.xml
+++ /dev/null
@@ -1,220 +0,0 @@
-<!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.
- * "is-recording" (b): Whether this is a screen recording. May be
- be used for choosing appropriate visual feedback.
- Default: false. Available since API version 4.
-
- 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).
- * "is-recording" (b): Whether this is a screen recording. May be
- be used for choosing panel icon.
- Default: false. Available since API version 4.
-
- -->
- <method name="RecordWindow">
- <arg name="properties" type="a{sv}" direction="in" />
- <arg name="stream_path" type="o" direction="out" />
- </method>
-
- <!--
- RecordArea:
- @x: X position of the recorded area
- @y: Y position of the recorded area
- @width: width of the recorded area
- @height: height of the recorded area
- @properties: Properties
- @stream_path: Path to the new stream object
-
- Record an area of the stage. The coordinates are in stage coordinates.
- The size of the stream does not necessarily match the size of the
- recorded area, and will depend on DPI scale of the affected monitors.
-
- Available @properties include:
-
- * "cursor-mode" (u): Cursor mode. Default: 'hidden' (see below)
- Available since API version 2.
- * "is-recording" (b): Whether this is a screen recording. May be
- be used for choosing panel icon.
- Default: false. Available since API version 4.
-
- 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="RecordArea">
- <arg name="x" type="i" direction="in" />
- <arg name="y" type="i" direction="in" />
- <arg name="width" type="i" direction="in" />
- <arg name="height" type="i" direction="in" />
- <arg name="properties" type="a{sv}" direction="in" />
- <arg name="stream_path" type="o" direction="out" />
- </method>
-
- <!--
- RecordVirtual:
- @properties: Properties
- @stream_path: Path to the new stream object
-
- Record a virtual area that will be represented as a virtual monitor. The
- width and height corresponds to the non-scaled intended stream size.
-
- Available @properties include:
-
- * "cursor-mode" (u): Cursor mode. Default: 'hidden' (see below)
- Available since API version 2.
- * "is-platform" (b): Whether this virtual output should be considered
- part of the platform, meaning it will not be
- interpreted as if the screen is shared, but more
- transparently as if it was a real monitor.
- Available since API version 3. Default: FALSE.
-
- 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="RecordVirtual">
- <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/tests/README b/src/tests/README
deleted file mode 100644
index 9c620c328..000000000
--- a/src/tests/README
+++ /dev/null
@@ -1,93 +0,0 @@
-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/tests/anonymous-file.c b/src/tests/anonymous-file.c
deleted file mode 100644
index 29f5ceac8..000000000
--- a/src/tests/anonymous-file.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Copyright (C) 2020 Jonas Dreßler.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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/resource.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <core/meta-anonymous-file.h>
-
-#if defined(HAVE_MEMFD_CREATE)
-#define READONLY_SEALS (F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE)
-#endif
-
-static const char *teststring = "test string 1234567890";
-
-static gboolean
-test_read_fd_mmap (int fd,
- const char *expected_string)
-{
- void *mem;
- int string_size;
-
- string_size = strlen (expected_string) + 1;
-
- mem = mmap (NULL, string_size, PROT_READ, MAP_PRIVATE, fd, 0);
- g_assert (mem != MAP_FAILED);
-
- if (strcmp (expected_string, mem) != 0)
- {
- munmap (mem, string_size);
- return FALSE;
- }
-
- munmap (mem, string_size);
- return TRUE;
-}
-
-static gboolean
-test_write_fd (int fd,
- const char *string)
-{
- int written_size, string_size;
-
- string_size = strlen (string) + 1;
- written_size = write (fd, string, string_size);
- if (written_size != string_size)
- return FALSE;
-
- return TRUE;
-}
-
-#if defined(HAVE_MEMFD_CREATE)
-static gboolean
-test_readonly_seals (int fd)
-{
- unsigned int seals;
-
- seals = fcntl (fd, F_GET_SEALS);
- if (seals == -1)
- return FALSE;
-
- if (seals != READONLY_SEALS)
- return FALSE;
-
- return TRUE;
-}
-#endif
-
-static gboolean
-test_write_read (int fd)
-{
- g_autofree char *new_string = g_uuid_string_random ();
-
- if (!test_write_fd (fd, new_string))
- return FALSE;
-
- if (!test_read_fd_mmap (fd, new_string))
- return FALSE;
-
- return TRUE;
-}
-
-#if defined(HAVE_MEMFD_CREATE)
-static gboolean
-test_open_write_read (const char *path)
-{
- int fd;
-
- fd = open (path, O_RDWR);
- g_assert (fd != -1);
-
- if (!test_write_read (fd))
- {
- close (fd);
- return FALSE;
- }
-
- close (fd);
- return TRUE;
-}
-#endif
-
-int
-main (int argc,
- char **argv)
-{
- MetaAnonymousFile *file;
- int fd = -1, other_fd = -1;
- g_autofree char *fd_path = NULL;
-
- file = meta_anonymous_file_new (strlen (teststring) + 1,
- (const uint8_t *) teststring);
- if (!file)
- {
- g_critical ("%s: Creating file failed", __func__);
- return EXIT_FAILURE;
- }
-
-#if defined(HAVE_MEMFD_CREATE)
- fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_PRIVATE);
- g_assert (fd != -1);
- other_fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_PRIVATE);
- g_assert (other_fd != -1);
-
- /* When MAPMODE_PRIVATE was used, meta_anonymous_file_open_fd() should always
- * return the same fd. */
- if (other_fd != fd)
- goto fail;
-
- /* If memfd_create was used and we request a MAPMODE_PRIVATE file, all the
- * readonly seals should be set. */
- if (!test_readonly_seals (fd))
- goto fail;
-
- if (!test_read_fd_mmap (fd, teststring))
- goto fail;
-
- /* Writing and reading the written data should fail */
- if (test_write_read (fd))
- goto fail;
-
- /* Instead we should still be reading the teststring */
- if (!test_read_fd_mmap (fd, teststring))
- goto fail;
-
- /* Opening the fd manually in RW mode and writing to it should fail */
- fd_path = g_strdup_printf ("/proc/%d/fd/%d", getpid (), fd);
- if (test_open_write_read (fd_path))
- goto fail;
-
- /* Instead we should still be reading the teststring */
- if (!test_read_fd_mmap (fd, teststring))
- goto fail;
-
- /* Just to be sure test the other fd, too */
- if (!test_read_fd_mmap (other_fd, teststring))
- goto fail;
-
- meta_anonymous_file_close_fd (fd);
- meta_anonymous_file_close_fd (fd);
-
-
- fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_SHARED);
- g_assert (fd != -1);
- other_fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_SHARED);
- g_assert (other_fd != -1);
-
- /* The MAPMODE_SHARED fd should not have readonly seals applied */
- if (test_readonly_seals (fd))
- goto fail;
-
- if (!test_read_fd_mmap (fd, teststring))
- goto fail;
-
- if (!test_read_fd_mmap (other_fd, teststring))
- goto fail;
-
- /* Writing and reading the written data should succeed */
- if (!test_write_read (fd))
- goto fail;
-
- /* The other fd should still read the teststring though */
- if (!test_read_fd_mmap (other_fd, teststring))
- goto fail;
-
- meta_anonymous_file_close_fd (fd);
- meta_anonymous_file_close_fd (other_fd);
-
-
- /* Test an artificial out-of-space situation by setting the maximum file
- * size this process may create to 2 bytes, if memfd_create with
- * MAPMODE_PRIVATE is used, everything should still work (the existing FD
- * should be used). */
-
- if (!getenv ("CI_JOB_ID"))
- {
- struct rlimit rlimit = {
- .rlim_cur = 2,
- .rlim_max = 2,
- };
-
- if (setrlimit (RLIMIT_FSIZE, &rlimit) == -1)
- goto fail;
-
- fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_PRIVATE);
- g_assert (fd != -1);
-
- if (!test_read_fd_mmap (fd, teststring))
- goto fail;
-
- meta_anonymous_file_close_fd (fd);
- }
-#else
- fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_PRIVATE);
- g_assert (fd != -1);
- other_fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_PRIVATE);
- g_assert (other_fd != -1);
-
- /* Writing and reading the written data should succeed */
- if (!test_write_read (fd))
- goto fail;
-
- /* The other fd should still read the teststring though */
- if (!test_read_fd_mmap (other_fd, teststring))
- goto fail;
-
- meta_anonymous_file_close_fd (fd);
- meta_anonymous_file_close_fd (other_fd);
-
-
- fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_SHARED);
- g_assert (fd != -1);
- other_fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_SHARED);
- g_assert (other_fd != -1);
-
- if (!test_read_fd_mmap (fd, teststring))
- goto fail;
-
- if (!test_read_fd_mmap (other_fd, teststring))
- goto fail;
-
- /* Writing and reading the written data should succeed */
- if (!test_write_read (fd))
- goto fail;
-
- /* The other fd should still read the teststring though */
- if (!test_read_fd_mmap (other_fd, teststring))
- goto fail;
-
- meta_anonymous_file_close_fd (fd);
- meta_anonymous_file_close_fd (other_fd);
-#endif
-
- meta_anonymous_file_free (file);
- return EXIT_SUCCESS;
-
- fail:
- if (fd > 0)
- meta_anonymous_file_close_fd (fd);
- if (other_fd > 0)
- meta_anonymous_file_close_fd (other_fd);
- meta_anonymous_file_free (file);
- return EXIT_FAILURE;
-}
diff --git a/src/tests/boxes-tests.c b/src/tests/boxes-tests.c
deleted file mode 100644
index 0c27ea77e..000000000
--- a/src/tests/boxes-tests.c
+++ /dev/null
@@ -1,1389 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Mutter box operation testing program */
-
-/*
- * 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/>.
- */
-
-#include "config.h"
-
-#include "tests/boxes-tests.h"
-
-#include <glib.h>
-#include <stdlib.h>
-#include <stdio.h>
-#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 (void)
-{
- srand (time (NULL));
-}
-
-static void
-get_random_rect (MetaRectangle *rect)
-{
- rect->x = rand () % 1600;
- rect->y = rand () % 1200;
- rect->width = rand () % 1600 + 1;
- rect->height = rand () % 1200 + 1;
-}
-
-static MetaRectangle*
-new_meta_rect (int x, int y, int width, int height)
-{
- MetaRectangle* temporary;
- temporary = g_new (MetaRectangle, 1);
- temporary->x = x;
- temporary->y = y;
- temporary->width = width;
- temporary->height = height;
-
- return temporary;
-}
-
-static MetaStrut*
-new_meta_strut (int x, int y, int width, int height, int side)
-{
- MetaStrut* temporary;
- temporary = g_new (MetaStrut, 1);
- temporary->rect = meta_rect(x, y, width, height);
- temporary->side = side;
-
- return temporary;
-}
-
-static MetaEdge*
-new_screen_edge (int x, int y, int width, int height, int side_type)
-{
- MetaEdge* temporary;
- temporary = g_new (MetaEdge, 1);
- temporary->rect.x = x;
- temporary->rect.y = y;
- temporary->rect.width = width;
- temporary->rect.height = height;
- temporary->side_type = side_type;
- temporary->edge_type = META_EDGE_SCREEN;
-
- return temporary;
-}
-
-static MetaEdge*
-new_monitor_edge (int x, int y, int width, int height, int side_type)
-{
- MetaEdge* temporary;
- temporary = g_new (MetaEdge, 1);
- temporary->rect.x = x;
- temporary->rect.y = y;
- temporary->rect.width = width;
- temporary->rect.height = height;
- temporary->side_type = side_type;
- temporary->edge_type = META_EDGE_MONITOR;
-
- return temporary;
-}
-
-static void
-test_area (void)
-{
- MetaRectangle temp;
- int i;
- for (i = 0; i < NUM_RANDOM_RUNS; i++)
- {
- get_random_rect (&temp);
- g_assert (meta_rectangle_area (&temp) == temp.width * temp.height);
- }
-
- temp = meta_rect (0, 0, 5, 7);
- g_assert (meta_rectangle_area (&temp) == 35);
-}
-
-static void
-test_intersect (void)
-{
- MetaRectangle a = {100, 200, 50, 40};
- MetaRectangle b = { 0, 50, 110, 152};
- MetaRectangle c = { 0, 0, 10, 10};
- MetaRectangle d = {100, 100, 50, 50};
- MetaRectangle b_intersect_d = {100, 100, 10, 50};
- MetaRectangle temp;
- MetaRectangle temp2;
-
- meta_rectangle_intersect (&a, &b, &temp);
- temp2 = meta_rect (100, 200, 10, 2);
- g_assert (meta_rectangle_equal (&temp, &temp2));
- g_assert (meta_rectangle_area (&temp) == 20);
-
- meta_rectangle_intersect (&a, &c, &temp);
- g_assert (meta_rectangle_area (&temp) == 0);
-
- meta_rectangle_intersect (&a, &d, &temp);
- g_assert (meta_rectangle_area (&temp) == 0);
-
- meta_rectangle_intersect (&b, &d, &b);
- g_assert (meta_rectangle_equal (&b, &b_intersect_d));
-}
-
-static void
-test_equal (void)
-{
- MetaRectangle a = {10, 12, 4, 18};
- MetaRectangle b = a;
- MetaRectangle c = {10, 12, 4, 19};
- MetaRectangle d = {10, 12, 7, 18};
- MetaRectangle e = {10, 62, 4, 18};
- MetaRectangle f = {27, 12, 4, 18};
-
- g_assert ( meta_rectangle_equal (&a, &b));
- g_assert (!meta_rectangle_equal (&a, &c));
- g_assert (!meta_rectangle_equal (&a, &d));
- g_assert (!meta_rectangle_equal (&a, &e));
- g_assert (!meta_rectangle_equal (&a, &f));
-}
-
-static void
-test_overlap_funcs (void)
-{
- MetaRectangle temp1, temp2;
- int i;
- for (i = 0; i < NUM_RANDOM_RUNS; i++)
- {
- get_random_rect (&temp1);
- get_random_rect (&temp2);
- g_assert (meta_rectangle_overlap (&temp1, &temp2) ==
- (meta_rectangle_horiz_overlap (&temp1, &temp2) &&
- meta_rectangle_vert_overlap (&temp1, &temp2)));
- }
-
- temp1 = meta_rect ( 0, 0, 10, 10);
- temp2 = meta_rect (20, 0, 10, 5);
- g_assert (!meta_rectangle_overlap (&temp1, &temp2));
- g_assert (!meta_rectangle_horiz_overlap (&temp1, &temp2));
- g_assert ( meta_rectangle_vert_overlap (&temp1, &temp2));
-}
-
-static void
-test_basic_fitting (void)
-{
- MetaRectangle temp1, temp2, temp3;
- int i;
- /* Four cases:
- * case temp1 fits temp2 temp1 could fit temp2
- * 1 Y Y
- * 2 N Y
- * 3 Y N
- * 4 N N
- * Of the four cases, case 3 is impossible. An alternate way of looking
- * at this table is that either the middle column must be no, or the last
- * column must be yes. So we test that. Also, we can repeat the test
- * reversing temp1 and temp2.
- */
- for (i = 0; i < NUM_RANDOM_RUNS; i++)
- {
- get_random_rect (&temp1);
- get_random_rect (&temp2);
- g_assert (meta_rectangle_contains_rect (&temp1, &temp2) == FALSE ||
- meta_rectangle_could_fit_rect (&temp1, &temp2) == TRUE);
- g_assert (meta_rectangle_contains_rect (&temp2, &temp1) == FALSE ||
- meta_rectangle_could_fit_rect (&temp2, &temp1) == TRUE);
- }
-
- temp1 = meta_rect ( 0, 0, 10, 10);
- temp2 = meta_rect ( 5, 5, 5, 5);
- temp3 = meta_rect ( 8, 2, 3, 7);
- g_assert ( meta_rectangle_contains_rect (&temp1, &temp2));
- g_assert (!meta_rectangle_contains_rect (&temp2, &temp1));
- 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));
-}
-
-static void
-free_strut_list (GSList *struts)
-{
- g_slist_free_full (struts, g_free);
-}
-
-static GSList*
-get_strut_list (int which)
-{
- GSList *ans;
- MetaSide wc = 0; /* wc == who cares? ;-) */
-
- ans = NULL;
-
- g_assert (which >=0 && which <= 6);
- switch (which)
- {
- case 0:
- break;
- case 1:
- ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, META_SIDE_TOP));
- ans = g_slist_prepend (ans, new_meta_strut ( 400, 1160, 1600, 40, META_SIDE_BOTTOM));
- break;
- case 2:
- ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, META_SIDE_TOP));
- ans = g_slist_prepend (ans, new_meta_strut ( 800, 1100, 400, 100, META_SIDE_BOTTOM));
- ans = g_slist_prepend (ans, new_meta_strut ( 300, 1150, 150, 50, META_SIDE_BOTTOM));
- break;
- case 3:
- ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, META_SIDE_TOP));
- ans = g_slist_prepend (ans, new_meta_strut ( 800, 1100, 400, 100, META_SIDE_LEFT));
- ans = g_slist_prepend (ans, new_meta_strut ( 300, 1150, 80, 50, META_SIDE_BOTTOM));
- ans = g_slist_prepend (ans, new_meta_strut ( 700, 525, 200, 150, wc));
- break;
- case 4:
- ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 800, 1200, META_SIDE_LEFT));
- ans = g_slist_prepend (ans, new_meta_strut ( 800, 0, 1600, 20, META_SIDE_TOP));
- break;
- case 5:
- ans = g_slist_prepend (ans, new_meta_strut ( 800, 0, 1600, 20, META_SIDE_TOP));
- ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 800, 1200, META_SIDE_LEFT));
- ans = g_slist_prepend (ans, new_meta_strut ( 800, 10, 800, 1200, META_SIDE_RIGHT));
- break;
- case 6:
- ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 40, META_SIDE_TOP));
- ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, META_SIDE_TOP));
- break;
- }
-
- return ans;
-}
-
-static GList*
-get_screen_region (int which)
-{
- GList *ret;
- GSList *struts;
- MetaRectangle basic_rect;
-
- basic_rect = meta_rect (0, 0, 1600, 1200);
- ret = NULL;
-
- struts = get_strut_list (which);
- ret = meta_rectangle_get_minimal_spanning_set_for_region (&basic_rect, struts);
- free_strut_list (struts);
-
- return ret;
-}
-
-static GList*
-get_screen_edges (int which)
-{
- GList *ret;
- GSList *struts;
- MetaRectangle basic_rect;
-
- basic_rect = meta_rect (0, 0, 1600, 1200);
- ret = NULL;
-
- struts = get_strut_list (which);
- ret = meta_rectangle_find_onscreen_edges (&basic_rect, struts);
- free_strut_list (struts);
-
- return ret;
-}
-
-static GList*
-get_monitor_edges (int which_monitor_set, int which_strut_set)
-{
- GList *ret;
- GSList *struts;
- GList *xins;
-
- xins = NULL;
- g_assert (which_monitor_set >=0 && which_monitor_set <= 3);
- switch (which_monitor_set)
- {
- case 0:
- xins = g_list_prepend (xins, new_meta_rect ( 0, 0, 1600, 1200));
- break;
- case 1:
- xins = g_list_prepend (xins, new_meta_rect ( 0, 0, 800, 1200));
- xins = g_list_prepend (xins, new_meta_rect (800, 0, 800, 1200));
- break;
- case 2:
- xins = g_list_prepend (xins, new_meta_rect ( 0, 0, 1600, 600));
- xins = g_list_prepend (xins, new_meta_rect ( 0, 600, 1600, 600));
- break;
- case 3:
- xins = g_list_prepend (xins, new_meta_rect ( 0, 0, 1600, 600));
- xins = g_list_prepend (xins, new_meta_rect ( 0, 600, 800, 600));
- xins = g_list_prepend (xins, new_meta_rect (800, 600, 800, 600));
- break;
- }
-
- ret = NULL;
-
- struts = get_strut_list (which_strut_set);
- ret = meta_rectangle_find_nonintersected_monitor_edges (xins, struts);
-
- free_strut_list (struts);
- meta_rectangle_free_list_and_elements (xins);
-
- return ret;
-}
-
-#if 0
-static void
-test_merge_regions (void)
-{
- /* logarithmically distributed random number of struts (range?)
- * logarithmically distributed random size of struts (up to screen size???)
- * uniformly distributed location of center of struts (within screen)
- * merge all regions that are possible
- * print stats on problem setup
- * number of (non-completely-occluded?) struts
- * percentage of screen covered
- * length of resulting non-minimal spanning set
- * length of resulting minimal spanning set
- * print stats on merged regions:
- * number boxes merged
- * number of those merges that were of the form A contains B
- * number of those merges that were of the form A partially contains B
- * number of those merges that were of the form A is adjacent to B
- */
-
- GList* region;
- GList* compare;
- int num_contains, num_merged, num_part_contains, num_adjacent;
-
- num_contains = num_merged = num_part_contains = num_adjacent = 0;
- compare = region = get_screen_region (2);
- g_assert (region);
-
- printf ("Merging stats:\n");
- printf (" Length of initial list: %d\n", g_list_length (region));
-#ifdef PRINT_DEBUG
- char rect1[RECT_LENGTH], rect2[RECT_LENGTH];
- char region_list[(RECT_LENGTH + 2) * g_list_length (region)];
- meta_rectangle_region_to_string (region, ", ", region_list);
- printf (" Initial rectangles: %s\n", region_list);
-#endif
-
- while (compare && compare->next)
- {
- MetaRectangle *a = compare->data;
- GList *other = compare->next;
-
- g_assert (a->width > 0 && a->height > 0);
-
- while (other)
- {
- MetaRectangle *b = other->data;
- GList *delete_me = NULL;
-
- g_assert (b->width > 0 && b->height > 0);
-
-#ifdef PRINT_DEBUG
- printf (" -- Comparing %s to %s --\n",
- meta_rectangle_to_string (a, rect1),
- meta_rectangle_to_string (b, rect2));
-#endif
-
- /* If a contains b, just remove b */
- if (meta_rectangle_contains_rect (a, b))
- {
- delete_me = other;
- num_contains++;
- num_merged++;
- }
- /* If b contains a, just remove a */
- else if (meta_rectangle_contains_rect (a, b))
- {
- delete_me = compare;
- num_contains++;
- num_merged++;
- }
- /* If a and b might be mergeable horizontally */
- else if (a->y == b->y && a->height == b->height)
- {
- /* If a and b overlap */
- if (meta_rectangle_overlap (a, b))
- {
- int new_x = MIN (a->x, b->x);
- a->width = MAX (a->x + a->width, b->x + b->width) - new_x;
- a->x = new_x;
- delete_me = other;
- num_part_contains++;
- num_merged++;
- }
- /* If a and b are adjacent */
- else if (a->x + a->width == b->x || a->x == b->x + b->width)
- {
- int new_x = MIN (a->x, b->x);
- a->width = MAX (a->x + a->width, b->x + b->width) - new_x;
- a->x = new_x;
- delete_me = other;
- num_adjacent++;
- num_merged++;
- }
- }
- /* If a and b might be mergeable vertically */
- else if (a->x == b->x && a->width == b->width)
- {
- /* If a and b overlap */
- if (meta_rectangle_overlap (a, b))
- {
- int new_y = MIN (a->y, b->y);
- a->height = MAX (a->y + a->height, b->y + b->height) - new_y;
- a->y = new_y;
- delete_me = other;
- num_part_contains++;
- num_merged++;
- }
- /* If a and b are adjacent */
- else if (a->y + a->height == b->y || a->y == b->y + b->height)
- {
- int new_y = MIN (a->y, b->y);
- a->height = MAX (a->y + a->height, b->y + b->height) - new_y;
- a->y = new_y;
- delete_me = other;
- num_adjacent++;
- num_merged++;
- }
- }
-
- other = other->next;
-
- /* Delete any rectangle in the list that is no longer wanted */
- if (delete_me != NULL)
- {
-#ifdef PRINT_DEBUG
- MetaRectangle *bla = delete_me->data;
- printf (" Deleting rect %s\n",
- meta_rectangle_to_string (bla, rect1));
-#endif
-
- /* Deleting the rect we're compare others to is a little tricker */
- if (compare == delete_me)
- {
- compare = compare->next;
- other = compare->next;
- a = compare->data;
- }
-
- /* Okay, we can free it now */
- g_free (delete_me->data);
- region = g_list_delete_link (region, delete_me);
- }
-
-#ifdef PRINT_DEBUG
- char region_list[(RECT_LENGTH + 2) * g_list_length (region)];
- meta_rectangle_region_to_string (region, ", ", region_list);
- printf (" After comparison, new list is: %s\n", region_list);
-#endif
- }
-
- compare = compare->next;
- }
-
- printf (" Num rectangles contained in others : %d\n",
- num_contains);
- printf (" Num rectangles partially contained in others: %d\n",
- num_part_contains);
- printf (" Num rectangles adjacent to others : %d\n",
- num_adjacent);
- printf (" Num rectangles merged with others : %d\n",
- num_merged);
-#ifdef PRINT_DEBUG
- char region_list2[(RECT_LENGTH + 2) * g_list_length (region)];
- meta_rectangle_region_to_string (region, ", ", region_list2);
- printf (" Final rectangles: %s\n", region_list2);
-#endif
-
- meta_rectangle_free_spanning_set (region);
- region = NULL;
-
- printf ("%s passed.\n", G_STRFUNC);
-}
-#endif
-
-static void
-verify_lists_are_equal (GList *code, GList *answer)
-{
- int which = 0;
-
- while (code && answer)
- {
- MetaRectangle *a = code->data;
- MetaRectangle *b = answer->data;
-
- if (a->x != b->x ||
- a->y != b->y ||
- a->width != b->width ||
- a->height != b->height)
- {
- g_error ("%dth item in code answer answer lists do not match; "
- "code rect: %d,%d + %d,%d; answer rect: %d,%d + %d,%d\n",
- which,
- a->x, a->y, a->width, a->height,
- b->x, b->y, b->width, b->height);
- }
-
- code = code->next;
- answer = answer->next;
-
- which++;
- }
-
- /* Ought to be at the end of both lists; check if we aren't */
- if (code)
- {
- MetaRectangle *tmp = code->data;
- g_error ("code list longer than answer list by %d items; "
- "first extra item: %d,%d +%d,%d\n",
- g_list_length (code),
- tmp->x, tmp->y, tmp->width, tmp->height);
- }
-
- if (answer)
- {
- MetaRectangle *tmp = answer->data;
- g_error ("answer list longer than code list by %d items; "
- "first extra item: %d,%d +%d,%d\n",
- g_list_length (answer),
- tmp->x, tmp->y, tmp->width, tmp->height);
- }
-}
-
-static void
-test_regions_okay (void)
-{
- GList* region;
- GList* tmp;
-
- /*************************************************************/
- /* Make sure test region 0 has the right spanning rectangles */
- /*************************************************************/
- region = get_screen_region (0);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_meta_rect (0, 0, 1600, 1200));
- verify_lists_are_equal (region, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (region);
-
- /*************************************************************/
- /* Make sure test region 1 has the right spanning rectangles */
- /*************************************************************/
- region = get_screen_region (1);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_meta_rect (0, 20, 400, 1180));
- tmp = g_list_prepend (tmp, new_meta_rect (0, 20, 1600, 1140));
- verify_lists_are_equal (region, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (region);
-
- /*************************************************************/
- /* Make sure test region 2 has the right spanning rectangles */
- /*************************************************************/
- region = get_screen_region (2);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 300, 1180));
- tmp = g_list_prepend (tmp, new_meta_rect ( 450, 20, 350, 1180));
- tmp = g_list_prepend (tmp, new_meta_rect (1200, 20, 400, 1180));
- tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 800, 1130));
- tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 1600, 1080));
- verify_lists_are_equal (region, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (region);
-
- /*************************************************************/
- /* Make sure test region 3 has the right spanning rectangles */
- /*************************************************************/
- region = get_screen_region (3);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 300, 1180)); /* 354000 */
- tmp = g_list_prepend (tmp, new_meta_rect ( 380, 20, 1220, 1180)); /* 377600 */
- tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 1600, 1130)); /* 791000 */
-#if 0
- printf ("Got to here...\n");
- char region_list[(RECT_LENGTH+2) * g_list_length (region)];
- char tmp_list[ (RECT_LENGTH+2) * g_list_length (tmp)];
- meta_rectangle_region_to_string (region, ", ", region_list);
- meta_rectangle_region_to_string (region, ", ", tmp_list);
- printf ("%s vs. %s\n", region_list, tmp_list);
-#endif
- verify_lists_are_equal (region, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (region);
-
- /*************************************************************/
- /* Make sure test region 4 has the right spanning rectangles */
- /*************************************************************/
- region = get_screen_region (4);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_meta_rect ( 800, 20, 800, 1180));
- verify_lists_are_equal (region, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (region);
-
- /*************************************************************/
- /* Make sure test region 5 has the right spanning rectangles */
- /*************************************************************/
- 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
- */
-}
-
-static void
-test_region_fitting (void)
-{
- GList* region;
- MetaRectangle rect;
-
- /* See test_basic_fitting() for how/why these automated random tests work */
- int i;
- region = get_screen_region (3);
- for (i = 0; i < NUM_RANDOM_RUNS; i++)
- {
- get_random_rect (&rect);
- g_assert (meta_rectangle_contained_in_region (region, &rect) == FALSE ||
- meta_rectangle_could_fit_in_region (region, &rect) == TRUE);
- }
- meta_rectangle_free_list_and_elements (region);
-
- /* Do some manual tests too */
- region = get_screen_region (1);
-
- rect = meta_rect (50, 50, 400, 400);
- g_assert (meta_rectangle_could_fit_in_region (region, &rect));
- g_assert (meta_rectangle_contained_in_region (region, &rect));
-
- rect = meta_rect (250, 0, 500, 1150);
- g_assert (!meta_rectangle_could_fit_in_region (region, &rect));
- g_assert (!meta_rectangle_contained_in_region (region, &rect));
-
- rect = meta_rect (250, 0, 400, 400);
- g_assert (meta_rectangle_could_fit_in_region (region, &rect));
- g_assert (!meta_rectangle_contained_in_region (region, &rect));
-
- meta_rectangle_free_list_and_elements (region);
-
- region = get_screen_region (2);
- rect = meta_rect (1000, 50, 600, 1100);
- g_assert (meta_rectangle_could_fit_in_region (region, &rect));
- g_assert (!meta_rectangle_contained_in_region (region, &rect));
-
- meta_rectangle_free_list_and_elements (region);
-}
-
-static void
-test_clamping_to_region (void)
-{
- GList* region;
- MetaRectangle rect;
- MetaRectangle min_size;
- FixedDirections fixed_directions;
- int i;
-
- min_size.height = min_size.width = 1;
- fixed_directions = 0;
-
- region = get_screen_region (3);
- for (i = 0; i < NUM_RANDOM_RUNS; i++)
- {
- MetaRectangle temp;
- get_random_rect (&rect);
- temp = rect;
- meta_rectangle_clamp_to_fit_into_region (region,
- fixed_directions,
- &rect,
- &min_size);
- g_assert (meta_rectangle_could_fit_in_region (region, &rect) == TRUE);
- g_assert (rect.x == temp.x && rect.y == temp.y);
- }
- meta_rectangle_free_list_and_elements (region);
-
- /* Do some manual tests too */
- region = get_screen_region (1);
-
- rect = meta_rect (50, 50, 10000, 10000);
- meta_rectangle_clamp_to_fit_into_region (region,
- fixed_directions,
- &rect,
- &min_size);
- g_assert (rect.width == 1600 && rect.height == 1140);
-
- rect = meta_rect (275, -50, 410, 10000);
- meta_rectangle_clamp_to_fit_into_region (region,
- fixed_directions,
- &rect,
- &min_size);
- g_assert (rect.width == 400 && rect.height == 1180);
-
- rect = meta_rect (50, 50, 10000, 10000);
- min_size.height = 1170;
- meta_rectangle_clamp_to_fit_into_region (region,
- fixed_directions,
- &rect,
- &min_size);
- g_assert (rect.width == 400 && rect.height == 1180);
-
- 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);
- min_size.width = 1; min_size.height = 1;
- fixed_directions = FIXED_DIRECTION_X;
- meta_rectangle_clamp_to_fit_into_region (region,
- fixed_directions,
- &rect,
- &min_size);
- g_assert (rect.width == 100 && rect.height == 1100);
-
- rect = meta_rect (300, 70, 500, 1100);
- min_size.width = 1; min_size.height = 1;
- fixed_directions = FIXED_DIRECTION_Y;
- meta_rectangle_clamp_to_fit_into_region (region,
- fixed_directions,
- &rect,
- &min_size);
- g_assert (rect.width == 400 && rect.height == 1100);
-
- 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);
-}
-
-static gboolean
-rect_overlaps_region (const GList *spanning_rects,
- const MetaRectangle *rect)
-{
- /* FIXME: Should I move this to boxes.[ch]? */
- const GList *temp;
- gboolean overlaps;
-
- temp = spanning_rects;
- overlaps = FALSE;
- while (!overlaps && temp != NULL)
- {
- overlaps = overlaps || meta_rectangle_overlap (temp->data, rect);
- temp = temp->next;
- }
-
- return overlaps;
-}
-
-gboolean time_to_print = FALSE;
-
-static void
-test_clipping_to_region (void)
-{
- GList* region;
- MetaRectangle rect, temp;
- FixedDirections fixed_directions = 0;
- int i;
-
- region = get_screen_region (3);
- for (i = 0; i < NUM_RANDOM_RUNS; i++)
- {
- get_random_rect (&rect);
- if (rect_overlaps_region (region, &rect))
- {
- meta_rectangle_clip_to_region (region, 0, &rect);
- g_assert (meta_rectangle_contained_in_region (region, &rect) == TRUE);
- }
- }
- meta_rectangle_free_list_and_elements (region);
-
- /* Do some manual tests too */
- region = get_screen_region (2);
-
- rect = meta_rect (-50, -10, 10000, 10000);
- meta_rectangle_clip_to_region (region,
- fixed_directions,
- &rect);
- g_assert (meta_rectangle_equal (region->data, &rect));
-
- rect = meta_rect (300, 1000, 400, 200);
- temp = meta_rect (300, 1000, 400, 150);
- meta_rectangle_clip_to_region (region,
- fixed_directions,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (400, 1000, 300, 200);
- temp = meta_rect (450, 1000, 250, 200);
- meta_rectangle_clip_to_region (region,
- fixed_directions,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (400, 1000, 300, 200);
- temp = meta_rect (400, 1000, 300, 150);
- meta_rectangle_clip_to_region (region,
- FIXED_DIRECTION_X,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (400, 1000, 300, 200);
- temp = meta_rect (400, 1000, 300, 150);
- meta_rectangle_clip_to_region (region,
- FIXED_DIRECTION_X,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- meta_rectangle_free_list_and_elements (region);
-}
-
-static void
-test_shoving_into_region (void)
-{
- GList* region;
- MetaRectangle rect, temp;
- FixedDirections fixed_directions = 0;
- int i;
-
- region = get_screen_region (3);
- for (i = 0; i < NUM_RANDOM_RUNS; i++)
- {
- get_random_rect (&rect);
- if (meta_rectangle_could_fit_in_region (region, &rect))
- {
- meta_rectangle_shove_into_region (region, 0, &rect);
- g_assert (meta_rectangle_contained_in_region (region, &rect));
- }
- }
- meta_rectangle_free_list_and_elements (region);
-
- /* Do some manual tests too */
- region = get_screen_region (2);
-
- rect = meta_rect (300, 1000, 400, 200);
- temp = meta_rect (300, 950, 400, 200);
- meta_rectangle_shove_into_region (region,
- fixed_directions,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (425, 1000, 300, 200);
- temp = meta_rect (450, 1000, 300, 200);
- meta_rectangle_shove_into_region (region,
- fixed_directions,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (425, 1000, 300, 200);
- temp = meta_rect (425, 950, 300, 200);
- meta_rectangle_shove_into_region (region,
- FIXED_DIRECTION_X,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 300, 1000, 400, 200);
- temp = meta_rect (1200, 1000, 400, 200);
- meta_rectangle_shove_into_region (region,
- FIXED_DIRECTION_Y,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 800, 1150, 400, 50); /* Completely "offscreen" :) */
- temp = meta_rect ( 800, 1050, 400, 50);
- meta_rectangle_shove_into_region (region,
- 0,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (-1000, 0, 400, 150); /* Offscreen in 2 directions */
- temp = meta_rect ( 0, 20, 400, 150);
- meta_rectangle_shove_into_region (region,
- 0,
- &rect);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- meta_rectangle_free_list_and_elements (region);
-}
-
-static void
-verify_edge_lists_are_equal (GList *code, GList *answer)
-{
- int which = 0;
-
- while (code && answer)
- {
- MetaEdge *a = code->data;
- MetaEdge *b = answer->data;
-
- if (!meta_rectangle_equal (&a->rect, &b->rect) ||
- a->side_type != b->side_type ||
- a->edge_type != b->edge_type)
- {
- g_error ("%dth item in code answer answer lists do not match; "
- "code rect: %d,%d + %d,%d; answer rect: %d,%d + %d,%d\n",
- which,
- a->rect.x, a->rect.y, a->rect.width, a->rect.height,
- b->rect.x, b->rect.y, b->rect.width, b->rect.height);
- }
-
- code = code->next;
- answer = answer->next;
-
- which++;
- }
-
- /* Ought to be at the end of both lists; check if we aren't */
- if (code)
- {
- MetaEdge *tmp = code->data;
- g_error ("code list longer than answer list by %d items; "
- "first extra item rect: %d,%d +%d,%d\n",
- g_list_length (code),
- tmp->rect.x, tmp->rect.y, tmp->rect.width, tmp->rect.height);
- }
-
- if (answer)
- {
- MetaEdge *tmp = answer->data;
- g_error ("answer list longer than code list by %d items; "
- "first extra item rect: %d,%d +%d,%d\n",
- g_list_length (answer),
- tmp->rect.x, tmp->rect.y, tmp->rect.width, tmp->rect.height);
- }
-}
-
-static void
-test_find_onscreen_edges (void)
-{
- GList* edges;
- GList* tmp;
-
- int left = META_DIRECTION_LEFT;
- int right = META_DIRECTION_RIGHT;
- int top = META_DIRECTION_TOP;
- int bottom = META_DIRECTION_BOTTOM;
-
- /*************************************************/
- /* Make sure test region 0 has the correct edges */
- /*************************************************/
- edges = get_screen_edges (0);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 1600, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 0, 1600, 0, top));
- tmp = g_list_prepend (tmp, new_screen_edge (1600, 0, 0, 1200, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 0, 0, 1200, left));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************/
- /* Make sure test region 1 has the correct edges */
- /*************************************************/
- edges = get_screen_edges (1);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 400, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 400, 1160, 1200, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 20, 1600, 0, top));
- tmp = g_list_prepend (tmp, new_screen_edge (1600, 20, 0, 1140, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 400, 1160, 0, 40, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 20, 0, 1180, left));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************/
- /* Make sure test region 2 has the correct edges */
- /*************************************************/
- edges = get_screen_edges (2);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_screen_edge (1200, 1200, 400, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 450, 1200, 350, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 300, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 300, 1150, 150, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1100, 400, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 20, 1600, 0, top));
- tmp = g_list_prepend (tmp, new_screen_edge (1600, 20, 0, 1180, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1100, 0, 100, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 300, 1150, 0, 50, right));
- tmp = g_list_prepend (tmp, new_screen_edge (1200, 1100, 0, 100, left));
- tmp = g_list_prepend (tmp, new_screen_edge ( 450, 1150, 0, 50, left));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 20, 0, 1180, left));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************/
- /* Make sure test region 3 has the correct edges */
- /*************************************************/
- edges = get_screen_edges (3);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_screen_edge (1200, 1200, 400, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 380, 1200, 420, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 300, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 300, 1150, 80, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1100, 400, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 700, 525, 200, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 700, 675, 200, 0, top));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 20, 1600, 0, top));
- tmp = g_list_prepend (tmp, new_screen_edge (1600, 20, 0, 1180, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1100, 0, 100, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 700, 525, 0, 150, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 300, 1150, 0, 50, right));
- tmp = g_list_prepend (tmp, new_screen_edge (1200, 1100, 0, 100, left));
- tmp = g_list_prepend (tmp, new_screen_edge ( 900, 525, 0, 150, left));
- tmp = g_list_prepend (tmp, new_screen_edge ( 380, 1150, 0, 50, left));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 20, 0, 1180, left));
-
-#if 0
- #define FUDGE 50 /* number of edges */
- char big_buffer1[(EDGE_LENGTH+2)*FUDGE], big_buffer2[(EDGE_LENGTH+2)*FUDGE];
- meta_rectangle_edge_list_to_string (edges, "\n ", big_buffer1);
- meta_rectangle_edge_list_to_string (tmp, "\n ", big_buffer2);
- printf("Generated edge list:\n %s\nComparison edges list:\n %s\n",
- big_buffer1, big_buffer2);
-#endif
-
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************/
- /* Make sure test region 4 has the correct edges */
- /*************************************************/
- edges = get_screen_edges (4);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1200, 800, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 800, 20, 800, 0, top));
- tmp = g_list_prepend (tmp, new_screen_edge (1600, 20, 0, 1180, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 800, 20, 0, 1180, left));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************/
- /* Make sure test region 5 has the correct edges */
- /*************************************************/
- edges = get_screen_edges (5);
- tmp = NULL;
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************/
- /* Make sure test region 6 has the correct edges */
- /*************************************************/
- edges = get_screen_edges (6);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 1600, 0, bottom));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 40, 1600, 0, top));
- tmp = g_list_prepend (tmp, new_screen_edge (1600, 40, 0, 1160, right));
- tmp = g_list_prepend (tmp, new_screen_edge ( 0, 40, 0, 1160, left));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-}
-
-static void
-test_find_nonintersected_monitor_edges (void)
-{
- GList* edges;
- GList* tmp;
-
- int left = META_DIRECTION_LEFT;
- int right = META_DIRECTION_RIGHT;
- int top = META_DIRECTION_TOP;
- int bottom = META_DIRECTION_BOTTOM;
-
- /*************************************************************************/
- /* Make sure test monitor set 0 for with region 0 has the correct edges */
- /*************************************************************************/
- edges = get_monitor_edges (0, 0);
- tmp = NULL;
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************************************/
- /* Make sure test monitor set 2 for with region 1 has the correct edges */
- /*************************************************************************/
- edges = get_monitor_edges (2, 1);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_monitor_edge ( 0, 600, 1600, 0, bottom));
- tmp = g_list_prepend (tmp, new_monitor_edge ( 0, 600, 1600, 0, top));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************************************/
- /* Make sure test monitor set 1 for with region 2 has the correct edges */
- /*************************************************************************/
- edges = get_monitor_edges (1, 2);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_monitor_edge ( 800, 20, 0, 1080, right));
- tmp = g_list_prepend (tmp, new_monitor_edge ( 800, 20, 0, 1180, left));
-#if 0
- #define FUDGE 50
- char big_buffer1[(EDGE_LENGTH+2)*FUDGE], big_buffer2[(EDGE_LENGTH+2)*FUDGE];
- meta_rectangle_edge_list_to_string (edges, "\n ", big_buffer1);
- meta_rectangle_edge_list_to_string (tmp, "\n ", big_buffer2);
- printf("Generated edge list:\n %s\nComparison edges list:\n %s\n",
- big_buffer1, big_buffer2);
-#endif
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************************************/
- /* Make sure test monitor set 3 for with region 3 has the correct edges */
- /*************************************************************************/
- edges = get_monitor_edges (3, 3);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_monitor_edge ( 900, 600, 700, 0, bottom));
- tmp = g_list_prepend (tmp, new_monitor_edge ( 0, 600, 700, 0, bottom));
- tmp = g_list_prepend (tmp, new_monitor_edge ( 900, 600, 700, 0, top));
- tmp = g_list_prepend (tmp, new_monitor_edge ( 0, 600, 700, 0, top));
- tmp = g_list_prepend (tmp, new_monitor_edge ( 800, 675, 0, 425, right));
- tmp = g_list_prepend (tmp, new_monitor_edge ( 800, 675, 0, 525, left));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************************************/
- /* Make sure test monitor set 3 for with region 4 has the correct edges */
- /*************************************************************************/
- edges = get_monitor_edges (3, 4);
- tmp = NULL;
- tmp = g_list_prepend (tmp, new_monitor_edge ( 800, 600, 800, 0, bottom));
- tmp = g_list_prepend (tmp, new_monitor_edge ( 800, 600, 800, 0, top));
- tmp = g_list_prepend (tmp, new_monitor_edge ( 800, 600, 0, 600, right));
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-
- /*************************************************************************/
- /* Make sure test monitor set 3 for with region 5has the correct edges */
- /*************************************************************************/
- edges = get_monitor_edges (3, 5);
- tmp = NULL;
- verify_edge_lists_are_equal (edges, tmp);
- meta_rectangle_free_list_and_elements (tmp);
- meta_rectangle_free_list_and_elements (edges);
-}
-
-static void
-test_gravity_resize (void)
-{
- MetaRectangle oldrect, rect, temp;
-
- rect.x = -500; /* Some random amount not equal to oldrect.x to ensure that
- * the resize is done with respect to oldrect instead of rect
- */
- oldrect = meta_rect ( 50, 300, 250, 400);
- temp = meta_rect ( 50, 300, 20, 5);
- meta_rectangle_resize_with_gravity (&oldrect,
- &rect,
- META_GRAVITY_NORTH_WEST,
- 20,
- 5);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 50, 300, 250, 400);
- temp = meta_rect (165, 300, 20, 5);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- META_GRAVITY_NORTH,
- 20,
- 5);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 50, 300, 250, 400);
- temp = meta_rect (280, 300, 20, 5);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- META_GRAVITY_NORTH_EAST,
- 20,
- 5);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 50, 300, 250, 400);
- temp = meta_rect ( 50, 695, 50, 5);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- META_GRAVITY_SOUTH_WEST,
- 50,
- 5);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 50, 300, 250, 400);
- temp = meta_rect (150, 695, 50, 5);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- META_GRAVITY_SOUTH,
- 50,
- 5);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 50, 300, 250, 400);
- temp = meta_rect (250, 695, 50, 5);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- META_GRAVITY_SOUTH_EAST,
- 50,
- 5);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (167, 738, 237, 843);
- temp = meta_rect (167, 1113, 832, 93);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- META_GRAVITY_WEST,
- 832,
- 93);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect ( 167, 738, 237, 843);
- temp = meta_rect (-131, 1113, 833, 93);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- META_GRAVITY_CENTER,
- 832,
- 93);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (300, 1000, 400, 200);
- temp = meta_rect (270, 994, 430, 212);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- META_GRAVITY_EAST,
- 430,
- 211);
- g_assert (meta_rectangle_equal (&rect, &temp));
-
- rect = meta_rect (300, 1000, 400, 200);
- temp = meta_rect (300, 1000, 430, 211);
- meta_rectangle_resize_with_gravity (&rect,
- &rect,
- META_GRAVITY_STATIC,
- 430,
- 211);
- g_assert (meta_rectangle_equal (&rect, &temp));
-}
-
-#define EPSILON 0.000000001
-static void
-test_find_closest_point_to_line (void)
-{
- double x1, y1, x2, y2, px, py, rx, ry;
- double answer_x, answer_y;
-
- x1 = 3.0; y1 = 49.0;
- x2 = 2.0; y2 = - 1.0;
- px = -2.6; py = 19.1;
- answer_x = 2.4; answer_y = 19;
- meta_rectangle_find_linepoint_closest_to_point (x1, y1,
- x2, y2,
- px, py,
- &rx, &ry);
- 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;
- x2 = 3.0; y2 = - 1.0;
- px = -2.6; py = 19.1;
- answer_x = 3.0; answer_y = 19.1;
- meta_rectangle_find_linepoint_closest_to_point (x1, y1,
- x2, y2,
- px, py,
- &rx, &ry);
- 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;
- x2 = 2.718; y2 = 7.0;
- px = -2.6; py = 19.1;
- answer_x = -2.6; answer_y = 7;
- meta_rectangle_find_linepoint_closest_to_point (x1, y1,
- x2, y2,
- px, py,
- &rx, &ry);
- 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;
- x2 = 2.0; y2 = - 1.0;
- px = 2.4; py = 19.0;
- answer_x = 2.4; answer_y = 19;
- meta_rectangle_find_linepoint_closest_to_point (x1, y1,
- x2, y2,
- px, py,
- &rx, &ry);
- g_assert (fabs (rx - answer_x) < EPSILON && fabs (ry - answer_y) < EPSILON);
-}
-
-void
-init_boxes_tests (void)
-{
- init_random_ness ();
-
- 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);
-
- 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 */
- 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... */
- 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
deleted file mode 100644
index 9f3b778b7..000000000
--- a/src/tests/boxes-tests.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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/src/tests/clutter-test-utils.c b/src/tests/clutter-test-utils.c
deleted file mode 100644
index de4b94e23..000000000
--- a/src/tests/clutter-test-utils.c
+++ /dev/null
@@ -1,473 +0,0 @@
-#include "clutter-test-utils.h"
-
-#include <stdlib.h>
-#include <glib-object.h>
-#include <clutter/clutter.h>
-
-#include "compositor/meta-plugin-manager.h"
-#include "core/meta-context-private.h"
-
-typedef struct {
- gpointer dummy_field;
-} ClutterTestEnvironment;
-
-static ClutterTestEnvironment *test_environ = NULL;
-
-static GMainLoop *clutter_test_main_loop = 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
- * @argv: (inout) (array length=argc) (nullable): array of arguments
- *
- * Initializes the Clutter test environment.
- *
- * Since: 1.18
- */
-void
-clutter_test_init (int *argc,
- char ***argv)
-{
- MetaContext *context;
-
- context = meta_create_test_context (META_CONTEXT_TEST_TYPE_NESTED,
- META_CONTEXT_TEST_FLAG_NO_X11);
- g_assert (meta_context_configure (context, argc, argv, NULL));
- g_assert (meta_context_setup (context, NULL));
-
- test_environ = g_new0 (ClutterTestEnvironment, 1);
-
- g_assert (meta_context_start (context, NULL));
-
- clutter_test_main_loop = g_main_loop_new (NULL, FALSE);
-}
-
-/**
- * clutter_test_get_stage:
- *
- * Retrieves the #ClutterStage used for testing.
- *
- * Return value: (transfer none): the stage used for testing
- *
- * Since: 1.18
- */
-ClutterActor *
-clutter_test_get_stage (void)
-{
- MetaBackend *backend = meta_get_backend ();
-
- return meta_backend_get_stage (backend);
-}
-
-typedef struct {
- gpointer test_func;
- gpointer test_data;
- GDestroyNotify test_notify;
-} ClutterTestData;
-
-static gboolean
-list_equal_unsorted (GList *list_a,
- GList *list_b)
-{
- GList *l_a;
- GList *l_b;
-
- for (l_a = list_a, l_b = list_b;
- l_a && l_b;
- l_a = l_a->next, l_b = l_b->next)
- {
- if (l_a->data != l_b->data)
- return FALSE;
- }
-
- return !l_a && !l_b;
-}
-
-static void
-clutter_test_func_wrapper (gconstpointer data_)
-{
- const ClutterTestData *data = data_;
- ClutterActor *stage;
- GList *pre_stage_children;
- GList *post_stage_children;
-
- g_test_log_set_fatal_handler (log_func, NULL);
-
- /* ensure that the previous test state has been cleaned up */
- stage = clutter_test_get_stage ();
- clutter_actor_hide (stage);
-
- pre_stage_children = clutter_actor_get_children (stage);
-
- if (data->test_data != NULL)
- {
- GTestDataFunc test_func = data->test_func;
-
- test_func (data->test_data);
- }
- else
- {
- GTestFunc test_func = data->test_func;
-
- test_func ();
- }
-
- if (data->test_notify != NULL)
- data->test_notify (data->test_data);
-
- post_stage_children = clutter_actor_get_children (stage);
-
- g_assert_true (list_equal_unsorted (pre_stage_children, post_stage_children));
-
- g_list_free (pre_stage_children);
- g_list_free (post_stage_children);
-
- clutter_actor_hide (stage);
-}
-
-/**
- * clutter_test_add: (skip)
- * @test_path: unique path for identifying the test
- * @test_func: function containing the test
- *
- * Adds a test unit to the Clutter test environment.
- *
- * See also: g_test_add()
- *
- * Since: 1.18
- */
-void
-clutter_test_add (const char *test_path,
- GTestFunc test_func)
-{
- clutter_test_add_data_full (test_path, (GTestDataFunc) test_func, NULL, NULL);
-}
-
-/**
- * clutter_test_add_data: (skip)
- * @test_path: unique path for identifying the test
- * @test_func: function containing the test
- * @test_data: data to pass to the test function
- *
- * Adds a test unit to the Clutter test environment.
- *
- * See also: g_test_add_data_func()
- *
- * Since: 1.18
- */
-void
-clutter_test_add_data (const char *test_path,
- GTestDataFunc test_func,
- gpointer test_data)
-{
- clutter_test_add_data_full (test_path, test_func, test_data, NULL);
-}
-
-/**
- * clutter_test_add_data_full:
- * @test_path: unique path for identifying the test
- * @test_func: (scope notified): function containing the test
- * @test_data: (closure): data to pass to the test function
- * @test_notify: function called when the test function ends
- *
- * Adds a test unit to the Clutter test environment.
- *
- * See also: g_test_add_data_func_full()
- *
- * Since: 1.18
- */
-void
-clutter_test_add_data_full (const char *test_path,
- GTestDataFunc test_func,
- gpointer test_data,
- GDestroyNotify test_notify)
-{
- ClutterTestData *data;
-
- g_return_if_fail (test_path != NULL);
- g_return_if_fail (test_func != NULL);
-
- g_assert (test_environ != NULL);
-
- data = g_new (ClutterTestData, 1);
- data->test_func = test_func;
- data->test_data = test_data;
- data->test_notify = test_notify;
-
- g_test_add_data_func_full (test_path, data,
- clutter_test_func_wrapper,
- g_free);
-}
-
-/**
- * clutter_test_run:
- *
- * Runs the test suite using the units added by calling
- * clutter_test_add().
- *
- * The typical test suite is composed of a list of functions
- * called by clutter_test_run(), for instance:
- *
- * |[
- * static void unit_foo (void) { ... }
- *
- * static void unit_bar (void) { ... }
- *
- * static void unit_baz (void) { ... }
- *
- * int
- * main (int argc, char *argv[])
- * {
- * clutter_test_init (&argc, &argv);
- *
- * clutter_test_add ("/unit/foo", unit_foo);
- * clutter_test_add ("/unit/bar", unit_bar);
- * clutter_test_add ("/unit/baz", unit_baz);
- *
- * return clutter_test_run ();
- * }
- * ]|
- *
- * Return value: the exit code for the test suite
- *
- * Since: 1.18
- */
-int
-clutter_test_run (void)
-{
- int res;
-
- g_assert (test_environ != NULL);
-
- res = g_test_run ();
-
- g_free (test_environ);
-
- return res;
-}
-
-void
-clutter_test_main (void)
-{
- g_assert_nonnull (clutter_test_main_loop);
-
- g_main_loop_run (clutter_test_main_loop);
-}
-
-void
-clutter_test_quit (void)
-{
- g_assert_nonnull (clutter_test_main_loop);
-
- g_main_loop_quit (clutter_test_main_loop);
-}
-
-typedef struct {
- ClutterActor *stage;
-
- graphene_point_t point;
-
- gpointer result;
-
- guint check_actor : 1;
- guint check_color : 1;
-
- guint was_painted : 1;
-} ValidateData;
-
-static gboolean
-validate_stage (gpointer data_)
-{
- ValidateData *data = data_;
-
- if (data->check_actor)
- {
- data->result =
- clutter_stage_get_actor_at_pos (CLUTTER_STAGE (data->stage),
- CLUTTER_PICK_ALL,
- data->point.x,
- data->point.y);
- }
-
- if (data->check_color)
- {
- data->result =
- clutter_stage_read_pixels (CLUTTER_STAGE (data->stage),
- data->point.x,
- data->point.y,
- 1, 1);
- }
-
- if (!g_test_verbose ())
- {
- clutter_actor_hide (data->stage);
- data->was_painted = TRUE;
- }
-
- return G_SOURCE_REMOVE;
-}
-
-static gboolean
-on_key_press_event (ClutterActor *stage,
- ClutterEvent *event,
- gpointer data_)
-{
- ValidateData *data = data_;
-
- if (data->stage == stage &&
- clutter_event_get_key_symbol (event) == CLUTTER_KEY_Escape)
- {
- clutter_actor_hide (stage);
-
- data->was_painted = TRUE;
- }
-
- return CLUTTER_EVENT_PROPAGATE;
-}
-
-/**
- * clutter_test_check_actor_at_point:
- * @stage: a #ClutterStage
- * @point: coordinates to check
- * @actor: the expected actor at the given coordinates
- * @result: (out) (nullable): actor at the coordinates
- *
- * Checks the given coordinates of the @stage and compares the
- * actor found there with the given @actor.
- *
- * Returns: %TRUE if the actor at the given coordinates matches
- *
- * Since: 1.18
- */
-gboolean
-clutter_test_check_actor_at_point (ClutterActor *stage,
- const graphene_point_t *point,
- ClutterActor *actor,
- ClutterActor **result)
-{
- ValidateData *data;
- gulong press_id = 0;
-
- g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
- g_return_val_if_fail (point != NULL, FALSE);
- g_return_val_if_fail (CLUTTER_IS_ACTOR (stage), FALSE);
- g_return_val_if_fail (result != NULL, FALSE);
-
- data = g_new0 (ValidateData, 1);
- data->stage = stage;
- data->point = *point;
- data->check_actor = TRUE;
-
- if (g_test_verbose ())
- {
- g_printerr ("Press ESC to close the stage and resume the test\n");
- press_id = g_signal_connect (stage, "key-press-event",
- G_CALLBACK (on_key_press_event),
- data);
- }
-
- clutter_actor_show (stage);
-
- clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
- validate_stage,
- data,
- NULL);
-
- while (!data->was_painted)
- g_main_context_iteration (NULL, TRUE);
-
- *result = data->result;
-
- g_clear_signal_handler (&press_id, stage);
-
- g_free (data);
-
- return *result == actor;
-}
-
-/**
- * clutter_test_check_color_at_point:
- * @stage: a #ClutterStage
- * @point: coordinates to check
- * @color: expected color
- * @result: (out caller-allocates): color at the given coordinates
- *
- * Checks the color at the given coordinates on @stage, and matches
- * it with the red, green, and blue channels of @color. The alpha
- * component of @color and @result is ignored.
- *
- * Returns: %TRUE if the colors match
- *
- * Since: 1.18
- */
-gboolean
-clutter_test_check_color_at_point (ClutterActor *stage,
- const graphene_point_t *point,
- const ClutterColor *color,
- ClutterColor *result)
-{
- ValidateData *data;
- gboolean retval;
- guint8 *buffer;
- gulong press_id = 0;
-
- g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
- g_return_val_if_fail (point != NULL, FALSE);
- g_return_val_if_fail (color != NULL, FALSE);
- g_return_val_if_fail (result != NULL, FALSE);
-
- data = g_new0 (ValidateData, 1);
- data->stage = stage;
- data->point = *point;
- data->check_color = TRUE;
-
- if (g_test_verbose ())
- {
- g_printerr ("Press ESC to close the stage and resume the test\n");
- press_id = g_signal_connect (stage, "key-press-event",
- G_CALLBACK (on_key_press_event),
- data);
- }
-
- clutter_actor_show (stage);
-
- clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
- validate_stage,
- data,
- NULL);
-
- while (!data->was_painted)
- g_main_context_iteration (NULL, TRUE);
-
- g_clear_signal_handler (&press_id, stage);
-
- buffer = data->result;
-
- clutter_color_init (result, buffer[0], buffer[1], buffer[2], 255);
-
- /* we only check the color channels, so we can't use clutter_color_equal() */
- retval = buffer[0] == color->red &&
- buffer[1] == color->green &&
- buffer[2] == color->blue;
-
- g_free (data->result);
- g_free (data);
-
- return retval;
-}
diff --git a/src/tests/clutter-test-utils.h b/src/tests/clutter-test-utils.h
deleted file mode 100644
index 95f54ceed..000000000
--- a/src/tests/clutter-test-utils.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Clutter.
- *
- * An OpenGL based 'interactive canvas' library.
- *
- * Copyright (C) 2013 Emmanuele Bassi <ebassi@gnome.org>
- *
- * 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"
-
-#ifndef __CLUTTER_TEST_UTILS_H__
-#define __CLUTTER_TEST_UTILS_H__
-
-#define __CLUTTER_H_INSIDE__
-
-#include "clutter/clutter-types.h"
-#include "clutter/clutter-actor.h"
-#include "clutter/clutter-color.h"
-#include "clutter/clutter-private.h"
-#include "meta/common.h"
-#include "meta-test/meta-context-test.h"
-
-G_BEGIN_DECLS
-
-/**
- * CLUTTER_TEST_UNIT:
- * @path: the GTest path for the test function
- * @func: the GTestFunc function
- *
- * Adds @func at the given @path in the test suite.
- *
- * Since: 1.18
- */
-#define CLUTTER_TEST_UNIT(path,func) \
- clutter_test_add (path, func);
-
-/**
- * CLUTTER_TEST_SUITE:
- * @units: a list of %CLUTTER_TEST_UNIT definitions
- *
- * Defines the entry point and initializes a Clutter test unit, e.g.:
- *
- * |[
- * CLUTTER_TEST_SUITE (
- * CLUTTER_TEST_UNIT ("/foobarize", foobarize)
- * CLUTTER_TEST_UNIT ("/bar-enabled", bar_enabled)
- * )
- * ]|
- *
- * Expands to:
- *
- * |[
- * int
- * main (int argc,
- * char *argv[])
- * {
- * clutter_test_init (&argc, &argv);
- *
- * clutter_test_add ("/foobarize", foobarize);
- * clutter_test_add ("/bar-enabled", bar_enabled);
- *
- * return clutter_test_run ();
- * }
- * ]|
- *
- * Since: 1.18
- */
-#define CLUTTER_TEST_SUITE(units) \
-int \
-main (int argc, char *argv[]) \
-{ \
- clutter_test_init (&argc, &argv); \
-\
- { \
- units \
- } \
-\
- return clutter_test_run (); \
-}
-
-CLUTTER_EXPORT
-void clutter_test_init (int *argc,
- char ***argv);
-
-CLUTTER_EXPORT
-int clutter_test_run (void);
-
-CLUTTER_EXPORT
-void clutter_test_main (void);
-
-CLUTTER_EXPORT
-void clutter_test_quit (void);
-
-CLUTTER_EXPORT
-void clutter_test_add (const char *test_path,
- GTestFunc test_func);
-CLUTTER_EXPORT
-void clutter_test_add_data (const char *test_path,
- GTestDataFunc test_func,
- gpointer test_data);
-CLUTTER_EXPORT
-void clutter_test_add_data_full (const char *test_path,
- GTestDataFunc test_func,
- gpointer test_data,
- GDestroyNotify test_notify);
-
-CLUTTER_EXPORT
-ClutterActor * clutter_test_get_stage (void);
-
-#define clutter_test_assert_actor_at_point(stage,point,actor) \
-G_STMT_START { \
- const graphene_point_t *__p = (point); \
- ClutterActor *__actor = (actor); \
- ClutterActor *__stage = (stage); \
- ClutterActor *__res; \
- if (clutter_test_check_actor_at_point (__stage, __p, actor, &__res)) ; else { \
- const char *__str1 = clutter_actor_get_name (__actor) != NULL \
- ? clutter_actor_get_name (__actor) \
- : G_OBJECT_TYPE_NAME (__actor); \
- const char *__str2 = clutter_actor_get_name (__res) != NULL \
- ? clutter_actor_get_name (__res) \
- : G_OBJECT_TYPE_NAME (__res); \
- 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); \
- g_free (__msg); \
- } \
-} G_STMT_END
-
-#define clutter_test_assert_color_at_point(stage,point,color) \
-G_STMT_START { \
- const graphene_point_t *__p = (point); \
- const ClutterColor *__c = (color); \
- ClutterActor *__stage = (stage); \
- ClutterColor __res; \
- if (clutter_test_check_color_at_point (__stage, __p, __c, &__res)) ; else { \
- char *__str1 = clutter_color_to_string (__c); \
- char *__str2 = clutter_color_to_string (&__res); \
- 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); \
- g_free (__msg); \
- g_free (__str1); \
- g_free (__str2); \
- } \
-} G_STMT_END
-
-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
-
-#endif /* __CLUTTER_TEST_UTILS_H__ */
diff --git a/src/tests/clutter/README b/src/tests/clutter/README
deleted file mode 100644
index b5665e6ab..000000000
--- a/src/tests/clutter/README
+++ /dev/null
@@ -1,38 +0,0 @@
-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/src/tests/clutter/accessibility/cally-atkcomponent-example.c b/src/tests/clutter/accessibility/cally-atkcomponent-example.c
deleted file mode 100644
index 4e7024597..000000000
--- a/src/tests/clutter/accessibility/cally-atkcomponent-example.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* CALLY - The Clutter Accessibility Implementation Library
- *
- * Copyright (C) 2009 Igalia, S.L.
- *
- * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
- *
- * 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.
- */
-
-#include <clutter/clutter.h>
-
-#include "cally-examples-util.h"
-
-#define WIDTH 300
-#define HEIGHT 300
-#define SIZE 50
-#define DEPTH -100
-
-int
-main (int argc, char *argv[])
-{
- ClutterActor *stage = NULL;
- ClutterActor *button1 = NULL;
- ClutterActor *button2 = NULL;
- ClutterActor *button3 = NULL;
- ClutterActor *button4 = NULL;
- ClutterActor *group[4];
- int i = 0;
-
- cally_util_a11y_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
-
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Cally - AtkComponent Test");
- clutter_actor_set_background_color (CLUTTER_ACTOR (stage), CLUTTER_COLOR_White);
- clutter_actor_set_size (stage, WIDTH, HEIGHT);
-
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- button1 = clutter_actor_new ();
- clutter_actor_set_background_color (button1, CLUTTER_COLOR_Yellow);
- clutter_actor_set_size (button1, SIZE, SIZE);
-
- button2 = clutter_actor_new ();
- clutter_actor_set_background_color (button2, CLUTTER_COLOR_Green);
- clutter_actor_set_position (button2, 2 * SIZE, 0);
- clutter_actor_set_size (button2, SIZE, SIZE);
-
- button3 = clutter_actor_new ();
- clutter_actor_set_background_color (button3, CLUTTER_COLOR_Blue);
- clutter_actor_set_position (button3, 0, 2 * SIZE);
- clutter_actor_set_size (button3, SIZE, SIZE);
- clutter_actor_set_z_position (button3, DEPTH);
-
- /* a nested hierarchy, to check that the relative positions are
- computed properly */
- button4 = clutter_actor_new ();
- clutter_actor_set_background_color (button4, CLUTTER_COLOR_Magenta);
- clutter_actor_set_position (button4, SIZE / 2, SIZE / 2);
- clutter_actor_set_size (button4, SIZE, SIZE);
-
- for (i = 0; i < 4; i++) {
- group[i] = clutter_actor_new ();
- clutter_actor_set_position (group[i], SIZE / 2, SIZE / 2);
- clutter_actor_set_size (group[i], SIZE, SIZE);
-
- if (i > 0)
- clutter_container_add_actor (CLUTTER_CONTAINER (group[i]), group [i - 1]);
- }
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), button1);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), button2);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), button3);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), group[3]);
- clutter_container_add_actor (CLUTTER_CONTAINER (group[0]), button4);
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return 0;
-}
diff --git a/src/tests/clutter/accessibility/cally-atkeditabletext-example.c b/src/tests/clutter/accessibility/cally-atkeditabletext-example.c
deleted file mode 100644
index 0c28ee90b..000000000
--- a/src/tests/clutter/accessibility/cally-atkeditabletext-example.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/* CALLY - The Clutter Accessibility Implementation Library
- *
- * Copyright (C) 2009 Igalia, S.L.
- *
- * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
- *
- * 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.
- */
-
-#include <atk/atk.h>
-#include <clutter/clutter.h>
-
-#include "cally-examples-util.h"
-
-#define WIDTH 800
-#define HEIGHT 600
-
-static ClutterActor *text_actor = NULL;
-static ClutterActor *text_editable_actor = NULL;
-
-/*
- * Test AtkText interface
- */
-static void
-test_atk_text (ClutterActor *actor)
-{
- AtkObject *object = NULL;
- AtkEditableText *cally_editable_text = NULL;
- gint pos = 0;
-
- object = atk_gobject_accessible_for_object (G_OBJECT (actor));
- cally_editable_text = ATK_EDITABLE_TEXT (object);
-
- if (cally_editable_text != NULL) {
- atk_editable_text_set_text_contents (cally_editable_text, "New text");
- atk_editable_text_delete_text (cally_editable_text, 0, 3);
- pos = 3;
- atk_editable_text_insert_text (cally_editable_text, "New", 0, &pos);
-
- /* Not implemented in cally, just checking that we can call this
- functions */
- atk_editable_text_copy_text (cally_editable_text, 0, -1);
- atk_editable_text_paste_text (cally_editable_text, 5);
- atk_editable_text_cut_text (cally_editable_text, 0, -1);
- }
-}
-
-static gboolean
-insert_text_press_cb (ClutterActor *actor,
- ClutterButtonEvent *event,
- gpointer data)
-{
- AtkObject *object = NULL;
- AtkEditableText *cally_editable_text = NULL;
- gint pos = 0;
-
- object = atk_gobject_accessible_for_object (G_OBJECT (text_editable_actor));
- cally_editable_text = ATK_EDITABLE_TEXT (object);
-
- pos = 3;
- atk_editable_text_insert_text (cally_editable_text, "New", 0, &pos);
-
- return TRUE;
-}
-
-static gboolean
-delete_text_press_cb (ClutterActor *actor,
- ClutterButtonEvent *event,
- gpointer data)
-{
- AtkObject *object = NULL;
- AtkEditableText *cally_editable_text = NULL;
-
- object = atk_gobject_accessible_for_object (G_OBJECT (text_editable_actor));
- cally_editable_text = ATK_EDITABLE_TEXT (object);
-
- atk_editable_text_delete_text (cally_editable_text, 0, 3);
-
- return TRUE;
-}
-
-static gboolean
-set_text_press_cb (ClutterActor *actor,
- ClutterButtonEvent *event,
- gpointer data)
-{
- AtkObject *object = NULL;
- AtkEditableText *cally_editable_text = NULL;
-
- object = atk_gobject_accessible_for_object (G_OBJECT (text_editable_actor));
- cally_editable_text = ATK_EDITABLE_TEXT (object);
-
- atk_editable_text_set_text_contents (cally_editable_text, "New text");
-
- return TRUE;
-}
-
-static gboolean
-activate_deactivate_press_cb (ClutterActor *actor,
- ClutterButtonEvent *event,
- gpointer data)
-{
- gboolean active = FALSE;
-
- active = clutter_text_get_activatable (CLUTTER_TEXT (text_editable_actor));
- clutter_text_set_activatable (CLUTTER_TEXT (text_editable_actor), !active);
-
- return TRUE;
-}
-
-static gboolean
-print_cursor_position_press_cb (ClutterActor *actor,
- ClutterButtonEvent *event,
- gpointer data)
-{
- gint pos = 0;
-
- pos = clutter_text_get_cursor_position (CLUTTER_TEXT (text_editable_actor));
-
- g_print ("current cursor position %i\n", pos);
-
- return TRUE;
-}
-
-static void
-activate_cb (ClutterActor *actor,
- gpointer data)
-{
- g_print ("Actor activated\n");
-}
-
-static ClutterActor*
-_create_button (const gchar *text)
-{
- ClutterActor *button = NULL;
- ClutterActor *rectangle = NULL;
- ClutterActor *label = NULL;
-
- button = clutter_actor_new ();
- rectangle = clutter_actor_new ();
- clutter_actor_set_background_color (rectangle, CLUTTER_COLOR_Magenta);
- clutter_actor_set_size (rectangle, 375, 35);
-
- label = clutter_text_new_full ("Sans Bold 32px",
- text,
- CLUTTER_COLOR_Black);
- clutter_container_add_actor (CLUTTER_CONTAINER (button), rectangle);
- clutter_container_add_actor (CLUTTER_CONTAINER (button), label);
- clutter_actor_set_reactive (button, TRUE);
-
- return button;
-}
-
-static void
-make_ui (ClutterActor *stage)
-{
- ClutterActor *button = NULL;
-
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Cally - AtkEditable Test");
- clutter_actor_set_background_color (CLUTTER_ACTOR (stage), CLUTTER_COLOR_White);
- clutter_actor_set_size (stage, WIDTH, HEIGHT);
-
- /* text */
- text_actor = clutter_text_new_full ("Sans Bold 32px",
- "Lorem ipsum dolor sit amet",
- CLUTTER_COLOR_Red);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), text_actor);
-
- /* text_editable */
- text_editable_actor = clutter_text_new_full ("Sans Bold 32px",
- "consectetur adipisicing elit",
- CLUTTER_COLOR_Red);
- clutter_actor_set_position (text_editable_actor, 0, 100);
- clutter_text_set_editable (CLUTTER_TEXT (text_editable_actor), TRUE);
- clutter_text_set_selectable (CLUTTER_TEXT (text_editable_actor), TRUE);
- clutter_text_set_selection_color (CLUTTER_TEXT (text_editable_actor),
- CLUTTER_COLOR_Green);
- clutter_text_set_activatable (CLUTTER_TEXT (text_editable_actor),
- TRUE);
- clutter_text_set_line_wrap (CLUTTER_TEXT (text_editable_actor), TRUE);
- clutter_actor_grab_key_focus (text_editable_actor);
- clutter_actor_set_reactive (text_editable_actor, TRUE);
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), text_editable_actor);
- g_signal_connect (text_editable_actor, "activate",
- G_CALLBACK (activate_cb), NULL);
-
- /* test buttons */
- button = _create_button ("Set");
- clutter_actor_set_position (button, 100, 200);
-
- g_signal_connect_after (button, "button-press-event",
- G_CALLBACK (set_text_press_cb), NULL);
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), button);
-
- button = _create_button ("Delete");
- clutter_actor_set_position (button, 100, 250);
-
- g_signal_connect_after (button, "button-press-event",
- G_CALLBACK (delete_text_press_cb), NULL);
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), button);
-
- button = _create_button ("Insert");
- clutter_actor_set_position (button, 100, 300);
-
- g_signal_connect_after (button, "button-press-event",
- G_CALLBACK (insert_text_press_cb), NULL);
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), button);
-
- button = _create_button ("Activate/Deactivate");
- clutter_actor_set_position (button, 100, 350);
-
- g_signal_connect_after (button, "button-press-event",
- G_CALLBACK (activate_deactivate_press_cb), NULL);
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), button);
-
- button = _create_button ("Cursor position");
- clutter_actor_set_position (button, 100, 450);
-
- g_signal_connect_after (button, "button-press-event",
- G_CALLBACK (print_cursor_position_press_cb), NULL);
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), button);
-
-}
-
-int
-main (int argc, char *argv[])
-{
- ClutterActor *stage = NULL;
-
- g_set_application_name ("AtkEditableText");
-
- cally_util_a11y_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- make_ui (stage);
-
- clutter_actor_show (stage);
-
- test_atk_text (text_actor);
- test_atk_text (text_editable_actor);
-
- clutter_test_main ();
-
- return 0;
-}
diff --git a/src/tests/clutter/accessibility/cally-atkevents-example.c b/src/tests/clutter/accessibility/cally-atkevents-example.c
deleted file mode 100644
index a94b7880a..000000000
--- a/src/tests/clutter/accessibility/cally-atkevents-example.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/* CALLY - The Clutter Accessibility Implementation Library
- *
- * Copyright (C) 2009 Igalia, S.L.
- *
- * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
- *
- * 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.
- */
-
-/*
- * The purpose of this example is test key event and global event
- * implementation, specifically:
- *
- * atk_add_global_event_listener
- * atk_remove_global_event_listener
- * atk_add_key_event_listener
- * atk_remove_key_event_listener
- */
-#include <atk/atk.h>
-#include <clutter/clutter.h>
-#include <cally/cally.h>
-
-#include "cally-examples-util.h"
-
-#define WIDTH 800
-#define HEIGHT 600
-#define HEIGHT_STEP 100
-#define NUM_ENTRIES 3
-
-struct _Data{
- gint value;
-};
-typedef struct _Data Data;
-
-static gboolean
-atk_key_listener (AtkKeyEventStruct *event, gpointer data)
-{
- Data *my_data = (Data*) data;
-
- g_print ("atk_listener: 0x%x ", event->keyval);
-
- if (my_data != NULL) {
- g_print ("\t Data value: %i\n", my_data->value);
- } else {
- g_print ("\tNo data!!\n");
- }
-
- return FALSE;
-}
-
-static gboolean
-window_event_listener (GSignalInvocationHint * signal_hint,
- guint n_param_values,
- const GValue * param_values, gpointer data)
-{
- AtkObject *accessible;
- GSignalQuery signal_query;
- const gchar *name, *s;
-
- g_signal_query (signal_hint->signal_id, &signal_query);
- name = signal_query.signal_name;
-
- accessible = ATK_OBJECT (g_value_get_object (&param_values[0]));
- s = atk_object_get_name (accessible);
-
- g_print ("Detected window event \"%s\" from object \"%p\" named \"%s\"\n",
- name, accessible, s);
-
- return TRUE;
-}
-static void
-make_ui (ClutterActor *stage)
-{
- gint i = 0;
- ClutterActor *editable = NULL;
- ClutterActor *rectangle = NULL;
- ClutterActor *label = NULL;
- ClutterColor color_sel = { 0x00, 0xff, 0x00, 0x55 };
- ClutterColor color_label = { 0x00, 0xff, 0x55, 0xff };
- ClutterColor color_rect = { 0x00, 0xff, 0xff, 0x55 };
- float label_geom_y, editable_geom_y;
-
- clutter_actor_set_background_color (CLUTTER_ACTOR (stage), CLUTTER_COLOR_White);
- clutter_actor_set_size (stage, WIDTH, HEIGHT);
-
- label_geom_y = 50;
- editable_geom_y = 50;
-
- for (i = 0; i < NUM_ENTRIES; i++)
- {
- /* label */
- label = clutter_text_new_full ("Sans Bold 32px",
- "Entry",
- &color_label);
- clutter_actor_set_position (label, 0, label_geom_y);
-
- /* editable */
- editable = clutter_text_new_full ("Sans Bold 32px",
- "ddd",
- CLUTTER_COLOR_Red);
- clutter_actor_set_position (editable, 150, editable_geom_y);
- clutter_actor_set_size (editable, 500, 75);
- clutter_text_set_editable (CLUTTER_TEXT (editable), TRUE);
- clutter_text_set_selectable (CLUTTER_TEXT (editable), TRUE);
- clutter_text_set_selection_color (CLUTTER_TEXT (editable),
- &color_sel);
- clutter_actor_grab_key_focus (editable);
- clutter_actor_set_reactive (editable, TRUE);
-
- /* rectangle: to create a entry "feeling" */
- rectangle = clutter_actor_new ();
- clutter_actor_set_background_color (rectangle, &color_rect);
- clutter_actor_set_position (rectangle, 150, editable_geom_y);
- clutter_actor_set_size (rectangle, 500, 75);
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), label);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), editable);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), rectangle);
-
- label_geom_y += HEIGHT_STEP;
- editable_geom_y += HEIGHT_STEP;
- }
-}
-
-int
-main (int argc, char *argv[])
-{
- ClutterActor *stage, *stage_main;
- Data data1, data2, data3;
- guint id_1 = 0, id_2 = 0, id_3 = 0;
-
- g_set_application_name ("AtkText");
-
- if (cally_util_a11y_init (&argc, &argv) == FALSE)
- {
- g_error ("This example requires the accessibility support, "
- "specifically AtkUtil implementation loaded, "
- "as it tries to register and remove event listeners");
- }
-
- data1.value = 10;
- data2.value = 20;
- data3.value = 30;
-
- /* key event listeners */
- id_1 = atk_add_key_event_listener ((AtkKeySnoopFunc)atk_key_listener, &data1);
- atk_remove_key_event_listener (id_1);
- id_2 = atk_add_key_event_listener ((AtkKeySnoopFunc)atk_key_listener, &data2);
- id_3 = atk_add_key_event_listener ((AtkKeySnoopFunc)atk_key_listener, &data3);
-
- atk_remove_key_event_listener (id_2);
-
- g_print ("key event listener ids registered: (%i, %i, %i)\n", id_1, id_2, id_3);
-
- /* event listeners */
- atk_add_global_event_listener (window_event_listener, "Atk:AtkWindow:create");
- atk_add_global_event_listener (window_event_listener, "Atk:AtkWindow:destroy");
- atk_add_global_event_listener (window_event_listener, "Atk:AtkWindow:activate");
- atk_add_global_event_listener (window_event_listener, "Atk:AtkWindow:deactivate");
-
- stage_main = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage_main), "Cally - AtkEvents/1");
- g_signal_connect (stage_main, "destroy", G_CALLBACK (clutter_test_quit), NULL);
- make_ui (stage_main);
-
- clutter_actor_show (stage_main);
-
- if (clutter_feature_available (CLUTTER_FEATURE_STAGE_MULTIPLE))
- {
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Cally - AtkEvents/2");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- make_ui (stage);
- clutter_actor_show (stage);
- }
-
- clutter_test_main ();
-
- return 0;
-}
diff --git a/src/tests/clutter/accessibility/cally-atktext-example.c b/src/tests/clutter/accessibility/cally-atktext-example.c
deleted file mode 100644
index 64a920da5..000000000
--- a/src/tests/clutter/accessibility/cally-atktext-example.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/* CALLY - The Clutter Accessibility Implementation Library
- *
- * Copyright (C) 2009 Igalia, S.L.
- *
- * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
- *
- * 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.
- */
-
-#include <atk/atk.h>
-#include <clutter/clutter.h>
-
-#include "cally-examples-util.h"
-
-#define WIDTH 800
-#define HEIGHT 600
-
-static ClutterActor *text_actor = NULL;
-static ClutterActor *text_editable_actor = NULL;
-
-/*
- * Test AtkText interface
- */
-static void
-test_atk_text (ClutterActor *actor)
-{
- gchar *text = NULL;
- AtkObject *object = NULL;
- AtkText *cally_text = NULL;
- gboolean boolean = FALSE;
- gunichar unichar;
- gint count = -1;
- gint start = -1;
- gint end = -1;
- gint pos = -1;
- AtkAttributeSet *at_set = NULL;
- GSList *attrs;
- gchar *buf;
- gint x, y, width, height;
-
- object = atk_gobject_accessible_for_object (G_OBJECT (actor));
- cally_text = ATK_TEXT (object);
-
- if (!cally_text)
- return;
-
- text = atk_text_get_text (cally_text, 0, -1);
- g_print ("atk_text_get_text output: %s\n", text);
-
- 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]);
- g_free (text); text = NULL;
- g_free (buf); buf = NULL;
-
- 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);
- g_free (text); text = NULL;
-
- pos = atk_text_get_caret_offset (cally_text);
- g_print ("atk_text_get_caret_offset: %i\n", pos);
-
- atk_text_set_caret_offset (cally_text, 5);
-
- count = atk_text_get_character_count (cally_text);
- g_print ("atk_text_get_character_count: %i\n", count);
-
- count = atk_text_get_n_selections (cally_text);
- g_print ("atk_text_get_n_selections: %i\n", count);
-
- text = atk_text_get_selection (cally_text, 0, &start, &end);
- g_print ("atk_text_get_selection: %s, %i, %i\n", text, start, end);
- g_free(text); text = NULL;
-
- boolean = atk_text_remove_selection (cally_text, 0);
- g_print ("atk_text_remove_selection (0): %i\n", boolean);
-
- boolean = atk_text_remove_selection (cally_text, 1);
- g_print ("atk_text_remove_selection (1): %i\n", boolean);
-
- boolean = atk_text_add_selection (cally_text, 5, 10);
- g_print ("atk_text_add_selection: %i\n", boolean);
-
- 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);
- g_print ("atk_text_get_run_attributes: %i, %i\n", start, end);
- attrs = (GSList*) at_set;
- while (attrs)
- {
- AtkAttribute *at = (AtkAttribute *) attrs->data;
- g_print ("text run %s = %s\n", at->name, at->value);
- attrs = g_slist_next (attrs);
- }
-
- atk_text_get_character_extents (cally_text, 0, &x, &y, &width, &height,
- ATK_XY_WINDOW);
- g_print ("atk_text_get_character_extents (0, window): x=%i y=%i width=%i height=%i\n",
- x, y, width, height);
-
- atk_text_get_character_extents (cally_text, 0, &x, &y, &width, &height,
- ATK_XY_SCREEN);
- g_print ("atk_text_get_character_extents (0, screen): x=%i y=%i width=%i height=%i\n",
- x, y, width, height);
-
- pos = atk_text_get_offset_at_point (cally_text, 200, 10, ATK_XY_WINDOW);
- g_print ("atk_text_get_offset_at_point (200, 10, window): %i\n", pos);
-
- pos = atk_text_get_offset_at_point (cally_text, 200, 100, ATK_XY_SCREEN);
- g_print ("atk_text_get_offset_at_point (200, 100, screen): %i\n", pos);
-
-}
-
-static void
-dump_actor_default_atk_attributes (ClutterActor *actor)
-{
- AtkObject *object = NULL;
- AtkText *cally_text = NULL;
- AtkAttributeSet *at_set = NULL;
- GSList *attrs;
- const gchar *text_value = NULL;
-
- object = atk_gobject_accessible_for_object (G_OBJECT (actor));
- cally_text = ATK_TEXT (object);
-
- if (!cally_text)
- return;
-
- text_value = clutter_text_get_text (CLUTTER_TEXT (actor));
- g_print ("text value = %s\n", text_value);
-
- at_set = atk_text_get_default_attributes (cally_text);
- attrs = (GSList*) at_set;
- while (attrs) {
- AtkAttribute *at = (AtkAttribute *) attrs->data;
- g_print ("text default %s = %s\n", at->name, at->value);
- attrs = g_slist_next (attrs);
- }
-}
-
-static gboolean
-button_press_cb (ClutterActor *actor,
- ClutterButtonEvent *event,
- gpointer data)
-{
- test_atk_text (text_actor);
- test_atk_text (text_editable_actor);
-
- return TRUE;
-}
-
-static void
-make_ui (ClutterActor *stage)
-{
- ClutterColor color_stage = { 0x00, 0x00, 0x00, 0xff };
- ClutterColor color_text = { 0xff, 0x00, 0x00, 0xff };
- ClutterColor color_sel = { 0x00, 0xff, 0x00, 0x55 };
- ClutterColor color_rect = { 0x00, 0xff, 0xff, 0xff };
- ClutterColor color_label = { 0x00, 0x00, 0x00, 0xff };
- ClutterActor *button = NULL;
- ClutterActor *rectangle = NULL;
- ClutterActor *label = NULL;
-
- clutter_actor_set_background_color (CLUTTER_ACTOR (stage), &color_stage);
- clutter_actor_set_size (stage, WIDTH, HEIGHT);
-
- /* text */
- text_actor = clutter_text_new_full ("Sans Bold 32px",
- "",
- &color_text);
- clutter_text_set_markup (CLUTTER_TEXT(text_actor),
- "<span fgcolor=\"#FFFF00\" bgcolor=\"#00FF00\"><s>Lorem ipsum dolor sit amet</s></span>");
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), text_actor);
- dump_actor_default_atk_attributes (text_actor);
-
- /* text_editable */
- text_editable_actor = clutter_text_new_full ("Sans Bold 32px",
- "consectetur adipisicing elit",
- &color_text);
- clutter_actor_set_position (text_editable_actor, 20, 100);
- clutter_text_set_editable (CLUTTER_TEXT (text_editable_actor), TRUE);
- clutter_text_set_selectable (CLUTTER_TEXT (text_editable_actor), TRUE);
- clutter_text_set_selection_color (CLUTTER_TEXT (text_editable_actor),
- &color_sel);
- clutter_text_set_line_wrap (CLUTTER_TEXT (text_editable_actor), TRUE);
- clutter_actor_grab_key_focus (text_editable_actor);
- clutter_actor_set_reactive (text_editable_actor, TRUE);
- dump_actor_default_atk_attributes (text_editable_actor);
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), text_editable_actor);
-
- /* test button */
- button = clutter_actor_new ();
- rectangle = clutter_actor_new ();
- clutter_actor_set_background_color (rectangle, &color_rect);
- clutter_actor_set_size (rectangle, 75, 35);
-
- label = clutter_text_new_full ("Sans Bold 32px",
- "Test", &color_label);
- clutter_actor_set_position (button, 100, 200);
- clutter_container_add_actor (CLUTTER_CONTAINER (button), rectangle);
- clutter_container_add_actor (CLUTTER_CONTAINER (button), label);
- clutter_actor_set_reactive (button, TRUE);
-
- g_signal_connect_after (button, "button-press-event",
- G_CALLBACK (button_press_cb), NULL);
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), button);
-}
-
-int
-main (int argc, char *argv[])
-{
- ClutterActor *stage;
-
- g_set_application_name ("AtkText");
-
- cally_util_a11y_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Cally - AtkText Test");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- make_ui (stage);
-
- clutter_actor_show (stage);
-
- test_atk_text (text_actor);
- test_atk_text (text_editable_actor);
-
- clutter_test_main ();
-
- return 0;
-}
diff --git a/src/tests/clutter/accessibility/cally-clone-example.c b/src/tests/clutter/accessibility/cally-clone-example.c
deleted file mode 100644
index 0078a9855..000000000
--- a/src/tests/clutter/accessibility/cally-clone-example.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/* CALLY - The Clutter Accessibility Implementation Library
- *
- * Copyright (C) 2009 Igalia, S.L.
- *
- * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
- *
- * 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.
- */
-
-#include <atk/atk.h>
-#include <clutter/clutter.h>
-
-#include "cally-examples-util.h"
-
-#define WIDTH 800
-#define HEIGHT 600
-#define HEIGHT_STEP 100
-#define NUM_ENTRIES 3
-
-static void
-make_ui (ClutterActor *stage)
-{
- ClutterActor *editable = NULL;
- ClutterActor *rectangle = NULL;
- ClutterActor *label = NULL;
- ClutterColor color_stage = { 0x00, 0x00, 0x00, 0xff };
- ClutterColor color_text = { 0xff, 0x00, 0x00, 0xff };
- ClutterColor color_sel = { 0x00, 0xff, 0x00, 0x55 };
- ClutterColor color_label = { 0x00, 0xff, 0x55, 0xff };
- ClutterColor color_rect = { 0x00, 0xff, 0xff, 0x55 };
- ClutterActor *full_entry = NULL;
- ClutterActor *cloned_entry = NULL;
-
-
- clutter_actor_set_background_color (CLUTTER_ACTOR (stage), &color_stage);
- clutter_actor_set_size (stage, WIDTH, HEIGHT);
-
- label = clutter_text_new_full ("Sans Bold 32px",
- "Entry",
- &color_label);
- clutter_actor_set_position (label, 0, 50);
-
- /* editable */
- editable = clutter_text_new_full ("Sans Bold 32px",
- "ddd",
- &color_text);
- clutter_actor_set_position (editable, 150, 50);
- clutter_text_set_editable (CLUTTER_TEXT (editable), TRUE);
- clutter_text_set_selectable (CLUTTER_TEXT (editable), TRUE);
- clutter_text_set_selection_color (CLUTTER_TEXT (editable),
- &color_sel);
- clutter_actor_grab_key_focus (editable);
- clutter_actor_set_reactive (editable, TRUE);
-
- /* rectangle: to create a entry "feeling" */
- rectangle = clutter_actor_new ();
- clutter_actor_set_background_color (rectangle, &color_rect);
- clutter_actor_set_position (rectangle, 150, 50);
- clutter_actor_add_constraint (rectangle, clutter_bind_constraint_new (editable, CLUTTER_BIND_SIZE, 0));
-
- full_entry = clutter_actor_new ();
- clutter_actor_set_position (full_entry, 0, 50);
- clutter_actor_set_size (full_entry, 100, 75);
- clutter_container_add_actor (CLUTTER_CONTAINER (full_entry), label);
- clutter_container_add_actor (CLUTTER_CONTAINER (full_entry), editable);
- clutter_container_add_actor (CLUTTER_CONTAINER (full_entry), rectangle);
- clutter_actor_set_scale (full_entry, 2, 1);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), full_entry);
-
- /* Cloning! */
- cloned_entry = clutter_clone_new (full_entry);
- clutter_actor_set_position (cloned_entry, 50, 200);
- clutter_actor_set_scale (cloned_entry, 1, 2);
- clutter_actor_set_reactive (cloned_entry, TRUE);
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), cloned_entry);
-}
-
-int
-main (int argc, char *argv[])
-{
- ClutterActor *stage;
-
- g_set_application_name ("Clone Example");
-
- cally_util_a11y_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Cally - Clone Test");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- make_ui (stage);
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return 0;
-}
diff --git a/src/tests/clutter/accessibility/cally-examples-util.c b/src/tests/clutter/accessibility/cally-examples-util.c
deleted file mode 100644
index cf8dd8742..000000000
--- a/src/tests/clutter/accessibility/cally-examples-util.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/* CALLY - The Clutter Accessibility Implementation Library
- *
- * Copyright (C) 2009 Igalia, S.L.
- *
- * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
- *
- * 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.
- */
-
-
-#include <gmodule.h>
-#include <stdlib.h>
-
-#include <clutter/clutter.h>
-
-#include "cally-examples-util.h"
-
-/* Checking the at-spi sources, the module directory is
- * $(libdir)/gtk-2.0/modules
- *
- * It is supposed cally would be installed on the same libdir.
- *
- * You could use the option atk-bridge-dir to use other directory.
- */
-#define ATK_BRIDGE_DEFAULT_MODULE_DIRECTORY PREFIXDIR"/gtk-2.0/modules"
-
-static gchar *
-_search_for_bridge_module (const gchar *module_name)
-{
- /* We simplify the search for the atk bridge, see see the definition
- * of the macro for more information*/
- return g_strdup (ATK_BRIDGE_DEFAULT_MODULE_DIRECTORY);
-}
-
-static gchar*
-_a11y_check_custom_bridge (int *argc,
- char ***argv)
-{
- GError *error = NULL;
- GOptionContext *context;
- static gchar *bridge_dir = NULL;
- static GOptionEntry entries [] =
- {
- {"atk-bridge-dir", 'd', 0, G_OPTION_ARG_STRING, &bridge_dir, "atk-bridge module directory", NULL}
- };
-
- context = g_option_context_new ("- cally examples");
- g_option_context_add_main_entries (context, entries, NULL);
- if (!g_option_context_parse (context, argc, argv, &error))
- {
- g_print ("%s\n", error->message);
- g_print ("Use --help for more information.\n");
- exit (0);
- }
-
- return bridge_dir;
-}
-
-
-static gboolean
-_a11y_invoke_module (const gchar *module_path,
- gboolean init)
-{
- GModule *handle;
- void (*invoke_fn) (void);
- const char *method;
-
- if (init)
- method = "gnome_accessibility_module_init";
- else
- method = "gnome_accessibility_module_shutdown";
-
- if (!module_path)
- return FALSE;
-
- if (!(handle = g_module_open (module_path, G_MODULE_BIND_LAZY)))
- {
- g_warning ("Accessibility: failed to load module '%s': '%s'",
- module_path, g_module_error ());
-
- return FALSE;
- }
-
- if (!g_module_symbol (handle, method, (gpointer *)&invoke_fn))
- {
- g_warning ("Accessibility: error library '%s' does not include "
- "method '%s' required for accessibility support",
- module_path, method);
- g_module_close (handle);
-
- return FALSE;
- }
-
- g_debug ("Module %s loaded successfully", module_path);
- invoke_fn ();
-
- return TRUE;
-}
-
-/**
- * This method will initialize the accessibility support provided by cally.
- *
- * Basically it will load the cally module using gmodule functions.
- *
- * Returns if it was able to init the a11y support or not.
- */
-gboolean
-cally_util_a11y_init (int *argc, char ***argv)
-{
- gchar *bridge_dir = NULL;
- gchar *bridge_path = NULL;
- gboolean result = FALSE;
-
- clutter_test_init (argc, argv);
-
- if (clutter_get_accessibility_enabled () == FALSE)
- {
- g_warning ("Accessibility: clutter has no accessibility enabled"
- " skipping the atk-bridge load");
- return FALSE;
- }
-
- bridge_dir = _a11y_check_custom_bridge (argc, argv);
- if (bridge_dir == NULL)
- bridge_dir = _search_for_bridge_module ("atk-bridge");
-
- bridge_path = g_module_build_path (bridge_dir, "libatk-bridge");
-
- result = _a11y_invoke_module (bridge_path, TRUE);
-
- g_free (bridge_dir);
- g_free (bridge_path);
-
- return result;
-}
diff --git a/src/tests/clutter/accessibility/cally-examples-util.h b/src/tests/clutter/accessibility/cally-examples-util.h
deleted file mode 100644
index ea7d2c0b2..000000000
--- a/src/tests/clutter/accessibility/cally-examples-util.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* CALLY - The Clutter Accessibility Implementation Library
- *
- * Copyright (C) 2009 Igalia, S.L.
- *
- * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
- *
- * 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.
- */
-
-#include "tests/clutter-test-utils.h"
-
-gboolean
-cally_util_a11y_init (int *argc, char ***argv);
diff --git a/src/tests/clutter/accessibility/meson.build b/src/tests/clutter/accessibility/meson.build
deleted file mode 100644
index ce6361b59..000000000
--- a/src/tests/clutter/accessibility/meson.build
+++ /dev/null
@@ -1,39 +0,0 @@
-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',
- '-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()),
-]
-
-clutter_test_accessibility_c_args += clutter_debug_c_args
-
-clutter_accessibility_tests_dependencies = [
- libmutter_test_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',
- clutter_test_utils,
- ],
- include_directories: clutter_includes,
- c_args: clutter_test_accessibility_c_args,
- dependencies: [clutter_accessibility_tests_dependencies],
- install: false,
- )
-endforeach
diff --git a/src/tests/clutter/clutter-1.0.suppressions b/src/tests/clutter/clutter-1.0.suppressions
deleted file mode 100644
index b7f82ab30..000000000
--- a/src/tests/clutter/clutter-1.0.suppressions
+++ /dev/null
@@ -1,165 +0,0 @@
-{
- ioctl_1
- Memcheck:Param
- ioctl(generic)
- fun:ioctl
- fun:driDrawableInitVBlank
- fun:intelMakeCurrent
- fun:glXMakeContextCurrent
-}
-
-{
- ioctl_2
- Memcheck:Param
- ioctl(generic)
- fun:ioctl
- fun:driDrawableGetMSC32
- fun:clutter_backend_glx_redraw
-}
-
-{
- ioctl_3
- Memcheck:Param
- ioctl(generic)
- fun:ioctl
- fun:driWaitForMSC32
- fun:clutter_backend_glx_redraw
-}
-
-{
- mesa_init_context
- Memcheck:Leak
- fun:*alloc
- ...
- fun:glXCreateNewContext
-}
-
-{
- type_register
- Memcheck:Leak
- fun:*alloc
- ...
- fun:g_type_register_*
-}
-
-{
- type_ref
- Memcheck:Leak
- fun:*alloc
- ...
- fun:g_type_class_ref
-}
-
-{
- type_interface_prereq
- Memcheck:Leak
- fun:*alloc
- ...
- fun:g_type_interface_add_prerequisite
-}
-
-{
- get_charset
- Memcheck:Leak
- fun:*alloc
- ...
- fun:g_get_charset
-}
-
-{
- glx_query_version
- Memcheck:Leak
- fun:*alloc
- ...
- fun:glXQueryVersion
-}
-
-{
- glx_create_context
- Memcheck:Leak
- fun:*alloc
- ...
- fun:glXCreateNewContext
-}
-
-{
- glx_make_current
- Memcheck:Leak
- fun:*alloc
- ...
- fun:glXMakeContextCurrent
-}
-
-{
- gl_draw_arrays
- Memcheck:Leak
- fun:*malloc
- ...
- fun:glDrawArrays
-}
-
-{
- cogl_clear
- Memcheck:Leak
- fun:*alloc
- ...
- fun:cogl_clear
-}
-
-{
- default_font
- Memcheck:Leak
- fun:*alloc
- ...
- fun:clutter_backend_get_font_name
-}
-
-{
- id_pool
- Memcheck:Leak
- fun:*alloc
- ...
- fun:clutter_id_pool_new
-}
-
-{
- x_open_display
- Memcheck:Leak
- fun:*alloc
- ...
- fun:XOpenDisplay
-}
-
-# ... and font descriptions from every "sans 12" type string
-{
- pango_font_description_from_string
- Memcheck:Leak
- fun:*alloc
- ...
- fun:pango_font_description_from_string
-}
-
-# other lib init
-{
- fontconfig_init
- Memcheck:Leak
- fun:*alloc
- ...
- fun:FcConfigParseAndLoad
-}
-
-{
- freetype_init
- Memcheck:Leak
- fun:*alloc
- ...
- fun:FT_Open_Face
-}
-
-{
- x_init_ext
- Memcheck:Leak
- fun:*alloc
- ...
- fun:XInitExtension
-}
diff --git a/src/tests/clutter/conform/actor-clone.c b/src/tests/clutter/conform/actor-clone.c
deleted file mode 100644
index 582ddbbf3..000000000
--- a/src/tests/clutter/conform/actor-clone.c
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-static void
-on_presented (ClutterStage *stage,
- ClutterStageView *view,
- 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/src/tests/clutter/conform/actor-destroy.c b/src/tests/clutter/conform/actor-destroy.c
deleted file mode 100644
index eebcacc47..000000000
--- a/src/tests/clutter/conform/actor-destroy.c
+++ /dev/null
@@ -1,200 +0,0 @@
-#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))
-
-typedef struct _TestDestroy TestDestroy;
-typedef struct _TestDestroyClass TestDestroyClass;
-
-struct _TestDestroy
-{
- ClutterActor parent_instance;
-
- ClutterActor *bg;
- ClutterActor *label;
-
- GList *children;
-};
-
-struct _TestDestroyClass
-{
- ClutterActorClass parent_class;
-};
-
-static void clutter_container_init (ClutterContainerIface *iface);
-
-GType test_destroy_get_type (void);
-
-G_DEFINE_TYPE_WITH_CODE (TestDestroy, test_destroy, CLUTTER_TYPE_ACTOR,
- G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
- clutter_container_init));
-
-static void
-test_destroy_add (ClutterContainer *container,
- ClutterActor *actor)
-{
- TestDestroy *self = TEST_DESTROY (container);
-
- if (!g_test_quiet ())
- g_print ("Adding '%s' (type:%s)\n",
- clutter_actor_get_name (actor),
- G_OBJECT_TYPE_NAME (actor));
-
- self->children = g_list_prepend (self->children, actor);
- clutter_actor_add_child (CLUTTER_ACTOR (container), actor);
-}
-
-static void
-test_destroy_remove (ClutterContainer *container,
- ClutterActor *actor)
-{
- TestDestroy *self = TEST_DESTROY (container);
-
- if (!g_test_quiet ())
- g_print ("Removing '%s' (type:%s)\n",
- clutter_actor_get_name (actor),
- G_OBJECT_TYPE_NAME (actor));
-
- g_assert_true (g_list_find (self->children, actor));
- self->children = g_list_remove (self->children, actor);
-
- clutter_actor_remove_child (CLUTTER_ACTOR (container), actor);
-}
-
-static void
-clutter_container_init (ClutterContainerIface *iface)
-{
- iface->add = test_destroy_add;
- iface->remove = test_destroy_remove;
-}
-
-static void
-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_quiet ())
- g_print ("Destroying '%s' (type:%s)\n",
- clutter_actor_get_name (test->bg),
- G_OBJECT_TYPE_NAME (test->bg));
-
- clutter_actor_destroy (test->bg);
- test->bg = NULL;
- }
-
- if (test->label != NULL)
- {
- if (!g_test_quiet ())
- g_print ("Destroying '%s' (type:%s)\n",
- clutter_actor_get_name (test->label),
- G_OBJECT_TYPE_NAME (test->label));
-
- clutter_actor_destroy (test->label);
- test->label = 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
-test_destroy_class_init (TestDestroyClass *klass)
-{
- ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
-
- actor_class->destroy = test_destroy_destroy;
-}
-
-static void
-test_destroy_init (TestDestroy *self)
-{
- self->bg = clutter_actor_new ();
- clutter_container_add_actor (CLUTTER_CONTAINER (self), self->bg);
- clutter_actor_set_name (self->bg, "Background");
-
- self->label = clutter_text_new ();
- clutter_container_add_actor (CLUTTER_CONTAINER (self), self->label);
- clutter_actor_set_name (self->label, "Label");
-}
-
-static void
-on_destroy (ClutterActor *actor,
- gpointer data)
-{
- 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_actor_new ();
- gboolean destroy_called = FALSE;
- gboolean parent_set_called = FALSE;
- gboolean property_changed = FALSE;
-
- g_object_ref_sink (test);
-
- g_object_add_weak_pointer (G_OBJECT (test), (gpointer *) &test);
- g_object_add_weak_pointer (G_OBJECT (child), (gpointer *) &child);
-
- if (!g_test_quiet ())
- g_print ("Adding external child...\n");
-
- 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_quiet ())
- g_print ("Calling destroy()...\n");
-
- 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);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/actor/destruction", actor_destruction)
-)
diff --git a/src/tests/clutter/conform/actor-graph.c b/src/tests/clutter/conform/actor-graph.c
deleted file mode 100644
index 06255ebe8..000000000
--- a/src/tests/clutter/conform/actor-graph.c
+++ /dev/null
@@ -1,552 +0,0 @@
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-static void
-actor_add_child (void)
-{
- ClutterActor *actor = clutter_actor_new ();
- ClutterActor *iter;
-
- g_object_ref_sink (actor);
- g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
-
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "foo",
- NULL));
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "bar",
- NULL));
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "baz",
- NULL));
-
- g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 3);
-
- iter = clutter_actor_get_first_child (actor);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
-
- iter = clutter_actor_get_next_sibling (iter);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
-
- iter = clutter_actor_get_next_sibling (iter);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "baz");
- g_assert (iter == clutter_actor_get_last_child (actor));
- g_assert (clutter_actor_get_next_sibling (iter) == NULL);
-
- iter = clutter_actor_get_last_child (actor);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "baz");
-
- iter = clutter_actor_get_previous_sibling (iter);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
-
- iter = clutter_actor_get_previous_sibling (iter);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
- g_assert (iter == clutter_actor_get_first_child (actor));
- g_assert (clutter_actor_get_previous_sibling (iter) == NULL);
-
- clutter_actor_destroy (actor);
- g_assert (actor == NULL);
-}
-
-static void
-actor_insert_child (void)
-{
- ClutterActor *actor = clutter_actor_new ();
- ClutterActor *iter;
-
- g_object_ref_sink (actor);
- g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
-
- clutter_actor_insert_child_at_index (actor,
- g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "foo",
- NULL),
- 0);
-
- iter = clutter_actor_get_first_child (actor);
- g_assert (iter != NULL);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
- g_assert (iter == clutter_actor_get_child_at_index (actor, 0));
-
- clutter_actor_insert_child_below (actor,
- g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "bar",
- NULL),
- iter);
-
- g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 2);
-
- iter = clutter_actor_get_first_child (actor);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
- iter = clutter_actor_get_next_sibling (iter);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
- g_assert (iter == clutter_actor_get_child_at_index (actor, 1));
-
- iter = clutter_actor_get_first_child (actor);
- clutter_actor_insert_child_above (actor,
- g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "baz",
- NULL),
- iter);
-
- iter = clutter_actor_get_last_child (actor);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
-
- iter = clutter_actor_get_previous_sibling (iter);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "baz");
-
- iter = clutter_actor_get_previous_sibling (iter);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
-
- clutter_actor_remove_all_children (actor);
-
- clutter_actor_insert_child_at_index (actor,
- g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "1",
- NULL),
- 0);
- iter = clutter_actor_get_child_at_index (actor, 0);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "1");
- g_assert (clutter_actor_get_first_child (actor) == iter);
- g_assert (clutter_actor_get_last_child (actor) == iter);
-
- clutter_actor_insert_child_at_index (actor,
- g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "2",
- NULL),
- 0);
- iter = clutter_actor_get_child_at_index (actor, 0);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "2");
- g_assert (clutter_actor_get_first_child (actor) == iter);
- iter = clutter_actor_get_child_at_index (actor, 1);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "1");
- g_assert (clutter_actor_get_last_child (actor) == iter);
-
- clutter_actor_insert_child_at_index (actor,
- g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "3",
- NULL),
- -1);
- iter = clutter_actor_get_child_at_index (actor, 2);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "3");
- g_assert (clutter_actor_get_last_child (actor) == iter);
-
- clutter_actor_destroy (actor);
- g_assert (actor == NULL);
-}
-
-static void
-actor_remove_child (void)
-{
- ClutterActor *actor = clutter_actor_new ();
- ClutterActor *iter;
-
- g_object_ref_sink (actor);
- g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
-
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "foo",
- NULL));
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "bar",
- NULL));
-
- g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 2);
-
- g_assert (clutter_actor_get_first_child (actor) != clutter_actor_get_last_child (actor));
-
- iter = clutter_actor_get_first_child (actor);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
-
- iter = clutter_actor_get_last_child (actor);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
-
- clutter_actor_remove_child (actor, clutter_actor_get_first_child (actor));
-
- g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 1);
-
- iter = clutter_actor_get_first_child (actor);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
- g_assert (clutter_actor_get_first_child (actor) == clutter_actor_get_last_child (actor));
-
- clutter_actor_remove_child (actor, clutter_actor_get_first_child (actor));
-
- g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 0);
- g_assert (clutter_actor_get_first_child (actor) == NULL);
- g_assert (clutter_actor_get_last_child (actor) == NULL);
-
- clutter_actor_destroy (actor);
- g_assert (actor == NULL);
-}
-
-static void
-actor_raise_child (void)
-{
- ClutterActor *actor = clutter_actor_new ();
- ClutterActor *iter;
- gboolean show_on_set_parent;
-
- g_object_ref_sink (actor);
- g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
-
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "foo",
- "visible", FALSE,
- NULL));
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "bar",
- "visible", FALSE,
- NULL));
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "baz",
- "visible", FALSE,
- NULL));
-
- g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 3);
-
- iter = clutter_actor_get_child_at_index (actor, 1);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
-
- clutter_actor_set_child_above_sibling (actor, iter,
- clutter_actor_get_child_at_index (actor, 2));
-
- g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 0)),
- ==,
- "foo");
- g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 1)),
- ==,
- "baz");
- g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 2)),
- ==,
- "bar");
- g_assert (!clutter_actor_is_visible (iter));
- g_object_get (iter, "show-on-set-parent", &show_on_set_parent, NULL);
- g_assert (!show_on_set_parent);
-
- iter = clutter_actor_get_child_at_index (actor, 0);
- clutter_actor_set_child_above_sibling (actor, iter, NULL);
- g_object_add_weak_pointer (G_OBJECT (iter), (gpointer *) &iter);
-
- g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 0)),
- ==,
- "baz");
- g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 1)),
- ==,
- "bar");
- g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 2)),
- ==,
- "foo");
- g_assert (!clutter_actor_is_visible (iter));
- g_object_get (iter, "show-on-set-parent", &show_on_set_parent, NULL);
- g_assert (!show_on_set_parent);
-
- clutter_actor_destroy (actor);
- g_assert (actor == NULL);
- g_assert (iter == NULL);
-}
-
-static void
-actor_lower_child (void)
-{
- ClutterActor *actor = clutter_actor_new ();
- ClutterActor *iter;
- gboolean show_on_set_parent;
-
- g_object_ref_sink (actor);
- g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
-
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "foo",
- "visible", FALSE,
- NULL));
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "bar",
- "visible", FALSE,
- NULL));
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "baz",
- "visible", FALSE,
- NULL));
-
- g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 3);
-
- iter = clutter_actor_get_child_at_index (actor, 1);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
-
- clutter_actor_set_child_below_sibling (actor, iter,
- clutter_actor_get_child_at_index (actor, 0));
-
- g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 0)),
- ==,
- "bar");
- g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 1)),
- ==,
- "foo");
- g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 2)),
- ==,
- "baz");
- g_assert (!clutter_actor_is_visible (iter));
- g_object_get (iter, "show-on-set-parent", &show_on_set_parent, NULL);
- g_assert (!show_on_set_parent);
-
- iter = clutter_actor_get_child_at_index (actor, 2);
- clutter_actor_set_child_below_sibling (actor, iter, NULL);
-
- g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 0)),
- ==,
- "baz");
- g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 1)),
- ==,
- "bar");
- g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 2)),
- ==,
- "foo");
- g_assert (!clutter_actor_is_visible (iter));
- g_object_get (iter, "show-on-set-parent", &show_on_set_parent, NULL);
- g_assert (!show_on_set_parent);
-
- clutter_actor_destroy (actor);
- g_assert (actor == NULL);
-}
-
-static void
-actor_replace_child (void)
-{
- ClutterActor *actor = clutter_actor_new ();
- ClutterActor *iter;
-
- g_object_ref_sink (actor);
- g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
-
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "foo",
- NULL));
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "bar",
- NULL));
-
- iter = clutter_actor_get_child_at_index (actor, 0);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
-
- clutter_actor_replace_child (actor, iter,
- g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "baz",
- NULL));
-
- iter = clutter_actor_get_child_at_index (actor, 0);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "baz");
-
- iter = clutter_actor_get_child_at_index (actor, 1);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
-
- clutter_actor_replace_child (actor, iter,
- g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "qux",
- NULL));
-
- iter = clutter_actor_get_child_at_index (actor, 0);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "baz");
-
- iter = clutter_actor_get_child_at_index (actor, 1);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "qux");
-
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "foo",
- NULL));
-
- clutter_actor_replace_child (actor, iter,
- g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "bar",
- NULL));
-
- iter = clutter_actor_get_last_child (actor);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
- iter = clutter_actor_get_previous_sibling (iter);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
- iter = clutter_actor_get_previous_sibling (iter);
- g_assert_cmpstr (clutter_actor_get_name (iter), ==, "baz");
-
- clutter_actor_destroy (actor);
- g_assert (actor == NULL);
-}
-
-static void
-actor_remove_all (void)
-{
- ClutterActor *actor = clutter_actor_new ();
-
- g_object_ref_sink (actor);
- g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
-
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "foo",
- NULL));
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "bar",
- NULL));
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "baz",
- NULL));
-
- g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 3);
-
- clutter_actor_remove_all_children (actor);
-
- g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 0);
-
- clutter_actor_destroy (actor);
- g_assert (actor == NULL);
-}
-
-static void
-actor_added (ClutterContainer *container,
- ClutterActor *child,
- gpointer data)
-{
- ClutterActor *actor = CLUTTER_ACTOR (container);
- int *counter = data;
- ClutterActor *old_child;
-
- if (!g_test_quiet ())
- g_print ("Adding actor '%s'\n", clutter_actor_get_name (child));
-
- old_child = clutter_actor_get_child_at_index (actor, 0);
- if (old_child != child)
- clutter_actor_remove_child (actor, old_child);
-
- *counter += 1;
-}
-
-static void
-actor_removed (ClutterContainer *container,
- ClutterActor *child,
- gpointer data)
-{
- int *counter = data;
-
- if (!g_test_quiet ())
- g_print ("Removing actor '%s'\n", clutter_actor_get_name (child));
-
- *counter += 1;
-}
-
-static void
-actor_container_signals (void)
-{
- ClutterActor *actor = clutter_actor_new ();
- int add_count, remove_count;
-
- g_object_ref_sink (actor);
- g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
-
- add_count = remove_count = 0;
- g_signal_connect (actor,
- "actor-added", G_CALLBACK (actor_added),
- &add_count);
- g_signal_connect (actor,
- "actor-removed", G_CALLBACK (actor_removed),
- &remove_count);
-
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "foo",
- NULL));
-
- g_assert_cmpint (add_count, ==, 1);
- g_assert_cmpint (remove_count, ==, 0);
- g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 1);
-
- clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
- "name", "bar",
- NULL));
-
- g_assert_cmpint (add_count, ==, 2);
- g_assert_cmpint (remove_count, ==, 1);
- g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 1);
-
- g_signal_handlers_disconnect_by_func (actor, G_CALLBACK (actor_added),
- &add_count);
- g_signal_handlers_disconnect_by_func (actor, G_CALLBACK (actor_removed),
- &remove_count);
-
- clutter_actor_destroy (actor);
- g_assert (actor == NULL);
-}
-
-static void
-actor_contains (void)
-{
- /* This build up the following tree:
- *
- * a
- * ╱ │ ╲
- * ╱ │ ╲
- * b c d
- * ╱ ╲ ╱ ╲ ╱ ╲
- * e f g h i j
- */
- struct {
- ClutterActor *actor_a, *actor_b, *actor_c, *actor_d, *actor_e;
- ClutterActor *actor_f, *actor_g, *actor_h, *actor_i, *actor_j;
- } d;
- int x, y;
- ClutterActor **actor_array = &d.actor_a;
-
- /* Matrix of expected results */
- static const gboolean expected_results[] =
- { /* a, b, c, d, e, f, g, h, i, j */
- /* a */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* b */ 0, 1, 0, 0, 1, 1, 0, 0, 0, 0,
- /* c */ 0, 0, 1, 0, 0, 0, 1, 1, 0, 0,
- /* d */ 0, 0, 0, 1, 0, 0, 0, 0, 1, 1,
- /* e */ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
- /* f */ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- /* g */ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- /* h */ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- /* i */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- /* j */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
- };
-
- d.actor_a = clutter_actor_new ();
- d.actor_b = clutter_actor_new ();
- d.actor_c = clutter_actor_new ();
- d.actor_d = clutter_actor_new ();
- d.actor_e = clutter_actor_new ();
- d.actor_f = clutter_actor_new ();
- d.actor_g = clutter_actor_new ();
- d.actor_h = clutter_actor_new ();
- d.actor_i = clutter_actor_new ();
- d.actor_j = clutter_actor_new ();
-
- clutter_actor_add_child (d.actor_a, d.actor_b);
- clutter_actor_add_child (d.actor_a, d.actor_c);
- clutter_actor_add_child (d.actor_a, d.actor_d);
-
- clutter_actor_add_child (d.actor_b, d.actor_e);
- clutter_actor_add_child (d.actor_b, d.actor_f);
-
- clutter_actor_add_child (d.actor_c, d.actor_g);
- clutter_actor_add_child (d.actor_c, d.actor_h);
-
- clutter_actor_add_child (d.actor_d, d.actor_i);
- clutter_actor_add_child (d.actor_d, d.actor_j);
-
- for (y = 0; y < 10; y++)
- for (x = 0; x < 10; x++)
- g_assert_cmpint (clutter_actor_contains (actor_array[x],
- actor_array[y]),
- ==,
- expected_results[x * 10 + y]);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/actor/graph/add-child", actor_add_child)
- CLUTTER_TEST_UNIT ("/actor/graph/insert-child", actor_insert_child)
- CLUTTER_TEST_UNIT ("/actor/graph/remove-child", actor_remove_child)
- CLUTTER_TEST_UNIT ("/actor/graph/raise-child", actor_raise_child)
- CLUTTER_TEST_UNIT ("/actor/graph/lower-child", actor_lower_child)
- CLUTTER_TEST_UNIT ("/actor/graph/replace-child", actor_replace_child)
- CLUTTER_TEST_UNIT ("/actor/graph/remove-all", actor_remove_all)
- CLUTTER_TEST_UNIT ("/actor/graph/container-signals", actor_container_signals)
- CLUTTER_TEST_UNIT ("/actor/graph/contains", actor_contains)
-)
diff --git a/src/tests/clutter/conform/actor-invariants.c b/src/tests/clutter/conform/actor-invariants.c
deleted file mode 100644
index 652bdcfa7..000000000
--- a/src/tests/clutter/conform/actor-invariants.c
+++ /dev/null
@@ -1,368 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-
-#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-static void
-actor_initial_state (void)
-{
- ClutterActor *actor;
-
- actor = clutter_actor_new ();
- g_object_ref_sink (actor);
- g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
-
- if (!g_test_quiet ())
- g_print ("initial state - visible: %s, realized: %s, mapped: %s\n",
- CLUTTER_ACTOR_IS_VISIBLE (actor) ? "yes" : "no",
- CLUTTER_ACTOR_IS_REALIZED (actor) ? "yes" : "no",
- CLUTTER_ACTOR_IS_MAPPED (actor) ? "yes" : "no");
-
- g_assert (!(CLUTTER_ACTOR_IS_REALIZED (actor)));
- g_assert (!(CLUTTER_ACTOR_IS_MAPPED (actor)));
- g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (actor)));
-
- clutter_actor_destroy (actor);
- g_assert (actor == NULL);
-}
-
-static void
-actor_shown_not_parented (void)
-{
- ClutterActor *actor;
-
- actor = clutter_actor_new ();
- g_object_ref_sink (actor);
- g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
-
- clutter_actor_show (actor);
-
- if (!g_test_quiet ())
- g_print ("show without a parent - visible: %s, realized: %s, mapped: %s\n",
- CLUTTER_ACTOR_IS_VISIBLE (actor) ? "yes" : "no",
- CLUTTER_ACTOR_IS_REALIZED (actor) ? "yes" : "no",
- CLUTTER_ACTOR_IS_MAPPED (actor) ? "yes" : "no");
-
- g_assert (!CLUTTER_ACTOR_IS_REALIZED (actor));
- g_assert (!CLUTTER_ACTOR_IS_MAPPED (actor));
- g_assert (CLUTTER_ACTOR_IS_VISIBLE (actor));
-
- clutter_actor_destroy (actor);
- g_assert (actor == NULL);
-}
-
-static void
-actor_realized (void)
-{
- ClutterActor *actor;
- ClutterActor *stage;
-
- stage = clutter_test_get_stage ();
-
- actor = clutter_actor_new ();
-
- g_assert (!(CLUTTER_ACTOR_IS_REALIZED (actor)));
-
- clutter_actor_hide (actor); /* don't show, so won't map */
- clutter_actor_add_child (stage, actor);
- clutter_actor_realize (actor);
-
- g_assert (CLUTTER_ACTOR_IS_REALIZED (actor));
-
- g_assert (!(CLUTTER_ACTOR_IS_MAPPED (actor)));
- g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (actor)));
-
- clutter_actor_destroy (actor);
-}
-
-static void
-actor_mapped (void)
-{
- ClutterActor *actor;
- ClutterActor *stage;
-
- stage = clutter_test_get_stage ();
- clutter_actor_show (stage);
-
- actor = clutter_actor_new ();
-
- g_assert (!(CLUTTER_ACTOR_IS_REALIZED (actor)));
- g_assert (!(CLUTTER_ACTOR_IS_MAPPED (actor)));
-
- clutter_actor_add_child (stage, actor);
-
- if (!g_test_quiet ())
- g_print ("adding to a container should map - "
- "visible: %s, realized: %s, mapped: %s\n",
- CLUTTER_ACTOR_IS_VISIBLE (actor) ? "yes" : "no",
- CLUTTER_ACTOR_IS_REALIZED (actor) ? "yes" : "no",
- CLUTTER_ACTOR_IS_MAPPED (actor) ? "yes" : "no");
-
- g_assert (CLUTTER_ACTOR_IS_REALIZED (actor));
- g_assert (CLUTTER_ACTOR_IS_MAPPED (actor));
- g_assert (CLUTTER_ACTOR_IS_VISIBLE (actor));
-
- clutter_actor_hide (actor);
-
- if (!g_test_quiet ())
- g_print ("hiding should unmap - "
- "visible: %s, realized: %s, mapped: %s\n",
- CLUTTER_ACTOR_IS_VISIBLE (actor) ? "yes" : "no",
- CLUTTER_ACTOR_IS_REALIZED (actor) ? "yes" : "no",
- CLUTTER_ACTOR_IS_MAPPED (actor) ? "yes" : "no");
-
- g_assert (CLUTTER_ACTOR_IS_REALIZED (actor));
- g_assert (!CLUTTER_ACTOR_IS_MAPPED (actor));
- g_assert (!CLUTTER_ACTOR_IS_VISIBLE (actor));
-
- clutter_actor_destroy (actor);
-}
-
-static void
-actor_visibility_not_recursive (void)
-{
- ClutterActor *actor, *group;
- ClutterActor *stage;
-
- stage = clutter_test_get_stage ();
-
- group = clutter_actor_new ();
- actor = clutter_actor_new ();
-
- clutter_actor_hide (group); /* don't show, so won't map */
- clutter_actor_hide (actor); /* don't show, so won't map */
-
- g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (stage)));
- g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (group)));
- g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (actor)));
-
- clutter_actor_add_child (stage, group);
- clutter_actor_add_child (group, actor);
-
- clutter_actor_show (actor);
- g_assert (CLUTTER_ACTOR_IS_VISIBLE (actor));
- g_assert (!CLUTTER_ACTOR_IS_VISIBLE (group));
- g_assert (!CLUTTER_ACTOR_IS_VISIBLE (stage));
-
- clutter_actor_show (stage);
- g_assert (CLUTTER_ACTOR_IS_VISIBLE (actor));
- g_assert (!CLUTTER_ACTOR_IS_VISIBLE (group));
- g_assert (CLUTTER_ACTOR_IS_VISIBLE (stage));
-
- clutter_actor_hide (actor);
- clutter_actor_hide (group);
- clutter_actor_hide (stage);
- g_assert (!CLUTTER_ACTOR_IS_VISIBLE (actor));
-
- clutter_actor_show (stage);
- g_assert (!CLUTTER_ACTOR_IS_VISIBLE (actor));
-
- clutter_actor_destroy (actor);
- clutter_actor_destroy (group);
-}
-
-static void
-actor_realize_not_recursive (void)
-{
- ClutterActor *actor, *group;
- ClutterActor *stage;
-
- stage = clutter_test_get_stage ();
- clutter_actor_show (stage);
-
- group = clutter_actor_new ();
-
- actor = clutter_actor_new ();
-
- clutter_actor_hide (group); /* don't show, so won't map */
- clutter_actor_hide (actor); /* don't show, so won't map */
-
- g_assert (!(CLUTTER_ACTOR_IS_REALIZED (group)));
- g_assert (!(CLUTTER_ACTOR_IS_REALIZED (actor)));
-
- clutter_actor_add_child (stage, group);
- clutter_actor_add_child (group, actor);
-
- clutter_actor_realize (group);
-
- g_assert (CLUTTER_ACTOR_IS_REALIZED (group));
-
- g_assert (!(CLUTTER_ACTOR_IS_MAPPED (group)));
- g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (group)));
-
- /* realizing group did not realize the child */
- g_assert (!CLUTTER_ACTOR_IS_REALIZED (actor));
- g_assert (!(CLUTTER_ACTOR_IS_MAPPED (actor)));
- g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (actor)));
-
- clutter_actor_destroy (actor);
- clutter_actor_destroy (group);
-}
-
-static void
-actor_map_recursive (void)
-{
- ClutterActor *actor, *group;
- ClutterActor *stage;
-
- stage = clutter_test_get_stage ();
- clutter_actor_show (stage);
-
- group = clutter_actor_new ();
-
- actor = clutter_actor_new ();
-
- clutter_actor_hide (group); /* hide at first */
- clutter_actor_show (actor); /* show at first */
-
- g_assert (!(CLUTTER_ACTOR_IS_REALIZED (group)));
- g_assert (!(CLUTTER_ACTOR_IS_REALIZED (actor)));
- g_assert (!(CLUTTER_ACTOR_IS_MAPPED (group)));
- g_assert (!(CLUTTER_ACTOR_IS_MAPPED (actor)));
- g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (group)));
- g_assert ((CLUTTER_ACTOR_IS_VISIBLE (actor)));
-
- clutter_actor_add_child (stage, group);
- clutter_actor_add_child (group, actor);
-
- g_assert (!(CLUTTER_ACTOR_IS_REALIZED (group)));
- g_assert (!(CLUTTER_ACTOR_IS_REALIZED (actor)));
- g_assert (!(CLUTTER_ACTOR_IS_MAPPED (group)));
- g_assert (!(CLUTTER_ACTOR_IS_MAPPED (actor)));
- g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (group)));
- g_assert ((CLUTTER_ACTOR_IS_VISIBLE (actor)));
-
- /* show group, which should map and realize both
- * group and child.
- */
- clutter_actor_show (group);
- g_assert (CLUTTER_ACTOR_IS_REALIZED (group));
- g_assert (CLUTTER_ACTOR_IS_REALIZED (actor));
- g_assert (CLUTTER_ACTOR_IS_MAPPED (group));
- g_assert (CLUTTER_ACTOR_IS_MAPPED (actor));
- g_assert (CLUTTER_ACTOR_IS_VISIBLE (group));
- g_assert (CLUTTER_ACTOR_IS_VISIBLE (actor));
-
- clutter_actor_destroy (actor);
- clutter_actor_destroy (group);
-}
-
-static void
-actor_show_on_set_parent (void)
-{
- ClutterActor *actor, *group;
- gboolean show_on_set_parent;
- ClutterActor *stage;
-
- stage = clutter_test_get_stage ();
-
- group = clutter_actor_new ();
-
- g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (group)));
-
- clutter_actor_add_child (stage, group);
-
- actor = clutter_actor_new ();
- g_object_get (actor,
- "show-on-set-parent", &show_on_set_parent,
- NULL);
-
- g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (actor)));
- g_assert (show_on_set_parent);
-
- clutter_actor_add_child (group, actor);
- g_object_get (actor,
- "show-on-set-parent", &show_on_set_parent,
- NULL);
-
- g_assert (CLUTTER_ACTOR_IS_VISIBLE (actor));
- g_assert (show_on_set_parent);
-
- g_object_ref (actor);
- clutter_actor_remove_child (group, actor);
- g_object_get (actor,
- "show-on-set-parent", &show_on_set_parent,
- NULL);
-
- g_assert (!CLUTTER_ACTOR_IS_REALIZED (actor));
- g_assert (!CLUTTER_ACTOR_IS_MAPPED (actor));
- g_assert (CLUTTER_ACTOR_IS_VISIBLE (actor));
- g_assert (show_on_set_parent);
-
- clutter_actor_destroy (actor);
- clutter_actor_destroy (group);
-
- actor = clutter_actor_new ();
- clutter_actor_add_child (stage, actor);
- clutter_actor_hide (actor);
- g_object_get (actor,
- "show-on-set-parent", &show_on_set_parent,
- NULL);
- g_assert (!CLUTTER_ACTOR_IS_VISIBLE (actor));
- g_assert (!CLUTTER_ACTOR_IS_MAPPED (actor));
- g_assert (show_on_set_parent);
-
- clutter_actor_destroy (actor);
-
- actor = clutter_actor_new ();
- clutter_actor_hide (actor);
- clutter_actor_add_child (stage, actor);
- g_object_get (actor,
- "show-on-set-parent", &show_on_set_parent,
- NULL);
- g_assert (!CLUTTER_ACTOR_IS_VISIBLE (actor));
- g_assert (!CLUTTER_ACTOR_IS_MAPPED (actor));
- g_assert (!show_on_set_parent);
-
- clutter_actor_destroy (actor);
-}
-
-static void
-clone_no_map (void)
-{
- ClutterActor *stage;
- ClutterActor *group;
- ClutterActor *actor;
- ClutterActor *clone;
-
- stage = clutter_test_get_stage ();
- clutter_actor_show (stage);
-
- group = clutter_actor_new ();
- actor = clutter_actor_new ();
-
- clutter_actor_hide (group);
-
- clutter_actor_add_child (group, actor);
- clutter_actor_add_child (stage, group);
-
- g_assert (!(CLUTTER_ACTOR_IS_MAPPED (group)));
- g_assert (!(CLUTTER_ACTOR_IS_MAPPED (actor)));
-
- clone = clutter_clone_new (group);
-
- clutter_actor_add_child (stage, clone);
-
- g_assert (CLUTTER_ACTOR_IS_MAPPED (clone));
- g_assert (!(CLUTTER_ACTOR_IS_MAPPED (group)));
- g_assert (!(CLUTTER_ACTOR_IS_MAPPED (actor)));
-
- clutter_actor_destroy (actor);
- clutter_actor_destroy (CLUTTER_ACTOR (clone));
- clutter_actor_destroy (CLUTTER_ACTOR (group));
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/actor/invariants/initial-state", actor_initial_state)
- CLUTTER_TEST_UNIT ("/actor/invariants/show-not-parented", actor_shown_not_parented)
- CLUTTER_TEST_UNIT ("/actor/invariants/realized", actor_realized)
- CLUTTER_TEST_UNIT ("/actor/invariants/mapped", actor_mapped)
- CLUTTER_TEST_UNIT ("/actor/invariants/visibility-not-recursive", actor_visibility_not_recursive)
- CLUTTER_TEST_UNIT ("/actor/invariants/realize-not-recursive", actor_realize_not_recursive)
- CLUTTER_TEST_UNIT ("/actor/invariants/map-recursive", actor_map_recursive)
- CLUTTER_TEST_UNIT ("/actor/invariants/show-on-set-parent", actor_show_on_set_parent)
- CLUTTER_TEST_UNIT ("/actor/invariants/clone-no-map", clone_no_map)
-)
diff --git a/src/tests/clutter/conform/actor-iter.c b/src/tests/clutter/conform/actor-iter.c
deleted file mode 100644
index 06a7812d9..000000000
--- a/src/tests/clutter/conform/actor-iter.c
+++ /dev/null
@@ -1,220 +0,0 @@
-#include <glib.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-static void
-actor_iter_traverse_children (void)
-{
- ClutterActorIter iter;
- ClutterActor *actor;
- ClutterActor *child;
- int i, n_actors;
-
- actor = clutter_actor_new ();
- clutter_actor_set_name (actor, "root");
- g_object_ref_sink (actor);
-
- n_actors = g_random_int_range (10, 50);
- for (i = 0; i < n_actors; i++)
- {
- char *name;
-
- name = g_strdup_printf ("actor%d", i);
- child = clutter_actor_new ();
- clutter_actor_set_name (child, name);
-
- clutter_actor_add_child (actor, child);
-
- g_free (name);
- }
-
- g_assert_cmpint (clutter_actor_get_n_children (actor), ==, n_actors);
-
- i = 0;
- clutter_actor_iter_init (&iter, actor);
- g_assert (clutter_actor_iter_is_valid (&iter));
-
- while (clutter_actor_iter_next (&iter, &child))
- {
- g_assert (CLUTTER_IS_ACTOR (child));
- g_assert (clutter_actor_get_parent (child) == actor);
-
- if (!g_test_quiet ())
- g_print ("actor %d = '%s'\n", i, clutter_actor_get_name (child));
-
- if (i == 0)
- g_assert (child == clutter_actor_get_first_child (actor));
-
- if (i == (n_actors - 1))
- g_assert (child == clutter_actor_get_last_child (actor));
-
- i += 1;
- }
-
- g_assert_cmpint (i, ==, n_actors);
-
- i = 0;
- clutter_actor_iter_init (&iter, actor);
- g_assert (clutter_actor_iter_is_valid (&iter));
-
- while (clutter_actor_iter_prev (&iter, &child))
- {
- g_assert (CLUTTER_IS_ACTOR (child));
- g_assert (clutter_actor_get_parent (child) == actor);
-
- if (!g_test_quiet ())
- g_print ("actor %d = '%s'\n", i, clutter_actor_get_name (child));
-
- if (i == 0)
- g_assert (child == clutter_actor_get_last_child (actor));
-
- if (i == (n_actors - 1))
- g_assert (child == clutter_actor_get_first_child (actor));
-
- i += 1;
- }
-
- g_object_unref (actor);
-}
-
-static void
-actor_iter_traverse_remove (void)
-{
- ClutterActorIter iter;
- ClutterActor *actor;
- ClutterActor *child;
- int i, n_actors;
-
- actor = clutter_actor_new ();
- clutter_actor_set_name (actor, "root");
- g_object_ref_sink (actor);
-
- n_actors = g_random_int_range (10, 50);
- for (i = 0; i < n_actors; i++)
- {
- char *name;
-
- name = g_strdup_printf ("actor%d", i);
- child = clutter_actor_new ();
- clutter_actor_set_name (child, name);
-
- clutter_actor_add_child (actor, child);
-
- g_free (name);
- }
-
- g_assert_cmpint (clutter_actor_get_n_children (actor), ==, n_actors);
-
- i = 0;
- clutter_actor_iter_init (&iter, actor);
- g_assert (clutter_actor_iter_is_valid (&iter));
-
- while (clutter_actor_iter_next (&iter, &child))
- {
- g_assert (CLUTTER_IS_ACTOR (child));
- g_assert (clutter_actor_get_parent (child) == actor);
-
- if (!g_test_quiet ())
- g_print ("actor %d = '%s'\n", i, clutter_actor_get_name (child));
-
- if (i == 0)
- g_assert (child == clutter_actor_get_first_child (actor));
-
- if (i == (n_actors - 1))
- g_assert (child == clutter_actor_get_last_child (actor));
-
- clutter_actor_iter_remove (&iter);
- g_assert (clutter_actor_iter_is_valid (&iter));
-
- i += 1;
- }
-
- g_assert_cmpint (i, ==, n_actors);
- g_assert_cmpint (0, ==, clutter_actor_get_n_children (actor));
-}
-
-static void
-actor_iter_assignment (void)
-{
- ClutterActorIter iter_a, iter_b;
- ClutterActor *actor;
- ClutterActor *child;
- int i, n_actors;
-
- actor = clutter_actor_new ();
- clutter_actor_set_name (actor, "root");
- g_object_ref_sink (actor);
-
- n_actors = g_random_int_range (10, 50);
- for (i = 0; i < n_actors; i++)
- {
- char *name;
-
- name = g_strdup_printf ("actor[%02d]", i);
- child = clutter_actor_new ();
- clutter_actor_set_name (child, name);
-
- clutter_actor_add_child (actor, child);
-
- g_free (name);
- }
-
- g_assert_cmpint (clutter_actor_get_n_children (actor), ==, n_actors);
-
- i = 0;
-
- clutter_actor_iter_init (&iter_a, actor);
-
- iter_b = iter_a;
-
- g_assert (clutter_actor_iter_is_valid (&iter_a));
- g_assert (clutter_actor_iter_is_valid (&iter_b));
-
- while (clutter_actor_iter_next (&iter_a, &child))
- {
- g_assert (CLUTTER_IS_ACTOR (child));
- g_assert (clutter_actor_get_parent (child) == actor);
-
- if (!g_test_quiet ())
- g_print ("actor %2d = '%s'\n", i, clutter_actor_get_name (child));
-
- if (i == 0)
- g_assert (child == clutter_actor_get_first_child (actor));
-
- if (i == (n_actors - 1))
- g_assert (child == clutter_actor_get_last_child (actor));
-
- i += 1;
- }
-
- g_assert_cmpint (i, ==, n_actors);
-
- i = n_actors - 1;
-
- while (clutter_actor_iter_prev (&iter_b, &child))
- {
- g_assert (clutter_actor_get_parent (child) == actor);
-
- if (!g_test_quiet ())
- g_print ("actor %2d = '%s'\n", i, clutter_actor_get_name (child));
-
- if (i == n_actors - 1)
- g_assert (child == clutter_actor_get_last_child (actor));
-
- if (i == 0)
- g_assert (child == clutter_actor_get_first_child (actor));
-
- i -= 1;
- }
-
- g_assert_cmpint (i, ==, -1);
-
- g_object_unref (actor);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/actor/iter/traverse-children", actor_iter_traverse_children)
- CLUTTER_TEST_UNIT ("/actor/iter/traverse-remove", actor_iter_traverse_remove)
- CLUTTER_TEST_UNIT ("/actor/iter/assignment", actor_iter_assignment)
-)
diff --git a/src/tests/clutter/conform/actor-layout.c b/src/tests/clutter/conform/actor-layout.c
deleted file mode 100644
index 9af90f55a..000000000
--- a/src/tests/clutter/conform/actor-layout.c
+++ /dev/null
@@ -1,98 +0,0 @@
-#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];
- graphene_point_t p;
-
- vase = clutter_actor_new ();
- clutter_actor_set_name (vase, "Vase");
- clutter_actor_set_layout_manager (vase, clutter_flow_layout_new (CLUTTER_FLOW_HORIZONTAL));
- clutter_actor_add_child (stage, vase);
-
- flower[0] = clutter_actor_new ();
- clutter_actor_set_background_color (flower[0], CLUTTER_COLOR_Red);
- clutter_actor_set_size (flower[0], 100, 100);
- clutter_actor_set_name (flower[0], "Red Flower");
- clutter_actor_add_child (vase, flower[0]);
-
- flower[1] = clutter_actor_new ();
- clutter_actor_set_background_color (flower[1], CLUTTER_COLOR_Yellow);
- clutter_actor_set_size (flower[1], 100, 100);
- clutter_actor_set_name (flower[1], "Yellow Flower");
- clutter_actor_add_child (vase, flower[1]);
-
- flower[2] = clutter_actor_new ();
- clutter_actor_set_background_color (flower[2], CLUTTER_COLOR_Green);
- clutter_actor_set_size (flower[2], 100, 100);
- clutter_actor_set_name (flower[2], "Green Flower");
- clutter_actor_add_child (vase, flower[2]);
-
- graphene_point_init (&p, 50, 50);
- clutter_test_assert_actor_at_point (stage, &p, flower[0]);
-
- graphene_point_init (&p, 150, 50);
- clutter_test_assert_actor_at_point (stage, &p, flower[1]);
-
- graphene_point_init (&p, 250, 50);
- clutter_test_assert_actor_at_point (stage, &p, flower[2]);
-
- clutter_actor_destroy (vase);
-}
-
-static void
-actor_margin_layout (void)
-{
- ClutterActor *stage = clutter_test_get_stage ();
- ClutterActor *vase;
- ClutterActor *flower[3];
- graphene_point_t p;
-
- vase = clutter_actor_new ();
- clutter_actor_set_name (vase, "Vase");
- clutter_actor_set_layout_manager (vase, clutter_box_layout_new ());
- clutter_actor_add_child (stage, vase);
-
- flower[0] = clutter_actor_new ();
- clutter_actor_set_background_color (flower[0], CLUTTER_COLOR_Red);
- clutter_actor_set_size (flower[0], 100, 100);
- clutter_actor_set_name (flower[0], "Red Flower");
- clutter_actor_add_child (vase, flower[0]);
-
- flower[1] = clutter_actor_new ();
- clutter_actor_set_background_color (flower[1], CLUTTER_COLOR_Yellow);
- clutter_actor_set_size (flower[1], 100, 100);
- clutter_actor_set_name (flower[1], "Yellow Flower");
- clutter_actor_set_margin_right (flower[1], 6);
- clutter_actor_set_margin_left (flower[1], 6);
- clutter_actor_add_child (vase, flower[1]);
-
- flower[2] = clutter_actor_new ();
- clutter_actor_set_background_color (flower[2], CLUTTER_COLOR_Green);
- clutter_actor_set_size (flower[2], 100, 100);
- clutter_actor_set_name (flower[2], "Green Flower");
- clutter_actor_set_margin_top (flower[2], 6);
- clutter_actor_set_margin_bottom (flower[2], 6);
- clutter_actor_add_child (vase, flower[2]);
-
- graphene_point_init (&p, 0, 7);
- clutter_test_assert_actor_at_point (stage, &p, flower[0]);
-
- graphene_point_init (&p, 106, 50);
- clutter_test_assert_actor_at_point (stage, &p, flower[1]);
-
- graphene_point_init (&p, 212, 7);
- clutter_test_assert_actor_at_point (stage, &p, flower[2]);
-
- clutter_actor_destroy (vase);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/actor/layout/basic", actor_basic_layout)
- CLUTTER_TEST_UNIT ("/actor/layout/margin", actor_margin_layout)
-)
diff --git a/src/tests/clutter/conform/actor-meta.c b/src/tests/clutter/conform/actor-meta.c
deleted file mode 100644
index 0211f99ae..000000000
--- a/src/tests/clutter/conform/actor-meta.c
+++ /dev/null
@@ -1,42 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-static void
-actor_meta_clear (void)
-{
- ClutterActor *actor, *stage;
-
- stage = clutter_test_get_stage ();
-
- actor = clutter_actor_new ();
- g_object_ref_sink (actor);
- g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
-
- clutter_actor_add_action (actor, clutter_click_action_new ());
- clutter_actor_add_constraint (actor, clutter_bind_constraint_new (stage, CLUTTER_BIND_ALL, 0));
- clutter_actor_add_effect (actor, clutter_blur_effect_new ());
-
- g_assert (clutter_actor_has_actions (actor));
- g_assert (clutter_actor_has_constraints (actor));
- g_assert (clutter_actor_has_effects (actor));
-
- clutter_actor_clear_actions (actor);
- g_assert (!clutter_actor_has_actions (actor));
-
- clutter_actor_clear_constraints (actor);
- g_assert (!clutter_actor_has_constraints (actor));
-
- clutter_actor_clear_effects (actor);
- g_assert (!clutter_actor_has_effects (actor));
-
- clutter_actor_destroy (actor);
- g_assert (actor == NULL);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/actor/meta/clear", actor_meta_clear)
-)
diff --git a/src/tests/clutter/conform/actor-offscreen-redirect.c b/src/tests/clutter/conform/actor-offscreen-redirect.c
deleted file mode 100644
index d7088beda..000000000
--- a/src/tests/clutter/conform/actor-offscreen-redirect.c
+++ /dev/null
@@ -1,452 +0,0 @@
-#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-typedef struct _FooActor FooActor;
-typedef struct _FooActorClass FooActorClass;
-
-struct _FooActorClass
-{
- ClutterActorClass parent_class;
-};
-
-struct _FooActor
-{
- ClutterActor parent;
-
- guint8 last_paint_opacity;
- int paint_count;
-};
-
-typedef struct
-{
- ClutterActor *stage;
- FooActor *foo_actor;
- ClutterActor *parent_container;
- ClutterActor *container;
- ClutterActor *child;
- ClutterActor *unrelated_actor;
- gboolean was_painted;
-} Data;
-
-GType foo_actor_get_type (void) G_GNUC_CONST;
-
-G_DEFINE_TYPE (FooActor, foo_actor, CLUTTER_TYPE_ACTOR);
-
-static gboolean group_has_overlaps;
-
-static void
-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++;
-
- clutter_actor_get_allocation_box (actor, &allocation);
-
- /* Paint a red rectangle with the right opacity */
- 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
-foo_actor_get_paint_volume (ClutterActor *actor,
- ClutterPaintVolume *volume)
-{
- return clutter_paint_volume_set_from_allocation (volume, actor);
-}
-
-static gboolean
-foo_actor_has_overlaps (ClutterActor *actor)
-{
- return FALSE;
-}
-
-static void
-foo_actor_class_init (FooActorClass *klass)
-{
- ClutterActorClass *actor_class = (ClutterActorClass *) klass;
-
- actor_class->paint = foo_actor_paint;
- actor_class->get_paint_volume = foo_actor_get_paint_volume;
- actor_class->has_overlaps = foo_actor_has_overlaps;
-}
-
-static void
-foo_actor_init (FooActor *self)
-{
-}
-
-typedef struct _FooGroup FooGroup;
-typedef struct _FooGroupClass FooGroupClass;
-
-struct _FooGroupClass
-{
- ClutterActorClass parent_class;
-};
-
-struct _FooGroup
-{
- ClutterActor parent;
-};
-
-GType foo_group_get_type (void);
-
-G_DEFINE_TYPE (FooGroup, foo_group, CLUTTER_TYPE_ACTOR)
-
-static gboolean
-foo_group_has_overlaps (ClutterActor *actor)
-{
- return group_has_overlaps;
-}
-
-static void
-foo_group_class_init (FooGroupClass *klass)
-{
- ClutterActorClass *actor_class = (ClutterActorClass *) klass;
-
- actor_class->has_overlaps = foo_group_has_overlaps;
-}
-
-static void
-foo_group_init (FooGroup *self)
-{
-}
-
-static void
-verify_results (Data *data,
- guint8 expected_color_red,
- guint8 expected_color_green,
- guint8 expected_color_blue,
- int expected_paint_count,
- int expected_paint_opacity)
-{
- guchar *pixel;
-
- data->foo_actor->paint_count = 0;
-
- /* Read a pixel at the center of the to determine what color it
- painted. This should cause a redraw */
- pixel = clutter_stage_read_pixels (CLUTTER_STAGE (data->stage),
- 50, 50, /* x/y */
- 1, 1 /* width/height */);
-
- g_assert_cmpint (expected_paint_count, ==, data->foo_actor->paint_count);
- g_assert_cmpint (expected_paint_opacity,
- ==,
- data->foo_actor->last_paint_opacity);
-
- g_assert_cmpint (ABS ((int) expected_color_red - (int) pixel[0]), <=, 2);
- g_assert_cmpint (ABS ((int) expected_color_green - (int) pixel[1]), <=, 2);
- g_assert_cmpint (ABS ((int) expected_color_blue - (int) pixel[2]), <=, 2);
-
- g_free (pixel);
-}
-
-static void
-verify_redraw (Data *data, int expected_paint_count)
-{
- GMainLoop *main_loop = g_main_loop_new (NULL, TRUE);
- gulong paint_handler;
-
- paint_handler = g_signal_connect_data (CLUTTER_STAGE (data->stage),
- "after-paint",
- G_CALLBACK (g_main_loop_quit),
- main_loop,
- NULL,
- G_CONNECT_SWAPPED);
-
- /* Queue a redraw on the stage */
- clutter_actor_queue_redraw (data->stage);
-
- data->foo_actor->paint_count = 0;
-
- /* Wait for it to paint */
- g_main_loop_run (main_loop);
-
- g_clear_signal_handler (&paint_handler, data->stage);
-
- g_assert_cmpint (data->foo_actor->paint_count, ==, expected_paint_count);
-}
-
-static gboolean
-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);
-
- /* Queueing a redraw on a child should cause a redraw */
- clutter_actor_queue_redraw (data->child);
- verify_redraw (data, 1);
-
- /* 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_translation (data->parent_container, 0.f, -1.f, 0.f);
- verify_redraw (data, 0);
-
- /* Redrawing an unrelated actor shouldn't cause a redraw */
- clutter_actor_set_position (data->unrelated_actor, 0, 1);
- verify_redraw (data, 0);
-
- data->was_painted = TRUE;
-
- return G_SOURCE_REMOVE;
-}
-
-static gboolean
-run_verify (gpointer user_data)
-{
- Data *data = user_data;
- int i;
-
- group_has_overlaps = FALSE;
-
- /* By default the actor shouldn't be redirected so the redraw should
- cause the actor to be painted */
- verify_results (data,
- 255, 0, 0,
- 1,
- 255);
-
- /* Make the actor semi-transparent and verify the paint opacity */
- clutter_actor_set_opacity (data->container, 127);
- verify_results (data,
- 255, 127, 127,
- 1,
- 127);
-
- /* With automatic redirect for opacity it shouldn't redirect if
- * has_overlaps returns FALSE; */
- clutter_actor_set_offscreen_redirect
- (data->container, CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY);
- verify_results (data,
- 255, 127, 127,
- 1,
- 127);
-
- /* We do a double check here to verify that the actor wasn't cached
- * during the last check. If it was cached then this check wouldn't
- * result in any foo-actor re-paint. */
- verify_results (data,
- 255, 127, 127,
- 1,
- 127);
-
- /* With automatic redirect for opacity it should redirect if
- * has_overlaps returns TRUE.
- * The first paint will still cause the actor to draw because
- * it needs to fill the cache first. It should be painted with full
- * opacity */
- group_has_overlaps = TRUE;
-
- verify_results (data,
- 255, 127, 127,
- 1,
- 255);
-
- /* The second time the actor is painted it should be cached */
- verify_results (data,
- 255, 127, 127,
- 0,
- 255);
-
- /* We should be able to change the opacity without causing the actor
- to redraw */
- clutter_actor_set_opacity (data->container, 64);
- verify_results (data,
- 255, 191, 191,
- 0,
- 255);
-
- /* Changing it back to fully opaque should cause it not to go
- through the FBO so it will draw */
- clutter_actor_set_opacity (data->container, 255);
- verify_results (data,
- 255, 0, 0,
- 1,
- 255);
-
- /* Tell it to always redirect through the FBO. This should cause a
- paint of the actor because the last draw didn't go through the
- FBO */
- clutter_actor_set_offscreen_redirect (data->container,
- CLUTTER_OFFSCREEN_REDIRECT_ALWAYS);
- verify_results (data,
- 255, 0, 0,
- 1,
- 255);
-
- /* We should be able to change the opacity without causing the actor
- to redraw */
- clutter_actor_set_opacity (data->container, 64);
- verify_results (data,
- 255, 191, 191,
- 0,
- 255);
-
- /* Even changing it back to fully opaque shouldn't cause a redraw */
- clutter_actor_set_opacity (data->container, 255);
- verify_results (data,
- 255, 0, 0,
- 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);
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-actor_offscreen_redirect (void)
-{
- Data data = { 0 };
-
- 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);
-
- clutter_actor_add_child (data.container, CLUTTER_ACTOR (data.foo_actor));
- clutter_actor_add_child (data.parent_container, data.container);
- clutter_actor_add_child (data.stage, data.parent_container);
-
- data.child = clutter_actor_new ();
- clutter_actor_set_size (data.child, 1, 1);
- clutter_actor_add_child (data.container, data.child);
-
- data.unrelated_actor = clutter_actor_new ();
- clutter_actor_set_size (data.child, 1, 1);
- clutter_actor_add_child (data.stage, data.unrelated_actor);
-
- clutter_actor_show (data.stage);
-
- clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
- run_verify,
- &data,
- NULL);
-
- while (!data.was_painted)
- g_main_context_iteration (NULL, FALSE);
-
- clutter_actor_destroy (data.parent_container);
- clutter_actor_destroy (data.unrelated_actor);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/actor/offscreen/redirect", actor_offscreen_redirect)
-)
diff --git a/src/tests/clutter/conform/actor-paint-opacity.c b/src/tests/clutter/conform/actor-paint-opacity.c
deleted file mode 100644
index f73a8f0f7..000000000
--- a/src/tests/clutter/conform/actor-paint-opacity.c
+++ /dev/null
@@ -1,151 +0,0 @@
-#include <clutter/clutter.h>
-#include <stdlib.h>
-
-#include "tests/clutter-test-utils.h"
-
-static void
-opacity_label (void)
-{
- ClutterActor *stage;
- ClutterActor *label;
- ClutterColor label_color = { 255, 0, 0, 128 };
- ClutterColor color_check = { 0, };
-
- stage = clutter_test_get_stage ();
-
- label = clutter_text_new_with_text ("Sans 18px", "Label, 50% opacity");
- clutter_text_set_color (CLUTTER_TEXT (label), &label_color);
-
- if (!g_test_quiet ())
- g_print ("label 50%%.get_color()/1\n");
- clutter_text_get_color (CLUTTER_TEXT (label), &color_check);
- g_assert (color_check.alpha == label_color.alpha);
-
- clutter_actor_add_child (stage, label);
- clutter_actor_set_position (label, 10, 10);
-
- if (!g_test_quiet ())
- g_print ("label 50%%.get_color()/2\n");
- clutter_text_get_color (CLUTTER_TEXT (label), &color_check);
- g_assert (color_check.alpha == label_color.alpha);
-
- if (!g_test_quiet ())
- g_print ("label 50%%.get_paint_opacity()/1\n");
- g_assert (clutter_actor_get_paint_opacity (label) == 255);
-
- if (!g_test_quiet ())
- g_print ("label 50%%.get_paint_opacity()/2\n");
- clutter_actor_set_opacity (label, 128);
- g_assert (clutter_actor_get_paint_opacity (label) == 128);
-
- clutter_actor_destroy (label);
-}
-
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-static void
-opacity_rectangle (void)
-{
- ClutterActor *stage;
- ClutterActor *rect;
- ClutterColor rect_color = { 0, 0, 255, 255 };
- ClutterColor color_check = { 0, };
-
- stage = clutter_test_get_stage ();
-
- rect = clutter_actor_new ();
- clutter_actor_set_background_color (rect, &rect_color);
- clutter_actor_set_size (rect, 128, 128);
- clutter_actor_set_position (rect, 150, 90);
-
- if (!g_test_quiet ())
- g_print ("rect 100%%.get_color()/1\n");
- clutter_actor_get_background_color (rect, &color_check);
- g_assert (color_check.alpha == rect_color.alpha);
-
- clutter_actor_add_child (stage, rect);
-
- if (!g_test_quiet ())
- g_print ("rect 100%%.get_color()/2\n");
- clutter_actor_set_background_color (rect, &color_check);
- g_assert (color_check.alpha == rect_color.alpha);
-
- if (!g_test_quiet ())
- g_print ("rect 100%%.get_paint_opacity()\n");
- g_assert (clutter_actor_get_paint_opacity (rect) == 255);
-
- clutter_actor_destroy (rect);
-}
-G_GNUC_END_IGNORE_DEPRECATIONS
-
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-static void
-opacity_paint (void)
-{
- ClutterActor *stage, *group1, *group2;
- ClutterActor *label, *rect;
- ClutterColor label_color = { 255, 0, 0, 128 };
- ClutterColor rect_color = { 0, 0, 255, 255 };
- ClutterColor color_check = { 0, };
-
- stage = clutter_test_get_stage ();
-
- group1 = clutter_actor_new ();
- clutter_actor_set_opacity (group1, 128);
- clutter_container_add (CLUTTER_CONTAINER (stage), group1, NULL);
- clutter_actor_set_position (group1, 10, 30);
- clutter_actor_show (group1);
-
- label = clutter_text_new_with_text ("Sans 18px", "Label+Group, 25% opacity");
- clutter_text_set_color (CLUTTER_TEXT (label), &label_color);
-
- if (!g_test_quiet ())
- g_print ("label 50%% + group 50%%.get_color()/1\n");
- clutter_text_get_color (CLUTTER_TEXT (label), &color_check);
- g_assert (color_check.alpha == label_color.alpha);
-
- clutter_container_add (CLUTTER_CONTAINER (group1), label, NULL);
-
- if (!g_test_quiet ())
- g_print ("label 50%% + group 50%%.get_color()/2\n");
- clutter_text_get_color (CLUTTER_TEXT (label), &color_check);
- g_assert (color_check.alpha == label_color.alpha);
-
- if (!g_test_quiet ())
- g_print ("label 50%% + group 50%%.get_paint_opacity() = 128\n");
- g_assert (clutter_actor_get_paint_opacity (label) == 128);
-
- clutter_actor_destroy (label);
-
- group2 = clutter_actor_new ();
- clutter_container_add (CLUTTER_CONTAINER (group1), group2, NULL);
- clutter_actor_set_position (group2, 10, 60);
-
- rect = clutter_actor_new ();
- clutter_actor_set_background_color (rect, &rect_color);
- clutter_actor_set_size (rect, 128, 128);
-
- if (!g_test_quiet ())
- g_print ("rect 100%% + group 100%% + group 50%%.get_color()/1\n");
- clutter_actor_get_background_color (rect, &color_check);
- g_assert (color_check.alpha == rect_color.alpha);
-
- clutter_container_add (CLUTTER_CONTAINER (group2), rect, NULL);
-
- if (!g_test_quiet ())
- g_print ("rect 100%% + group 100%% + group 50%%.get_color()/2\n");
- clutter_actor_get_background_color (rect, &color_check);
- g_assert (color_check.alpha == rect_color.alpha);
-
- if (!g_test_quiet ())
- g_print ("rect 100%%.get_paint_opacity()\n");
- g_assert (clutter_actor_get_paint_opacity (rect) == 128);
-
- clutter_actor_destroy (group1);
-}
-G_GNUC_END_IGNORE_DEPRECATIONS
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/actor/opacity/text", opacity_label)
- CLUTTER_TEST_UNIT ("/actor/opacity/rectangle", opacity_rectangle)
- CLUTTER_TEST_UNIT ("/actor/opacity/paint", opacity_paint)
-)
diff --git a/src/tests/clutter/conform/actor-pick.c b/src/tests/clutter/conform/actor-pick.c
deleted file mode 100644
index 011acec4a..000000000
--- a/src/tests/clutter/conform/actor-pick.c
+++ /dev/null
@@ -1,231 +0,0 @@
-#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
-
-typedef struct _State State;
-
-struct _State
-{
- ClutterActor *stage;
- int y, x;
- ClutterActor *actors[ACTORS_X * ACTORS_Y];
- guint actor_width, actor_height;
- guint failed_pass;
- guint failed_idx;
- gboolean pass;
- GList *actor_list;
-};
-
-static const char *test_passes[] = {
- "No covering actor",
- "Invisible covering actor",
- "Clipped covering actor",
- "Blur effect",
-};
-
-static gboolean
-on_timeout (gpointer data)
-{
- State *state = data;
- int test_num = 0;
- int y, x;
- ClutterActor *over_actor = NULL;
-
- /* This will cause an unclipped pick redraw that will get buffered.
- We'll check below that this buffer is discarded because we also need
- to pick non-reactive actors */
- clutter_stage_get_actor_at_pos (CLUTTER_STAGE (state->stage),
- CLUTTER_PICK_REACTIVE, 10, 10);
-
- clutter_stage_get_actor_at_pos (CLUTTER_STAGE (state->stage),
- CLUTTER_PICK_REACTIVE, 10, 10);
-
- for (test_num = 0; test_num < G_N_ELEMENTS (test_passes); test_num++)
- {
- if (test_num == 0)
- {
- if (!g_test_quiet ())
- g_print ("No covering actor:\n");
- }
- if (test_num == 1)
- {
- static const ClutterColor red = { 0xff, 0x00, 0x00, 0xff };
- /* Create an actor that covers the whole stage but that
- isn't visible so it shouldn't affect the picking */
- over_actor = clutter_actor_new ();
- clutter_actor_set_background_color (over_actor, &red);
- clutter_actor_set_size (over_actor, STAGE_WIDTH, STAGE_HEIGHT);
- clutter_actor_add_child (state->stage, over_actor);
- state->actor_list = g_list_prepend (state->actor_list, over_actor);
- clutter_actor_hide (over_actor);
-
- if (!g_test_quiet ())
- g_print ("Invisible covering actor:\n");
- }
- 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);
- clutter_actor_set_clip (over_actor,
- state->actor_width * 2,
- state->actor_height * 2,
- 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);
-
- if (!g_test_quiet ())
- g_print ("Clipped covering actor:\n");
- }
- else if (test_num == 3)
- {
- if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
- continue;
-
- clutter_actor_hide (over_actor);
-
- clutter_actor_add_effect_with_name (CLUTTER_ACTOR (state->stage),
- "blur",
- clutter_blur_effect_new ());
-
- if (!g_test_quiet ())
- g_print ("With blur effect:\n");
- }
-
- for (y = 0; y < ACTORS_Y; y++)
- {
- x = 0;
-
- for (; x < ACTORS_X; x++)
- {
- gboolean pass = FALSE;
- gfloat pick_x;
- ClutterActor *actor;
-
- pick_x = x * state->actor_width + state->actor_width / 2;
-
- actor =
- clutter_stage_get_actor_at_pos (CLUTTER_STAGE (state->stage),
- CLUTTER_PICK_ALL,
- pick_x,
- y * state->actor_height
- + state->actor_height / 2);
-
- if (!g_test_quiet ())
- g_print ("% 3i,% 3i / %p -> ",
- x, y, state->actors[y * ACTORS_X + x]);
-
- if (actor == NULL)
- {
- if (!g_test_quiet ())
- g_print ("NULL: FAIL\n");
- }
- else if (actor == over_actor)
- {
- if (test_num == 2
- && x >= 2 && x < ACTORS_X - 2
- && y >= 2 && y < ACTORS_Y - 2)
- pass = TRUE;
-
- if (!g_test_quiet ())
- g_print ("over_actor: %s\n", pass ? "pass" : "FAIL");
- }
- else
- {
- if (actor == state->actors[y * ACTORS_X + x]
- && (test_num != 2
- || x < 2 || x >= ACTORS_X - 2
- || y < 2 || y >= ACTORS_Y - 2))
- pass = TRUE;
-
- if (!g_test_quiet ())
- g_print ("%p: %s\n", actor, pass ? "pass" : "FAIL");
- }
-
- if (!pass)
- {
- state->failed_pass = test_num;
- state->failed_idx = y * ACTORS_X + x;
- state->pass = FALSE;
- }
- }
- }
- }
-
- clutter_test_quit ();
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-actor_pick (void)
-{
- int y, x;
- State state = { 0 };
-
- state.pass = TRUE;
-
- state.stage = clutter_test_get_stage ();
-
- state.actor_width = STAGE_WIDTH / ACTORS_X;
- state.actor_height = STAGE_HEIGHT / ACTORS_Y;
-
- 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_actor_new ();
- state.actor_list = g_list_prepend (state.actor_list, rect);
-
- clutter_actor_set_background_color (rect, &color);
- clutter_actor_set_position (rect,
- x * state.actor_width,
- y * state.actor_height);
- clutter_actor_set_size (rect,
- state.actor_width,
- state.actor_height);
-
- clutter_actor_add_child (state.stage, rect);
-
- state.actors[y * ACTORS_X + x] = rect;
- }
-
- clutter_actor_show (state.stage);
-
- clutter_threads_add_idle (on_timeout, &state);
-
- clutter_test_main ();
-
- if (!g_test_quiet ())
- {
- if (!state.pass)
- g_test_message ("Failed pass: %s[%d], actor index: %d [%p]\n",
- test_passes[state.failed_pass],
- state.failed_pass,
- state.failed_idx,
- state.actors[state.failed_idx]);
- }
-
- g_assert (state.pass);
-
- g_list_free_full (state.actor_list, (GDestroyNotify) clutter_actor_destroy);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/actor/pick", actor_pick)
-)
diff --git a/src/tests/clutter/conform/actor-pivot-point.c b/src/tests/clutter/conform/actor-pivot-point.c
deleted file mode 100644
index 6a5cdf22c..000000000
--- a/src/tests/clutter/conform/actor-pivot-point.c
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-
-#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-static void
-actor_pivot (void)
-{
- ClutterActor *stage, *actor_implicit, *actor_explicit;
- graphene_matrix_t transform, result_implicit, result_explicit;
- ClutterActorBox allocation = CLUTTER_ACTOR_BOX_INIT (0, 0, 90, 30);
- gfloat angle = 30;
-
- stage = clutter_test_get_stage ();
-
- actor_implicit = clutter_actor_new ();
- actor_explicit = clutter_actor_new ();
-
- clutter_actor_add_child (stage, actor_implicit);
- clutter_actor_add_child (stage, actor_explicit);
-
- clutter_actor_show (stage);
-
- /* Fake allocation or pivot-point will not have any effect */
- clutter_actor_allocate (actor_implicit, &allocation);
- clutter_actor_allocate (actor_explicit, &allocation);
-
- clutter_actor_set_pivot_point (actor_implicit, 0.5, 0.5);
- clutter_actor_set_pivot_point (actor_explicit, 0.5, 0.5);
-
- /* Implicit transformation */
- clutter_actor_set_rotation_angle (actor_implicit, CLUTTER_Z_AXIS, angle);
-
- /* Explicit transformation */
- graphene_matrix_init_rotate (&transform, angle, graphene_vec3_z_axis ());
- clutter_actor_set_transform (actor_explicit, &transform);
-
- clutter_actor_get_transform (actor_implicit, &result_implicit);
- clutter_actor_get_transform (actor_explicit, &result_explicit);
-
- g_assert (graphene_matrix_equal (&result_implicit, &result_explicit));
-
- clutter_actor_destroy (actor_implicit);
- clutter_actor_destroy (actor_explicit);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/actor/transforms/pivot-point", actor_pivot)
-)
diff --git a/src/tests/clutter/conform/actor-shader-effect.c b/src/tests/clutter/conform/actor-shader-effect.c
deleted file mode 100644
index a22ae5f99..000000000
--- a/src/tests/clutter/conform/actor-shader-effect.c
+++ /dev/null
@@ -1,301 +0,0 @@
-#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
- ****************************************************************/
-
-static const gchar
-old_shader_effect_source[] =
- "uniform vec3 override_color;\n"
- "\n"
- "void\n"
- "main ()\n"
- "{\n"
- " cogl_color_out = vec4 (override_color, 1.0);\n"
- "}";
-
-typedef struct _FooOldShaderEffectClass
-{
- ClutterShaderEffectClass parent_class;
-} FooOldShaderEffectClass;
-
-typedef struct _FooOldShaderEffect
-{
- ClutterShaderEffect parent;
-} FooOldShaderEffect;
-
-GType foo_old_shader_effect_get_type (void);
-
-G_DEFINE_TYPE (FooOldShaderEffect,
- foo_old_shader_effect,
- CLUTTER_TYPE_SHADER_EFFECT);
-
-static void
-foo_old_shader_effect_paint_target (ClutterOffscreenEffect *effect,
- ClutterPaintNode *node,
- ClutterPaintContext *paint_context)
-{
- clutter_shader_effect_set_shader_source (CLUTTER_SHADER_EFFECT (effect),
- old_shader_effect_source);
- clutter_shader_effect_set_uniform (CLUTTER_SHADER_EFFECT (effect),
- "override_color",
- G_TYPE_FLOAT, 3,
- 1.0f, 0.0f, 0.0f);
-
- CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_old_shader_effect_parent_class)->
- paint_target (effect, node, paint_context);
-}
-
-static void
-foo_old_shader_effect_class_init (FooOldShaderEffectClass *klass)
-{
- ClutterOffscreenEffectClass *offscreen_effect_class =
- CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
-
- offscreen_effect_class->paint_target = foo_old_shader_effect_paint_target;
-}
-
-static void
-foo_old_shader_effect_init (FooOldShaderEffect *self)
-{
-}
-
-/****************************************************************
- New style shader effect
- This overrides get_static_shader_source()
- ****************************************************************/
-
-static const gchar
-new_shader_effect_source[] =
- "uniform vec3 override_color;\n"
- "\n"
- "void\n"
- "main ()\n"
- "{\n"
- " cogl_color_out = (vec4 (override_color, 1.0) +\n"
- " vec4 (0.0, 0.0, 1.0, 0.0));\n"
- "}";
-
-typedef struct _FooNewShaderEffectClass
-{
- ClutterShaderEffectClass parent_class;
-} FooNewShaderEffectClass;
-
-typedef struct _FooNewShaderEffect
-{
- ClutterShaderEffect parent;
-} FooNewShaderEffect;
-
-GType foo_new_shader_effect_get_type (void);
-
-G_DEFINE_TYPE (FooNewShaderEffect,
- foo_new_shader_effect,
- CLUTTER_TYPE_SHADER_EFFECT);
-
-static gchar *
-foo_new_shader_effect_get_static_source (ClutterShaderEffect *effect)
-{
- static gboolean already_called = FALSE;
-
- /* This should only be called once even though we have two actors
- using this effect */
- g_assert (!already_called);
-
- already_called = TRUE;
-
- return g_strdup (new_shader_effect_source);
-}
-
-static void
-foo_new_shader_effect_paint_target (ClutterOffscreenEffect *effect,
- ClutterPaintNode *node,
- ClutterPaintContext *paint_context)
-{
- clutter_shader_effect_set_uniform (CLUTTER_SHADER_EFFECT (effect),
- "override_color",
- G_TYPE_FLOAT, 3,
- 0.0f, 1.0f, 0.0f);
-
- CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_new_shader_effect_parent_class)->
- paint_target (effect, node, paint_context);
-}
-
-static void
-foo_new_shader_effect_class_init (FooNewShaderEffectClass *klass)
-{
- ClutterOffscreenEffectClass *offscreen_effect_class =
- CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
- ClutterShaderEffectClass *shader_effect_class =
- CLUTTER_SHADER_EFFECT_CLASS (klass);
-
- offscreen_effect_class->paint_target = foo_new_shader_effect_paint_target;
-
- shader_effect_class->get_static_shader_source =
- foo_new_shader_effect_get_static_source;
-}
-
-static void
-foo_new_shader_effect_init (FooNewShaderEffect *self)
-{
-}
-
-/****************************************************************
- Another new style shader effect
- This is the same but with a different shader. This is just
- sanity check that each class gets its own copy of the private
- data
- ****************************************************************/
-
-static const gchar
-another_new_shader_effect_source[] =
- "\n"
- "void\n"
- "main ()\n"
- "{\n"
- " cogl_color_out = vec4 (1.0, 0.0, 1.0, 1.0);\n"
- "}";
-
-typedef struct _FooAnotherNewShaderEffectClass
-{
- ClutterShaderEffectClass parent_class;
-} FooAnotherNewShaderEffectClass;
-
-typedef struct _FooAnotherNewShaderEffect
-{
- ClutterShaderEffect parent;
-} FooAnotherNewShaderEffect;
-
-GType foo_another_new_shader_effect_get_type (void);
-
-G_DEFINE_TYPE (FooAnotherNewShaderEffect,
- foo_another_new_shader_effect,
- CLUTTER_TYPE_SHADER_EFFECT);
-
-static gchar *
-foo_another_new_shader_effect_get_static_source (ClutterShaderEffect *effect)
-{
- return g_strdup (another_new_shader_effect_source);
-}
-
-static void
-foo_another_new_shader_effect_class_init (FooAnotherNewShaderEffectClass *klass)
-{
- ClutterShaderEffectClass *shader_effect_class =
- CLUTTER_SHADER_EFFECT_CLASS (klass);
-
- shader_effect_class->get_static_shader_source =
- foo_another_new_shader_effect_get_static_source;
-}
-
-static void
-foo_another_new_shader_effect_init (FooAnotherNewShaderEffect *self)
-{
-}
-
-/****************************************************************/
-
-static ClutterActor *
-make_actor (GType shader_type)
-{
- ClutterActor *rect;
- const ClutterColor white = { 0xff, 0xff, 0xff, 0xff };
-
- rect = clutter_actor_new ();
- clutter_actor_set_background_color (rect, &white);
- clutter_actor_set_size (rect, 50, 50);
-
- clutter_actor_add_effect (rect, g_object_new (shader_type, NULL));
-
- return rect;
-}
-
-static guint32
-get_pixel (CoglFramebuffer *fb,
- int x,
- int y)
-{
- guint8 data[4];
-
- 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) |
- data[2]);
-}
-
-static void
-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 (fb, 0, 25), ==, 0xff0000);
- /* new shader effect */
- g_assert_cmpint (get_pixel (fb, 100, 25), ==, 0x00ffff);
- /* another new shader effect */
- g_assert_cmpint (get_pixel (fb, 200, 25), ==, 0xff00ff);
- /* new shader effect */
- g_assert_cmpint (get_pixel (fb, 300, 25), ==, 0x00ffff);
-
- *was_painted = TRUE;
-}
-
-static void
-actor_shader_effect (void)
-{
- ClutterActor *stage;
- ClutterActor *rect;
- gboolean was_painted;
- GList *actors = NULL;
-
- if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
- return;
-
- stage = clutter_test_get_stage ();
-
- rect = make_actor (foo_old_shader_effect_get_type ());
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
- actors = g_list_prepend (actors, rect);
-
- rect = make_actor (foo_new_shader_effect_get_type ());
- clutter_actor_set_x (rect, 100);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
- actors = g_list_prepend (actors, rect);
-
- rect = make_actor (foo_another_new_shader_effect_get_type ());
- clutter_actor_set_x (rect, 200);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
- actors = g_list_prepend (actors, rect);
-
- rect = make_actor (foo_new_shader_effect_get_type ());
- clutter_actor_set_x (rect, 300);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
- actors = g_list_prepend (actors, rect);
-
- clutter_actor_show (stage);
-
- was_painted = FALSE;
- g_signal_connect_after (stage, "paint-view",
- G_CALLBACK (view_painted_cb),
- &was_painted);
-
- while (!was_painted)
- g_main_context_iteration (NULL, FALSE);
-
- g_list_free_full (actors, (GDestroyNotify) clutter_actor_destroy);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/actor/shader-effect", actor_shader_effect)
-)
diff --git a/src/tests/clutter/conform/actor-size.c b/src/tests/clutter/conform/actor-size.c
deleted file mode 100644
index e8b04af3b..000000000
--- a/src/tests/clutter/conform/actor-size.c
+++ /dev/null
@@ -1,218 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-#define TEST_TYPE_ACTOR (test_actor_get_type ())
-
-typedef struct _TestActor TestActor;
-typedef struct _ClutterActorClass TestActorClass;
-
-struct _TestActor
-{
- ClutterActor parent_instance;
-
- guint preferred_width_called : 1;
- guint preferred_height_called : 1;
-};
-
-GType test_actor_get_type (void);
-
-G_DEFINE_TYPE (TestActor, test_actor, CLUTTER_TYPE_ACTOR);
-
-static void
-test_actor_get_preferred_width (ClutterActor *self,
- gfloat for_height,
- gfloat *min_width_p,
- gfloat *nat_width_p)
-{
- TestActor *test = (TestActor *) self;
-
- test->preferred_width_called = TRUE;
-
- if (for_height == 10)
- {
- *min_width_p = 10;
- *nat_width_p = 100;
- }
- else
- {
- *min_width_p = 100;
- *nat_width_p = 100;
- }
-}
-
-static void
-test_actor_get_preferred_height (ClutterActor *self,
- gfloat for_width,
- gfloat *min_height_p,
- gfloat *nat_height_p)
-{
- TestActor *test = (TestActor *) self;
-
- test->preferred_height_called = TRUE;
-
- if (for_width == 10)
- {
- *min_height_p = 50;
- *nat_height_p = 100;
- }
- else
- {
- *min_height_p = 100;
- *nat_height_p = 100;
- }
-}
-
-static void
-test_actor_class_init (TestActorClass *klass)
-{
- ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
-
- actor_class->get_preferred_width = test_actor_get_preferred_width;
- actor_class->get_preferred_height = test_actor_get_preferred_height;
-}
-
-static void
-test_actor_init (TestActor *self)
-{
-}
-
-static void
-actor_preferred_size (void)
-{
- ClutterActor *test;
- TestActor *self;
- gfloat min_width, min_height;
- gfloat nat_width, nat_height;
-
- test = g_object_new (TEST_TYPE_ACTOR, NULL);
- self = (TestActor *) test;
-
- if (!g_test_quiet ())
- g_print ("Preferred size\n");
-
- clutter_actor_get_preferred_size (test,
- &min_width, &min_height,
- &nat_width, &nat_height);
-
- g_assert (self->preferred_width_called);
- g_assert (self->preferred_height_called);
- g_assert_cmpfloat (min_width, ==, 100);
- g_assert_cmpfloat (min_height, ==, 100);
- g_assert_cmpfloat (nat_width, ==, min_width);
- g_assert_cmpfloat (nat_height, ==, min_height);
-
- if (!g_test_quiet ())
- g_print ("Preferred width\n");
- self->preferred_width_called = FALSE;
- clutter_actor_get_preferred_width (test, 10, &min_width, &nat_width);
- g_assert (self->preferred_width_called);
- g_assert_cmpfloat (min_width, ==, 10);
- g_assert_cmpfloat (nat_width, ==, 100);
-
- if (!g_test_quiet ())
- g_print ("Preferred height\n");
- self->preferred_height_called = FALSE;
- clutter_actor_get_preferred_height (test, 200, &min_height, &nat_height);
- g_assert (self->preferred_height_called);
- g_assert_cmpfloat (min_height, !=, 10);
- g_assert_cmpfloat (nat_height, ==, 100);
-
- if (!g_test_quiet ())
- g_print ("Preferred width (cached)\n");
- self->preferred_width_called = FALSE;
- clutter_actor_get_preferred_width (test, 10, &min_width, &nat_width);
- g_assert (!self->preferred_width_called);
- g_assert_cmpfloat (min_width, ==, 10);
- g_assert_cmpfloat (nat_width, ==, 100);
-
- if (!g_test_quiet ())
- g_print ("Preferred height (cache eviction)\n");
- self->preferred_height_called = FALSE;
- clutter_actor_get_preferred_height (test, 10, &min_height, &nat_height);
- g_assert (self->preferred_height_called);
- g_assert_cmpfloat (min_height, ==, 50);
- g_assert_cmpfloat (nat_height, ==, 100);
-
- clutter_actor_destroy (test);
-}
-
-static void
-actor_fixed_size (void)
-{
- ClutterActor *rect;
- gboolean min_width_set, nat_width_set;
- gboolean min_height_set, nat_height_set;
- gfloat min_width, min_height;
- gfloat nat_width, nat_height;
-
- rect = clutter_actor_new ();
- g_object_ref_sink (rect);
-
- if (!g_test_quiet ())
- g_print ("Initial size is 0\n");
-
- g_assert_cmpfloat (clutter_actor_get_width (rect), ==, 0);
- g_assert_cmpfloat (clutter_actor_get_height (rect), ==, 0);
-
- clutter_actor_set_size (rect, 100, 100);
-
- if (!g_test_quiet ())
- g_print ("Explicit size set\n");
-
- g_assert_cmpfloat (clutter_actor_get_width (rect), ==, 100);
- g_assert_cmpfloat (clutter_actor_get_height (rect), ==, 100);
-
- g_object_get (G_OBJECT (rect),
- "min-width-set", &min_width_set,
- "min-height-set", &min_height_set,
- "natural-width-set", &nat_width_set,
- "natural-height-set", &nat_height_set,
- NULL);
-
- if (!g_test_quiet ())
- g_print ("Notification properties\n");
-
- g_assert (min_width_set && nat_width_set);
- g_assert (min_height_set && nat_height_set);
-
- clutter_actor_get_preferred_size (rect,
- &min_width, &min_height,
- &nat_width, &nat_height);
-
- if (!g_test_quiet ())
- g_print ("Preferred size\n");
-
- g_assert_cmpfloat (min_width, ==, 100);
- g_assert_cmpfloat (min_height, ==, 100);
- g_assert_cmpfloat (min_width, ==, nat_width);
- g_assert_cmpfloat (min_height, ==, nat_height);
-
- clutter_actor_set_size (rect, -1, -1);
-
- if (!g_test_quiet ())
- g_print ("Explicit size unset\n");
-
- g_object_get (G_OBJECT (rect),
- "min-width-set", &min_width_set,
- "min-height-set", &min_height_set,
- "natural-width-set", &nat_width_set,
- "natural-height-set", &nat_height_set,
- NULL);
- g_assert (!min_width_set && !nat_width_set);
- g_assert (!min_height_set && !nat_height_set);
-
- g_assert_cmpfloat (clutter_actor_get_width (rect), ==, 0);
- g_assert_cmpfloat (clutter_actor_get_height (rect), ==, 0);
-
- clutter_actor_destroy (rect);
- g_object_unref (rect);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/actor/size/preferred", actor_preferred_size)
- CLUTTER_TEST_UNIT ("/actor/size/fixed", actor_fixed_size)
-)
diff --git a/src/tests/clutter/conform/binding-pool.c b/src/tests/clutter/conform/binding-pool.c
deleted file mode 100644
index a14ea573e..000000000
--- a/src/tests/clutter/conform/binding-pool.c
+++ /dev/null
@@ -1,311 +0,0 @@
-#include <string.h>
-
-#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))
-#define KEY_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_KEY_GROUP, KeyGroupClass))
-#define IS_KEY_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_KEY_GROUP))
-
-typedef struct _KeyGroup KeyGroup;
-typedef struct _KeyGroupClass KeyGroupClass;
-
-struct _KeyGroup
-{
- ClutterActor parent_instance;
-
- gint selected_index;
-};
-
-struct _KeyGroupClass
-{
- ClutterActorClass parent_class;
-
- void (* activate) (KeyGroup *group,
- ClutterActor *child);
-};
-
-GType key_group_get_type (void);
-
-G_DEFINE_TYPE (KeyGroup, key_group, CLUTTER_TYPE_ACTOR)
-
-enum
-{
- ACTIVATE,
-
- LAST_SIGNAL
-};
-
-static guint group_signals[LAST_SIGNAL] = { 0, };
-
-static gboolean
-key_group_action_move_left (KeyGroup *self,
- const gchar *action_name,
- guint key_val,
- ClutterModifierType modifiers)
-{
- gint n_children;
-
- g_assert_cmpstr (action_name, ==, "move-left");
- g_assert_cmpint (key_val, ==, CLUTTER_KEY_Left);
-
- n_children = clutter_actor_get_n_children (CLUTTER_ACTOR (self));
-
- self->selected_index -= 1;
-
- if (self->selected_index < 0)
- self->selected_index = n_children - 1;
-
- return TRUE;
-}
-
-static gboolean
-key_group_action_move_right (KeyGroup *self,
- const gchar *action_name,
- guint key_val,
- ClutterModifierType modifiers)
-{
- gint n_children;
-
- g_assert_cmpstr (action_name, ==, "move-right");
- g_assert_cmpint (key_val, ==, CLUTTER_KEY_Right);
-
- n_children = clutter_actor_get_n_children (CLUTTER_ACTOR (self));
-
- self->selected_index += 1;
-
- if (self->selected_index >= n_children)
- self->selected_index = 0;
-
- return TRUE;
-}
-
-static gboolean
-key_group_action_activate (KeyGroup *self,
- const gchar *action_name,
- guint key_val,
- ClutterModifierType modifiers)
-{
- ClutterActor *child = NULL;
-
- g_assert_cmpstr (action_name, ==, "activate");
- g_assert (key_val == CLUTTER_KEY_Return ||
- key_val == CLUTTER_KEY_KP_Enter ||
- key_val == CLUTTER_KEY_ISO_Enter);
-
- if (self->selected_index == -1)
- return FALSE;
-
- child = clutter_actor_get_child_at_index (CLUTTER_ACTOR (self), self->selected_index);
- if (child != NULL)
- {
- g_signal_emit (self, group_signals[ACTIVATE], 0, child);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static gboolean
-key_group_key_press (ClutterActor *actor,
- ClutterKeyEvent *event)
-{
- ClutterBindingPool *pool;
- gboolean res;
-
- pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (actor));
- g_assert (pool != NULL);
-
- res = clutter_binding_pool_activate (pool,
- event->keyval,
- event->modifier_state,
- G_OBJECT (actor));
-
- /* if we activate a key binding, redraw the actor */
- if (res)
- clutter_actor_queue_redraw (actor);
-
- return res;
-}
-
-static void
-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))
- {
- /* paint the selection rectangle */
- if (i == self->selected_index)
- {
- ClutterActorBox box = { 0, };
-
- clutter_actor_get_allocation_box (child, &box);
-
- box.x1 -= 2;
- box.y1 -= 2;
- box.x2 += 2;
- box.y2 += 2;
-
- cogl_framebuffer_draw_rectangle (framebuffer, pipeline,
- box.x1, box.y1, box.x2, box.y2);
- }
-
- clutter_actor_paint (child, paint_context);
- }
-
- cogl_object_unref (pipeline);
-}
-
-static void
-key_group_class_init (KeyGroupClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
- ClutterBindingPool *binding_pool;
-
- actor_class->paint = key_group_paint;
- actor_class->key_press_event = key_group_key_press;
-
- group_signals[ACTIVATE] =
- g_signal_new (g_intern_static_string ("activate"),
- G_OBJECT_CLASS_TYPE (gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (KeyGroupClass, activate),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1,
- CLUTTER_TYPE_ACTOR);
-
- binding_pool = clutter_binding_pool_get_for_class (klass);
-
- clutter_binding_pool_install_action (binding_pool, "move-right",
- CLUTTER_KEY_Right, 0,
- G_CALLBACK (key_group_action_move_right),
- NULL, NULL);
- clutter_binding_pool_install_action (binding_pool, "move-left",
- CLUTTER_KEY_Left, 0,
- G_CALLBACK (key_group_action_move_left),
- NULL, NULL);
- clutter_binding_pool_install_action (binding_pool, "activate",
- CLUTTER_KEY_Return, 0,
- G_CALLBACK (key_group_action_activate),
- NULL, NULL);
- clutter_binding_pool_install_action (binding_pool, "activate",
- CLUTTER_KEY_KP_Enter, 0,
- G_CALLBACK (key_group_action_activate),
- NULL, NULL);
- clutter_binding_pool_install_action (binding_pool, "activate",
- CLUTTER_KEY_ISO_Enter, 0,
- G_CALLBACK (key_group_action_activate),
- NULL, NULL);
-}
-
-static void
-key_group_init (KeyGroup *self)
-{
- self->selected_index = -1;
-}
-
-static void
-init_event (ClutterKeyEvent *event)
-{
- event->type = CLUTTER_KEY_PRESS;
- event->time = 0; /* not needed */
- event->flags = CLUTTER_EVENT_FLAG_SYNTHETIC;
- event->stage = NULL; /* not needed */
- event->source = NULL; /* not needed */
- event->modifier_state = 0;
- event->hardware_keycode = 0; /* not needed */
-}
-
-static void
-send_keyval (KeyGroup *group, int keyval)
-{
- ClutterKeyEvent event;
-
- init_event (&event);
- event.keyval = keyval;
- event.unicode_value = 0; /* should be ignored for cursor keys etc. */
-
- clutter_actor_event (CLUTTER_ACTOR (group), (ClutterEvent *) &event, FALSE);
-}
-
-static void
-on_activate (KeyGroup *key_group,
- ClutterActor *child,
- gpointer data)
-{
- gint _index = GPOINTER_TO_INT (data);
-
- g_assert_cmpint (key_group->selected_index, ==, _index);
-}
-
-static void
-binding_pool (void)
-{
- KeyGroup *key_group = g_object_new (TYPE_KEY_GROUP, NULL);
- g_object_ref_sink (key_group);
-
- clutter_actor_add_child (CLUTTER_ACTOR (key_group),
- g_object_new (CLUTTER_TYPE_ACTOR,
- "width", 50.0,
- "height", 50.0,
- "x", 0.0, "y", 0.0,
- NULL));
- clutter_actor_add_child (CLUTTER_ACTOR (key_group),
- g_object_new (CLUTTER_TYPE_ACTOR,
- "width", 50.0,
- "height", 50.0,
- "x", 75.0, "y", 0.0,
- NULL));
- clutter_actor_add_child (CLUTTER_ACTOR (key_group),
- g_object_new (CLUTTER_TYPE_ACTOR,
- "width", 50.0,
- "height", 50.0,
- "x", 150.0, "y", 0.0,
- NULL));
-
- g_assert_cmpint (key_group->selected_index, ==, -1);
-
- send_keyval (key_group, CLUTTER_KEY_Left);
- g_assert_cmpint (key_group->selected_index, ==, 2);
-
- send_keyval (key_group, CLUTTER_KEY_Left);
- g_assert_cmpint (key_group->selected_index, ==, 1);
-
- send_keyval (key_group, CLUTTER_KEY_Right);
- g_assert_cmpint (key_group->selected_index, ==, 2);
-
- send_keyval (key_group, CLUTTER_KEY_Right);
- g_assert_cmpint (key_group->selected_index, ==, 0);
-
- g_signal_connect (key_group,
- "activate", G_CALLBACK (on_activate),
- GINT_TO_POINTER (0));
-
- send_keyval (key_group, CLUTTER_KEY_Return);
-
- clutter_actor_destroy (CLUTTER_ACTOR (key_group));
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/binding-pool", binding_pool)
-)
diff --git a/src/tests/clutter/conform/cally-text.c b/src/tests/clutter/conform/cally-text.c
deleted file mode 100644
index 1644181f5..000000000
--- a/src/tests/clutter/conform/cally-text.c
+++ /dev/null
@@ -1,338 +0,0 @@
-#include <clutter/clutter.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "test-conform-common.h"
-
-#define TEST_FONT "Sans 10"
-
-typedef struct _CallbackData CallbackData;
-
-struct _CallbackData
-{
- ClutterActor *stage;
- ClutterActor *label;
- gint offset;
- gboolean test_failed;
-
- gint extents_x;
- gint extents_y;
- gint extents_width;
- gint extents_height;
- GSList *run_attributes;
- GSList *default_attributes;
- CallbackData *next;
-};
-
-
-static gint
-attribute_lookup_func (gconstpointer data,
- gconstpointer user_data)
-{
- AtkAttribute *lookup_attr = (AtkAttribute*) user_data;
- AtkAttribute *at = (AtkAttribute *) data;
- if (!data)
- return -1;
- if (!g_strcmp0 (at->name, lookup_attr->name))
- return g_strcmp0 (at->value, lookup_attr->value);
- return -1;
-}
-
-/* check l1 is a sub-set of l2 */
-static gboolean
-compare_lists (GSList* l1, GSList* l2)
-{
- gboolean fail = FALSE;
-
- if (l2 && !l1)
- return TRUE;
-
- while (l1)
- {
- AtkAttribute *at = (AtkAttribute *) l1->data;
- GSList* result = g_slist_find_custom ((GSList*) l2,
- (gconstpointer) at,
- attribute_lookup_func);
- if (!result)
- {
- fail = TRUE;
- break;
- }
- l1 = g_slist_next (l1);
- }
-
- return fail;
-}
-
-static void
-dump_attribute_set (AtkAttributeSet *at_set)
-{
- GSList *attrs = (GSList*) at_set;
-
- while (attrs) {
- AtkAttribute *at = (AtkAttribute *) attrs->data;
- g_print ("text attribute %s = %s\n", at->name, at->value);
- attrs = g_slist_next (attrs);
- }
-
-}
-
-static gboolean
-check_result (CallbackData *data)
-{
- gboolean fail = FALSE;
- gchar *text = NULL;
- const gchar *expected_text = NULL;
- AtkObject *object = NULL;
- AtkText *cally_text = NULL;
- gunichar unichar;
- gunichar expected_char;
- gint x, y, width, height;
- gint pos;
- AtkAttributeSet *at_set = NULL;
- GSList *attrs;
- gint start = -1;
- gint end = -1;
-
- object = atk_gobject_accessible_for_object (G_OBJECT (data->label));
- cally_text = ATK_TEXT (object);
-
- if (!cally_text) {
- g_print("no text\n");
- return TRUE;
- }
-
- text = atk_text_get_text (cally_text, 0, -1);
- expected_text = clutter_text_get_text (CLUTTER_TEXT (data->label));
-
- if (g_strcmp0 (expected_text, text) != 0)
- {
- if (!g_test_quiet ())
- g_print ("text value differs %s vs %s\n", expected_text, text);
- fail = TRUE;
- }
-
- unichar = atk_text_get_character_at_offset (cally_text, data->offset);
- expected_char = g_utf8_get_char (g_utf8_offset_to_pointer (text, data->offset));
- if (expected_char != unichar)
- {
- if (!g_test_quiet ())
- g_print ("text af offset differs\n");
- fail = TRUE;
- }
-
- atk_text_get_character_extents (cally_text, data->offset, &x, &y, &width, &height,
- ATK_XY_WINDOW);
- if (x != data->extents_x)
- {
- if (!g_test_quiet ())
- g_print ("extents x position at index 0 differs (current value=%d)\n", x);
- fail = TRUE;
- }
- if (y != data->extents_y)
- {
- if (!g_test_quiet ())
- g_print ("extents y position at index 0 differs (current value=%d)\n", y);
- fail = TRUE;
- }
- if (width != data->extents_width)
- {
- if (!g_test_quiet ())
- g_print ("extents width at index 0 differs (current value=%d)\n", width);
- fail = TRUE;
- }
- if (height != data->extents_height)
- {
- if (!g_test_quiet ())
- g_print ("extents height at index 0 differs (current value=%d)\n", height);
- fail = TRUE;
- }
-
- pos = atk_text_get_offset_at_point (cally_text, x, y, ATK_XY_WINDOW);
- if (pos != data->offset)
- {
- if (!g_test_quiet ())
- g_print ("offset at position (%d, %d) differs (current value=%d)\n", x,
- y, pos);
- fail = TRUE;
- }
-
- at_set = atk_text_get_run_attributes (cally_text, 0,
- &start, &end);
- if (start != 0)
- {
- if (!g_test_quiet ())
- g_print ("run attributes start offset is not 0: %d\n", start);
- fail = TRUE;
- }
- if (end != g_utf8_strlen (text, -1))
- {
- if (!g_test_quiet ())
- g_print ("run attributes end offset is not text length: %d\n", end);
- fail = TRUE;
- }
-
- attrs = (GSList*) at_set;
- fail = compare_lists (attrs, data->run_attributes);
- if (fail && !g_test_quiet ())
- {
- g_print ("run attributes mismatch\n");
- dump_attribute_set (attrs);
- }
-
- at_set = atk_text_get_default_attributes (cally_text);
- attrs = (GSList*) at_set;
- fail = compare_lists (attrs, data->default_attributes);
- if (fail && !g_test_quiet ())
- {
- g_print ("default attributes mismatch\n");
- dump_attribute_set (attrs);
- }
-
- g_free (text);
- text = NULL;
-
- if (fail)
- {
- if (!g_test_quiet ())
- g_print ("FAIL\n");
- data->test_failed = TRUE;
- }
- else if (!g_test_quiet ())
- g_print ("pass\n");
-
- return fail;
-}
-
-static gboolean
-do_tests (CallbackData *data)
-{
- while (data)
- {
- gboolean result = check_result (data);
- g_assert (result == FALSE);
- data = data->next;
- }
-
- clutter_test_quit ();
-
- return FALSE;
-}
-
-static GSList*
-build_attribute_set (const gchar* first_attribute, ...)
-{
- AtkAttributeSet *return_set = g_slist_alloc ();
- va_list args;
- const gchar *name;
- const gchar *value;
- gint i = 0;
-
- value = first_attribute;
- va_start (args, first_attribute);
-
- while (value)
- {
- if ((i> 0) && (i % 2 != 0))
- {
- AtkAttribute *at = g_malloc (sizeof (AtkAttribute));
- at->name = g_strdup (name);
- at->value = g_strdup (value);
- return_set = g_slist_prepend (return_set, at);
- }
- i++;
- name = g_strdup (value);
- value = va_arg (args, gchar*);
- }
- va_end (args);
- return return_set;
-}
-
-void
-cally_text (void)
-{
- CallbackData data;
- CallbackData data1;
- GSList* default_attributes = build_attribute_set ("left-margin", "0",
- "right-margin", "0",
- "indent", "0",
- "invisible", "false",
- "editable", "false",
- "pixels-above-lines", "0",
- "pixels-below-lines", "0",
- "pixels-inside-wrap", "0",
- "bg-full-height", "0",
- "bg-stipple", "false",
- "fg-stipple", "false",
- "fg-color", "0,0,0",
- "wrap-mode", "word",
- "justification", "left",
- "size", "10",
- "weight", "400",
- "family-name", "Sans",
- "stretch", "normal",
- "variant", "normal",
- "style", "normal",
- "language", "en-us",
- "direction", "ltr",
- NULL);
-
- memset (&data, 0, sizeof (data));
-
- data.stage = clutter_test_get_stage ();
-
- data.default_attributes = default_attributes;
- data.run_attributes = build_attribute_set ("fg-color", "0,0,0", NULL);
-
- data.label = clutter_text_new_with_text (TEST_FONT, "Lorem ipsum dolor sit amet");
-
- clutter_container_add (CLUTTER_CONTAINER (data.stage), data.label, NULL);
- data.offset = 6;
- data.extents_x = 64;
- data.extents_y = 99;
- data.extents_width = 3;
- data.extents_height = 17;
- clutter_actor_set_position (data.label, 20, 100);
-
- memset (&data1, 0, sizeof (data1));
- data1.stage = data.stage;
- data1.default_attributes = default_attributes;
- data1.run_attributes = build_attribute_set ("bg-color", "0,65535,0",
- "fg-color", "65535,65535,0",
- "strikethrough", "true", NULL);
-
- data1.label = clutter_text_new_with_text (TEST_FONT, "");
- clutter_text_set_markup (CLUTTER_TEXT(data1.label), "<span fgcolor=\"#FFFF00\" bgcolor=\"#00FF00\"><s>Lorem ipsum dolor sit amet</s></span>");
-
- clutter_container_add (CLUTTER_CONTAINER (data1.stage), data1.label, NULL);
- data1.offset = 10;
- data1.extents_x = 90;
- data1.extents_y = 199;
- data1.extents_width = 13;
- data1.extents_height = 17;
- clutter_actor_set_position (data1.label, 20, 200);
- data.next = &data1;
-
- clutter_actor_show (data.stage);
- clutter_threads_add_idle ((GSourceFunc) do_tests, &data);
- clutter_test_main ();
-
- clutter_actor_destroy (data.stage);
-
- if (!g_test_quiet ())
- g_print ("\nOverall result: ");
-
- if (!g_test_quiet ())
- {
- if (data.test_failed)
- g_print ("FAIL\n");
- else
- g_print ("pass\n");
- }
- else
- {
- g_assert (data.test_failed != TRUE);
- g_assert (data1.test_failed != TRUE);
- }
-}
-
diff --git a/src/tests/clutter/conform/color.c b/src/tests/clutter/conform/color.c
deleted file mode 100644
index b66d5f63a..000000000
--- a/src/tests/clutter/conform/color.c
+++ /dev/null
@@ -1,321 +0,0 @@
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-static void
-color_hls_roundtrip (void)
-{
- ClutterColor color;
- gfloat hue, luminance, saturation;
-
- /* test luminance only */
- clutter_color_from_string (&color, "#7f7f7f");
- g_assert_cmpuint (color.red, ==, 0x7f);
- g_assert_cmpuint (color.green, ==, 0x7f);
- g_assert_cmpuint (color.blue, ==, 0x7f);
-
- clutter_color_to_hls (&color, &hue, &luminance, &saturation);
- g_assert_cmpfloat (hue, ==, 0.0);
- g_assert (luminance >= 0.0 && luminance <= 1.0);
- g_assert_cmpfloat (saturation, ==, 0.0);
- if (!g_test_quiet ())
- {
- g_print ("RGB = { %x, %x, %x }, HLS = { %.2f, %.2f, %.2f }\n",
- color.red,
- color.green,
- color.blue,
- hue,
- luminance,
- saturation);
- }
-
- color.red = color.green = color.blue = 0;
- clutter_color_from_hls (&color, hue, luminance, saturation);
-
- g_assert_cmpuint (color.red, ==, 0x7f);
- g_assert_cmpuint (color.green, ==, 0x7f);
- g_assert_cmpuint (color.blue, ==, 0x7f);
-
- /* full conversion */
- clutter_color_from_string (&color, "#7f8f7f");
- color.alpha = 255;
-
- g_assert_cmpuint (color.red, ==, 0x7f);
- g_assert_cmpuint (color.green, ==, 0x8f);
- g_assert_cmpuint (color.blue, ==, 0x7f);
-
- clutter_color_to_hls (&color, &hue, &luminance, &saturation);
- g_assert (hue >= 0.0 && hue < 360.0);
- g_assert (luminance >= 0.0 && luminance <= 1.0);
- g_assert (saturation >= 0.0 && saturation <= 1.0);
- if (!g_test_quiet ())
- {
- g_print ("RGB = { %x, %x, %x }, HLS = { %.2f, %.2f, %.2f }\n",
- color.red,
- color.green,
- color.blue,
- hue,
- luminance,
- saturation);
- }
-
- color.red = color.green = color.blue = 0;
- clutter_color_from_hls (&color, hue, luminance, saturation);
-
- g_assert_cmpuint (color.red, ==, 0x7f);
- g_assert_cmpuint (color.green, ==, 0x8f);
- g_assert_cmpuint (color.blue, ==, 0x7f);
-
- /* the alpha channel should be untouched */
- g_assert_cmpuint (color.alpha, ==, 255);
-}
-
-static void
-color_from_string_invalid (void)
-{
- ClutterColor color;
-
- g_assert (!clutter_color_from_string (&color, "ff0000ff"));
- g_assert (!clutter_color_from_string (&color, "#decaffbad"));
- g_assert (!clutter_color_from_string (&color, "ponies"));
- g_assert (!clutter_color_from_string (&color, "rgb(255, 0, 0, 0)"));
- g_assert (!clutter_color_from_string (&color, "rgba(1.0, 0, 0)"));
- g_assert (!clutter_color_from_string (&color, "hsl(100, 0, 0)"));
- g_assert (!clutter_color_from_string (&color, "hsla(10%, 0%, 50%)"));
- g_assert (!clutter_color_from_string (&color, "hsla(100%, 0%, 50%, 20%)"));
- g_assert (!clutter_color_from_string (&color, "hsla(0.5, 0.9, 0.2, 0.4)"));
-}
-
-static void
-color_from_string_valid (void)
-{
- ClutterColor color;
-
- g_assert (clutter_color_from_string (&color, "#ff0000ff"));
- if (!g_test_quiet ())
- {
- g_print ("color = { %x, %x, %x, %x }, expected = { 0xff, 0, 0, 0xff }\n",
- color.red,
- color.green,
- color.blue,
- color.alpha);
- }
- g_assert_cmpuint (color.red, ==, 0xff);
- g_assert_cmpuint (color.green, ==, 0);
- g_assert_cmpuint (color.blue, ==, 0);
- g_assert_cmpuint (color.alpha, ==, 0xff);
-
- g_assert (clutter_color_from_string (&color, "#0f0f"));
- if (!g_test_quiet ())
- {
- g_print ("color = { %x, %x, %x, %x }, expected = { 0, 0xff, 0, 0xff }\n",
- color.red,
- color.green,
- color.blue,
- color.alpha);
- }
- g_assert_cmpuint (color.red, ==, 0);
- g_assert_cmpuint (color.green, ==, 0xff);
- g_assert_cmpuint (color.blue, ==, 0);
- g_assert_cmpuint (color.alpha, ==, 0xff);
-
- g_assert (clutter_color_from_string (&color, "#0000ff"));
- if (!g_test_quiet ())
- {
- g_print ("color = { %x, %x, %x, %x }, expected = { 0, 0, 0xff, 0xff }\n",
- color.red,
- color.green,
- color.blue,
- color.alpha);
- }
- g_assert_cmpuint (color.red, ==, 0);
- g_assert_cmpuint (color.green, ==, 0);
- g_assert_cmpuint (color.blue, ==, 0xff);
- g_assert_cmpuint (color.alpha, ==, 0xff);
-
- g_assert (clutter_color_from_string (&color, "#abc"));
- if (!g_test_quiet ())
- {
- g_print ("color = { %x, %x, %x, %x }, expected = { 0xaa, 0xbb, 0xcc, 0xff }\n",
- color.red,
- color.green,
- color.blue,
- color.alpha);
- }
- g_assert_cmpuint (color.red, ==, 0xaa);
- g_assert_cmpuint (color.green, ==, 0xbb);
- g_assert_cmpuint (color.blue, ==, 0xcc);
- g_assert_cmpuint (color.alpha, ==, 0xff);
-
- g_assert (clutter_color_from_string (&color, "#123abc"));
- if (!g_test_quiet ())
- {
- g_print ("color = { %x, %x, %x, %x }, expected = { 0x12, 0x3a, 0xbc, 0xff }\n",
- color.red,
- color.green,
- color.blue,
- color.alpha);
- }
- g_assert (color.red == 0x12);
- g_assert (color.green == 0x3a);
- g_assert (color.blue == 0xbc);
- g_assert (color.alpha == 0xff);
-
- g_assert (clutter_color_from_string (&color, "rgb(255, 128, 64)"));
- if (!g_test_quiet ())
- {
- g_print ("color = { %x, %x, %x, %x }, expected = { 255, 128, 64, 255 }\n",
- color.red,
- color.green,
- color.blue,
- color.alpha);
- }
- g_assert_cmpuint (color.red, ==, 255);
- g_assert_cmpuint (color.green, ==, 128);
- g_assert_cmpuint (color.blue, ==, 64);
- g_assert_cmpuint (color.alpha, ==, 255);
-
- g_assert (clutter_color_from_string (&color, "rgba ( 30%, 0, 25%, 0.5 ) "));
- if (!g_test_quiet ())
- {
- g_print ("color = { %x, %x, %x, %x }, expected = { %.1f, 0, %.1f, 128 }\n",
- color.red,
- color.green,
- color.blue,
- color.alpha,
- CLAMP (255.0 / 100.0 * 30.0, 0, 255),
- CLAMP (255.0 / 100.0 * 25.0, 0, 255));
- }
- g_assert_cmpuint (color.red, ==, (255.0 / 100.0 * 30.0));
- g_assert_cmpuint (color.green, ==, 0);
- g_assert_cmpuint (color.blue, ==, (255.0 / 100.0 * 25.0));
- g_assert_cmpuint (color.alpha, ==, 127);
-
- g_assert (clutter_color_from_string (&color, "rgb( 50%, -50%, 150% )"));
- if (!g_test_quiet ())
- {
- g_print ("color = { %x, %x, %x, %x }, expected = { 127, 0, 255, 255 }\n",
- color.red,
- color.green,
- color.blue,
- color.alpha);
- }
- g_assert_cmpuint (color.red, ==, 127);
- g_assert_cmpuint (color.green, ==, 0);
- g_assert_cmpuint (color.blue, ==, 255);
- g_assert_cmpuint (color.alpha, ==, 255);
-
- g_assert (clutter_color_from_string (&color, "hsl( 0, 100%, 50% )"));
- if (!g_test_quiet ())
- {
- g_print ("color = { %x, %x, %x, %x }, expected = { 255, 0, 0, 255 }\n",
- color.red,
- color.green,
- color.blue,
- color.alpha);
- }
- g_assert_cmpuint (color.red, ==, 255);
- g_assert_cmpuint (color.green, ==, 0);
- g_assert_cmpuint (color.blue, ==, 0);
- g_assert_cmpuint (color.alpha, ==, 255);
-
- g_assert (clutter_color_from_string (&color, "hsl( 0, 100%, 50% )"));
-
- g_assert (clutter_color_from_string (&color, "hsla( 0, 100%, 50%, 0.5 )"));
- if (!g_test_quiet ())
- {
- g_print ("color = { %x, %x, %x, %x }, expected = { 255, 0, 0, 127 }\n",
- color.red,
- color.green,
- color.blue,
- color.alpha);
- }
- g_assert_cmpuint (color.red, ==, 255);
- g_assert_cmpuint (color.green, ==, 0);
- g_assert_cmpuint (color.blue, ==, 0);
- g_assert_cmpuint (color.alpha, ==, 127);
-
- g_test_bug ("662818");
- g_assert (clutter_color_from_string (&color, "hsla(0,100%,50% , 0.5)"));
-}
-
-static void
-color_to_string (void)
-{
- ClutterColor color;
- gchar *str;
-
- color.red = 0xcc;
- color.green = 0xcc;
- color.blue = 0xcc;
- color.alpha = 0x22;
-
- str = clutter_color_to_string (&color);
- g_assert_cmpstr (str, ==, "#cccccc22");
-
- g_free (str);
-}
-
-static void
-color_operators (void)
-{
- ClutterColor op1, op2;
- ClutterColor res;
-
- clutter_color_from_pixel (&op1, 0xff0000ff);
- g_assert_cmpuint (op1.red, ==, 0xff);
- g_assert_cmpuint (op1.green, ==, 0);
- g_assert_cmpuint (op1.blue, ==, 0);
- g_assert_cmpuint (op1.alpha, ==, 0xff);
-
- clutter_color_from_pixel (&op2, 0x00ff00ff);
- g_assert_cmpuint (op2.red, ==, 0);
- g_assert_cmpuint (op2.green, ==, 0xff);
- g_assert_cmpuint (op2.blue, ==, 0);
- g_assert_cmpuint (op2.alpha, ==, 0xff);
-
- if (!g_test_quiet ())
- g_print ("Adding %x, %x; expected result: %x\n",
- clutter_color_to_pixel (&op1),
- clutter_color_to_pixel (&op2),
- 0xffff00ff);
-
- clutter_color_add (&op1, &op2, &res);
- g_assert_cmpuint (clutter_color_to_pixel (&res), ==, 0xffff00ff);
-
- if (!g_test_quiet ())
- g_print ("Checking alpha channel on color add\n");
-
- op1.alpha = 0xdd;
- op2.alpha = 0xcc;
- clutter_color_add (&op1, &op2, &res);
- g_assert_cmpuint (clutter_color_to_pixel (&res), ==, 0xffff00dd);
-
- clutter_color_from_pixel (&op1, 0xffffffff);
- clutter_color_from_pixel (&op2, 0xff00ffff);
-
- if (!g_test_quiet ())
- g_print ("Subtracting %x, %x; expected result: %x\n",
- clutter_color_to_pixel (&op1),
- clutter_color_to_pixel (&op2),
- 0x00ff00ff);
-
- clutter_color_subtract (&op1, &op2, &res);
- g_assert_cmpuint (clutter_color_to_pixel (&res), ==, 0x00ff00ff);
-
- if (!g_test_quiet ())
- g_print ("Checking alpha channel on color subtract\n");
-
- op1.alpha = 0xdd;
- op2.alpha = 0xcc;
- clutter_color_subtract (&op1, &op2, &res);
- g_assert_cmpuint (clutter_color_to_pixel (&res), ==, 0x00ff00cc);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/color/hls-roundtrip", color_hls_roundtrip)
- CLUTTER_TEST_UNIT ("/color/from-string/invalid", color_from_string_invalid)
- CLUTTER_TEST_UNIT ("/color/from-string/valid", color_from_string_valid)
- CLUTTER_TEST_UNIT ("/color/to-string", color_to_string)
- CLUTTER_TEST_UNIT ("/color/operators", color_operators)
-)
diff --git a/src/tests/clutter/conform/frame-clock-timeline.c b/src/tests/clutter/conform/frame-clock-timeline.c
deleted file mode 100644
index 0f9f04d79..000000000
--- a/src/tests/clutter/conform/frame-clock-timeline.c
+++ /dev/null
@@ -1,209 +0,0 @@
-#include "clutter/clutter.h"
-#include "tests/clutter-test-utils.h"
-
-static const float refresh_rate = 60.0;
-
-static ClutterFrameResult
-timeline_frame_clock_frame (ClutterFrameClock *frame_clock,
- int64_t frame_count,
- int64_t time_us,
- gpointer user_data)
-{
- ClutterFrameInfo frame_info;
-
- frame_info = (ClutterFrameInfo) {
- .presentation_time = g_get_monotonic_time (),
- .refresh_rate = refresh_rate,
- .flags = CLUTTER_FRAME_INFO_FLAG_NONE,
- .sequence = 0,
- };
- clutter_frame_clock_notify_presented (frame_clock, &frame_info);
- clutter_frame_clock_schedule_update (frame_clock);
-
- return CLUTTER_FRAME_RESULT_PENDING_PRESENTED;
-}
-
-static const ClutterFrameListenerIface timeline_frame_listener_iface = {
- .frame = timeline_frame_clock_frame,
-};
-
-static void
-on_marker_reached (ClutterTimeline *timeline,
- const char *marker_name,
- unsigned int frame_number,
- gboolean *marker_reached)
-{
- *marker_reached = TRUE;
-}
-
-static void
-on_timeline_new_frame (ClutterTimeline *timeline,
- int time_ms,
- int *frame_counter)
-{
- (*frame_counter)++;
-}
-
-static void
-on_timeline_completed (ClutterTimeline *timeline,
- GMainLoop *main_loop)
-{
- g_main_loop_quit (main_loop);
-}
-
-static void
-frame_clock_timeline_basic (void)
-{
- GMainLoop *main_loop;
- ClutterFrameClock *frame_clock;
- ClutterTimeline *timeline;
- gboolean marker1_reached;
- int frame_counter;
- int64_t before_us;
- int64_t after_us;
-
- main_loop = g_main_loop_new (NULL, FALSE);
- frame_clock = clutter_frame_clock_new (refresh_rate,
- 0,
- &timeline_frame_listener_iface,
- NULL);
- g_object_add_weak_pointer (G_OBJECT (frame_clock), (gpointer *) &frame_clock);
-
- timeline = g_object_new (CLUTTER_TYPE_TIMELINE,
- "duration", 1000,
- "frame-clock", frame_clock,
- NULL);
- g_object_add_weak_pointer (G_OBJECT (timeline), (gpointer *) &timeline);
-
- clutter_timeline_add_marker_at_time (timeline, "marker1", 500);
-
- marker1_reached = FALSE;
- frame_counter = 0;
-
- g_signal_connect (timeline, "marker-reached::marker1",
- G_CALLBACK (on_marker_reached),
- &marker1_reached);
- g_signal_connect (timeline, "new-frame",
- G_CALLBACK (on_timeline_new_frame),
- &frame_counter);
- g_signal_connect (timeline, "completed",
- G_CALLBACK (on_timeline_completed),
- main_loop);
-
- clutter_timeline_start (timeline);
-
- before_us = g_get_monotonic_time ();
-
- g_main_loop_run (main_loop);
-
- after_us = g_get_monotonic_time ();
-
- g_assert_cmpint (after_us - before_us,
- >=,
- ms2us (clutter_timeline_get_duration (timeline)));
-
- g_assert_true (marker1_reached);
-
- /* Just check that we got at least a few frames. Require too high and we'll be
- * flaky.
- */
- g_assert_cmpint (frame_counter, >, 20);
-
- g_main_loop_unref (main_loop);
- g_object_unref (timeline);
- g_assert_null (timeline);
- clutter_frame_clock_destroy (frame_clock);
- g_assert_null (frame_clock);
-}
-
-static void
-on_switch_reached (ClutterTimeline *timeline,
- const char *marker_name,
- unsigned int frame_number,
- ClutterFrameClock *new_frame_clock)
-{
- ClutterFrameClock *old_frame_clock;
-
- old_frame_clock = clutter_timeline_get_frame_clock (timeline);
- clutter_frame_clock_inhibit (old_frame_clock);
-
- clutter_timeline_set_frame_clock (timeline, new_frame_clock);
-}
-
-static void
-frame_clock_timeline_switch (void)
-{
- GMainLoop *main_loop;
- ClutterFrameClock *frame_clock2;
- ClutterFrameClock *frame_clock1;
- ClutterTimeline *timeline;
- int frame_counter;
- int64_t before_us;
- int64_t after_us;
-
- main_loop = g_main_loop_new (NULL, FALSE);
-
- frame_clock1 = clutter_frame_clock_new (refresh_rate,
- 0,
- &timeline_frame_listener_iface,
- NULL);
- g_object_add_weak_pointer (G_OBJECT (frame_clock1), (gpointer *) &frame_clock1);
- frame_clock2 = clutter_frame_clock_new (refresh_rate,
- 0,
- &timeline_frame_listener_iface,
- NULL);
- g_object_add_weak_pointer (G_OBJECT (frame_clock2), (gpointer *) &frame_clock2);
-
- timeline = g_object_new (CLUTTER_TYPE_TIMELINE,
- "duration", 1000,
- "frame-clock", frame_clock1,
- NULL);
- g_object_add_weak_pointer (G_OBJECT (timeline), (gpointer *) &timeline);
-
- clutter_timeline_add_marker_at_time (timeline, "switch", 500);
-
- frame_counter = 0;
-
- g_signal_connect (timeline, "marker-reached::switch",
- G_CALLBACK (on_switch_reached),
- frame_clock2);
- g_signal_connect (timeline, "new-frame",
- G_CALLBACK (on_timeline_new_frame),
- &frame_counter);
- g_signal_connect (timeline, "completed",
- G_CALLBACK (on_timeline_completed),
- main_loop);
-
- clutter_timeline_start (timeline);
-
- before_us = g_get_monotonic_time ();
-
- g_main_loop_run (main_loop);
-
- after_us = g_get_monotonic_time ();
-
- g_assert_cmpint (after_us - before_us,
- >=,
- ms2us (clutter_timeline_get_duration (timeline)));
-
- g_assert (clutter_timeline_get_frame_clock (timeline) == frame_clock2);
-
- /* The duration is 1s, with a 60hz clock, and we switch after 0.5s. To verify
- * we continued to get frames, check that we have a bit more than half of the
- * frames accounted for.
- */
- g_assert_cmpint (frame_counter, >, 35);
-
- g_main_loop_unref (main_loop);
- g_object_unref (timeline);
- g_assert_null (timeline);
- clutter_frame_clock_destroy (frame_clock1);
- g_assert_null (frame_clock1);
- clutter_frame_clock_destroy (frame_clock2);
- g_assert_null (frame_clock2);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/frame-clock/timeline/basic", frame_clock_timeline_basic)
- CLUTTER_TEST_UNIT ("/frame-clock/timeline/switch", frame_clock_timeline_switch)
-)
diff --git a/src/tests/clutter/conform/frame-clock.c b/src/tests/clutter/conform/frame-clock.c
deleted file mode 100644
index 810c39a02..000000000
--- a/src/tests/clutter/conform/frame-clock.c
+++ /dev/null
@@ -1,846 +0,0 @@
-#include "clutter/clutter.h"
-#include "tests/clutter-test-utils.h"
-
-static const float refresh_rate = 60.0;
-static const int64_t refresh_interval_us = (int64_t) (0.5 + G_USEC_PER_SEC /
- refresh_rate);
-
-static int64_t test_frame_count;
-static int64_t expected_frame_count;
-
-typedef struct _FakeHwClock
-{
- GSource source;
-
- ClutterFrameClock *frame_clock;
-
- int64_t next_presentation_time_us;
- gboolean has_pending_present;
-} FakeHwClock;
-
-typedef struct _FrameClockTest
-{
- FakeHwClock *fake_hw_clock;
-
- GMainLoop *main_loop;
-} FrameClockTest;
-
-static void
-init_frame_info (ClutterFrameInfo *frame_info,
- int64_t presentation_time_us)
-{
- *frame_info = (ClutterFrameInfo) {
- .presentation_time = presentation_time_us,
- .refresh_rate = refresh_rate,
- .flags = CLUTTER_FRAME_INFO_FLAG_NONE,
- .sequence = 0,
- };
-}
-
-static gboolean
-fake_hw_clock_source_dispatch (GSource *source,
- GSourceFunc callback,
- gpointer user_data)
-{
- FakeHwClock *fake_hw_clock = (FakeHwClock *) source;
- ClutterFrameClock *frame_clock = fake_hw_clock->frame_clock;
-
- if (fake_hw_clock->has_pending_present)
- {
- ClutterFrameInfo frame_info;
-
- fake_hw_clock->has_pending_present = FALSE;
- init_frame_info (&frame_info, g_source_get_time (source));
- clutter_frame_clock_notify_presented (frame_clock, &frame_info);
- if (callback)
- callback (user_data);
- }
-
- fake_hw_clock->next_presentation_time_us += refresh_interval_us;
- g_source_set_ready_time (source, fake_hw_clock->next_presentation_time_us);
-
- return G_SOURCE_CONTINUE;
-}
-
-static GSourceFuncs fake_hw_clock_source_funcs = {
- NULL,
- NULL,
- fake_hw_clock_source_dispatch,
- NULL
-};
-
-static FakeHwClock *
-fake_hw_clock_new (ClutterFrameClock *frame_clock,
- GSourceFunc callback,
- gpointer user_data)
-{
- GSource *source;
- FakeHwClock *fake_hw_clock;
-
- source = g_source_new (&fake_hw_clock_source_funcs, sizeof (FakeHwClock));
- fake_hw_clock = (FakeHwClock *) source;
- fake_hw_clock->frame_clock = frame_clock;
-
- fake_hw_clock->next_presentation_time_us =
- g_get_monotonic_time () + refresh_interval_us;
- g_source_set_ready_time (source, fake_hw_clock->next_presentation_time_us);
- g_source_set_callback (source, callback, user_data, NULL);
-
- return fake_hw_clock;
-}
-
-static ClutterFrameResult
-frame_clock_frame (ClutterFrameClock *frame_clock,
- int64_t frame_count,
- int64_t time_us,
- gpointer user_data)
-{
- FrameClockTest *test = user_data;
- GMainLoop *main_loop = test->main_loop;
-
- g_assert_cmpint (frame_count, ==, expected_frame_count);
-
- expected_frame_count++;
-
- if (test_frame_count == 0)
- {
- g_main_loop_quit (main_loop);
- return CLUTTER_FRAME_RESULT_IDLE;
- }
- else
- {
- test->fake_hw_clock->has_pending_present = TRUE;
- }
-
- test_frame_count--;
-
- return CLUTTER_FRAME_RESULT_PENDING_PRESENTED;
-}
-
-static const ClutterFrameListenerIface frame_listener_iface = {
- .frame = frame_clock_frame,
-};
-
-static gboolean
-schedule_update_hw_callback (gpointer user_data)
-{
- ClutterFrameClock *frame_clock = user_data;
-
- clutter_frame_clock_schedule_update (frame_clock);
-
- return G_SOURCE_CONTINUE;
-}
-
-static void
-frame_clock_schedule_update (void)
-{
- FrameClockTest test;
- ClutterFrameClock *frame_clock;
- int64_t before_us;
- int64_t after_us;
- GSource *source;
- FakeHwClock *fake_hw_clock;
-
- test_frame_count = 10;
- expected_frame_count = 0;
-
- test.main_loop = g_main_loop_new (NULL, FALSE);
- frame_clock = clutter_frame_clock_new (refresh_rate,
- 0,
- &frame_listener_iface,
- &test);
-
- fake_hw_clock = fake_hw_clock_new (frame_clock,
- schedule_update_hw_callback,
- frame_clock);
- source = &fake_hw_clock->source;
- g_source_attach (source, NULL);
-
- test.fake_hw_clock = fake_hw_clock;
-
- before_us = g_get_monotonic_time ();
-
- clutter_frame_clock_schedule_update (frame_clock);
- g_main_loop_run (test.main_loop);
-
- after_us = g_get_monotonic_time ();
-
- g_assert_cmpint (after_us - before_us, >, 10 * refresh_interval_us);
-
- g_main_loop_unref (test.main_loop);
-
- clutter_frame_clock_destroy (frame_clock);
- g_source_destroy (source);
- g_source_unref (source);
-}
-
-static gboolean
-schedule_update_idle (gpointer user_data)
-{
- ClutterFrameClock *frame_clock = user_data;
-
- clutter_frame_clock_schedule_update (frame_clock);
-
- return G_SOURCE_REMOVE;
-}
-
-static ClutterFrameResult
-immediate_frame_clock_frame (ClutterFrameClock *frame_clock,
- int64_t frame_count,
- int64_t time_us,
- gpointer user_data)
-{
- GMainLoop *main_loop = user_data;
- ClutterFrameInfo frame_info;
-
- g_assert_cmpint (frame_count, ==, expected_frame_count);
-
- expected_frame_count++;
-
- if (test_frame_count == 0)
- {
- g_main_loop_quit (main_loop);
- return CLUTTER_FRAME_RESULT_IDLE;
- }
-
- test_frame_count--;
-
- init_frame_info (&frame_info, g_get_monotonic_time ());
- clutter_frame_clock_notify_presented (frame_clock, &frame_info);
- g_idle_add (schedule_update_idle, frame_clock);
-
- return CLUTTER_FRAME_RESULT_PENDING_PRESENTED;
-}
-
-static const ClutterFrameListenerIface immediate_frame_listener_iface = {
- .frame = immediate_frame_clock_frame,
-};
-
-static void
-frame_clock_immediate_present (void)
-{
- GMainLoop *main_loop;
- ClutterFrameClock *frame_clock;
- int64_t before_us;
- int64_t after_us;
-
- test_frame_count = 10;
- expected_frame_count = 0;
-
- main_loop = g_main_loop_new (NULL, FALSE);
- frame_clock = clutter_frame_clock_new (refresh_rate,
- 0,
- &immediate_frame_listener_iface,
- main_loop);
-
- before_us = g_get_monotonic_time ();
-
- clutter_frame_clock_schedule_update (frame_clock);
- g_main_loop_run (main_loop);
-
- after_us = g_get_monotonic_time ();
-
- /* The initial frame will only be delayed by 2 ms, so we are checking one
- * less.
- */
- g_assert_cmpint (after_us - before_us, >, 9 * refresh_interval_us);
-
- g_main_loop_unref (main_loop);
- clutter_frame_clock_destroy (frame_clock);
-}
-
-static gboolean
-schedule_update_timeout (gpointer user_data)
-{
- ClutterFrameClock *frame_clock = user_data;
-
- clutter_frame_clock_schedule_update (frame_clock);
-
- return G_SOURCE_REMOVE;
-}
-
-static ClutterFrameResult
-delayed_damage_frame_clock_frame (ClutterFrameClock *frame_clock,
- int64_t frame_count,
- int64_t time_us,
- gpointer user_data)
-{
- FrameClockTest *test = user_data;
- GMainLoop *main_loop = test->main_loop;
-
- g_assert_cmpint (frame_count, ==, expected_frame_count);
-
- expected_frame_count++;
-
- if (test_frame_count == 0)
- {
- g_main_loop_quit (main_loop);
- return CLUTTER_FRAME_RESULT_IDLE;
- }
- else
- {
- test->fake_hw_clock->has_pending_present = TRUE;
- }
-
- test_frame_count--;
-
- g_timeout_add (100, schedule_update_timeout, frame_clock);
-
- return CLUTTER_FRAME_RESULT_PENDING_PRESENTED;
-}
-
-static const ClutterFrameListenerIface delayed_damage_frame_listener_iface = {
- .frame = delayed_damage_frame_clock_frame,
-};
-
-static void
-frame_clock_delayed_damage (void)
-{
- FrameClockTest test;
- ClutterFrameClock *frame_clock;
- int64_t before_us;
- int64_t after_us;
- FakeHwClock *fake_hw_clock;
- GSource *source;
-
- test_frame_count = 2;
- expected_frame_count = 0;
-
- test.main_loop = g_main_loop_new (NULL, FALSE);
- frame_clock = clutter_frame_clock_new (refresh_rate,
- 0,
- &delayed_damage_frame_listener_iface,
- &test);
-
- fake_hw_clock = fake_hw_clock_new (frame_clock, NULL, NULL);
- source = &fake_hw_clock->source;
- g_source_attach (source, NULL);
-
- test.fake_hw_clock = fake_hw_clock;
-
- before_us = g_get_monotonic_time ();
-
- clutter_frame_clock_schedule_update (frame_clock);
- g_main_loop_run (test.main_loop);
-
- after_us = g_get_monotonic_time ();
-
- g_assert_cmpint (after_us - before_us, >, 100000 + refresh_interval_us);
-
- g_main_loop_unref (test.main_loop);
- clutter_frame_clock_destroy (frame_clock);
- g_source_destroy (source);
- g_source_unref (source);
-}
-
-static ClutterFrameResult
-no_damage_frame_clock_frame (ClutterFrameClock *frame_clock,
- int64_t frame_count,
- int64_t time_us,
- gpointer user_data)
-{
- g_assert_not_reached ();
-
- return CLUTTER_FRAME_RESULT_PENDING_PRESENTED;
-}
-
-static const ClutterFrameListenerIface no_damage_frame_listener_iface = {
- .frame = no_damage_frame_clock_frame,
-};
-
-static gboolean
-quit_main_loop_idle (gpointer user_data)
-{
- GMainLoop *main_loop = user_data;
-
- g_main_loop_quit (main_loop);
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-frame_clock_no_damage (void)
-{
- GMainLoop *main_loop;
- ClutterFrameClock *frame_clock;
-
- test_frame_count = 10;
- expected_frame_count = 0;
-
- main_loop = g_main_loop_new (NULL, FALSE);
- frame_clock = clutter_frame_clock_new (refresh_rate,
- 0,
- &no_damage_frame_listener_iface,
- NULL);
-
- g_timeout_add (100, quit_main_loop_idle, main_loop);
-
- g_main_loop_run (main_loop);
-
- g_main_loop_unref (main_loop);
- clutter_frame_clock_destroy (frame_clock);
-}
-
-typedef struct _UpdateNowFrameClockTest
-{
- FrameClockTest base;
- guint idle_source_id;
-} UpdateNowFrameClockTest;
-
-static ClutterFrameResult
-update_now_frame_clock_frame (ClutterFrameClock *frame_clock,
- int64_t frame_count,
- int64_t time_us,
- gpointer user_data)
-{
- UpdateNowFrameClockTest *test = user_data;
- GMainLoop *main_loop = test->base.main_loop;
-
- g_assert_cmpint (frame_count, ==, expected_frame_count);
-
- expected_frame_count++;
-
- g_clear_handle_id (&test->idle_source_id, g_source_remove);
-
- if (test_frame_count == 0)
- {
- g_main_loop_quit (main_loop);
- return CLUTTER_FRAME_RESULT_IDLE;
- }
- else
- {
- test->base.fake_hw_clock->has_pending_present = TRUE;
- }
-
- test_frame_count--;
-
- return CLUTTER_FRAME_RESULT_PENDING_PRESENTED;
-}
-
-static const ClutterFrameListenerIface update_now_frame_listener_iface = {
- .frame = update_now_frame_clock_frame,
-};
-
-static gboolean
-assert_not_reached_idle (gpointer user_data)
-{
- g_assert_not_reached ();
- return G_SOURCE_REMOVE;
-}
-
-static gboolean
-schedule_update_now_hw_callback (gpointer user_data)
-{
- UpdateNowFrameClockTest *test = user_data;
- ClutterFrameClock *frame_clock = test->base.fake_hw_clock->frame_clock;
-
- clutter_frame_clock_schedule_update_now (frame_clock);
- g_assert (!test->idle_source_id);
- test->idle_source_id = g_idle_add (assert_not_reached_idle, NULL);
-
- return G_SOURCE_CONTINUE;
-}
-
-static void
-frame_clock_schedule_update_now (void)
-{
- UpdateNowFrameClockTest test = { 0 };
- ClutterFrameClock *frame_clock;
- int64_t before_us;
- int64_t after_us;
- GSource *source;
- FakeHwClock *fake_hw_clock;
-
- test_frame_count = 10;
- expected_frame_count = 0;
-
- test.base.main_loop = g_main_loop_new (NULL, FALSE);
- frame_clock = clutter_frame_clock_new (refresh_rate,
- 0,
- &update_now_frame_listener_iface,
- &test);
-
- fake_hw_clock = fake_hw_clock_new (frame_clock,
- schedule_update_now_hw_callback,
- &test);
- source = &fake_hw_clock->source;
- g_source_attach (source, NULL);
-
- test.base.fake_hw_clock = fake_hw_clock;
-
- before_us = g_get_monotonic_time ();
-
- clutter_frame_clock_schedule_update (frame_clock);
- g_main_loop_run (test.base.main_loop);
-
- after_us = g_get_monotonic_time ();
-
- g_assert_cmpint (after_us - before_us, >, 10 * refresh_interval_us);
-
- g_main_loop_unref (test.base.main_loop);
-
- clutter_frame_clock_destroy (frame_clock);
- g_source_destroy (source);
- g_source_unref (source);
-}
-
-static void
-before_frame_frame_clock_before_frame (ClutterFrameClock *frame_clock,
- int64_t frame_count,
- gpointer user_data)
-{
- int64_t *expected_frame_count = user_data;
-
- g_assert_cmpint (*expected_frame_count, ==, frame_count);
-}
-
-static ClutterFrameResult
-before_frame_frame_clock_frame (ClutterFrameClock *frame_clock,
- int64_t frame_count,
- int64_t time_us,
- gpointer user_data)
-{
- int64_t *expected_frame_count = user_data;
- ClutterFrameInfo frame_info;
-
- g_assert_cmpint (*expected_frame_count, ==, frame_count);
-
- (*expected_frame_count)++;
-
- init_frame_info (&frame_info, g_get_monotonic_time ());
- clutter_frame_clock_notify_presented (frame_clock, &frame_info);
- clutter_frame_clock_schedule_update (frame_clock);
-
- return CLUTTER_FRAME_RESULT_PENDING_PRESENTED;
-}
-
-static const ClutterFrameListenerIface before_frame_frame_listener_iface = {
- .before_frame = before_frame_frame_clock_before_frame,
- .frame = before_frame_frame_clock_frame,
-};
-
-static gboolean
-quit_main_loop_timeout (gpointer user_data)
-{
- GMainLoop *main_loop = user_data;
-
- g_main_loop_quit (main_loop);
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-frame_clock_before_frame (void)
-{
- GMainLoop *main_loop;
- ClutterFrameClock *frame_clock;
-
- expected_frame_count = 0;
-
- main_loop = g_main_loop_new (NULL, FALSE);
- frame_clock = clutter_frame_clock_new (refresh_rate,
- 0,
- &before_frame_frame_listener_iface,
- &expected_frame_count);
-
- clutter_frame_clock_schedule_update (frame_clock);
- g_timeout_add (100, quit_main_loop_timeout, main_loop);
- g_main_loop_run (main_loop);
-
- /* We should have at least processed a couple of frames within 100 ms. */
- g_assert_cmpint (expected_frame_count, >, 2);
-
- g_main_loop_unref (main_loop);
- clutter_frame_clock_destroy (frame_clock);
-}
-
-typedef struct _InhibitTest
-{
- GMainLoop *main_loop;
- ClutterFrameClock *frame_clock;
-
- gboolean frame_count;
- gboolean pending_inhibit;
- gboolean pending_quit;
-} InhibitTest;
-
-static ClutterFrameResult
-inhibit_frame_clock_frame (ClutterFrameClock *frame_clock,
- int64_t frame_count,
- int64_t time_us,
- gpointer user_data)
-{
- InhibitTest *test = user_data;
- ClutterFrameInfo frame_info;
-
- g_assert_cmpint (frame_count, ==, test->frame_count);
-
- test->frame_count++;
-
- init_frame_info (&frame_info, g_get_monotonic_time ());
- clutter_frame_clock_notify_presented (frame_clock, &frame_info);
- clutter_frame_clock_schedule_update (frame_clock);
-
- if (test->pending_inhibit)
- {
- test->pending_inhibit = FALSE;
- clutter_frame_clock_inhibit (frame_clock);
- }
-
- clutter_frame_clock_schedule_update (frame_clock);
-
- if (test->pending_quit)
- g_main_loop_quit (test->main_loop);
-
- return CLUTTER_FRAME_RESULT_PENDING_PRESENTED;
-}
-
-static const ClutterFrameListenerIface inhibit_frame_listener_iface = {
- .frame = inhibit_frame_clock_frame,
-};
-
-static gboolean
-uninhibit_timeout (gpointer user_data)
-{
- InhibitTest *test = user_data;
-
- g_assert_cmpint (test->frame_count, ==, 1);
-
- clutter_frame_clock_uninhibit (test->frame_clock);
- test->pending_quit = TRUE;
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-frame_clock_inhibit (void)
-{
- InhibitTest test = { 0 };
-
- expected_frame_count = 0;
-
- test.main_loop = g_main_loop_new (NULL, FALSE);
- test.frame_clock = clutter_frame_clock_new (refresh_rate,
- 0,
- &inhibit_frame_listener_iface,
- &test);
-
- test.pending_inhibit = TRUE;
-
- clutter_frame_clock_schedule_update (test.frame_clock);
- g_timeout_add (100, uninhibit_timeout, &test);
- g_main_loop_run (test.main_loop);
-
- g_assert_cmpint (test.frame_count, ==, 2);
-
- g_main_loop_unref (test.main_loop);
- clutter_frame_clock_destroy (test.frame_clock);
-}
-
-typedef struct _RescheduleOnIdleFrameClockTest
-{
- FrameClockTest base;
-} RescheduleOnIdleFrameClockTest;
-
-static ClutterFrameResult
-reschedule_on_idle_clock_frame (ClutterFrameClock *frame_clock,
- int64_t frame_count,
- int64_t time_us,
- gpointer user_data)
-{
- RescheduleOnIdleFrameClockTest *test = user_data;
- GMainLoop *main_loop = test->base.main_loop;
-
- g_assert_cmpint (frame_count, ==, expected_frame_count);
-
- expected_frame_count++;
-
- if (test_frame_count == 0)
- {
- g_main_loop_quit (main_loop);
- return CLUTTER_FRAME_RESULT_IDLE;
- }
-
- test_frame_count--;
-
- clutter_frame_clock_schedule_update (frame_clock);
-
- return CLUTTER_FRAME_RESULT_IDLE;
-}
-
-static const ClutterFrameListenerIface reschedule_on_idle_listener_iface = {
- .frame = reschedule_on_idle_clock_frame,
-};
-
-static void
-frame_clock_reschedule_on_idle (void)
-{
- RescheduleOnIdleFrameClockTest test;
- ClutterFrameClock *frame_clock;
- FakeHwClock *fake_hw_clock;
- GSource *source;
-
- test_frame_count = 10;
- expected_frame_count = 0;
-
- test.base.main_loop = g_main_loop_new (NULL, FALSE);
- frame_clock = clutter_frame_clock_new (refresh_rate,
- 0,
- &reschedule_on_idle_listener_iface,
- &test);
- fake_hw_clock = fake_hw_clock_new (frame_clock, NULL, NULL);
- source = &fake_hw_clock->source;
- g_source_attach (source, NULL);
- test.base.fake_hw_clock = fake_hw_clock;
-
- clutter_frame_clock_schedule_update (frame_clock);
- g_main_loop_run (test.base.main_loop);
-
- g_main_loop_unref (test.base.main_loop);
- clutter_frame_clock_destroy (frame_clock);
-}
-
-static const ClutterFrameListenerIface dummy_frame_listener_iface = {
- .frame = NULL,
-};
-
-static void
-on_destroy (ClutterFrameClock *frame_clock,
- gboolean *destroy_signalled)
-{
- g_assert_false (*destroy_signalled);
- *destroy_signalled = TRUE;
-}
-
-static void
-frame_clock_destroy_signal (void)
-{
- ClutterFrameClock *frame_clock;
- ClutterFrameClock *frame_clock_backup;
- gboolean destroy_signalled;
-
- /* Test that the destroy signal is emitted when removing last reference. */
-
- frame_clock = clutter_frame_clock_new (refresh_rate,
- 0,
- &dummy_frame_listener_iface,
- NULL);
-
- destroy_signalled = FALSE;
- g_signal_connect (frame_clock, "destroy",
- G_CALLBACK (on_destroy),
- &destroy_signalled);
- g_object_add_weak_pointer (G_OBJECT (frame_clock), (gpointer *) &frame_clock);
-
- g_object_unref (frame_clock);
- g_assert_true (destroy_signalled);
- g_assert_null (frame_clock);
-
- /* Test that destroy signal is emitted when destroying with references still
- * left.
- */
-
- frame_clock = clutter_frame_clock_new (refresh_rate,
- 0,
- &dummy_frame_listener_iface,
- NULL);
- frame_clock_backup = frame_clock;
-
- destroy_signalled = FALSE;
- g_signal_connect (frame_clock, "destroy",
- G_CALLBACK (on_destroy),
- &destroy_signalled);
- g_object_add_weak_pointer (G_OBJECT (frame_clock), (gpointer *) &frame_clock);
- g_object_ref (frame_clock);
-
- clutter_frame_clock_destroy (frame_clock);
- g_assert_true (destroy_signalled);
- g_assert_null (frame_clock);
- g_object_unref (frame_clock_backup);
-}
-
-static gboolean
-notify_ready_and_schedule_update_idle (gpointer user_data)
-{
- ClutterFrameClock *frame_clock = user_data;
-
- clutter_frame_clock_notify_ready (frame_clock);
- clutter_frame_clock_schedule_update (frame_clock);
-
- return G_SOURCE_REMOVE;
-}
-
-static ClutterFrameResult
-frame_clock_ready_frame (ClutterFrameClock *frame_clock,
- int64_t frame_count,
- int64_t time_us,
- gpointer user_data)
-{
- GMainLoop *main_loop = user_data;
-
- g_assert_cmpint (frame_count, ==, expected_frame_count);
-
- expected_frame_count++;
-
- if (test_frame_count == 0)
- {
- g_main_loop_quit (main_loop);
- return CLUTTER_FRAME_RESULT_IDLE;
- }
-
- test_frame_count--;
-
- g_idle_add (notify_ready_and_schedule_update_idle, frame_clock);
-
- return CLUTTER_FRAME_RESULT_PENDING_PRESENTED;
-}
-
-static const ClutterFrameListenerIface frame_clock_ready_listener_iface = {
- .frame = frame_clock_ready_frame,
-};
-
-static void
-frame_clock_notify_ready (void)
-{
- GMainLoop *main_loop;
- ClutterFrameClock *frame_clock;
- int64_t before_us;
- int64_t after_us;
-
- test_frame_count = 10;
- expected_frame_count = 0;
-
- main_loop = g_main_loop_new (NULL, FALSE);
- frame_clock = clutter_frame_clock_new (refresh_rate,
- 0,
- &frame_clock_ready_listener_iface,
- main_loop);
-
- before_us = g_get_monotonic_time ();
-
- clutter_frame_clock_schedule_update (frame_clock);
- g_main_loop_run (main_loop);
-
- after_us = g_get_monotonic_time ();
-
- /* The initial frame will only be delayed by 2 ms, so we are checking one
- * less.
- */
- g_assert_cmpint (after_us - before_us, >, 8 * refresh_interval_us);
-
- g_main_loop_unref (main_loop);
- clutter_frame_clock_destroy (frame_clock);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/frame-clock/schedule-update", frame_clock_schedule_update)
- CLUTTER_TEST_UNIT ("/frame-clock/immediate-present", frame_clock_immediate_present)
- CLUTTER_TEST_UNIT ("/frame-clock/delayed-damage", frame_clock_delayed_damage)
- CLUTTER_TEST_UNIT ("/frame-clock/no-damage", frame_clock_no_damage)
- CLUTTER_TEST_UNIT ("/frame-clock/schedule-update-now", frame_clock_schedule_update_now)
- CLUTTER_TEST_UNIT ("/frame-clock/before-frame", frame_clock_before_frame)
- CLUTTER_TEST_UNIT ("/frame-clock/inhibit", frame_clock_inhibit)
- CLUTTER_TEST_UNIT ("/frame-clock/reschedule-on-idle", frame_clock_reschedule_on_idle)
- CLUTTER_TEST_UNIT ("/frame-clock/destroy-signal", frame_clock_destroy_signal)
- CLUTTER_TEST_UNIT ("/frame-clock/notify-ready", frame_clock_notify_ready)
-)
diff --git a/src/tests/clutter/conform/interval.c b/src/tests/clutter/conform/interval.c
deleted file mode 100644
index 263a25b37..000000000
--- a/src/tests/clutter/conform/interval.c
+++ /dev/null
@@ -1,119 +0,0 @@
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-static void
-interval_initial_state (void)
-{
- ClutterInterval *interval;
- int initial, final;
- const GValue *value;
-
- interval = clutter_interval_new (G_TYPE_INT, 0, 100);
- g_assert (CLUTTER_IS_INTERVAL (interval));
- g_assert (clutter_interval_get_value_type (interval) == G_TYPE_INT);
-
- clutter_interval_get_interval (interval, &initial, &final);
- g_assert_cmpint (initial, ==, 0);
- g_assert_cmpint (final, ==, 100);
-
- value = clutter_interval_compute (interval, 0);
- g_assert (G_VALUE_HOLDS_INT (value));
- g_assert_cmpint (g_value_get_int (value), ==, 0);
-
- value = clutter_interval_compute (interval, 1);
- g_assert (G_VALUE_HOLDS_INT (value));
- g_assert_cmpint (g_value_get_int (value), ==, 100);
-
- value = clutter_interval_compute (interval, 0.5);
- g_assert (G_VALUE_HOLDS_INT (value));
- g_assert_cmpint (g_value_get_int (value), ==, 50);
-
- clutter_interval_set_final (interval, 200);
- value = clutter_interval_peek_final_value (interval);
- g_assert (G_VALUE_HOLDS_INT (value));
- g_assert_cmpint (g_value_get_int (value), ==, 200);
-
- g_object_unref (interval);
-}
-
-static void
-interval_transform (void)
-{
- ClutterInterval *interval;
- GValue value = G_VALUE_INIT;
- const GValue *value_p = NULL;
-
- interval = clutter_interval_new_with_values (G_TYPE_FLOAT, NULL, NULL);
-
- g_value_init (&value, G_TYPE_DOUBLE);
-
- g_value_set_double (&value, 0.0);
- clutter_interval_set_initial_value (interval, &value);
-
- g_value_set_double (&value, 100.0);
- clutter_interval_set_final_value (interval, &value);
-
- g_value_unset (&value);
-
- value_p = clutter_interval_peek_initial_value (interval);
- g_assert (G_VALUE_HOLDS_FLOAT (value_p));
- g_assert_cmpfloat (g_value_get_float (value_p), ==, 0.f);
-
- value_p = clutter_interval_peek_final_value (interval);
- g_assert (G_VALUE_HOLDS_FLOAT (value_p));
- g_assert_cmpfloat (g_value_get_float (value_p), ==, 100.f);
-
- g_object_unref (interval);
-}
-
-static void
-interval_from_script (void)
-{
- ClutterScript *script = clutter_script_new ();
- ClutterInterval *interval;
- gchar *test_file;
- GError *error = NULL;
- GValue *initial, *final;
-
- test_file = g_test_build_filename (G_TEST_DIST,
- "scripts",
- "test-script-interval.json",
- NULL);
- clutter_script_load_from_file (script, test_file, &error);
- if (!g_test_quiet () && error)
- g_printerr ("\tError: %s", error->message);
-
- g_assert_no_error (error);
-
- interval = CLUTTER_INTERVAL (clutter_script_get_object (script, "int-1"));
- initial = clutter_interval_peek_initial_value (interval);
- if (!g_test_quiet ())
- g_test_message ("\tinitial ['%s'] = '%.2f'",
- g_type_name (G_VALUE_TYPE (initial)),
- g_value_get_float (initial));
- g_assert (G_VALUE_HOLDS (initial, G_TYPE_FLOAT));
- g_assert_cmpfloat (g_value_get_float (initial), ==, 23.3f);
- final = clutter_interval_peek_final_value (interval);
- if (!g_test_quiet ())
- g_test_message ("\tfinal ['%s'] = '%.2f'",
- g_type_name (G_VALUE_TYPE (final)),
- g_value_get_float (final));
- g_assert (G_VALUE_HOLDS (final, G_TYPE_FLOAT));
- g_assert_cmpfloat (g_value_get_float (final), ==, 42.2f);
-
- interval = CLUTTER_INTERVAL (clutter_script_get_object (script, "int-2"));
- initial = clutter_interval_peek_initial_value (interval);
- g_assert (G_VALUE_HOLDS (initial, CLUTTER_TYPE_COLOR));
- final = clutter_interval_peek_final_value (interval);
- g_assert (G_VALUE_HOLDS (final, CLUTTER_TYPE_COLOR));
-
- g_object_unref (script);
- g_free (test_file);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/interval/initial-state", interval_initial_state)
- CLUTTER_TEST_UNIT ("/interval/transform", interval_transform)
- CLUTTER_TEST_UNIT ("/interval/from-script", interval_from_script)
-)
diff --git a/src/tests/clutter/conform/meson.build b/src/tests/clutter/conform/meson.build
deleted file mode 100644
index aec4a9148..000000000
--- a/src/tests/clutter/conform/meson.build
+++ /dev/null
@@ -1,79 +0,0 @@
-clutter_tests_conform_c_args = [
- '-DG_LOG_DOMAIN="Clutter-Conform"',
- '-DCOGL_DISABLE_DEPRECATION_WARNINGS',
- '-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()),
-]
-clutter_tests_conform_c_args += clutter_debug_c_args
-
-clutter_tests_conform_link_args = [
- '-Wl,--export-dynamic',
-]
-
-clutter_conform_tests_actor_tests = [
- 'actor-clone',
- 'actor-destroy',
- 'actor-graph',
- 'actor-invariants',
- 'actor-iter',
- 'actor-layout',
- 'actor-meta',
- 'actor-offscreen-redirect',
- 'actor-paint-opacity',
- 'actor-pick',
- 'actor-pivot-point',
- 'actor-shader-effect',
- 'actor-size',
-]
-
-clutter_conform_tests_classes_tests = [
- 'text',
-]
-
-clutter_conform_tests_general_tests = [
- 'binding-pool',
- 'color',
- 'frame-clock',
- 'frame-clock-timeline',
- 'interval',
- 'script-parser',
- 'timeline',
- 'timeline-interpolate',
- 'timeline-progress',
- 'timeline-rewind',
- 'units',
-]
-
-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
-
-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')
-test_env.set('MUTTER_TEST_PLUGIN_PATH', '@0@'.format(default_plugin.full_path()))
-
-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: [
- libmutter_test_dep,
- ],
- install: false,
- )
-
- test(test, test_executable,
- suite: ['clutter', 'clutter/conform'],
- env: test_env,
- is_parallel: false,
- )
-endforeach
diff --git a/src/tests/clutter/conform/path.c b/src/tests/clutter/conform/path.c
deleted file mode 100644
index 55620069a..000000000
--- a/src/tests/clutter/conform/path.c
+++ /dev/null
@@ -1,740 +0,0 @@
-#include <clutter/clutter.h>
-#include <cairo.h>
-#include <string.h>
-#include <math.h>
-
-#include "test-conform-common.h"
-
-#define MAX_NODES 128
-
-#define FLOAT_FUZZ_AMOUNT 5.0f
-
-typedef struct _CallbackData CallbackData;
-
-typedef gboolean (* PathTestFunc) (CallbackData *data);
-
-static void compare_node (const ClutterPathNode *node, gpointer data_p);
-
-struct _CallbackData
-{
- ClutterPath *path;
-
- guint n_nodes;
- ClutterPathNode nodes[MAX_NODES];
-
- gboolean nodes_different;
- guint nodes_found;
-};
-
-static const char path_desc[] =
- "M 21 22 "
- "L 25 26 "
- "C 29 30 31 32 33 34 "
- "m 23 24 "
- "l 27 28 "
- "c 35 36 37 38 39 40 "
- "z";
-static const ClutterPathNode path_nodes[] =
- { { CLUTTER_PATH_MOVE_TO, { { 21, 22 }, { 0, 0 }, { 0, 0 } } },
- { CLUTTER_PATH_LINE_TO, { { 25, 26 }, { 0, 0 }, { 0, 0 } } },
- { CLUTTER_PATH_CURVE_TO, { { 29, 30 }, { 31, 32 }, { 33, 34 } } },
- { CLUTTER_PATH_REL_MOVE_TO, { { 23, 24 }, { 0, 0 }, { 0, 0 } } },
- { CLUTTER_PATH_REL_LINE_TO, { { 27, 28 }, { 0, 0 }, { 0, 0 } } },
- { CLUTTER_PATH_REL_CURVE_TO, { { 35, 36 }, { 37, 38 }, { 39, 40 } } },
- { CLUTTER_PATH_CLOSE, { { 0, 0 }, { 0, 0 }, { 0, 0 } } } };
-
-static gboolean
-path_test_add_move_to (CallbackData *data)
-{
- ClutterPathNode node = { 0, };
-
- node.type = CLUTTER_PATH_MOVE_TO;
- node.points[0].x = 1;
- node.points[0].y = 2;
-
- clutter_path_add_move_to (data->path, node.points[0].x, node.points[0].y);
-
- data->nodes[data->n_nodes++] = node;
-
- return TRUE;
-}
-
-static gboolean
-path_test_add_line_to (CallbackData *data)
-{
- ClutterPathNode node = { 0, };
-
- node.type = CLUTTER_PATH_LINE_TO;
- node.points[0].x = 3;
- node.points[0].y = 4;
-
- clutter_path_add_line_to (data->path, node.points[0].x, node.points[0].y);
-
- data->nodes[data->n_nodes++] = node;
-
- return TRUE;
-}
-
-static gboolean
-path_test_add_curve_to (CallbackData *data)
-{
- ClutterPathNode node = { 0, };
-
- node.type = CLUTTER_PATH_CURVE_TO;
- node.points[0].x = 5;
- node.points[0].y = 6;
- node.points[1].x = 7;
- node.points[1].y = 8;
- node.points[2].x = 9;
- node.points[2].y = 10;
-
- clutter_path_add_curve_to (data->path,
- node.points[0].x, node.points[0].y,
- node.points[1].x, node.points[1].y,
- node.points[2].x, node.points[2].y);
-
- data->nodes[data->n_nodes++] = node;
-
- return TRUE;
-}
-
-static gboolean
-path_test_add_close (CallbackData *data)
-{
- ClutterPathNode node = { 0, };
-
- node.type = CLUTTER_PATH_CLOSE;
-
- clutter_path_add_close (data->path);
-
- data->nodes[data->n_nodes++] = node;
-
- return TRUE;
-}
-
-static gboolean
-path_test_add_rel_move_to (CallbackData *data)
-{
- ClutterPathNode node = { 0, };
-
- node.type = CLUTTER_PATH_REL_MOVE_TO;
- node.points[0].x = 11;
- node.points[0].y = 12;
-
- clutter_path_add_rel_move_to (data->path, node.points[0].x, node.points[0].y);
-
- data->nodes[data->n_nodes++] = node;
-
- return TRUE;
-}
-
-static gboolean
-path_test_add_rel_line_to (CallbackData *data)
-{
- ClutterPathNode node = { 0, };
-
- node.type = CLUTTER_PATH_REL_LINE_TO;
- node.points[0].x = 13;
- node.points[0].y = 14;
-
- clutter_path_add_rel_line_to (data->path, node.points[0].x, node.points[0].y);
-
- data->nodes[data->n_nodes++] = node;
-
- return TRUE;
-}
-
-static gboolean
-path_test_add_rel_curve_to (CallbackData *data)
-{
- ClutterPathNode node = { 0, };
-
- node.type = CLUTTER_PATH_REL_CURVE_TO;
- node.points[0].x = 15;
- node.points[0].y = 16;
- node.points[1].x = 17;
- node.points[1].y = 18;
- node.points[2].x = 19;
- node.points[2].y = 20;
-
- clutter_path_add_rel_curve_to (data->path,
- node.points[0].x, node.points[0].y,
- node.points[1].x, node.points[1].y,
- node.points[2].x, node.points[2].y);
-
- data->nodes[data->n_nodes++] = node;
-
- return TRUE;
-}
-
-static gboolean
-path_test_add_string (CallbackData *data)
-{
- int i;
-
- for (i = 0; i < G_N_ELEMENTS (path_nodes); i++)
- data->nodes[data->n_nodes++] = path_nodes[i];
-
- clutter_path_add_string (data->path, path_desc);
-
- return TRUE;
-}
-
-static gboolean
-path_test_add_node_by_struct (CallbackData *data)
-{
- int i;
-
- for (i = 0; i < G_N_ELEMENTS (path_nodes); i++)
- {
- data->nodes[data->n_nodes++] = path_nodes[i];
- clutter_path_add_node (data->path, path_nodes + i);
- }
-
- return TRUE;
-}
-
-static gboolean
-path_test_get_n_nodes (CallbackData *data)
-{
- return clutter_path_get_n_nodes (data->path) == data->n_nodes;
-}
-
-static gboolean
-path_test_get_node (CallbackData *data)
-{
- int i;
-
- data->nodes_found = 0;
- data->nodes_different = FALSE;
-
- for (i = 0; i < data->n_nodes; i++)
- {
- ClutterPathNode node;
-
- clutter_path_get_node (data->path, i, &node);
-
- compare_node (&node, data);
- }
-
- return !data->nodes_different;
-}
-
-static gboolean
-path_test_get_nodes (CallbackData *data)
-{
- GSList *list, *node;
-
- data->nodes_found = 0;
- data->nodes_different = FALSE;
-
- list = clutter_path_get_nodes (data->path);
-
- for (node = list; node; node = node->next)
- compare_node (node->data, data);
-
- g_slist_free (list);
-
- return !data->nodes_different && data->nodes_found == data->n_nodes;
-}
-
-static gboolean
-path_test_insert_beginning (CallbackData *data)
-{
- ClutterPathNode node;
-
- node.type = CLUTTER_PATH_LINE_TO;
- node.points[0].x = 41;
- node.points[0].y = 42;
-
- memmove (data->nodes + 1, data->nodes,
- data->n_nodes++ * sizeof (ClutterPathNode));
- data->nodes[0] = node;
-
- clutter_path_insert_node (data->path, 0, &node);
-
- return TRUE;
-}
-
-static gboolean
-path_test_insert_end (CallbackData *data)
-{
- ClutterPathNode node;
-
- node.type = CLUTTER_PATH_LINE_TO;
- node.points[0].x = 43;
- node.points[0].y = 44;
-
- data->nodes[data->n_nodes++] = node;
-
- clutter_path_insert_node (data->path, -1, &node);
-
- return TRUE;
-}
-
-static gboolean
-path_test_insert_middle (CallbackData *data)
-{
- ClutterPathNode node;
- int pos = data->n_nodes / 2;
-
- node.type = CLUTTER_PATH_LINE_TO;
- node.points[0].x = 45;
- node.points[0].y = 46;
-
- memmove (data->nodes + pos + 1, data->nodes + pos,
- (data->n_nodes - pos) * sizeof (ClutterPathNode));
- data->nodes[pos] = node;
- data->n_nodes++;
-
- clutter_path_insert_node (data->path, pos, &node);
-
- return TRUE;
-}
-
-static gboolean
-path_test_clear (CallbackData *data)
-{
- clutter_path_clear (data->path);
-
- data->n_nodes = 0;
-
- return TRUE;
-}
-
-static gboolean
-path_test_clear_insert (CallbackData *data)
-{
- return path_test_clear (data) && path_test_insert_middle (data);
-}
-
-static gboolean
-path_test_remove_beginning (CallbackData *data)
-{
- memmove (data->nodes, data->nodes + 1,
- --data->n_nodes * sizeof (ClutterPathNode));
-
- clutter_path_remove_node (data->path, 0);
-
- return TRUE;
-}
-
-static gboolean
-path_test_remove_end (CallbackData *data)
-{
- clutter_path_remove_node (data->path, --data->n_nodes);
-
- return TRUE;
-}
-
-static gboolean
-path_test_remove_middle (CallbackData *data)
-{
- int pos = data->n_nodes / 2;
-
- memmove (data->nodes + pos, data->nodes + pos + 1,
- (--data->n_nodes - pos) * sizeof (ClutterPathNode));
-
- clutter_path_remove_node (data->path, pos);
-
- return TRUE;
-}
-
-static gboolean
-path_test_remove_only (CallbackData *data)
-{
- return path_test_clear (data)
- && path_test_add_line_to (data)
- && path_test_remove_beginning (data);
-}
-
-static gboolean
-path_test_replace (CallbackData *data)
-{
- ClutterPathNode node;
- int pos = data->n_nodes / 2;
-
- node.type = CLUTTER_PATH_LINE_TO;
- node.points[0].x = 47;
- node.points[0].y = 48;
-
- data->nodes[pos] = node;
-
- clutter_path_replace_node (data->path, pos, &node);
-
- return TRUE;
-}
-
-static gboolean
-path_test_set_description (CallbackData *data)
-{
- data->n_nodes = G_N_ELEMENTS (path_nodes);
- memcpy (data->nodes, path_nodes, sizeof (path_nodes));
-
- return clutter_path_set_description (data->path, path_desc);
-}
-
-static gboolean
-path_test_get_description (CallbackData *data)
-{
- char *desc1, *desc2;
- gboolean ret = TRUE;
-
- desc1 = clutter_path_get_description (data->path);
- clutter_path_clear (data->path);
- if (!clutter_path_set_description (data->path, desc1))
- ret = FALSE;
- desc2 = clutter_path_get_description (data->path);
-
- if (strcmp (desc1, desc2))
- ret = FALSE;
-
- g_free (desc1);
- g_free (desc2);
-
- return ret;
-}
-
-static gboolean
-path_test_convert_to_cairo_path (CallbackData *data)
-{
- cairo_surface_t *surface;
- cairo_t *cr;
- cairo_path_t *cpath;
- guint i, j;
- ClutterKnot path_start = { 0, 0 }, last_point = { 0, 0 };
-
- /* Create a temporary image surface and context to hold the cairo
- path */
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 10, 10);
- cr = cairo_create (surface);
-
- /* Convert to a cairo path */
- clutter_path_to_cairo_path (data->path, cr);
-
- /* Get a copy of the cairo path data */
- cpath = cairo_copy_path (cr);
-
- /* Convert back to a clutter path */
- clutter_path_clear (data->path);
- clutter_path_add_cairo_path (data->path, cpath);
-
- /* The relative nodes will have been converted to absolute so we
- need to reflect this in the node array for comparison */
- for (i = 0; i < data->n_nodes; i++)
- {
- switch (data->nodes[i].type)
- {
- case CLUTTER_PATH_MOVE_TO:
- path_start = last_point = data->nodes[i].points[0];
- break;
-
- case CLUTTER_PATH_LINE_TO:
- last_point = data->nodes[i].points[0];
- break;
-
- case CLUTTER_PATH_CURVE_TO:
- last_point = data->nodes[i].points[2];
- break;
-
- case CLUTTER_PATH_REL_MOVE_TO:
- last_point.x += data->nodes[i].points[0].x;
- last_point.y += data->nodes[i].points[0].y;
- data->nodes[i].points[0] = last_point;
- data->nodes[i].type = CLUTTER_PATH_MOVE_TO;
- path_start = last_point;
- break;
-
- case CLUTTER_PATH_REL_LINE_TO:
- last_point.x += data->nodes[i].points[0].x;
- last_point.y += data->nodes[i].points[0].y;
- data->nodes[i].points[0] = last_point;
- data->nodes[i].type = CLUTTER_PATH_LINE_TO;
- break;
-
- case CLUTTER_PATH_REL_CURVE_TO:
- for (j = 0; j < 3; j++)
- {
- data->nodes[i].points[j].x += last_point.x;
- data->nodes[i].points[j].y += last_point.y;
- }
- last_point = data->nodes[i].points[2];
- data->nodes[i].type = CLUTTER_PATH_CURVE_TO;
- break;
-
- case CLUTTER_PATH_CLOSE:
- last_point = path_start;
-
- /* Cairo always adds a move to after every close so we need
- to insert one here. Since Cairo commit 166453c1abf2 it
- doesn't seem to do this anymore so will assume that if
- Cairo's minor version is >= 11 then it includes that
- commit */
- if (cairo_version () < CAIRO_VERSION_ENCODE (1, 11, 0))
- {
- memmove (data->nodes + i + 2, data->nodes + i + 1,
- (data->n_nodes - i - 1) * sizeof (ClutterPathNode));
- data->nodes[i + 1].type = CLUTTER_PATH_MOVE_TO;
- data->nodes[i + 1].points[0] = last_point;
- data->n_nodes++;
- }
- break;
- }
- }
-
- /* Free the cairo resources */
- cairo_path_destroy (cpath);
- cairo_destroy (cr);
- cairo_surface_destroy (surface);
-
- return TRUE;
-}
-
-static gboolean
-float_fuzzy_equals (float fa, float fb)
-{
- return fabs (fa - fb) <= FLOAT_FUZZ_AMOUNT;
-}
-
-static void
-set_triangle_path (CallbackData *data)
-{
- /* Triangular shaped path hitting (0,0), (64,64) and (128,0) in four
- parts. The two curves are actually straight lines */
- static const ClutterPathNode nodes[] =
- { { CLUTTER_PATH_MOVE_TO, { { 0, 0 } } },
- { CLUTTER_PATH_LINE_TO, { { 32, 32 } } },
- { CLUTTER_PATH_CURVE_TO, { { 40, 40 }, { 56, 56 }, { 64, 64 } } },
- { CLUTTER_PATH_REL_CURVE_TO, { { 8, -8 }, { 24, -24 }, { 32, -32 } } },
- { CLUTTER_PATH_REL_LINE_TO, { { 32, -32 } } } };
- gint i;
-
- clutter_path_clear (data->path);
-
- for (i = 0; i < G_N_ELEMENTS (nodes); i++)
- clutter_path_add_node (data->path, nodes + i);
-
- memcpy (data->nodes, nodes, sizeof (nodes));
- data->n_nodes = G_N_ELEMENTS (nodes);
-}
-
-static gboolean
-path_test_get_position (CallbackData *data)
-{
- static const float values[] = { 0.125f, 16.0f, 16.0f,
- 0.375f, 48.0f, 48.0f,
- 0.625f, 80.0f, 48.0f,
- 0.875f, 112.0f, 16.0f };
- gint i;
-
- set_triangle_path (data);
-
- for (i = 0; i < G_N_ELEMENTS (values); i += 3)
- {
- ClutterKnot pos;
-
- clutter_path_get_position (data->path,
- values[i],
- &pos);
-
- if (!float_fuzzy_equals (values[i + 1], pos.x)
- || !float_fuzzy_equals (values[i + 2], pos.y))
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-path_test_get_length (CallbackData *data)
-{
- const float actual_length /* sqrt(64**2 + 64**2) * 2 */ = 181.019336f;
- guint approx_length;
-
- clutter_path_set_description (data->path, "M 0 0 L 46340 0");
- g_object_get (data->path, "length", &approx_length, NULL);
-
- if (!(fabs (approx_length - 46340.f) / 46340.f <= 0.15f))
- {
- if (!g_test_quiet ())
- g_print ("M 0 0 L 46340 0 - Expected 46340, got %d instead.", approx_length);
-
- return FALSE;
- }
-
- clutter_path_set_description (data->path, "M 0 0 L 46341 0");
- g_object_get (data->path, "length", &approx_length, NULL);
-
- if (!(fabs (approx_length - 46341.f) / 46341.f <= 0.15f))
- {
- if (!g_test_quiet ())
- g_print ("M 0 0 L 46341 0 - Expected 46341, got %d instead.", approx_length);
-
- return FALSE;
- }
-
- set_triangle_path (data);
-
- g_object_get (data->path, "length", &approx_length, NULL);
-
- /* Allow 15% margin of error */
- if (!(fabs (approx_length - actual_length) / (float) actual_length <= 0.15f))
- {
- if (!g_test_quiet ())
- g_print ("Expected %g, got %d instead.\n", actual_length, approx_length);
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-path_test_boxed_type (CallbackData *data)
-{
- gboolean ret = TRUE;
- GSList *nodes, *l;
- GValue value;
-
- nodes = clutter_path_get_nodes (data->path);
-
- memset (&value, 0, sizeof (value));
-
- for (l = nodes; l; l = l->next)
- {
- g_value_init (&value, CLUTTER_TYPE_PATH_NODE);
-
- g_value_set_boxed (&value, l->data);
-
- if (!clutter_path_node_equal (l->data,
- g_value_get_boxed (&value)))
- ret = FALSE;
-
- g_value_unset (&value);
- }
-
- g_slist_free (nodes);
-
- return ret;
-}
-
-static const struct
-{
- const char *desc;
- PathTestFunc func;
-}
-path_tests[] =
- {
- { "Add line to", path_test_add_line_to },
- { "Add move to", path_test_add_move_to },
- { "Add curve to", path_test_add_curve_to },
- { "Add close", path_test_add_close },
- { "Add relative line to", path_test_add_rel_line_to },
- { "Add relative move to", path_test_add_rel_move_to },
- { "Add relative curve to", path_test_add_rel_curve_to },
- { "Add string", path_test_add_string },
- { "Add node by struct", path_test_add_node_by_struct },
- { "Get number of nodes", path_test_get_n_nodes },
- { "Get a node", path_test_get_node },
- { "Get all nodes", path_test_get_nodes },
- { "Insert at beginning", path_test_insert_beginning },
- { "Insert at end", path_test_insert_end },
- { "Insert at middle", path_test_insert_middle },
- { "Add after insert", path_test_add_line_to },
- { "Clear then insert", path_test_clear_insert },
- { "Add string again", path_test_add_string },
- { "Remove from beginning", path_test_remove_beginning },
- { "Remove from end", path_test_remove_end },
- { "Remove from middle", path_test_remove_middle },
- { "Add after remove", path_test_add_line_to },
- { "Remove only node", path_test_remove_only },
- { "Add after remove again", path_test_add_line_to },
- { "Replace a node", path_test_replace },
- { "Set description", path_test_set_description },
- { "Get description", path_test_get_description },
- { "Convert to cairo path and back", path_test_convert_to_cairo_path },
- { "Clear", path_test_clear },
- { "Get position", path_test_get_position },
- { "Check node boxed type", path_test_boxed_type },
- { "Get length", path_test_get_length }
- };
-
-static void
-compare_node (const ClutterPathNode *node, gpointer data_p)
-{
- CallbackData *data = data_p;
-
- if (data->nodes_found >= data->n_nodes)
- data->nodes_different = TRUE;
- else
- {
- guint n_points = 0, i;
- const ClutterPathNode *onode = data->nodes + data->nodes_found;
-
- if (node->type != onode->type)
- data->nodes_different = TRUE;
-
- switch (node->type & ~CLUTTER_PATH_RELATIVE)
- {
- case CLUTTER_PATH_MOVE_TO: n_points = 1; break;
- case CLUTTER_PATH_LINE_TO: n_points = 1; break;
- case CLUTTER_PATH_CURVE_TO: n_points = 3; break;
- case CLUTTER_PATH_CLOSE: n_points = 0; break;
-
- default:
- data->nodes_different = TRUE;
- break;
- }
-
- for (i = 0; i < n_points; i++)
- if (node->points[i].x != onode->points[i].x
- || node->points[i].y != onode->points[i].y)
- {
- data->nodes_different = TRUE;
- break;
- }
- }
-
- data->nodes_found++;
-}
-
-static gboolean
-compare_nodes (CallbackData *data)
-{
- data->nodes_different = FALSE;
- data->nodes_found = 0;
-
- clutter_path_foreach (data->path, compare_node, data);
-
- return !data->nodes_different && data->nodes_found == data->n_nodes;
-}
-
-void
-path_base (TestConformSimpleFixture *fixture,
- gconstpointer _data)
-{
- CallbackData data;
- gint i;
-
- memset (&data, 0, sizeof (data));
-
- data.path = clutter_path_new ();
-
- for (i = 0; i < G_N_ELEMENTS (path_tests); i++)
- {
- gboolean succeeded;
-
- if (!g_test_quiet ())
- g_print ("%s... ", path_tests[i].desc);
-
- succeeded = path_tests[i].func (&data) && compare_nodes (&data);
-
- if (!g_test_quiet ())
- g_print ("%s\n", succeeded ? "ok" : "FAIL");
-
- g_assert (succeeded);
- }
-
- g_object_unref (data.path);
-}
-
diff --git a/src/tests/clutter/conform/script-parser.c b/src/tests/clutter/conform/script-parser.c
deleted file mode 100644
index c51329e13..000000000
--- a/src/tests/clutter/conform/script-parser.c
+++ /dev/null
@@ -1,303 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-
-#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 ())
-
-#define TEST_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_GROUP, TestGroup))
-#define TEST_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_GROUP))
-
-#define TEST_GROUP_META(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_GROUP_META, TestGroupMeta))
-#define TEST_IS_GROUP_META(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_GROUP_META))
-
-typedef struct _ClutterActor TestGroup;
-typedef struct _ClutterActorClass TestGroupClass;
-
-typedef struct _TestGroupMeta {
- ClutterChildMeta parent_instance;
-
- guint is_focus : 1;
-} TestGroupMeta;
-
-typedef struct _ClutterChildMetaClass TestGroupMetaClass;
-
-GType test_group_meta_get_type (void);
-
-G_DEFINE_TYPE (TestGroupMeta, test_group_meta, CLUTTER_TYPE_CHILD_META)
-
-enum
-{
- PROP_META_0,
-
- PROP_META_FOCUS
-};
-
-static void
-test_group_meta_set_property (GObject *gobject,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- TestGroupMeta *self = TEST_GROUP_META (gobject);
-
- switch (prop_id)
- {
- case PROP_META_FOCUS:
- self->is_focus = g_value_get_boolean (value);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
- break;
- }
-}
-
-static void
-test_group_meta_get_property (GObject *gobject,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- TestGroupMeta *self = TEST_GROUP_META (gobject);
-
- switch (prop_id)
- {
- case PROP_META_FOCUS:
- g_value_set_boolean (value, self->is_focus);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
- break;
- }
-}
-
-static void
-test_group_meta_class_init (TestGroupMetaClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GParamSpec *pspec;
-
- gobject_class->set_property = test_group_meta_set_property;
- gobject_class->get_property = test_group_meta_get_property;
-
- pspec = g_param_spec_boolean ("focus", "Focus", "Focus",
- FALSE,
- G_PARAM_READWRITE);
- g_object_class_install_property (gobject_class, PROP_META_FOCUS, pspec);
-}
-
-static void
-test_group_meta_init (TestGroupMeta *meta)
-{
- meta->is_focus = FALSE;
-}
-
-static void
-clutter_container_iface_init (ClutterContainerIface *iface)
-{
- iface->child_meta_type = TEST_TYPE_GROUP_META;
-}
-
-GType test_group_get_type (void);
-
-G_DEFINE_TYPE_WITH_CODE (TestGroup, test_group, CLUTTER_TYPE_ACTOR,
- G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
- clutter_container_iface_init))
-
-static void
-test_group_class_init (TestGroupClass *klass)
-{
-}
-
-static void
-test_group_init (TestGroup *self)
-{
-}
-
-static void
-script_child (void)
-{
- ClutterScript *script = clutter_script_new ();
- GObject *container, *actor;
- GError *error = NULL;
- gboolean focus_ret;
- gchar *test_file;
-
- test_file = g_test_build_filename (G_TEST_DIST, "scripts", "test-script-child.json", NULL);
- clutter_script_load_from_file (script, test_file, &error);
- if (!g_test_quiet () && error)
- g_print ("Error: %s", error->message);
-
- g_assert_no_error (error);
-
- container = actor = NULL;
- clutter_script_get_objects (script,
- "test-group", &container,
- "test-rect-1", &actor,
- NULL);
- g_assert (TEST_IS_GROUP (container));
- g_assert (CLUTTER_IS_ACTOR (actor));
-
- focus_ret = FALSE;
- clutter_container_child_get (CLUTTER_CONTAINER (container),
- CLUTTER_ACTOR (actor),
- "focus", &focus_ret,
- NULL);
- g_assert (focus_ret);
-
- actor = clutter_script_get_object (script, "test-rect-2");
- g_assert (CLUTTER_IS_ACTOR (actor));
-
- focus_ret = FALSE;
- clutter_container_child_get (CLUTTER_CONTAINER (container),
- CLUTTER_ACTOR (actor),
- "focus", &focus_ret,
- NULL);
- g_assert (!focus_ret);
-
- g_object_unref (script);
- g_free (test_file);
-}
-
-static void
-script_single (void)
-{
- ClutterScript *script = clutter_script_new ();
- ClutterColor color = { 0, };
- GObject *actor = NULL;
- GError *error = NULL;
- ClutterActor *rect;
- gchar *test_file;
-
- test_file = g_test_build_filename (G_TEST_DIST, "scripts", "test-script-single.json", NULL);
- clutter_script_load_from_file (script, test_file, &error);
- if (!g_test_quiet () && error)
- g_print ("Error: %s", error->message);
-
- g_assert_no_error (error);
-
- actor = clutter_script_get_object (script, "test");
- g_assert (CLUTTER_IS_ACTOR (actor));
-
- rect = CLUTTER_ACTOR (actor);
- g_assert_cmpfloat (clutter_actor_get_width (rect), ==, 50.0);
- g_assert_cmpfloat (clutter_actor_get_y (rect), ==, 100.0);
-
- clutter_actor_get_background_color (rect, &color);
- g_assert_cmpint (color.red, ==, 255);
- g_assert_cmpint (color.green, ==, 0xcc);
- g_assert_cmpint (color.alpha, ==, 0xff);
-
- g_object_unref (script);
- g_free (test_file);
-}
-
-static void
-script_object_property (void)
-{
- ClutterScript *script = clutter_script_new ();
- ClutterLayoutManager *manager;
- GObject *actor = NULL;
- GError *error = NULL;
- gchar *test_file;
-
- test_file = g_test_build_filename (G_TEST_DIST, "scripts", "test-script-object-property.json", NULL);
- clutter_script_load_from_file (script, test_file, &error);
- if (!g_test_quiet () && error)
- g_print ("Error: %s", error->message);
-
- g_assert_no_error (error);
-
- actor = clutter_script_get_object (script, "test");
- g_assert (CLUTTER_IS_ACTOR (actor));
-
- manager = clutter_actor_get_layout_manager (CLUTTER_ACTOR (actor));
- g_assert (CLUTTER_IS_BIN_LAYOUT (manager));
-
- g_object_unref (script);
- g_free (test_file);
-}
-
-static void
-script_named_object (void)
-{
- ClutterScript *script = clutter_script_new ();
- ClutterLayoutManager *manager;
- GObject *actor = NULL;
- GError *error = NULL;
- gchar *test_file;
-
- test_file = g_test_build_filename (G_TEST_DIST, "scripts", "test-script-named-object.json", NULL);
- clutter_script_load_from_file (script, test_file, &error);
- if (!g_test_quiet () && error)
- g_print ("Error: %s", error->message);
-
- g_assert_no_error (error);
-
- actor = clutter_script_get_object (script, "test");
- g_assert (CLUTTER_IS_ACTOR (actor));
-
- manager = clutter_actor_get_layout_manager (CLUTTER_ACTOR (actor));
- g_assert (CLUTTER_IS_BOX_LAYOUT (manager));
- g_assert (clutter_box_layout_get_orientation (CLUTTER_BOX_LAYOUT (manager)) == CLUTTER_ORIENTATION_VERTICAL);
-
- g_object_unref (script);
- g_free (test_file);
-}
-
-static void
-script_margin (void)
-{
- ClutterScript *script = clutter_script_new ();
- ClutterActor *actor;
- gchar *test_file;
- GError *error = NULL;
-
- test_file = g_test_build_filename (G_TEST_DIST, "scripts", "test-script-margin.json", NULL);
- clutter_script_load_from_file (script, test_file, &error);
- if (!g_test_quiet () && error)
- g_print ("Error: %s", error->message);
-
- g_assert_no_error (error);
-
- actor = CLUTTER_ACTOR (clutter_script_get_object (script, "actor-1"));
- g_assert_cmpfloat (clutter_actor_get_margin_top (actor), ==, 10.0f);
- g_assert_cmpfloat (clutter_actor_get_margin_right (actor), ==, 10.0f);
- g_assert_cmpfloat (clutter_actor_get_margin_bottom (actor), ==, 10.0f);
- g_assert_cmpfloat (clutter_actor_get_margin_left (actor), ==, 10.0f);
-
- actor = CLUTTER_ACTOR (clutter_script_get_object (script, "actor-2"));
- g_assert_cmpfloat (clutter_actor_get_margin_top (actor), ==, 10.0f);
- g_assert_cmpfloat (clutter_actor_get_margin_right (actor), ==, 20.0f);
- g_assert_cmpfloat (clutter_actor_get_margin_bottom (actor), ==, 10.0f);
- g_assert_cmpfloat (clutter_actor_get_margin_left (actor), ==, 20.0f);
-
- actor = CLUTTER_ACTOR (clutter_script_get_object (script, "actor-3"));
- g_assert_cmpfloat (clutter_actor_get_margin_top (actor), ==, 10.0f);
- g_assert_cmpfloat (clutter_actor_get_margin_right (actor), ==, 20.0f);
- g_assert_cmpfloat (clutter_actor_get_margin_bottom (actor), ==, 30.0f);
- g_assert_cmpfloat (clutter_actor_get_margin_left (actor), ==, 20.0f);
-
- actor = CLUTTER_ACTOR (clutter_script_get_object (script, "actor-4"));
- g_assert_cmpfloat (clutter_actor_get_margin_top (actor), ==, 10.0f);
- g_assert_cmpfloat (clutter_actor_get_margin_right (actor), ==, 20.0f);
- g_assert_cmpfloat (clutter_actor_get_margin_bottom (actor), ==, 30.0f);
- g_assert_cmpfloat (clutter_actor_get_margin_left (actor), ==, 40.0f);
-
- g_object_unref (script);
- g_free (test_file);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/script/single-object", script_single)
- CLUTTER_TEST_UNIT ("/script/container-child", script_child)
- CLUTTER_TEST_UNIT ("/script/named-object", script_named_object)
- CLUTTER_TEST_UNIT ("/script/object-property", script_object_property)
- CLUTTER_TEST_UNIT ("/script/actor-margin", script_margin)
-)
diff --git a/src/tests/clutter/conform/scripts/test-script-child.json b/src/tests/clutter/conform/scripts/test-script-child.json
deleted file mode 100644
index f23208a79..000000000
--- a/src/tests/clutter/conform/scripts/test-script-child.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "type" : "TestGroup",
- "id" : "test-group",
- "children" : [
- {
- "type" : "ClutterActor",
- "id" : "test-rect-1",
- "width" : 100.0,
- "height" : 100.0,
- "background-color" : [ 255, 0, 0, 255 ],
- "child::focus" : true
- },
- {
- "type" : "ClutterActor",
- "id" : "test-rect-2",
- "width" : 100.0,
- "height" : 100.0,
- "background-color" : [ 0, 255, 0, 255 ]
- }
- ]
-}
diff --git a/src/tests/clutter/conform/scripts/test-script-interval.json b/src/tests/clutter/conform/scripts/test-script-interval.json
deleted file mode 100644
index 35fe5c22c..000000000
--- a/src/tests/clutter/conform/scripts/test-script-interval.json
+++ /dev/null
@@ -1,16 +0,0 @@
-[
- {
- "id" : "int-1",
- "type" : "ClutterInterval",
- "value-type" : "gfloat",
- "initial" : 23.3,
- "final" : 42.2
- },
- {
- "id" : "int-2",
- "type" : "ClutterInterval",
- "value-type" : "ClutterColor",
- "initial" : "red",
- "final" : "blue"
- }
-]
diff --git a/src/tests/clutter/conform/scripts/test-script-margin.json b/src/tests/clutter/conform/scripts/test-script-margin.json
deleted file mode 100644
index 1f5289fa6..000000000
--- a/src/tests/clutter/conform/scripts/test-script-margin.json
+++ /dev/null
@@ -1,22 +0,0 @@
-[
- {
- "id" : "actor-1",
- "type" : "ClutterActor",
- "margin" : [ 10 ]
- },
- {
- "id" : "actor-2",
- "type" : "ClutterActor",
- "margin" : [ 10, 20 ]
- },
- {
- "id" : "actor-3",
- "type" : "ClutterActor",
- "margin" : [ 10, 20, 30 ]
- },
- {
- "id" : "actor-4",
- "type" : "ClutterActor",
- "margin" : [ 10, 20, 30, 40]
- }
-]
diff --git a/src/tests/clutter/conform/scripts/test-script-model.json b/src/tests/clutter/conform/scripts/test-script-model.json
deleted file mode 100644
index dc4a62dc0..000000000
--- a/src/tests/clutter/conform/scripts/test-script-model.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "id" : "test-model",
- "type" : "ClutterListModel",
- "columns" : [
- [ "text-column", "gchararray" ],
- [ "int-column", "gint" ],
- [ "actor-column", "ClutterActor" ]
- ],
- "rows" : [
- [ "text-row-1", 1, null ],
- [ "text-row-2", 2, { "type" : "ClutterActor", "background-color" : "blue" } ],
- {
- "int-column" : 3,
- "actor-column" : { "type" : "ClutterActor", "name" : "actor-row-3" }
- }
- ]
-}
diff --git a/src/tests/clutter/conform/scripts/test-script-named-object.json b/src/tests/clutter/conform/scripts/test-script-named-object.json
deleted file mode 100644
index 4ba5d2c92..000000000
--- a/src/tests/clutter/conform/scripts/test-script-named-object.json
+++ /dev/null
@@ -1,44 +0,0 @@
-[
- {
- "id" : "layout",
- "type" : "ClutterBoxLayout",
- "orientation" : "vertical",
- "spacing" : 12,
- "pack-start" : false
- },
- {
- "type" : "ClutterStage",
- "id" : "main-stage",
- "children" : [
- {
- "id" : "test",
- "type" : "ClutterActor",
- "layout-manager" : "layout",
- "children" : [
- {
- "id" : "child-1",
- "type" : "ClutterActor",
- "width" : "3 em",
- "height" : "3 em"
- }
- ],
- "constraints" : [
- {
- "type" : "ClutterAlignConstraint",
- "name" : "x-align",
- "factor" : 0.5,
- "align-axis" : "x-axis",
- "source" : "main-stage"
- },
- {
- "type" : "ClutterAlignConstraint",
- "name" : "y-align",
- "factor" : 0.5,
- "align-axis" : "y-axis",
- "source" : "main-stage"
- }
- ]
- }
- ]
- }
-]
diff --git a/src/tests/clutter/conform/scripts/test-script-object-property.json b/src/tests/clutter/conform/scripts/test-script-object-property.json
deleted file mode 100644
index 58187bbb6..000000000
--- a/src/tests/clutter/conform/scripts/test-script-object-property.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "id" : "test",
- "type" : "ClutterActor",
- "layout-manager" : { "id" : "layout", "type" : "ClutterBinLayout" },
- "children" : [
- {
- "id" : "child-1",
- "type" : "ClutterActor",
- "width" : "3 em",
- "height" : "3 em"
- }
- ]
-}
diff --git a/src/tests/clutter/conform/scripts/test-script-single.json b/src/tests/clutter/conform/scripts/test-script-single.json
deleted file mode 100644
index cb09d696a..000000000
--- a/src/tests/clutter/conform/scripts/test-script-single.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "type" : "ClutterActor",
- "id" : "test",
- "width" : 50.0,
- "height" : 100.0,
- "x" : 100.0,
- "y" : 100.0,
- "background-color" : "#ffccdd",
- "name" : "Test Rectangle"
-}
diff --git a/src/tests/clutter/conform/scripts/test-script-timeline-markers.json b/src/tests/clutter/conform/scripts/test-script-timeline-markers.json
deleted file mode 100644
index e26ba5f01..000000000
--- a/src/tests/clutter/conform/scripts/test-script-timeline-markers.json
+++ /dev/null
@@ -1,16 +0,0 @@
-[
- { "id" : "actor0", "type" : "ClutterActor" },
- {
- "id" : "timeline0",
- "type" : "ClutterTimeline",
- "duration" : 1000,
- "actor" : "actor0",
-
- "markers" : [
- { "name" : "marker0", "time" : 250 },
- { "name" : "marker1", "time" : 500 },
- { "name" : "marker2", "time" : 750 },
- { "name" : "marker3", "progress" : 0.5 }
- ]
- }
-]
diff --git a/src/tests/clutter/conform/text-cache.c b/src/tests/clutter/conform/text-cache.c
deleted file mode 100644
index 63d38d07d..000000000
--- a/src/tests/clutter/conform/text-cache.c
+++ /dev/null
@@ -1,299 +0,0 @@
-#include <clutter/clutter.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "test-conform-common.h"
-
-#define TEST_FONT "Sans 10"
-
-static const char long_text[] =
- "<b>This</b> <i>is</i> some <span size=\"x-large\">REALLY</span> "
- "long text that contains markup for testing the <tt>use_markup</tt> "
- "property and to test word-wrapping, justification and alignment.";
-
-typedef struct _CallbackData CallbackData;
-
-struct _CallbackData
-{
- ClutterActor *stage;
- ClutterActor *label;
-
- PangoLayout *old_layout;
- gboolean layout_changed;
- PangoRectangle label_extents;
-
- PangoLayout *test_layout;
-
- gboolean test_failed;
-};
-
-static void
-on_paint (ClutterActor *stage,
- ClutterPaintContext *paint_context,
- CallbackData *data)
-{
- PangoLayout *new_layout;
-
- /* Check whether the layout used for this paint is different from
- the layout used for the last paint */
- new_layout = clutter_text_get_layout (CLUTTER_TEXT (data->label));
- data->layout_changed = data->old_layout != new_layout;
-
- if (data->old_layout)
- g_object_unref (data->old_layout);
- /* Keep a reference to the old layout so we can be sure it won't
- just reallocate a new layout with the same address */
- data->old_layout = g_object_ref (new_layout);
-
- pango_layout_get_extents (new_layout, NULL, &data->label_extents);
-}
-
-static void
-force_redraw (CallbackData *data)
-{
- /* XXX - this is fugly; we force a paint on the stage, which
- * will then paint the Text actor. inside the Text actor we
- * check for a Layout with the allocation size. if the allocation
- * has changed it will cause a relayout in the middle of the
- * paint, which is expensive and broken. this will ensure that
- * the test passes, though
- */
- clutter_actor_paint (clutter_actor_get_stage (data->label));
-}
-
-static gboolean
-check_result (CallbackData *data, const char *note,
- gboolean layout_should_change)
-{
- PangoRectangle test_extents;
- gboolean fail = FALSE;
-
- if (!g_test_quiet ())
- g_print ("%s: ", note);
-
- /* Force a redraw to get the on_paint handler to run */
- force_redraw (data);
-
- /* Compare the extents from the label with the extents from our test
- layout */
- pango_layout_get_extents (data->test_layout, NULL, &test_extents);
- if (memcmp (&test_extents, &data->label_extents, sizeof (PangoRectangle)))
- {
- if (!g_test_quiet ())
- g_print ("extents are different: expected: %d, %d, %d, %d "
- "-> text: %d, %d, %d, %d\n",
- test_extents.x / 1024,
- test_extents.y / 1024,
- test_extents.width / 1024,
- test_extents.height / 1024,
- data->label_extents.x / 1024,
- data->label_extents.y / 1024,
- data->label_extents.width / 1024,
- data->label_extents.height / 1024);
-
- fail = TRUE;
- }
- else
- {
- if (!g_test_quiet ())
- g_print ("extents are the same, ");
- }
-
- if (data->layout_changed)
- {
- if (!g_test_quiet ())
- g_print ("layout changed, ");
- }
- else
- {
- if (!g_test_quiet ())
- g_print ("layout did not change, ");
- }
-
- if (data->layout_changed != layout_should_change)
- fail = TRUE;
-
- if (fail)
- {
- if (!g_test_quiet ())
- g_print ("FAIL\n");
-
- data->test_failed = TRUE;
- }
- else
- {
- if (!g_test_quiet ())
- g_print ("pass\n");
- }
-
- return fail;
-}
-
-static gboolean
-do_tests (CallbackData *data)
-{
- PangoFontDescription *fd;
- static const ClutterColor red = { 0xff, 0x00, 0x00, 0xff };
- PangoAttrList *attr_list, *attr_list_copy;
- PangoAttribute *attr;
-
- /* TEST 1: change the text */
- clutter_text_set_text (CLUTTER_TEXT (data->label), "Counter 0");
- pango_layout_set_text (data->test_layout, "Counter 0", -1);
- g_assert (check_result (data, "Change text", TRUE) == FALSE);
-
- /* TEST 2: change a single character */
- clutter_text_set_text (CLUTTER_TEXT (data->label), "Counter 1");
- pango_layout_set_text (data->test_layout, "Counter 1", -1);
- g_assert (check_result (data, "Change a single character", TRUE) == FALSE);
-
- /* TEST 3: move the label */
- clutter_actor_set_position (data->label, 10, 0);
- g_assert (check_result (data, "Move the label", FALSE) == FALSE);
-
- /* TEST 4: change the font */
- clutter_text_set_font_name (CLUTTER_TEXT (data->label), "Serif 15");
- fd = pango_font_description_from_string ("Serif 15");
- pango_layout_set_font_description (data->test_layout, fd);
- pango_font_description_free (fd);
- g_assert (check_result (data, "Change the font", TRUE) == FALSE);
-
- /* TEST 5: change the color */
- clutter_text_set_color (CLUTTER_TEXT (data->label), &red);
- g_assert (check_result (data, "Change the color", FALSE) == FALSE);
-
- /* TEST 6: change the attributes */
- attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
- attr->start_index = 0;
- attr->end_index = 2;
- attr_list = pango_attr_list_new ();
- pango_attr_list_insert (attr_list, attr);
- attr_list_copy = pango_attr_list_copy (attr_list);
- clutter_text_set_attributes (CLUTTER_TEXT (data->label), attr_list);
- pango_layout_set_attributes (data->test_layout, attr_list_copy);
- pango_attr_list_unref (attr_list_copy);
- pango_attr_list_unref (attr_list);
- g_assert (check_result (data, "Change the attributes", TRUE) == FALSE);
-
- /* TEST 7: change the text again */
- clutter_text_set_attributes (CLUTTER_TEXT (data->label), NULL);
- clutter_text_set_text (CLUTTER_TEXT (data->label), long_text);
- pango_layout_set_attributes (data->test_layout, NULL);
- pango_layout_set_text (data->test_layout, long_text, -1);
- g_assert (check_result (data, "Change the text again", TRUE) == FALSE);
-
- /* TEST 8: enable markup */
- clutter_text_set_use_markup (CLUTTER_TEXT (data->label), TRUE);
- pango_layout_set_markup (data->test_layout, long_text, -1);
- g_assert (check_result (data, "Enable markup", TRUE) == FALSE);
-
- /* This part can't be a test because Clutter won't restrict the
- width if wrapping and ellipsizing is disabled so the extents will
- be different, but we still want to do it for the later tests */
- clutter_actor_set_width (data->label, 200);
- pango_layout_set_width (data->test_layout, 200 * PANGO_SCALE);
- /* Force a redraw so that changing the width won't affect the
- results */
- force_redraw (data);
-
- /* TEST 9: enable ellipsize */
- clutter_text_set_ellipsize (CLUTTER_TEXT (data->label),
- PANGO_ELLIPSIZE_END);
- pango_layout_set_ellipsize (data->test_layout, PANGO_ELLIPSIZE_END);
- g_assert (check_result (data, "Enable ellipsize", TRUE) == FALSE);
- clutter_text_set_ellipsize (CLUTTER_TEXT (data->label),
- PANGO_ELLIPSIZE_NONE);
- pango_layout_set_ellipsize (data->test_layout, PANGO_ELLIPSIZE_NONE);
- force_redraw (data);
-
- /* TEST 10: enable line wrap */
- clutter_text_set_line_wrap (CLUTTER_TEXT (data->label), TRUE);
- pango_layout_set_wrap (data->test_layout, PANGO_WRAP_WORD);
- g_assert (check_result (data, "Enable line wrap", TRUE) == FALSE);
-
- /* TEST 11: change wrap mode
- * FIXME - broken
- */
- clutter_text_set_line_wrap_mode (CLUTTER_TEXT (data->label),
- PANGO_WRAP_CHAR);
- pango_layout_set_wrap (data->test_layout, PANGO_WRAP_CHAR);
- g_assert (check_result (data, "Change wrap mode", TRUE) == FALSE);
-
- /* TEST 12: enable justify */
- clutter_text_set_justify (CLUTTER_TEXT (data->label), TRUE);
- pango_layout_set_justify (data->test_layout, TRUE);
- /* Pango appears to have a bug which means that you can't change the
- justification after setting the text but this fixes it.
- See http://bugzilla.gnome.org/show_bug.cgi?id=551865 */
- pango_layout_context_changed (data->test_layout);
- g_assert (check_result (data, "Enable justify", TRUE) == FALSE);
-
- /* TEST 13: change alignment */
- clutter_text_set_line_alignment (CLUTTER_TEXT (data->label),
- PANGO_ALIGN_RIGHT);
- pango_layout_set_alignment (data->test_layout, PANGO_ALIGN_RIGHT);
- g_assert (check_result (data, "Change alignment", TRUE) == FALSE);
-
- clutter_test_quit ();
-
- return FALSE;
-}
-
-static PangoLayout *
-make_layout_like_label (ClutterText *label)
-{
- PangoLayout *label_layout, *new_layout;
- PangoContext *context;
- PangoFontDescription *fd;
-
- /* Make another layout using the same context as the layout from the
- label */
- label_layout = clutter_text_get_layout (label);
- context = pango_layout_get_context (label_layout);
- new_layout = pango_layout_new (context);
- fd = pango_font_description_from_string (TEST_FONT);
- pango_layout_set_font_description (new_layout, fd);
- pango_font_description_free (fd);
-
- return new_layout;
-}
-
-void
-text_cache (void)
-{
- CallbackData data;
-
- memset (&data, 0, sizeof (data));
-
- data.stage = clutter_test_get_stage ();
-
- data.label = clutter_text_new_with_text (TEST_FONT, "");
-
- data.test_layout = make_layout_like_label (CLUTTER_TEXT (data.label));
-
- g_signal_connect (data.stage, "paint", G_CALLBACK (on_paint), &data);
-
- clutter_container_add (CLUTTER_CONTAINER (data.stage), data.label, NULL);
-
- clutter_actor_show (data.stage);
-
- clutter_threads_add_idle ((GSourceFunc) do_tests, &data);
-
- clutter_test_main ();
-
- clutter_actor_destroy (data.stage);
-
- if (!g_test_quiet ())
- g_print ("\nOverall result: ");
-
- if (!g_test_quiet ())
- {
- if (data.test_failed)
- g_print ("FAIL\n");
- else
- g_print ("pass\n");
- }
- else
- g_assert (data.test_failed != TRUE);
-}
-
diff --git a/src/tests/clutter/conform/text.c b/src/tests/clutter/conform/text.c
deleted file mode 100644
index 304fa1dd4..000000000
--- a/src/tests/clutter/conform/text.c
+++ /dev/null
@@ -1,564 +0,0 @@
-#include <glib.h>
-#include <clutter/clutter.h>
-#include <string.h>
-
-#include "tests/clutter-test-utils.h"
-
-typedef struct {
- gunichar unichar;
- const char bytes[6];
- gint nbytes;
-} TestData;
-
-static const TestData
-test_text_data[] = {
- { 0xe4, "\xc3\xa4", 2 }, /* LATIN SMALL LETTER A WITH DIAERESIS */
- { 0x2665, "\xe2\x99\xa5", 3 } /* BLACK HEART SUIT */
-};
-
-static void
-text_utf8_validation (void)
-{
- int i;
-
- for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
- {
- const TestData *t = &test_text_data[i];
- gunichar unichar;
- char bytes[6];
- int nbytes;
-
- g_assert (g_unichar_validate (t->unichar));
-
- nbytes = g_unichar_to_utf8 (t->unichar, bytes);
- bytes[nbytes] = '\0';
- g_assert_cmpint (nbytes, ==, t->nbytes);
- g_assert (memcmp (t->bytes, bytes, nbytes) == 0);
-
- unichar = g_utf8_get_char_validated (bytes, nbytes);
- g_assert_cmpint (unichar, ==, t->unichar);
- }
-}
-
-static int
-get_nbytes (ClutterText *text)
-{
- const char *s = clutter_text_get_text (text);
- return strlen (s);
-}
-
-static int
-get_nchars (ClutterText *text)
-{
- const char *s = clutter_text_get_text (text);
- g_assert (g_utf8_validate (s, -1, NULL));
- return g_utf8_strlen (s, -1);
-}
-
-#define DONT_MOVE_CURSOR (-2)
-
-static void
-insert_unichar (ClutterText *text, gunichar unichar, int position)
-{
- if (position > DONT_MOVE_CURSOR)
- {
- clutter_text_set_cursor_position (text, position);
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, position);
- }
-
- clutter_text_insert_unichar (text, unichar);
-}
-
-static void
-text_set_empty (void)
-{
- ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
- g_object_ref_sink (text);
-
- g_assert_cmpstr (clutter_text_get_text (text), ==, "");
- g_assert_cmpint (*clutter_text_get_text (text), ==, '\0');
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
-
- clutter_text_set_text (text, "");
- g_assert_cmpint (get_nchars (text), ==, 0);
- g_assert_cmpint (get_nbytes (text), ==, 0);
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
-
- clutter_actor_destroy (CLUTTER_ACTOR (text));
-}
-
-static void
-text_set_text (void)
-{
- ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
- g_object_ref_sink (text);
-
- clutter_text_set_text (text, "abcdef");
- g_assert_cmpint (get_nchars (text), ==, 6);
- g_assert_cmpint (get_nbytes (text), ==, 6);
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
-
- clutter_text_set_cursor_position (text, 5);
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 5);
-
- /* FIXME: cursor position should be -1?
- clutter_text_set_text (text, "");
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
- */
-
- clutter_actor_destroy (CLUTTER_ACTOR (text));
-}
-
-static void
-text_append_some (void)
-{
- ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
- int i;
-
- g_object_ref_sink (text);
-
- for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
- {
- const TestData *t = &test_text_data[i];
- int j;
-
- for (j = 1; j <= 4; j++)
- {
- insert_unichar (text, t->unichar, DONT_MOVE_CURSOR);
-
- g_assert_cmpint (get_nchars (text), ==, j);
- g_assert_cmpint (get_nbytes (text), ==, j * t->nbytes);
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
- }
-
- clutter_text_set_text (text, "");
- }
-
- clutter_actor_destroy (CLUTTER_ACTOR (text));
-}
-
-static void
-text_prepend_some (void)
-{
- ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
- int i;
-
- g_object_ref_sink (text);
-
- for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
- {
- const TestData *t = &test_text_data[i];
- int j;
-
- clutter_text_insert_unichar (text, t->unichar);
-
- g_assert_cmpint (get_nchars (text), ==, 1);
- g_assert_cmpint (get_nbytes (text), ==, 1 * t->nbytes);
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
-
- for (j = 2; j <= 4; j++)
- {
- insert_unichar (text, t->unichar, 0);
-
- g_assert_cmpint (get_nchars (text), ==, j);
- g_assert_cmpint (get_nbytes (text), ==, j * t->nbytes);
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 1);
- }
-
- clutter_text_set_text (text, "");
- }
-
- clutter_actor_destroy (CLUTTER_ACTOR (text));
-}
-
-static void
-text_insert (void)
-{
- ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
- int i;
-
- g_object_ref_sink (text);
-
- for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
- {
- const TestData *t = &test_text_data[i];
-
- clutter_text_insert_unichar (text, t->unichar);
- clutter_text_insert_unichar (text, t->unichar);
-
- insert_unichar (text, t->unichar, 1);
-
- g_assert_cmpint (get_nchars (text), ==, 3);
- g_assert_cmpint (get_nbytes (text), ==, 3 * t->nbytes);
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 2);
-
- clutter_text_set_text (text, "");
- }
-
- clutter_actor_destroy (CLUTTER_ACTOR (text));
-}
-
-static void
-text_delete_chars (void)
-{
- ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
- int i;
-
- g_object_ref_sink (text);
-
- for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
- {
- const TestData *t = &test_text_data[i];
- int j;
-
- for (j = 0; j < 4; j++)
- clutter_text_insert_unichar (text, t->unichar);
-
- if (!g_test_quiet ())
- g_print ("text: %s\n", clutter_text_get_text (text));
-
- clutter_text_set_cursor_position (text, 2);
- clutter_text_delete_chars (text, 1);
- if (!g_test_quiet ())
- g_print ("text: %s (cursor at: %d)\n",
- clutter_text_get_text (text),
- clutter_text_get_cursor_position (text));
- g_assert_cmpint (get_nchars (text), ==, 3);
- g_assert_cmpint (get_nbytes (text), ==, 3 * t->nbytes);
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 1);
-
- clutter_text_set_cursor_position (text, 2);
- clutter_text_delete_chars (text, 1);
- if (!g_test_quiet ())
- g_print ("text: %s (cursor at: %d)\n",
- clutter_text_get_text (text),
- clutter_text_get_cursor_position (text));
- g_assert_cmpint (get_nchars (text), ==, 2);
- g_assert_cmpint (get_nbytes (text), ==, 2 * t->nbytes);
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 1);
-
- clutter_text_set_text (text, "");
- }
-
- clutter_actor_destroy (CLUTTER_ACTOR (text));
-}
-
-static void
-text_get_chars (void)
-{
- ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
- gchar *chars;
-
- g_object_ref_sink (text);
-
- clutter_text_set_text (text, "00abcdef11");
- g_assert_cmpint (get_nchars (text), ==, 10);
- g_assert_cmpint (get_nbytes (text), ==, 10);
- g_assert_cmpstr (clutter_text_get_text (text), ==, "00abcdef11");
-
- chars = clutter_text_get_chars (text, 2, -1);
- g_assert_cmpstr (chars, ==, "abcdef11");
- g_free (chars);
-
- chars = clutter_text_get_chars (text, 0, 8);
- g_assert_cmpstr (chars, ==, "00abcdef");
- g_free (chars);
-
- chars = clutter_text_get_chars (text, 2, 8);
- g_assert_cmpstr (chars, ==, "abcdef");
- g_free (chars);
-
- chars = clutter_text_get_chars (text, 8, 12);
- g_assert_cmpstr (chars, ==, "11");
- g_free (chars);
-
- clutter_actor_destroy (CLUTTER_ACTOR (text));
-}
-
-static void
-text_delete_text (void)
-{
- ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
- int i;
-
- g_object_ref_sink (text);
-
- for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
- {
- const TestData *t = &test_text_data[i];
- int j;
-
- for (j = 0; j < 4; j++)
- clutter_text_insert_unichar (text, t->unichar);
-
- clutter_text_set_cursor_position (text, 3);
- clutter_text_delete_text (text, 2, 4);
-
- g_assert_cmpint (get_nchars (text), ==, 2);
- g_assert_cmpint (get_nbytes (text), ==, 2 * t->nbytes);
-
- /* FIXME: cursor position should be -1?
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
- */
-
- clutter_text_set_text (text, "");
- }
-
- clutter_actor_destroy (CLUTTER_ACTOR (text));
-}
-
-static void
-text_password_char (void)
-{
- ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
-
- g_object_ref_sink (text);
-
- g_assert_cmpint (clutter_text_get_password_char (text), ==, 0);
-
- clutter_text_set_text (text, "hello");
- g_assert_cmpstr (clutter_text_get_text (text), ==, "hello");
-
- clutter_text_set_password_char (text, '*');
- g_assert_cmpint (clutter_text_get_password_char (text), ==, '*');
-
- g_assert_cmpstr (clutter_text_get_text (text), ==, "hello");
-
- clutter_actor_destroy (CLUTTER_ACTOR (text));
-}
-
-static ClutterEvent *
-init_event (void)
-{
- ClutterEvent *retval = clutter_event_new (CLUTTER_KEY_PRESS);
-
- clutter_event_set_time (retval, CLUTTER_CURRENT_TIME);
- clutter_event_set_flags (retval, CLUTTER_EVENT_FLAG_SYNTHETIC);
-
- return retval;
-}
-
-static void
-send_keyval (ClutterText *text, int keyval)
-{
- ClutterEvent *event = init_event ();
-
- /* Unicode should be ignored for cursor keys etc. */
- clutter_event_set_key_unicode (event, 0);
- clutter_event_set_key_symbol (event, keyval);
-
- clutter_actor_event (CLUTTER_ACTOR (text), event, FALSE);
-
- clutter_event_free (event);
-}
-
-static void
-send_unichar (ClutterText *text, gunichar unichar)
-{
- ClutterEvent *event = init_event ();
-
- /* Key symbol should be ignored for printable characters */
- clutter_event_set_key_symbol (event, 0);
- clutter_event_set_key_unicode (event, unichar);
-
- clutter_actor_event (CLUTTER_ACTOR (text), event, FALSE);
-
- clutter_event_free (event);
-}
-
-static void
-text_cursor (void)
-{
- ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
- int i;
-
- g_object_ref_sink (text);
-
- /* only editable entries listen to events */
- clutter_text_set_editable (text, TRUE);
-
- for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
- {
- const TestData *t = &test_text_data[i];
- int j;
-
- for (j = 0; j < 4; ++j)
- clutter_text_insert_unichar (text, t->unichar);
-
- clutter_text_set_cursor_position (text, 2);
-
- /* test cursor moves and is clamped */
- send_keyval (text, CLUTTER_KEY_Left);
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 1);
-
- send_keyval (text, CLUTTER_KEY_Left);
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 0);
-
- send_keyval (text, CLUTTER_KEY_Left);
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 0);
-
- /* delete text containing the cursor */
- clutter_text_set_cursor_position (text, 3);
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, 3);
-
- clutter_text_delete_text (text, 2, 4);
- send_keyval (text, CLUTTER_KEY_Left);
-
- /* FIXME: cursor position should be -1?
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
- */
-
- clutter_text_set_text (text, "");
- }
-
- clutter_actor_destroy (CLUTTER_ACTOR (text));
-}
-
-static void
-text_event (void)
-{
- ClutterText *text = CLUTTER_TEXT (clutter_text_new ());
- int i;
-
- g_object_ref_sink (text);
-
- /* only editable entries listen to events */
- clutter_text_set_editable (text, TRUE);
-
- for (i = 0; i < G_N_ELEMENTS (test_text_data); i++)
- {
- const TestData *t = &test_text_data[i];
-
- send_unichar (text, t->unichar);
-
- g_assert_cmpint (get_nchars (text), ==, 1);
- g_assert_cmpint (get_nbytes (text), ==, 1 * t->nbytes);
- g_assert_cmpint (clutter_text_get_cursor_position (text), ==, -1);
-
- clutter_text_set_text (text, "");
- }
-
- clutter_actor_destroy (CLUTTER_ACTOR (text));
-}
-
-static inline void
-validate_markup_attributes (ClutterText *text,
- PangoAttrType attr_type,
- int start_index,
- int end_index)
-{
- PangoLayout *layout;
- PangoAttrList *attrs;
- PangoAttrIterator *iter;
-
- layout = clutter_text_get_layout (text);
- g_assert (layout != NULL);
-
- attrs = pango_layout_get_attributes (layout);
- g_assert (attrs != NULL);
-
- iter = pango_attr_list_get_iterator (attrs);
- while (pango_attr_iterator_next (iter))
- {
- GSList *attributes = pango_attr_iterator_get_attrs (iter);
- PangoAttribute *a;
-
- if (attributes == NULL)
- break;
-
- g_assert (attributes->data != NULL);
-
- a = attributes->data;
-
- if (a->klass->type == PANGO_ATTR_SCALE)
- {
- PangoAttrFloat *scale = (PangoAttrFloat*) a;
- float resource_scale;
-
- resource_scale = clutter_actor_get_resource_scale (CLUTTER_ACTOR (text));
-
- 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);
-
- g_slist_free_full (attributes, (GDestroyNotify) pango_attribute_destroy);
- }
-
- pango_attr_iterator_destroy (iter);
-}
-
-static void
-text_idempotent_use_markup (void)
-{
- ClutterText *text;
- const char *contents = "foo <b>bar</b>";
- const char *display = "foo bar";
- int bar_start_index = strstr (display, "bar") - display;
- int bar_end_index = bar_start_index + strlen ("bar");
-
- /* case 1: text -> use_markup */
- if (!g_test_quiet ())
- g_print ("text: '%s' -> use-markup: TRUE\n", contents);
-
- text = g_object_new (CLUTTER_TYPE_TEXT,
- "text", contents, "use-markup", TRUE,
- NULL);
- g_object_ref_sink (text);
-
- if (!g_test_quiet ())
- g_print ("Contents: '%s' (expected: '%s')\n",
- clutter_text_get_text (text),
- display);
-
- g_assert_cmpstr (clutter_text_get_text (text), ==, display);
-
- validate_markup_attributes (text,
- PANGO_ATTR_WEIGHT,
- bar_start_index,
- bar_end_index);
-
- clutter_actor_destroy (CLUTTER_ACTOR (text));
-
- /* case 2: use_markup -> text */
- if (!g_test_quiet ())
- g_print ("use-markup: TRUE -> text: '%s'\n", contents);
-
- text = g_object_new (CLUTTER_TYPE_TEXT,
- "use-markup", TRUE, "text", contents,
- NULL);
-
- if (!g_test_quiet ())
- g_print ("Contents: '%s' (expected: '%s')\n",
- clutter_text_get_text (text),
- display);
-
- g_assert_cmpstr (clutter_text_get_text (text), ==, display);
-
- validate_markup_attributes (text,
- PANGO_ATTR_WEIGHT,
- bar_start_index,
- bar_end_index);
-
- clutter_actor_destroy (CLUTTER_ACTOR (text));
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/text/utf8-validation", text_utf8_validation)
- CLUTTER_TEST_UNIT ("/text/set-empty", text_set_empty)
- CLUTTER_TEST_UNIT ("/text/set-text", text_set_text)
- CLUTTER_TEST_UNIT ("/text/append-some", text_append_some)
- CLUTTER_TEST_UNIT ("/text/prepend-some", text_prepend_some)
- CLUTTER_TEST_UNIT ("/text/insert", text_insert)
- CLUTTER_TEST_UNIT ("/text/delete-chars", text_delete_chars)
- CLUTTER_TEST_UNIT ("/text/get-chars", text_get_chars)
- CLUTTER_TEST_UNIT ("/text/delete-text", text_delete_text)
- CLUTTER_TEST_UNIT ("/text/password-char", text_password_char)
- CLUTTER_TEST_UNIT ("/text/cursor", text_cursor)
- CLUTTER_TEST_UNIT ("/text/event", text_event)
- CLUTTER_TEST_UNIT ("/text/idempotent-use-markup", text_idempotent_use_markup)
-)
diff --git a/src/tests/clutter/conform/texture-fbo.c b/src/tests/clutter/conform/texture-fbo.c
deleted file mode 100644
index f8f274cb2..000000000
--- a/src/tests/clutter/conform/texture-fbo.c
+++ /dev/null
@@ -1,227 +0,0 @@
-#include <clutter/clutter.h>
-#include <cogl/cogl.h>
-
-#include "test-conform-common.h"
-
-#define SOURCE_SIZE 32
-#define SOURCE_DIVISIONS_X 2
-#define SOURCE_DIVISIONS_Y 2
-#define DIVISION_WIDTH (SOURCE_SIZE / SOURCE_DIVISIONS_X)
-#define DIVISION_HEIGHT (SOURCE_SIZE / SOURCE_DIVISIONS_Y)
-
-static const ClutterColor
-corner_colors[SOURCE_DIVISIONS_X * SOURCE_DIVISIONS_Y] =
- {
- { 0xff, 0x00, 0x00, 0xff }, /* red top left */
- { 0x00, 0xff, 0x00, 0xff }, /* green top right */
- { 0x00, 0x00, 0xff, 0xff }, /* blue bottom left */
- { 0xff, 0x00, 0xff, 0xff } /* purple bottom right */
- };
-
-static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
-
-typedef struct _TestState
-{
- ClutterActor *stage;
- guint frame;
- gboolean was_painted;
-} TestState;
-
-static ClutterActor *
-create_source (void)
-{
- int x, y;
- ClutterActor *group = clutter_actor_new ();
-
- /* Create a group with a different coloured rectangle at each
- corner */
- for (y = 0; y < SOURCE_DIVISIONS_Y; y++)
- for (x = 0; x < SOURCE_DIVISIONS_X; x++)
- {
- ClutterActor *rect = clutter_actor_new ();
- clutter_actor_set_background_color (rect,
- corner_colors +
- (y * SOURCE_DIVISIONS_X + x));
- clutter_actor_set_size (rect, DIVISION_WIDTH, DIVISION_HEIGHT);
- clutter_actor_set_position (rect,
- DIVISION_WIDTH * x,
- DIVISION_HEIGHT * y);
- clutter_container_add (CLUTTER_CONTAINER (group), rect, NULL);
- }
-
- return group;
-}
-
-static void
-pre_paint_clip_cb (void)
-{
- /* Generate a clip path that clips out the top left division */
- cogl_path_move_to (DIVISION_WIDTH, 0);
- cogl_path_line_to (SOURCE_SIZE, 0);
- cogl_path_line_to (SOURCE_SIZE, SOURCE_SIZE);
- cogl_path_line_to (0, SOURCE_SIZE);
- cogl_path_line_to (0, DIVISION_HEIGHT);
- cogl_path_line_to (DIVISION_WIDTH, DIVISION_HEIGHT);
- cogl_path_close ();
- cogl_clip_push_from_path ();
-}
-
-static void
-post_paint_clip_cb (void)
-{
- cogl_clip_pop ();
-}
-
-static void
-validate_part (TestState *state,
- int xpos, int ypos,
- int clip_flags)
-{
- int x, y;
-
- /* Check whether the center of each division is the right color */
- for (y = 0; y < SOURCE_DIVISIONS_Y; y++)
- for (x = 0; x < SOURCE_DIVISIONS_X; x++)
- {
- guchar *pixels;
- const ClutterColor *correct_color;
-
- /* Read the center pixels of this division */
- pixels = clutter_stage_read_pixels (CLUTTER_STAGE (state->stage),
- x * DIVISION_WIDTH +
- DIVISION_WIDTH / 2 + xpos,
- y * DIVISION_HEIGHT +
- DIVISION_HEIGHT / 2 + ypos,
- 1, 1);
-
- /* If this division is clipped then it should be the stage
- color */
- if ((clip_flags & (1 << ((y * SOURCE_DIVISIONS_X) + x))))
- correct_color = &stage_color;
- else
- /* Otherwise it should be the color for this division */
- correct_color = corner_colors + (y * SOURCE_DIVISIONS_X) + x;
-
- g_assert (pixels != NULL);
- g_assert_cmpint (pixels[0], ==, correct_color->red);
- g_assert_cmpint (pixels[1], ==, correct_color->green);
- g_assert_cmpint (pixels[2], ==, correct_color->blue);
-
- g_free (pixels);
- }
-}
-
-static void
-validate_result (TestState *state)
-{
- int ypos = 0;
-
- if (!g_test_quiet ())
- g_print ("Testing onscreen clone...\n");
- validate_part (state, SOURCE_SIZE, ypos * SOURCE_SIZE, 0);
- ypos++;
-
-#if 0 /* this doesn't work */
- if (!g_test_quiet ())
- g_print ("Testing offscreen clone...\n");
- validate_part (state, SOURCE_SIZE, ypos * SOURCE_SIZE, 0);
-#endif
- ypos++;
-
- if (!g_test_quiet ())
- g_print ("Testing onscreen clone with rectangular clip...\n");
- validate_part (state, SOURCE_SIZE, ypos * SOURCE_SIZE, ~1);
- ypos++;
-
- if (!g_test_quiet ())
- g_print ("Testing onscreen clone with path clip...\n");
- validate_part (state, SOURCE_SIZE, ypos * SOURCE_SIZE, 1);
- ypos++;
-}
-
-static gboolean
-on_paint (gpointer data)
-{
- TestState *state = data;
- int frame_num;
-
- /* XXX: validate_result calls clutter_stage_read_pixels which will result in
- * another paint run so to avoid infinite recursion we only aim to validate
- * the first frame. */
- frame_num = state->frame++;
- if (frame_num == 1)
- validate_result (state);
-
- state->was_painted = TRUE;
-
- return G_SOURCE_REMOVE;
-}
-
-void
-texture_fbo (TestConformSimpleFixture *fixture,
- gconstpointer data)
-{
- TestState state;
- ClutterActor *actor;
- int ypos = 0;
-
- state.frame = 0;
-
- state.stage = clutter_test_get_stage ();
-
- clutter_actor_set_background_color (CLUTTER_ACTOR (state.stage), &stage_color);
-
- /* Onscreen source with clone next to it */
- actor = create_source ();
- clutter_container_add (CLUTTER_CONTAINER (state.stage), actor, NULL);
- clutter_actor_set_position (actor, 0, ypos * SOURCE_SIZE);
- actor = clutter_texture_new_from_actor (actor);
- clutter_actor_set_position (actor, SOURCE_SIZE, ypos * SOURCE_SIZE);
- clutter_container_add (CLUTTER_CONTAINER (state.stage), actor, NULL);
- ypos++;
-
- /* Offscreen source with clone */
-#if 0 /* this doesn't work */
- actor = create_source ();
- actor = clutter_texture_new_from_actor (actor);
- clutter_actor_set_position (actor, SOURCE_SIZE, ypos * SOURCE_SIZE);
- clutter_container_add (CLUTTER_CONTAINER (state.stage), actor, NULL);
-#endif
- ypos++;
-
- /* Source clipped to the top left division */
- actor = create_source ();
- clutter_container_add (CLUTTER_CONTAINER (state.stage), actor, NULL);
- clutter_actor_set_position (actor, 0, ypos * SOURCE_SIZE);
- clutter_actor_set_clip (actor, 0, 0, DIVISION_WIDTH, DIVISION_HEIGHT);
- actor = clutter_texture_new_from_actor (actor);
- clutter_actor_set_position (actor, SOURCE_SIZE, ypos * SOURCE_SIZE);
- clutter_container_add (CLUTTER_CONTAINER (state.stage), actor, NULL);
- ypos++;
-
- /* Source clipped to everything but top left division using a
- path */
- actor = create_source ();
- clutter_container_add (CLUTTER_CONTAINER (state.stage), actor, NULL);
- clutter_actor_set_position (actor, 0, ypos * SOURCE_SIZE);
- g_signal_connect (actor, "paint",
- G_CALLBACK (pre_paint_clip_cb), NULL);
- g_signal_connect_after (actor, "paint",
- G_CALLBACK (post_paint_clip_cb), NULL);
- actor = clutter_texture_new_from_actor (actor);
- clutter_actor_set_position (actor, SOURCE_SIZE, ypos * SOURCE_SIZE);
- clutter_container_add (CLUTTER_CONTAINER (state.stage), actor, NULL);
- ypos++;
-
- clutter_actor_show (state.stage);
-
- clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
- on_paint,
- &state,
- NULL);
-
- while (!state.was_painted)
- g_main_context_iteration (NULL, FALSE);
-
- clutter_actor_destroy (state.stage);
-}
diff --git a/src/tests/clutter/conform/timeline-interpolate.c b/src/tests/clutter/conform/timeline-interpolate.c
deleted file mode 100644
index b63461d93..000000000
--- a/src/tests/clutter/conform/timeline-interpolate.c
+++ /dev/null
@@ -1,211 +0,0 @@
-#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
-#include <stdlib.h>
-#include <glib.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-#define TEST_TIMELINE_DURATION 3000
-
-/*
- * Make the test tolarate being half a second off track in each direction,
- * the thing we're testing for will still be tested for.
- */
-#define TEST_ERROR_TOLERANCE 500
-
-typedef struct _TestState
-{
- ClutterTimeline *timeline;
- int64_t start_time_us;
- int new_frame_counter;
- int expected_frame;
- int completion_count;
- int cycle_frame_counter;
-} TestState;
-
-
-static void
-new_frame_cb (ClutterTimeline *timeline,
- int frame_num,
- TestState *state)
-{
- int64_t current_time_us;
- int current_frame_ms;
- long msec_diff;
- int loop_overflow = 0;
-
- current_time_us = g_get_monotonic_time ();
- current_frame_ms = clutter_timeline_get_elapsed_time (state->timeline);
- msec_diff = us2ms (current_time_us - state->start_time_us);
-
- /* If we expect to have interpolated past the end of the timeline
- * we keep track of the overflow so we can determine when
- * the next timeout will happen. We then clip expected_frames
- * to TEST_TIMELINE_DURATION since clutter-timeline
- * semantics guaranty this frame is always signaled before
- * looping */
- if (state->expected_frame > TEST_TIMELINE_DURATION)
- {
- loop_overflow = state->expected_frame - TEST_TIMELINE_DURATION;
- state->expected_frame = TEST_TIMELINE_DURATION;
- }
-
- switch (state->cycle_frame_counter)
- {
- case 0:
- case 1:
- if (current_frame_ms >= (state->expected_frame - TEST_ERROR_TOLERANCE) &&
- current_frame_ms <= (state->expected_frame + TEST_ERROR_TOLERANCE))
- {
- g_test_message ("elapsed milliseconds=%-5li "
- "expected frame=%-4i actual frame=%-4i (OK)",
- msec_diff,
- state->expected_frame,
- current_frame_ms);
- }
- else
- {
- g_test_message ("elapsed milliseconds=%-5li "
- "expected frame=%-4i actual frame=%-4i (FAILED)",
- msec_diff,
- state->expected_frame,
- current_frame_ms);
- g_test_fail ();
- }
- break;
- case 2:
- g_assert_cmpint (current_frame_ms, ==, TEST_TIMELINE_DURATION);
- break;
- default:
- g_assert_not_reached ();
- }
-
- /* We already tested that we interpolated when looping, lets stop now. */
- if (state->completion_count == 1 &&
- state->cycle_frame_counter == 0)
- {
- clutter_timeline_stop (timeline);
- return;
- }
-
- switch (state->cycle_frame_counter)
- {
- case 0:
- {
- /*
- * First frame, sleep so we're about in the middle of the cycle,
- * before the end of the timeline cycle.
- */
- int delay_ms = ms (1500);
-
- state->expected_frame = current_frame_ms + delay_ms;
- g_test_message ("Sleeping for 1.5 seconds "
- "so next frame should be (%d + %d) = %d",
- current_frame_ms,
- delay_ms,
- state->expected_frame);
- g_usleep (ms2us (delay_ms));
- break;
- }
- case 1:
- {
- /*
- * Second frame, we're about in the middle of the cycle; sleep one cycle,
- * and check that we end up in the middle again.
- */
- int delay_ms = TEST_TIMELINE_DURATION;
-
- state->expected_frame = current_frame_ms + delay_ms;
- g_test_message ("Sleeping for %d seconds "
- "so next frame should be (%d + %d) = %d, "
- "which is %d into the next cycle",
- TEST_TIMELINE_DURATION / 1000,
- current_frame_ms,
- delay_ms,
- state->expected_frame,
- state->expected_frame - TEST_TIMELINE_DURATION);
- g_usleep (ms2us (delay_ms));
-
- g_assert_cmpint (state->expected_frame, >, TEST_TIMELINE_DURATION);
-
- state->expected_frame += loop_overflow;
- state->expected_frame -= TEST_TIMELINE_DURATION;
- g_test_message ("End of timeline reached: "
- "Wrapping expected frame too %d",
- state->expected_frame);
- break;
- }
- case 2:
- case 3:
- {
- break;
- }
- }
-
- state->new_frame_counter++;
- state->cycle_frame_counter++;
-}
-
-static void
-completed_cb (ClutterTimeline *timeline,
- TestState *state)
-{
- state->completion_count++;
- state->cycle_frame_counter = 0;
-
- if (state->completion_count >= 2)
- g_assert_not_reached ();
-}
-
-static void
-stopped_cb (ClutterTimeline *timeline,
- gboolean is_finished,
- TestState *state)
-{
- g_assert_cmpint (state->completion_count, ==, 1);
-
- clutter_test_quit ();
-}
-
-static void
-timeline_interpolation (void)
-{
- ClutterActor *stage;
- TestState state;
-
- stage = clutter_test_get_stage ();
-
- state.timeline =
- clutter_timeline_new_for_actor (stage, TEST_TIMELINE_DURATION);
- clutter_timeline_set_repeat_count (state.timeline, -1);
- g_signal_connect (state.timeline,
- "new-frame",
- G_CALLBACK (new_frame_cb),
- &state);
- g_signal_connect (state.timeline,
- "completed",
- G_CALLBACK (completed_cb),
- &state);
- g_signal_connect (state.timeline,
- "stopped",
- G_CALLBACK (stopped_cb),
- &state);
-
- state.completion_count = 0;
- state.new_frame_counter = 0;
- state.cycle_frame_counter = 0;
- state.expected_frame = 0;
-
- clutter_actor_show (stage);
-
- state.start_time_us = g_get_monotonic_time ();
- clutter_timeline_start (state.timeline);
-
- clutter_test_main ();
-
- g_object_unref (state.timeline);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/timeline/interpolate", timeline_interpolation)
-)
diff --git a/src/tests/clutter/conform/timeline-progress.c b/src/tests/clutter/conform/timeline-progress.c
deleted file mode 100644
index fc4ce8421..000000000
--- a/src/tests/clutter/conform/timeline-progress.c
+++ /dev/null
@@ -1,117 +0,0 @@
-#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
-#include <glib.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-static void
-timeline_progress_step (void)
-{
- ClutterActor *stage = clutter_test_get_stage ();
- ClutterTimeline *timeline;
-
- timeline = clutter_timeline_new_for_actor (stage, 1000);
-
- if (!g_test_quiet ())
- g_print ("mode: step(3, end)\n");
-
- clutter_timeline_rewind (timeline);
- clutter_timeline_set_step_progress (timeline, 3, CLUTTER_STEP_MODE_END);
- g_assert_cmpint (clutter_timeline_get_progress (timeline), ==, 0);
-
- clutter_timeline_advance (timeline, 1000 / 3 - 1);
- g_assert_cmpint (clutter_timeline_get_progress (timeline) * 1000, ==, 0);
-
- clutter_timeline_advance (timeline, 1000 / 3 + 1);
- g_assert_cmpint (clutter_timeline_get_progress (timeline) * 1000, ==, 333);
-
- clutter_timeline_advance (timeline, 1000 / 3 * 2 - 1);
- g_assert_cmpint (clutter_timeline_get_progress (timeline) * 1000, ==, 333);
-
- clutter_timeline_advance (timeline, 1000 / 3 * 2 + 1);
- g_assert_cmpint (clutter_timeline_get_progress (timeline) * 1000, ==, 666);
-
- clutter_timeline_rewind (timeline);
- clutter_timeline_set_progress_mode (timeline, CLUTTER_STEP_START);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 0.0);
-
- clutter_timeline_advance (timeline, 1);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 1.0);
-
- clutter_timeline_advance (timeline, 500);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 1.0);
-
- clutter_timeline_advance (timeline, 999);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 1.0);
-
- clutter_timeline_advance (timeline, 1000);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 1.0);
-
- if (!g_test_quiet ())
- g_print ("mode: step-start\n");
-
- clutter_timeline_rewind (timeline);
- clutter_timeline_set_progress_mode (timeline, CLUTTER_STEP_START);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 0.0);
-
- clutter_timeline_advance (timeline, 1);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 1.0);
-
- clutter_timeline_advance (timeline, 500);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 1.0);
-
- clutter_timeline_advance (timeline, 999);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 1.0);
-
- clutter_timeline_advance (timeline, 1000);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 1.0);
-
- if (!g_test_quiet ())
- g_print ("mode: step-end\n");
-
- clutter_timeline_rewind (timeline);
- clutter_timeline_set_progress_mode (timeline, CLUTTER_STEP_END);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 0.0);
-
- clutter_timeline_advance (timeline, 1);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 0.0);
-
- clutter_timeline_advance (timeline, 500);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 0.0);
-
- clutter_timeline_advance (timeline, 999);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 0.0);
-
- clutter_timeline_advance (timeline, 1000);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 1.0);
-
- g_object_unref (timeline);
-}
-
-static void
-timeline_progress_mode (void)
-{
- ClutterActor *stage = clutter_test_get_stage ();
- ClutterTimeline *timeline;
-
- timeline = clutter_timeline_new_for_actor (stage, 1000);
-
- g_assert (clutter_timeline_get_progress_mode (timeline) == CLUTTER_LINEAR);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 0.0);
-
- clutter_timeline_advance (timeline, 500);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 0.5);
-
- clutter_timeline_advance (timeline, 1000);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 1.0);
-
- clutter_timeline_rewind (timeline);
- g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 0.0);
-
- g_object_unref (timeline);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/timeline/progress/step", timeline_progress_step);
- CLUTTER_TEST_UNIT ("/timeline/progress/mode", timeline_progress_mode)
-)
diff --git a/src/tests/clutter/conform/timeline-rewind.c b/src/tests/clutter/conform/timeline-rewind.c
deleted file mode 100644
index aadedc5d1..000000000
--- a/src/tests/clutter/conform/timeline-rewind.c
+++ /dev/null
@@ -1,102 +0,0 @@
-#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
-#include <stdlib.h>
-#include <glib.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-#define TEST_TIMELINE_DURATION 500
-#define TEST_WATCHDOG_KICK_IN_SECONDS 10
-
-typedef struct _TestState
-{
- ClutterTimeline *timeline;
- gint rewind_count;
-} TestState;
-
-static gboolean
-watchdog_timeout (gpointer data)
-{
- TestState *state = data;
-
- g_test_message ("Watchdog timer kicking in");
- g_test_message ("rewind_count=%i", state->rewind_count);
- if (state->rewind_count <= 3)
- {
- /* The test has hung */
- g_test_message ("Failed (This test shouldn't have hung!)");
- exit (EXIT_FAILURE);
- }
- else
- {
- g_test_message ("Passed");
- clutter_test_quit ();
- }
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-new_frame_cb (ClutterTimeline *timeline,
- gint elapsed_time,
- TestState *state)
-{
- if (elapsed_time == TEST_TIMELINE_DURATION)
- {
- g_test_message ("new-frame signal received (end of timeline)");
- g_test_message ("Rewinding timeline");
- clutter_timeline_rewind (timeline);
- state->rewind_count++;
- }
- else
- {
- if (elapsed_time == 0)
- {
- g_test_message ("new-frame signal received (start of timeline)");
- }
- else
- {
- g_test_message ("new-frame signal received (mid frame)");
- }
-
- if (state->rewind_count >= 2)
- {
- g_test_message ("Sleeping for 1 second");
- g_usleep (1000000);
- }
- }
-}
-
-static void
-timeline_rewind (void)
-{
- ClutterActor *stage;
- TestState state;
-
- stage = clutter_test_get_stage ();
-
- state.timeline =
- clutter_timeline_new_for_actor (stage, TEST_TIMELINE_DURATION);
- g_signal_connect (G_OBJECT(state.timeline),
- "new-frame",
- G_CALLBACK(new_frame_cb),
- &state);
- g_test_message ("Installing a watchdog timeout "
- "to determine if this test hangs");
- clutter_threads_add_timeout (TEST_WATCHDOG_KICK_IN_SECONDS * 1000,
- watchdog_timeout,
- &state);
- state.rewind_count = 0;
-
- clutter_actor_show (stage);
-
- clutter_timeline_start (state.timeline);
-
- clutter_test_main ();
-
- g_object_unref (state.timeline);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/timeline/rewind", timeline_rewind)
-)
diff --git a/src/tests/clutter/conform/timeline.c b/src/tests/clutter/conform/timeline.c
deleted file mode 100644
index 6bd8f32bb..000000000
--- a/src/tests/clutter/conform/timeline.c
+++ /dev/null
@@ -1,365 +0,0 @@
-#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-/* This test runs three timelines at 6 fps with 10 frames. Some of
- the timelines have markers. Once the timelines are run it then
- checks that all of the frames were hit, all of the markers were hit
- and that the completed signal was fired. The timelines are then run
- again but this time with a timeout source that introduces a
- delay. This should cause some frames to be skipped. The test is run
- again but only the markers and the completed signal is checked
- for. */
-
-#define FRAME_COUNT 10
-#define FPS 6
-
-typedef struct _TimelineData TimelineData;
-
-struct _TimelineData
-{
- int timeline_num;
-
- guint frame_hit_count[FRAME_COUNT + 1];
- GSList *markers_hit;
- guint completed_count;
-};
-
-static void
-timeline_data_init (TimelineData *data, int timeline_num)
-{
- memset (data, 0, sizeof (TimelineData));
- data->timeline_num = timeline_num;
-}
-
-static void
-timeline_data_destroy (TimelineData *data)
-{
- g_slist_free_full (data->markers_hit, g_free);
-}
-
-static void
-timeline_complete_cb (ClutterTimeline *timeline,
- TimelineData *data)
-{
- g_printerr ("%i: Completed\n", data->timeline_num);
-
- data->completed_count++;
-}
-
-static void
-timeline_new_frame_cb (ClutterTimeline *timeline,
- gint msec,
- TimelineData *data)
-{
- /* Calculate an approximate frame number from the duration with
- rounding */
- int frame_no = ((msec * FRAME_COUNT + (FRAME_COUNT * 1000 / FPS) / 2)
- / (FRAME_COUNT * 1000 / FPS));
-
- g_printerr ("%i: Doing frame %d, delta = %i\n",
- data->timeline_num, frame_no,
- clutter_timeline_get_delta (timeline));
-
- g_assert (frame_no >= 0 && frame_no <= FRAME_COUNT);
-
- data->frame_hit_count[frame_no]++;
-}
-
-static void
-timeline_marker_reached_cb (ClutterTimeline *timeline,
- const gchar *marker_name,
- guint frame_num,
- TimelineData *data)
-{
- g_printerr ("%i: Marker '%s' (%d) reached, delta = %i\n",
- data->timeline_num, marker_name, frame_num,
- clutter_timeline_get_delta (timeline));
- data->markers_hit = g_slist_prepend (data->markers_hit,
- g_strdup (marker_name));
-}
-
-static gboolean
-check_timeline (ClutterTimeline *timeline,
- TimelineData *data,
- gboolean check_missed_frames)
-{
- gchar **markers;
- gsize n_markers;
- guint *marker_reached_count;
- gboolean succeeded = TRUE;
- GSList *node;
- int i;
- int missed_frame_count = 0;
- int frame_offset;
-
- if (clutter_timeline_get_direction (timeline) == CLUTTER_TIMELINE_BACKWARD)
- frame_offset = 0;
- else
- frame_offset = 1;
-
- markers = clutter_timeline_list_markers (timeline, -1, &n_markers);
- marker_reached_count = g_new0 (guint, n_markers);
-
- for (node = data->markers_hit; node; node = node->next)
- {
- for (i = 0; i < n_markers; i++)
- if (!strcmp (node->data, markers[i]))
- break;
-
- if (i < n_markers)
- marker_reached_count[i]++;
- else
- {
- g_printerr ("FAIL: unknown marker '%s' hit for timeline %i\n",
- (char *) node->data, data->timeline_num);
- succeeded = FALSE;
- }
- }
-
- for (i = 0; i < n_markers; i++)
- if (marker_reached_count[i] != 1)
- {
- g_printerr ("FAIL: marker '%s' hit %i times for timeline %i\n",
- markers[i], marker_reached_count[i], data->timeline_num);
- succeeded = FALSE;
- }
-
- if (check_missed_frames)
- {
- for (i = 0; i < FRAME_COUNT; i++)
- if (data->frame_hit_count[i + frame_offset] < 1)
- missed_frame_count++;
-
- if (missed_frame_count)
- {
- g_printerr ("FAIL: missed %i frame%s for timeline %i\n",
- missed_frame_count, missed_frame_count == 1 ? "" : "s",
- data->timeline_num);
- succeeded = FALSE;
- }
- }
-
- if (data->completed_count != 1)
- {
- g_printerr ("FAIL: timeline %i completed %i times\n",
- data->timeline_num, data->completed_count);
- succeeded = FALSE;
- }
-
- g_strfreev (markers);
- g_free (marker_reached_count);
-
- return succeeded;
-}
-
-static gboolean
-timeout_cb (gpointer data G_GNUC_UNUSED)
-{
- clutter_test_quit ();
-
- return FALSE;
-}
-
-static gboolean
-delay_cb (gpointer data)
-{
- /* Waste a bit of time so that it will skip frames */
- g_usleep (G_USEC_PER_SEC * 66 / 1000);
-
- return TRUE;
-}
-
-static gboolean
-add_timeout_idle (gpointer user_data)
-{
- clutter_threads_add_timeout (2000, timeout_cb, NULL);
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-timeline_base (void)
-{
- ClutterActor *stage;
- ClutterTimeline *timeline_1;
- TimelineData data_1;
- ClutterTimeline *timeline_2;
- TimelineData data_2;
- ClutterTimeline *timeline_3;
- TimelineData data_3;
- gchar **markers;
- gsize n_markers;
- guint delay_tag;
-
- stage = clutter_test_get_stage ();
-
- timeline_data_init (&data_1, 1);
- timeline_1 = clutter_timeline_new_for_actor (stage, FRAME_COUNT * 1000 / FPS);
- clutter_timeline_add_marker_at_time (timeline_1, "start-marker",
- 0 * 1000 / FPS);
- clutter_timeline_add_marker_at_time (timeline_1, "foo", 5 * 1000 / FPS);
- clutter_timeline_add_marker_at_time (timeline_1, "bar", 5 * 1000 / FPS);
- clutter_timeline_add_marker_at_time (timeline_1, "baz", 5 * 1000 / FPS);
- clutter_timeline_add_marker_at_time (timeline_1, "near-end-marker",
- 9 * 1000 / FPS);
- clutter_timeline_add_marker_at_time (timeline_1, "end-marker",
- 10 * 1000 / FPS);
- markers = clutter_timeline_list_markers (timeline_1, 5 * 1000 / FPS,
- &n_markers);
- g_assert (markers != NULL);
- g_assert (n_markers == 3);
- g_strfreev (markers);
-
- timeline_data_init (&data_2, 2);
- timeline_2 = clutter_timeline_new_for_actor (stage, FRAME_COUNT * 1000 / FPS);
- clutter_timeline_add_marker_at_time (timeline_2, "bar", 2 * 1000 / FPS);
- markers = clutter_timeline_list_markers (timeline_2, -1, &n_markers);
- g_assert (markers != NULL);
- g_assert (n_markers == 1);
- g_assert (strcmp (markers[0], "bar") == 0);
- g_strfreev (markers);
-
- timeline_data_init (&data_3, 3);
- timeline_3 = clutter_timeline_new_for_actor (stage, FRAME_COUNT * 1000 / FPS);
- clutter_timeline_set_direction (timeline_3, CLUTTER_TIMELINE_BACKWARD);
- clutter_timeline_add_marker_at_time (timeline_3, "start-marker",
- FRAME_COUNT * 1000 / FPS);
- clutter_timeline_add_marker_at_time (timeline_3, "foo", 5 * 1000 / FPS);
- clutter_timeline_add_marker_at_time (timeline_3, "baz", 8 * 1000 / FPS);
- clutter_timeline_add_marker_at_time (timeline_3, "near-end-marker",
- 1 * 1000 / FPS);
- clutter_timeline_add_marker_at_time (timeline_3, "end-marker",
- 0 * 1000 / FPS);
-
- g_signal_connect (timeline_1,
- "marker-reached", G_CALLBACK (timeline_marker_reached_cb),
- &data_1);
- g_signal_connect (timeline_1,
- "new-frame", G_CALLBACK (timeline_new_frame_cb),
- &data_1);
- g_signal_connect (timeline_1,
- "completed", G_CALLBACK (timeline_complete_cb),
- &data_1);
-
- g_signal_connect (timeline_2,
- "marker-reached::bar",
- G_CALLBACK (timeline_marker_reached_cb),
- &data_2);
- g_signal_connect (timeline_2,
- "new-frame", G_CALLBACK (timeline_new_frame_cb),
- &data_2);
- g_signal_connect (timeline_2,
- "completed", G_CALLBACK (timeline_complete_cb),
- &data_2);
-
- g_signal_connect (timeline_3,
- "marker-reached", G_CALLBACK (timeline_marker_reached_cb),
- &data_3);
- g_signal_connect (timeline_3,
- "new-frame", G_CALLBACK (timeline_new_frame_cb),
- &data_3);
- g_signal_connect (timeline_3,
- "completed", G_CALLBACK (timeline_complete_cb),
- &data_3);
-
- clutter_actor_show (stage);
-
- g_printerr ("Without delay...\n");
-
- clutter_timeline_start (timeline_1);
- clutter_timeline_start (timeline_2);
- clutter_timeline_start (timeline_3);
-
- g_idle_add (add_timeout_idle, NULL);
-
- clutter_test_main ();
-
- g_assert (check_timeline (timeline_1, &data_1, TRUE));
- g_assert (check_timeline (timeline_2, &data_2, TRUE));
- g_assert (check_timeline (timeline_3, &data_3, TRUE));
-
- g_printerr ("With delay...\n");
-
- timeline_data_destroy (&data_1);
- timeline_data_init (&data_1, 1);
- timeline_data_destroy (&data_2);
- timeline_data_init (&data_2, 2);
- timeline_data_destroy (&data_3);
- timeline_data_init (&data_3, 3);
-
- clutter_timeline_start (timeline_1);
- clutter_timeline_start (timeline_2);
- clutter_timeline_start (timeline_3);
-
- clutter_threads_add_timeout (2000, timeout_cb, NULL);
- delay_tag = clutter_threads_add_timeout (99, delay_cb, NULL);
-
- clutter_test_main ();
-
- g_assert (check_timeline (timeline_1, &data_1, FALSE));
- g_assert (check_timeline (timeline_2, &data_2, FALSE));
- g_assert (check_timeline (timeline_3, &data_3, FALSE));
-
- g_object_unref (timeline_1);
- g_object_unref (timeline_2);
- g_object_unref (timeline_3);
-
- timeline_data_destroy (&data_1);
- timeline_data_destroy (&data_2);
- timeline_data_destroy (&data_3);
-
- g_clear_handle_id (&delay_tag, g_source_remove);
-}
-
-static void
-timeline_markers_from_script (void)
-{
- ClutterScript *script = clutter_script_new ();
- ClutterTimeline *timeline;
- GError *error = NULL;
- gchar *test_file;
- gchar **markers;
- gsize n_markers;
-
- test_file = g_test_build_filename (G_TEST_DIST,
- "scripts",
- "test-script-timeline-markers.json",
- NULL);
- if (!clutter_script_load_from_file (script, test_file, &error))
- g_printerr ("Error: %s", error->message);
-
- g_assert_no_error (error);
-
- timeline = CLUTTER_TIMELINE (clutter_script_get_object (script, "timeline0"));
-
- g_assert (clutter_timeline_has_marker (timeline, "marker0"));
- g_assert (clutter_timeline_has_marker (timeline, "marker1"));
- g_assert (!clutter_timeline_has_marker (timeline, "foo"));
- g_assert (clutter_timeline_has_marker (timeline, "marker2"));
- g_assert (clutter_timeline_has_marker (timeline, "marker3"));
-
- markers = clutter_timeline_list_markers (timeline, -1, &n_markers);
- g_assert_cmpint (n_markers, ==, 4);
- g_strfreev (markers);
-
- markers = clutter_timeline_list_markers (timeline, 500, &n_markers);
- g_assert_cmpint (n_markers, ==, 2);
- g_assert (markers != NULL);
- g_assert (g_strv_contains ((const char * const *) markers, "marker1"));
- g_assert (g_strv_contains ((const char * const *) markers, "marker3"));
- g_strfreev (markers);
-
- g_object_unref (script);
-
- g_free (test_file);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/timeline/base", timeline_base);
- CLUTTER_TEST_UNIT ("/timeline/markers-from-script", timeline_markers_from_script)
-)
diff --git a/src/tests/clutter/conform/units.c b/src/tests/clutter/conform/units.c
deleted file mode 100644
index bcfb5890d..000000000
--- a/src/tests/clutter/conform/units.c
+++ /dev/null
@@ -1,133 +0,0 @@
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-static void
-units_cache (void)
-{
- ClutterUnits units;
- ClutterSettings *settings;
- gfloat pixels;
- gint old_dpi;
-
- settings = clutter_settings_get_default ();
- g_object_get (settings, "font-dpi", &old_dpi, NULL);
-
- g_object_set (settings, "font-dpi", 96 * 1024, NULL);
- clutter_units_from_em (&units, 1.0);
- pixels = clutter_units_to_pixels (&units);
-
- g_object_set (settings, "font-dpi", ((96 * 2) * 1024), NULL);
- g_assert_cmpfloat (clutter_units_to_pixels (&units), !=, pixels);
-
- g_object_set (settings, "font-dpi", (96 * 1024), NULL);
- g_assert_cmpfloat (clutter_units_to_pixels (&units), ==, pixels);
-
- g_object_set (settings, "font-dpi", old_dpi, NULL);
-}
-
-static void
-units_constructors (void)
-{
- ClutterUnits units, units_cm;
-
- clutter_units_from_pixels (&units, 100);
- g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_PIXEL);
- g_assert_cmpfloat (clutter_units_get_unit_value (&units), ==, 100.0);
- g_assert_cmpfloat (clutter_units_to_pixels (&units), ==, 100.0);
-
- clutter_units_from_em (&units, 5.0);
- g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_EM);
- g_assert_cmpfloat (clutter_units_get_unit_value (&units), ==, 5.0);
- g_assert_cmpfloat (clutter_units_to_pixels (&units), !=, 5.0);
-
- clutter_units_from_cm (&units_cm, 5.0);
- g_assert (clutter_units_get_unit_type (&units_cm) == CLUTTER_UNIT_CM);
- g_assert_cmpfloat (clutter_units_get_unit_value (&units_cm), ==, 5.0);
- g_assert_cmpfloat (clutter_units_to_pixels (&units_cm), !=, 5.0);
-
- clutter_units_from_mm (&units, 50.0);
- g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_MM);
- g_assert_cmpfloat (clutter_units_to_pixels (&units),
- ==,
- clutter_units_to_pixels (&units_cm));
-}
-
-static void
-units_string (void)
-{
- ClutterUnits units;
- gchar *string;
-
- g_assert (clutter_units_from_string (&units, "") == FALSE);
-
- g_assert (clutter_units_from_string (&units, "10") == TRUE);
- g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_PIXEL);
- g_assert_cmpfloat (clutter_units_get_unit_value (&units), ==, 10);
-
- g_assert (clutter_units_from_string (&units, "10 px") == TRUE);
- g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_PIXEL);
-
- g_assert (clutter_units_from_string (&units, "10 mm") == TRUE);
- g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_MM);
-
- g_assert (clutter_units_from_string (&units, "10 cm") == TRUE);
- g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_CM);
-
- g_assert (clutter_units_from_string (&units, "10 ") == TRUE);
- g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_PIXEL);
- g_assert_cmpfloat (clutter_units_get_unit_value (&units), ==, 10);
-
- g_assert (clutter_units_from_string (&units, "5 em") == TRUE);
- g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_EM);
- g_assert_cmpfloat (clutter_units_get_unit_value (&units), ==, 5);
-
- g_assert (clutter_units_from_string (&units, "5 emeralds") == FALSE);
-
- g_assert (clutter_units_from_string (&units, " 16 mm") == TRUE);
- g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_MM);
- g_assert_cmpfloat (clutter_units_get_unit_value (&units), ==, 16);
-
- g_assert (clutter_units_from_string (&units, " 24 pt ") == TRUE);
- g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_POINT);
- g_assert_cmpfloat (clutter_units_get_unit_value (&units), ==, 24);
-
- g_assert (clutter_units_from_string (&units, " 32 em garbage") == FALSE);
-
- g_assert (clutter_units_from_string (&units, "5.1cm") == TRUE);
- g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_CM);
- g_assert_cmpfloat (clutter_units_get_unit_value (&units), ==, 5.1f);
-
- g_assert (clutter_units_from_string (&units, "5,mm") == FALSE);
-
- g_assert (clutter_units_from_string (&units, ".5pt") == TRUE);
- g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_POINT);
- g_assert_cmpfloat (clutter_units_get_unit_value (&units), ==, 0.5f);
-
- g_assert (clutter_units_from_string (&units, "1 omg!!pony") == FALSE);
-
- clutter_units_from_pt (&units, 24.0);
- string = clutter_units_to_string (&units);
- g_assert_cmpstr (string, ==, "24.0 pt");
- g_free (string);
-
- clutter_units_from_em (&units, 3.0);
- string = clutter_units_to_string (&units);
- g_assert_cmpstr (string, ==, "3.00 em");
-
- units.unit_type = CLUTTER_UNIT_PIXEL;
- units.value = 0;
-
- g_assert (clutter_units_from_string (&units, string) == TRUE);
- g_assert (clutter_units_get_unit_type (&units) != CLUTTER_UNIT_PIXEL);
- g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_EM);
- g_assert_cmpint ((int) clutter_units_get_unit_value (&units), ==, 3);
-
- g_free (string);
-}
-
-CLUTTER_TEST_SUITE (
- CLUTTER_TEST_UNIT ("/units/string", units_string)
- CLUTTER_TEST_UNIT ("/units/cache", units_cache)
- CLUTTER_TEST_UNIT ("/units/constructors", units_constructors)
-)
diff --git a/src/tests/clutter/interactive/light0.png b/src/tests/clutter/interactive/light0.png
deleted file mode 100644
index 52c64e81a..000000000
--- a/src/tests/clutter/interactive/light0.png
+++ /dev/null
Binary files differ
diff --git a/src/tests/clutter/interactive/meson.build b/src/tests/clutter/interactive/meson.build
deleted file mode 100644
index e853184ef..000000000
--- a/src/tests/clutter/interactive/meson.build
+++ /dev/null
@@ -1,74 +0,0 @@
-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',
- '-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()),
-]
-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-script.c',
- 'test-grab.c',
- 'test-cogl-shader-glsl.c',
- 'test-cogl-tex-tile.c',
- 'test-cogl-tex-convert.c',
- 'test-cogl-offscreen.c',
- 'test-cogl-tex-polygon.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-swipe-action.c',
- 'test-cogl-point-sprites.c',
- 'test-devices.c',
- 'test-content.c',
- 'test-keyframe-transition.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,
- clutter_test_utils,
-]
-
-executable('test-interactive',
- sources: clutter_tests_interactive_sources,
- include_directories: [
- clutter_includes,
- clutter_tests_includes,
- clutter_tests_interactive_includepath,
- ],
- c_args: clutter_tests_interactive_c_args,
- link_args: clutter_tests_interactive_link_args,
- dependencies: [
- libmutter_test_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
deleted file mode 100755
index 72c5bf362..000000000
--- a/src/tests/clutter/interactive/meson/gen-test-unit-names.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/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/src/tests/clutter/interactive/redhand.png b/src/tests/clutter/interactive/redhand.png
deleted file mode 100644
index c07d8acd3..000000000
--- a/src/tests/clutter/interactive/redhand.png
+++ /dev/null
Binary files differ
diff --git a/src/tests/clutter/interactive/redhand_alpha.png b/src/tests/clutter/interactive/redhand_alpha.png
deleted file mode 100644
index 42a93c3a4..000000000
--- a/src/tests/clutter/interactive/redhand_alpha.png
+++ /dev/null
Binary files differ
diff --git a/src/tests/clutter/interactive/test-actors.c b/src/tests/clutter/interactive/test-actors.c
deleted file mode 100644
index 353adc750..000000000
--- a/src/tests/clutter/interactive/test-actors.c
+++ /dev/null
@@ -1,264 +0,0 @@
-#include <clutter/clutter.h>
-
-#include <math.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <glib.h>
-#include <gmodule.h>
-
-#include "test-utils.h"
-#include "tests/clutter-test-utils.h"
-
-#define NHANDS 6
-
-typedef struct SuperOH
-{
- ClutterActor **hand;
- ClutterActor *bgtex;
- ClutterActor *real_hand;
- ClutterActor *group;
- ClutterActor *stage;
-
- gint stage_width;
- gint stage_height;
- gfloat radius;
-
- ClutterTimeline *timeline;
-} SuperOH;
-
-int
-test_actors_main (int argc, char *argv[]);
-
-static void
-on_group_destroy (ClutterActor *actor,
- SuperOH *oh)
-{
- oh->group = NULL;
-}
-
-static void
-on_hand_destroy (ClutterActor *actor,
- SuperOH *oh)
-{
- int i;
-
- for (i = 0; i < NHANDS; i++)
- {
- if (oh->hand[i] == actor)
- oh->hand[i] = NULL;
- }
-}
-
-static gboolean
-on_button_press_event (ClutterActor *actor,
- ClutterEvent *event,
- SuperOH *oh)
-{
- gfloat x, y;
-
- clutter_event_get_coords (event, &x, &y);
-
- g_print ("*** button press event (button:%d) at %.2f, %.2f on %s ***\n",
- clutter_event_get_button (event),
- x, y,
- clutter_actor_get_name (actor));
-
- clutter_actor_hide (actor);
-
- return TRUE;
-}
-
-static gboolean
-input_cb (ClutterActor *stage,
- ClutterEvent *event,
- gpointer data)
-{
- SuperOH *oh = data;
-
- if (event->type == CLUTTER_KEY_RELEASE)
- {
- g_print ("*** key press event (key:%c) ***\n",
- clutter_event_get_key_symbol (event));
-
- if (clutter_event_get_key_symbol (event) == CLUTTER_KEY_q)
- {
- clutter_test_quit ();
-
- return TRUE;
- }
- else if (clutter_event_get_key_symbol (event) == CLUTTER_KEY_r)
- {
- gint i;
-
- for (i = 0; i < NHANDS; i++)
- {
- if (oh->hand[i] != NULL)
- clutter_actor_show (oh->hand[i]);
- }
-
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/* Timeline handler */
-static void
-frame_cb (ClutterTimeline *timeline,
- gint msecs,
- gpointer data)
-{
- SuperOH *oh = data;
- gint i;
- float rotation = clutter_timeline_get_progress (timeline) * 360.0f;
-
- /* Rotate everything clockwise about stage center*/
- if (oh->group != NULL)
- clutter_actor_set_rotation_angle (oh->group, CLUTTER_Z_AXIS, rotation);
-
- for (i = 0; i < NHANDS; i++)
- {
- /* Rotate each hand around there centers - to get this we need
- * to take into account any scaling.
- */
- if (oh->hand[i] != NULL)
- clutter_actor_set_rotation_angle (oh->hand[i],
- CLUTTER_Z_AXIS,
- -6.0 * rotation);
- }
-}
-
-static void
-stop_and_quit (ClutterActor *stage,
- SuperOH *data)
-{
- clutter_timeline_stop (data->timeline);
-
- clutter_test_quit ();
-}
-
-G_MODULE_EXPORT int
-test_actors_main (int argc, char *argv[])
-{
- SuperOH *oh;
- gint i;
- GError *error;
- ClutterActor *real_hand;
- gchar *file;
-
- error = NULL;
-
- clutter_test_init (&argc, &argv);
-
- oh = g_new (SuperOH, 1);
-
- oh->stage = clutter_test_get_stage ();
- clutter_actor_set_size (oh->stage, 800, 600);
- clutter_actor_set_name (oh->stage, "Default Stage");
- clutter_actor_set_background_color (oh->stage, CLUTTER_COLOR_LightSkyBlue);
- g_signal_connect (oh->stage, "destroy", G_CALLBACK (stop_and_quit), oh);
-
- clutter_stage_set_title (CLUTTER_STAGE (oh->stage), "Actors");
-
- /* Create a timeline to manage animation */
- oh->timeline = clutter_timeline_new_for_actor (oh->stage, 6000);
- clutter_timeline_set_repeat_count (oh->timeline, -1);
-
- /* fire a callback for frame change */
- g_signal_connect (oh->timeline, "new-frame", G_CALLBACK (frame_cb), oh);
-
- file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL);
- real_hand = clutter_test_utils_create_texture_from_file (file, &error);
- if (real_hand == NULL)
- g_error ("image load failed: %s", error->message);
-
- g_free (file);
-
- /* create a new actor to hold other actors */
- oh->group = clutter_actor_new ();
- clutter_actor_set_pivot_point (oh->group, 0.5, 0.5);
- clutter_actor_set_layout_manager (oh->group, clutter_fixed_layout_new ());
- clutter_actor_set_name (oh->group, "Group");
- g_signal_connect (oh->group, "destroy", G_CALLBACK (on_group_destroy), oh);
- clutter_actor_add_constraint (oh->group, clutter_align_constraint_new (oh->stage, CLUTTER_ALIGN_BOTH, 0.5));
- clutter_actor_add_constraint (oh->group, clutter_bind_constraint_new (oh->stage, CLUTTER_BIND_SIZE, 0.0f));
-
- oh->hand = g_new (ClutterActor *, NHANDS);
-
- oh->stage_width = clutter_actor_get_width (oh->stage);
- oh->stage_height = clutter_actor_get_height (oh->stage);
- oh->radius = (oh->stage_width + oh->stage_height) / NHANDS;
-
- for (i = 0; i < NHANDS; i++)
- {
- gint x, y, w, h;
-
- if (i == 0)
- {
- oh->hand[i] = real_hand;
- clutter_actor_set_name (oh->hand[i], "Real Hand");
- }
- else
- {
- oh->hand[i] = clutter_clone_new (real_hand);
- clutter_actor_set_name (oh->hand[i], "Clone Hand");
- }
-
- clutter_actor_set_reactive (oh->hand[i], TRUE);
-
- clutter_actor_set_size (oh->hand[i], 200, 213);
-
- /* Place around a circle */
- w = clutter_actor_get_width (oh->hand[i]);
- h = clutter_actor_get_height (oh->hand[i]);
-
- x = oh->stage_width / 2
- + oh->radius
- * cos (i * G_PI / (NHANDS / 2))
- - w / 2;
-
- y = oh->stage_height / 2
- + oh->radius
- * sin (i * G_PI / (NHANDS / 2))
- - h / 2;
-
- clutter_actor_set_position (oh->hand[i], x, y);
- clutter_actor_set_translation (oh->hand[i], -100.f, -106.5, 0);
-
- /* Add to our group group */
- clutter_container_add_actor (CLUTTER_CONTAINER (oh->group), oh->hand[i]);
-
- g_signal_connect (oh->hand[i], "button-press-event",
- G_CALLBACK (on_button_press_event),
- oh);
-
- g_signal_connect (oh->hand[i], "destroy",
- G_CALLBACK (on_hand_destroy),
- oh);
- }
-
- /* Add the group to the stage */
- clutter_container_add_actor (CLUTTER_CONTAINER (oh->stage), oh->group);
-
- /* Show everying */
- clutter_actor_show (oh->stage);
-
- g_signal_connect (oh->stage, "key-release-event",
- G_CALLBACK (input_cb),
- oh);
-
- /* and start it */
- clutter_timeline_start (oh->timeline);
-
- clutter_test_main ();
-
- clutter_timeline_stop (oh->timeline);
-
- /* clean up */
- g_object_unref (oh->timeline);
- g_free (oh->hand);
- g_free (oh);
-
- return EXIT_SUCCESS;
-}
diff --git a/src/tests/clutter/interactive/test-animation.c b/src/tests/clutter/interactive/test-animation.c
deleted file mode 100644
index 12cea0f6d..000000000
--- a/src/tests/clutter/interactive/test-animation.c
+++ /dev/null
@@ -1,131 +0,0 @@
-#include <stdlib.h>
-#include <gmodule.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-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)
-{
- is_expanded = !is_expanded;
-
- g_print ("Animation complete\n");
-
- clutter_actor_set_reactive (actor, TRUE);
-}
-
-static void
-on_clicked (ClutterClickAction *action,
- ClutterActor *actor,
- gpointer dummy G_GNUC_UNUSED)
-{
- gfloat old_x, old_y, new_x, new_y;
- gfloat old_width, old_height, new_width, new_height;
- gdouble new_angle;
- const ClutterColor *new_color;
- guint8 new_opacity;
-
- clutter_actor_get_position (actor, &old_x, &old_y);
- clutter_actor_get_size (actor, &old_width, &old_height);
-
- /* determine the final state of the animation depending on
- * the state of the actor
- */
- if (!is_expanded)
- {
- new_x = old_x - 100;
- new_y = old_y - 100;
- new_width = old_width + 200;
- new_height = old_height + 200;
- new_angle = 360.0;
-
- new_color = CLUTTER_COLOR_DarkScarletRed;
-
- new_opacity = 255;
- }
- else
- {
- new_x = old_x + 100;
- new_y = old_y + 100;
- new_width = old_width - 200;
- new_height = old_height - 200;
- new_angle = 0.0;
-
- new_color = CLUTTER_COLOR_LightOrange;
-
- new_opacity = 128;
- }
-
- clutter_actor_save_easing_state (actor);
- clutter_actor_set_easing_mode (actor, CLUTTER_EASE_IN_EXPO);
- clutter_actor_set_easing_duration (actor, 2000);
-
- clutter_actor_set_position (actor, new_x, new_y);
- clutter_actor_set_size (actor, new_width, new_height);
- clutter_actor_set_background_color (actor, new_color);
- clutter_actor_set_rotation_angle (actor, CLUTTER_Z_AXIS, new_angle);
- clutter_actor_set_reactive (actor, FALSE);
-
- /* animate the opacity halfway through, with a different pacing */
- clutter_actor_save_easing_state (actor);
- clutter_actor_set_easing_mode (actor, CLUTTER_LINEAR);
- clutter_actor_set_easing_delay (actor, 1000);
- clutter_actor_set_easing_duration (actor, 1000);
- clutter_actor_set_opacity (actor, new_opacity);
- clutter_actor_restore_easing_state (actor);
-
- clutter_actor_restore_easing_state (actor);
-}
-
-G_MODULE_EXPORT int
-test_animation_main (int argc, char *argv[])
-{
- ClutterActor *stage, *rect;
- ClutterAction *action;
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_actor_set_background_color (stage, CLUTTER_COLOR_LightSkyBlue);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Animation");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- rect = clutter_actor_new ();
- clutter_actor_set_background_color (rect, CLUTTER_COLOR_LightOrange);
- clutter_actor_add_child (stage, rect);
- clutter_actor_set_size (rect, 50, 50);
- clutter_actor_set_pivot_point (rect, .5f, .5f);
- clutter_actor_set_translation (rect, -25, -25, 0);
- clutter_actor_set_position (rect,
- clutter_actor_get_width (stage) / 2,
- clutter_actor_get_height (stage) / 2);
- clutter_actor_set_opacity (rect, 128);
- clutter_actor_set_reactive (rect, TRUE);
- g_signal_connect (rect, "transitions-completed",
- G_CALLBACK (on_rect_transitions_completed),
- NULL);
-
- action = clutter_click_action_new ();
- g_signal_connect (action, "clicked", G_CALLBACK (on_clicked), NULL);
- clutter_actor_add_action_with_name (rect, "click", action);
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return EXIT_SUCCESS;
-}
-
-G_MODULE_EXPORT const char *
-test_animation_describe (void)
-{
- return "Simple animation demo";
-}
diff --git a/src/tests/clutter/interactive/test-bind-constraint.c b/src/tests/clutter/interactive/test-bind-constraint.c
deleted file mode 100644
index bc8da6cd6..000000000
--- a/src/tests/clutter/interactive/test-bind-constraint.c
+++ /dev/null
@@ -1,258 +0,0 @@
-#include <stdlib.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-#define RECT_SIZE 128
-
-#define H_PADDING 32
-#define V_PADDING 32
-
-enum
-{
- NorthWest, North, NorthEast,
- West, Center, East,
- SouthWest, South, SouthEast,
-
- N_RECTS
-};
-
-static ClutterActor *rects[N_RECTS] = { NULL, };
-static const gchar *colors[N_RECTS] = {
- "#8ae234", "#73d216", "#4e9a06",
- "#729fcf", "#3465a4", "#204a87",
- "#ef2929", "#cc0000", "#a40000"
-};
-static const gchar *names[N_RECTS] = {
- "North West", "North", "North East",
- "West", "Center", "East",
- "South West", "South", "South East"
-};
-
-static const gchar *desaturare_glsl_shader =
-"uniform sampler2D tex;\n"
-"uniform float factor;\n"
-"\n"
-"vec3 desaturate (const vec3 color, const float desaturation)\n"
-"{\n"
-" const vec3 gray_conv = vec3 (0.299, 0.587, 0.114);\n"
-" vec3 gray = vec3 (dot (gray_conv, color));\n"
-" return vec3 (mix (color.rgb, gray, desaturation));\n"
-"}\n"
-"\n"
-"void main ()\n"
-"{\n"
-" vec4 color = cogl_color_in * texture2D (tex, vec2 (cogl_tex_coord_in[0].xy));\n"
-" color.rgb = desaturate (color.rgb, factor);\n"
-" cogl_color_out = color;\n"
-"}\n";
-
-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,
- gpointer data G_GNUC_UNUSED)
-{
- if (!is_expanded)
- {
- gfloat north_offset, south_offset;
- gfloat west_offset, east_offset;
-
- /* expand the 8 rectangles by animating the offset of the
- * bind constraints
- */
-
- north_offset = (clutter_actor_get_height (rects[Center]) + V_PADDING)
- * -1.0f;
- south_offset = (clutter_actor_get_height (rects[Center]) + V_PADDING);
-
- west_offset = (clutter_actor_get_width (rects[Center]) + H_PADDING)
- * -1.0f;
- east_offset = (clutter_actor_get_width (rects[Center]) + H_PADDING);
-
- clutter_actor_animate (rects[NorthWest], CLUTTER_EASE_OUT_EXPO, 500,
- "opacity", 255,
- "@constraints.x-bind.offset", west_offset,
- "@constraints.y-bind.offset", north_offset,
- "reactive", TRUE,
- NULL);
- clutter_actor_animate (rects[North], CLUTTER_EASE_OUT_EXPO, 500,
- "opacity", 255,
- "@constraints.y-bind.offset", north_offset,
- "reactive", TRUE,
- NULL);
- clutter_actor_animate (rects[NorthEast], CLUTTER_EASE_OUT_EXPO, 500,
- "opacity", 255,
- "@constraints.x-bind.offset", east_offset,
- "@constraints.y-bind.offset", north_offset,
- "reactive", TRUE,
- NULL);
-
- clutter_actor_animate (rects[West], CLUTTER_EASE_OUT_EXPO, 500,
- "opacity", 255,
- "@constraints.x-bind.offset", west_offset,
- "reactive", TRUE,
- NULL);
- /* turn on the desaturation effect and set the center
- * rectangle not reactive
- */
- clutter_actor_animate (rects[Center], CLUTTER_LINEAR, 500,
- "@effects.desaturate.enabled", TRUE,
- "reactive", FALSE,
- NULL);
- clutter_actor_animate (rects[East], CLUTTER_EASE_OUT_EXPO, 500,
- "opacity", 255,
- "@constraints.x-bind.offset", east_offset,
- "reactive", TRUE,
- NULL);
-
- clutter_actor_animate (rects[SouthWest], CLUTTER_EASE_OUT_EXPO, 500,
- "opacity", 255,
- "@constraints.x-bind.offset", west_offset,
- "@constraints.y-bind.offset", south_offset,
- "reactive", TRUE,
- NULL);
- clutter_actor_animate (rects[South], CLUTTER_EASE_OUT_EXPO, 500,
- "opacity", 255,
- "@constraints.y-bind.offset", south_offset,
- "reactive", TRUE,
- NULL);
- clutter_actor_animate (rects[SouthEast], CLUTTER_EASE_OUT_EXPO, 500,
- "opacity", 255,
- "@constraints.x-bind.offset", east_offset,
- "@constraints.y-bind.offset", south_offset,
- "reactive", TRUE,
- NULL);
- }
- else
- {
- gint i;
-
- clutter_actor_animate (rects[Center], CLUTTER_LINEAR, 500,
- "@effects.desaturate.enabled", FALSE,
- "reactive", TRUE,
- NULL);
-
- for (i = NorthWest; i < N_RECTS; i++)
- {
- if (i == Center)
- continue;
-
- /* put the 8 rectangles back into their initial state */
- clutter_actor_animate (rects[i], CLUTTER_EASE_OUT_EXPO, 500,
- "opacity", 0,
- "@constraints.x-bind.offset", 0.0f,
- "@constraints.y-bind.offset", 0.0f,
- "reactive", FALSE,
- NULL);
- }
- }
-
- is_expanded = !is_expanded;
-
- g_print ("Selected: [%s]\n", clutter_actor_get_name (actor));
-
- return TRUE;
-}
-
-G_MODULE_EXPORT const char *
-test_bind_constraint_describe (void)
-{
- return "Demonstrate the usage of ClutterBindConstraint";
-}
-
-G_MODULE_EXPORT int
-test_bind_constraint_main (int argc, char *argv[])
-{
- ClutterActor *stage, *rect;
- ClutterConstraint *constraint;
- ClutterEffect *effect;
- ClutterColor rect_color;
- gint i;
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Constraints");
- clutter_actor_set_size (stage, 800, 600);
-
- /* main rectangle */
- clutter_color_from_string (&rect_color, "#3465a4");
- rect = clutter_actor_new ();
- g_signal_connect (rect, "button-release-event",
- G_CALLBACK (on_button_release),
- NULL);
- clutter_actor_set_background_color (rect, &rect_color);
- clutter_actor_set_size (rect, RECT_SIZE, RECT_SIZE);
- clutter_actor_set_reactive (rect, TRUE);
- clutter_actor_set_name (rect, names[Center]);
- clutter_actor_add_child (stage, rect);
-
- /* align the center rectangle to the center of the stage */
- constraint = clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5);
- clutter_actor_add_constraint_with_name (rect, "align", constraint);
-
- /* this is the equivalent of the DesaturateEffect; we cannot animate
- * the factor because the animation API only understands GObject
- * properties; so we use the ActorMeta:enabled property to toggle
- * the shader
- */
- effect = clutter_shader_effect_new (CLUTTER_FRAGMENT_SHADER);
- clutter_shader_effect_set_shader_source (CLUTTER_SHADER_EFFECT (effect),
- desaturare_glsl_shader);
- clutter_shader_effect_set_uniform (CLUTTER_SHADER_EFFECT (effect),
- "tex", G_TYPE_INT, 1, 0);
- clutter_shader_effect_set_uniform (CLUTTER_SHADER_EFFECT (effect),
- "factor", G_TYPE_FLOAT, 1, 0.66);
- clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
- clutter_actor_add_effect_with_name (rect, "desaturate", effect);
-
- rects[Center] = rect;
-
- /* build the other rectangles, and bind their position and size
- * to the center rectangle. we are going to animate the offset
- * of the BindConstraints
- */
- for (i = 0; i < N_RECTS; i++)
- {
- if (i == Center)
- continue;
-
- clutter_color_from_string (&rect_color, colors[i]);
-
- rect = clutter_actor_new ();
- clutter_actor_set_background_color (rect, &rect_color);
- clutter_actor_set_opacity (rect, 0);
- clutter_actor_set_name (rect, names[i]);
- clutter_actor_add_child (stage, rect);
-
- constraint = clutter_bind_constraint_new (rects[Center], CLUTTER_BIND_X, 0.0);
- clutter_actor_add_constraint_with_name (rect, "x-bind", constraint);
-
- constraint = clutter_bind_constraint_new (rects[Center], CLUTTER_BIND_Y, 0.0);
- clutter_actor_add_constraint_with_name (rect, "y-bind", constraint);
-
- constraint = clutter_bind_constraint_new (rects[Center], CLUTTER_BIND_SIZE, 0.0);
- clutter_actor_add_constraint_with_name (rect, "size-bind", constraint);
-
- g_signal_connect (rect, "button-release-event",
- G_CALLBACK (on_button_release),
- NULL);
-
- rects[i] = rect;
- }
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return EXIT_SUCCESS;
-}
diff --git a/src/tests/clutter/interactive/test-binding-pool.c b/src/tests/clutter/interactive/test-binding-pool.c
deleted file mode 100644
index 3d869662c..000000000
--- a/src/tests/clutter/interactive/test-binding-pool.c
+++ /dev/null
@@ -1,326 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <glib.h>
-#include <gmodule.h>
-
-#include <clutter/clutter.h>
-#include <clutter/clutter-keysyms.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))
-#define KEY_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_KEY_GROUP, KeyGroupClass))
-#define IS_KEY_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_KEY_GROUP))
-
-typedef struct _KeyGroup KeyGroup;
-typedef struct _KeyGroupClass KeyGroupClass;
-
-struct _KeyGroup
-{
- ClutterActor parent_instance;
-
- gint selected_index;
-};
-
-struct _KeyGroupClass
-{
- ClutterActorClass parent_class;
-
- void (* activate) (KeyGroup *group,
- 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
-{
- ACTIVATE,
-
- LAST_SIGNAL
-};
-
-static guint group_signals[LAST_SIGNAL] = { 0, };
-
-static gboolean
-key_group_action_move_left (KeyGroup *self,
- const gchar *action_name,
- guint key_val,
- ClutterModifierType modifiers)
-{
- gint n_children;
-
- g_debug ("%s: activated '%s' (k:%d, m:%d)",
- G_STRLOC,
- action_name,
- key_val,
- modifiers);
-
- n_children = clutter_actor_get_n_children (CLUTTER_ACTOR (self));
-
- self->selected_index -= 1;
-
- if (self->selected_index < 0)
- self->selected_index = n_children - 1;
-
- return TRUE;
-}
-
-static gboolean
-key_group_action_move_right (KeyGroup *self,
- const gchar *action_name,
- guint key_val,
- ClutterModifierType modifiers)
-{
- gint n_children;
-
- g_debug ("%s: activated '%s' (k:%d, m:%d)",
- G_STRLOC,
- action_name,
- key_val,
- modifiers);
-
- n_children = clutter_actor_get_n_children (CLUTTER_ACTOR (self));
-
- self->selected_index += 1;
-
- if (self->selected_index >= n_children)
- self->selected_index = 0;
-
- return TRUE;
-}
-
-static gboolean
-key_group_action_activate (KeyGroup *self,
- const gchar *action_name,
- guint key_val,
- ClutterModifierType modifiers)
-{
- ClutterActor *child = NULL;
-
- g_debug ("%s: activated '%s' (k:%d, m:%d)",
- G_STRLOC,
- action_name,
- key_val,
- modifiers);
-
- if (self->selected_index == -1)
- return FALSE;
-
- child = clutter_actor_get_child_at_index (CLUTTER_ACTOR (self),
- self->selected_index);
-
- if (child != NULL)
- {
- g_signal_emit (self, group_signals[ACTIVATE], 0, child);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static gboolean
-key_group_key_press (ClutterActor *actor,
- ClutterKeyEvent *event)
-{
- ClutterBindingPool *pool;
- gboolean res;
-
- pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (actor));
- g_assert (pool != NULL);
-
- res = clutter_binding_pool_activate (pool,
- event->keyval,
- event->modifier_state,
- G_OBJECT (actor));
-
- /* if we activate a key binding, redraw the actor */
- if (res)
- clutter_actor_queue_redraw (actor);
-
- return res ? CLUTTER_EVENT_STOP : CLUTTER_EVENT_PROPAGATE;
-}
-
-static void
-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))
- {
- /* paint the selection rectangle */
- if (i == self->selected_index)
- {
- ClutterActorBox box = { 0, };
-
- clutter_actor_get_allocation_box (child, &box);
-
- box.x1 -= 2;
- box.y1 -= 2;
- box.x2 += 2;
- box.y2 += 2;
-
- 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, paint_context);
-
- i += 1;
- }
-}
-
-static void
-key_group_class_init (KeyGroupClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
- ClutterBindingPool *binding_pool;
-
- actor_class->paint = key_group_paint;
- actor_class->key_press_event = key_group_key_press;
-
- group_signals[ACTIVATE] =
- g_signal_new (g_intern_static_string ("activate"),
- G_OBJECT_CLASS_TYPE (gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (KeyGroupClass, activate),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1,
- CLUTTER_TYPE_ACTOR);
-
- binding_pool = clutter_binding_pool_get_for_class (klass);
-
- clutter_binding_pool_install_action (binding_pool, "move-right",
- CLUTTER_KEY_Right, 0,
- G_CALLBACK (key_group_action_move_right),
- NULL, NULL);
- clutter_binding_pool_install_action (binding_pool, "move-left",
- CLUTTER_KEY_Left, 0,
- G_CALLBACK (key_group_action_move_left),
- NULL, NULL);
- clutter_binding_pool_install_action (binding_pool, "activate",
- CLUTTER_KEY_Return, 0,
- G_CALLBACK (key_group_action_activate),
- NULL, NULL);
- clutter_binding_pool_install_action (binding_pool, "activate",
- CLUTTER_KEY_KP_Enter, 0,
- G_CALLBACK (key_group_action_activate),
- NULL, NULL);
- clutter_binding_pool_install_action (binding_pool, "activate",
- CLUTTER_KEY_ISO_Enter, 0,
- G_CALLBACK (key_group_action_activate),
- NULL, NULL);
-}
-
-static void
-key_group_init (KeyGroup *self)
-{
- self->selected_index = -1;
-}
-
-static void
-on_key_group_activate (KeyGroup *group,
- ClutterActor *child)
-{
- g_print ("Child '%s' activated!\n", clutter_actor_get_name (child));
-}
-
-G_MODULE_EXPORT int
-test_binding_pool_main (int argc, char *argv[])
-{
- ClutterActor *stage, *key_group;
- gint group_x, group_y;
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Key Binding Pool");
- g_signal_connect (stage,
- "button-press-event", G_CALLBACK (clutter_test_quit),
- NULL);
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- key_group = g_object_new (TYPE_KEY_GROUP, NULL);
- clutter_actor_add_child (stage, key_group);
-
- /* add three rectangles to the key group */
- clutter_container_add (CLUTTER_CONTAINER (key_group),
- g_object_new (CLUTTER_TYPE_ACTOR,
- "background-color", CLUTTER_COLOR_Red,
- "name", "Red Rectangle",
- "width", 100.0,
- "height", 100.0,
- "x", 0.0,
- "y", 0.0,
- NULL),
- g_object_new (CLUTTER_TYPE_ACTOR,
- "background-color", CLUTTER_COLOR_Green,
- "name", "Green Rectangle",
- "width", 100.0,
- "height", 100.0,
- "x", 125.0,
- "y", 0.0,
- NULL),
- g_object_new (CLUTTER_TYPE_ACTOR,
- "background-color", CLUTTER_COLOR_Blue,
- "name", "Blue Rectangle",
- "width", 100.0,
- "height", 100.0,
- "x", 250.0,
- "y", 0.0,
- NULL),
- NULL);
-
- g_signal_connect (key_group,
- "activate", G_CALLBACK (on_key_group_activate),
- NULL);
-
- group_x =
- (clutter_actor_get_width (stage) - clutter_actor_get_width (key_group))
- / 2;
- group_y =
- (clutter_actor_get_height (stage) - clutter_actor_get_height (key_group))
- / 2;
-
- clutter_actor_set_position (key_group, group_x, group_y);
- clutter_actor_set_reactive (key_group, TRUE);
-
- clutter_stage_set_key_focus (CLUTTER_STAGE (stage), key_group);
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return EXIT_SUCCESS;
-}
-
-G_MODULE_EXPORT const char *
-test_binding_pool_describe (void)
-{
- return "Binding pools example";
-}
diff --git a/src/tests/clutter/interactive/test-cairo-clock.c b/src/tests/clutter/interactive/test-cairo-clock.c
deleted file mode 100644
index 9f0d210bf..000000000
--- a/src/tests/clutter/interactive/test-cairo-clock.c
+++ /dev/null
@@ -1,125 +0,0 @@
-#include <stdlib.h>
-#include <math.h>
-#include <cairo.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.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,
- int width,
- int height)
-{
- GDateTime *now;
- float hours, minutes, seconds;
-
- /* 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;
-
- /* clear the contents of the canvas, to avoid painting
- * over the previous frame
- */
- cairo_save (cr);
- cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
- cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
- cairo_paint (cr);
- cairo_restore (cr);
-
- /* 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 */
- clutter_cairo_set_source_color (cr, CLUTTER_COLOR_White);
- 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 */
- clutter_cairo_set_source_color (cr, CLUTTER_COLOR_DarkChameleon);
- 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 TRUE;
-}
-
-G_MODULE_EXPORT int
-test_cairo_clock_main (int argc, char *argv[])
-{
- ClutterActor *stage;
- ClutterContent *canvas;
-
- /* initialize Clutter */
- clutter_test_init (&argc, &argv);
-
- /* create a resizable stage */
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "2D Clock");
- 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);
- clutter_actor_set_content (stage, canvas);
-
- /* quit on destroy */
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_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_test_main ();
-
- return EXIT_SUCCESS;
-}
-
-G_MODULE_EXPORT const char *
-test_cairo_clock_describe (void)
-{
- return "Simple 2D canvas using a Cairo texture actor";
-}
diff --git a/src/tests/clutter/interactive/test-cairo-flowers.c b/src/tests/clutter/interactive/test-cairo-flowers.c
deleted file mode 100644
index 5cfce9a41..000000000
--- a/src/tests/clutter/interactive/test-cairo-flowers.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Pretty cairo flower hack.
- */
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-#ifndef _MSC_VER
-#include <unistd.h> /* for sleep(), used for screenshots */
-#endif
-#include <stdlib.h>
-#ifdef _MSC_VER
-#define _USE_MATH_DEFINES
-#endif
-#include <math.h>
-
-#define PETAL_MIN 20
-#define PETAL_VAR 40
-#define N_FLOWERS 40 /* reduce if you have a small card */
-
-typedef struct Flower
-{
- ClutterActor *ctex;
- gint x,y,rot,v,rv;
-}
-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,
- gint width,
- gint height,
- gpointer user_data)
-{
- /* No science here, just a hack from toying */
- gint i, j;
-
- double colors[] = {
- 0.71, 0.81, 0.83,
- 1.0, 0.78, 0.57,
- 0.64, 0.30, 0.35,
- 0.73, 0.40, 0.39,
- 0.91, 0.56, 0.64,
- 0.70, 0.47, 0.45,
- 0.92, 0.75, 0.60,
- 0.82, 0.86, 0.85,
- 0.51, 0.56, 0.67,
- 1.0, 0.79, 0.58,
-
- };
-
- gint size;
- gint petal_size;
- gint n_groups; /* Num groups of petals 1-3 */
- gint n_petals; /* num of petals 4 - 8 */
- gint pm1, pm2;
-
- gint idx, last_idx = -1;
-
- petal_size = GPOINTER_TO_INT (user_data);
- size = petal_size * 8;
-
- n_groups = rand() % 3 + 1;
-
- cairo_set_tolerance (cr, 0.1);
-
- /* Clear */
- cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
- cairo_paint(cr);
- cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
-
- cairo_translate(cr, size/2, size/2);
-
- for (i=0; i<n_groups; i++)
- {
- n_petals = rand() % 5 + 4;
- cairo_save (cr);
-
- cairo_rotate (cr, rand() % 6);
-
- do {
- idx = (rand() % (sizeof (colors) / sizeof (double) / 3)) * 3;
- } while (idx == last_idx);
-
- cairo_set_source_rgba (cr, colors[idx], colors[idx+1],
- colors[idx+2], 0.5);
-
- last_idx = idx;
-
- /* some bezier randomness */
- pm1 = rand() % 20;
- pm2 = rand() % 4;
-
- for (j=1; j<n_petals+1; j++)
- {
- cairo_save (cr);
- cairo_rotate (cr, ((2*M_PI)/n_petals)*j);
-
- /* Petals are made up beziers */
- cairo_new_path (cr);
- cairo_move_to (cr, 0, 0);
- cairo_rel_curve_to (cr,
- petal_size, petal_size,
- (pm2+2)*petal_size, petal_size,
- (2*petal_size) + pm1, 0);
- cairo_rel_curve_to (cr,
- 0 + (pm2*petal_size), -petal_size,
- -petal_size, -petal_size,
- -((2*petal_size) + pm1), 0);
- cairo_close_path (cr);
- cairo_fill (cr);
- cairo_restore (cr);
- }
-
- petal_size -= rand() % (size/8);
-
- cairo_restore (cr);
- }
-
- /* Finally draw flower center */
- do {
- idx = (rand() % (sizeof (colors) / sizeof (double) / 3)) * 3;
- } while (idx == last_idx);
-
- if (petal_size < 0)
- petal_size = rand() % 10;
-
- cairo_set_source_rgba (cr, colors[idx], colors[idx+1], colors[idx+2], 0.5);
-
- cairo_arc(cr, 0, 0, petal_size, 0, M_PI * 2);
- cairo_fill(cr);
-
- return TRUE;
-}
-
-static ClutterActor *
-make_flower_actor (void)
-{
- gint petal_size = PETAL_MIN + rand() % PETAL_VAR;
- gint size = petal_size * 8;
- ClutterActor *ctex;
- ClutterContent *canvas;
-
- canvas = clutter_canvas_new ();
- g_signal_connect (canvas, "draw",
- G_CALLBACK (draw_flower), GINT_TO_POINTER (petal_size));
-
- clutter_canvas_set_size (CLUTTER_CANVAS (canvas), size, size);
- ctex = g_object_new (CLUTTER_TYPE_ACTOR,
- "content", canvas,
- "width", (gfloat) size,
- "height", (gfloat) size,
- NULL);
- clutter_actor_set_pivot_point (ctex, 0.5, 0.5);
-
- g_object_unref (canvas);
-
- return ctex;
-}
-
-static void
-tick (ClutterTimeline *timeline,
- gint msecs,
- gpointer data)
-{
- Flower **flowers = data;
- gint i = 0;
-
- for (i = 0; i < N_FLOWERS; i++)
- {
- flowers[i]->y += flowers[i]->v;
- flowers[i]->rot += flowers[i]->rv;
-
- if (flowers[i]->y > (gint) clutter_actor_get_height (stage))
- flowers[i]->y = -clutter_actor_get_height (flowers[i]->ctex);
-
- clutter_actor_set_position (flowers[i]->ctex,
- flowers[i]->x, flowers[i]->y);
-
- clutter_actor_set_rotation_angle (flowers[i]->ctex,
- CLUTTER_Z_AXIS,
- flowers[i]->rot);
- }
-}
-
-static void
-stop_and_quit (ClutterActor *actor,
- ClutterTimeline *timeline)
-{
- clutter_timeline_stop (timeline);
- clutter_test_quit ();
-}
-
-G_MODULE_EXPORT int
-test_cairo_flowers_main (int argc, char **argv)
-{
- Flower *flowers[N_FLOWERS];
- ClutterTimeline *timeline;
- int i;
-
- srand (time (NULL));
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Cairo Flowers");
-
- /* Create a timeline to manage animation */
- timeline = clutter_timeline_new_for_actor (stage, 6000);
- clutter_timeline_set_repeat_count (timeline, -1);
- g_signal_connect (stage, "destroy", G_CALLBACK (stop_and_quit), timeline);
-
- clutter_actor_set_background_color (stage, CLUTTER_COLOR_Black);
-
- for (i=0; i< N_FLOWERS; i++)
- {
- flowers[i] = g_new0(Flower, 1);
- flowers[i]->ctex = make_flower_actor();
- flowers[i]->x = rand() % (int) clutter_actor_get_width (stage)
- - (PETAL_MIN + PETAL_VAR) * 2;
- flowers[i]->y = rand() % (int) clutter_actor_get_height (stage);
- flowers[i]->rv = rand() % 5 + 1;
- flowers[i]->v = rand() % 10 + 2;
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage),
- flowers[i]->ctex);
- clutter_actor_set_position (flowers[i]->ctex,
- flowers[i]->x, flowers[i]->y);
- }
-
- /* fire a callback for frame change */
- g_signal_connect (timeline, "new-frame", G_CALLBACK (tick), flowers);
-
- clutter_actor_show (stage);
-
- clutter_timeline_start (timeline);
-
- g_signal_connect (stage, "key-press-event",
- G_CALLBACK (clutter_test_quit),
- NULL);
-
- clutter_test_main ();
-
- g_object_unref (timeline);
-
- return EXIT_SUCCESS;
-}
-
-G_MODULE_EXPORT const char *
-test_cairo_flowers_describe (void)
-{
- return "Drawing pretty flowers with Cairo";
-}
diff --git a/src/tests/clutter/interactive/test-cogl-multitexture.c b/src/tests/clutter/interactive/test-cogl-multitexture.c
deleted file mode 100644
index f14f0b7d8..000000000
--- a/src/tests/clutter/interactive/test-cogl-multitexture.c
+++ /dev/null
@@ -1,254 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-#include <glib-object.h>
-#include <gmodule.h>
-
-#include <clutter/clutter.h>
-#include <cogl/cogl.h>
-
-#include "tests/clutter-test-utils.h"
-
-typedef struct _TestMultiLayerMaterialState
-{
- ClutterActor *group;
- CoglHandle alpha_tex;
- CoglHandle redhand_tex;
- gfloat *tex_coords;
-
- ClutterTimeline *timeline;
-
- CoglHandle material0;
- graphene_matrix_t tex_matrix0;
- graphene_matrix_t rot_matrix0;
- CoglHandle light_tex0;
-
- CoglHandle material1;
- graphene_matrix_t tex_matrix1;
- graphene_matrix_t rot_matrix1;
- CoglHandle light_tex1;
-
-} TestMultiLayerMaterialState;
-
-int
-test_cogl_multitexture_main (int argc, char *argv[]);
-
-const char *
-test_cogl_multitexture_describe (void);
-
-static void
-frame_cb (ClutterTimeline *timeline,
- gint frame_no,
- gpointer data)
-{
- TestMultiLayerMaterialState *state = data;
-
- graphene_matrix_multiply (&state->rot_matrix0,
- &state->tex_matrix0,
- &state->tex_matrix0);
- cogl_material_set_layer_matrix (state->material0, 2, &state->tex_matrix0);
-
- graphene_matrix_multiply (&state->rot_matrix1,
- &state->tex_matrix1,
- &state->tex_matrix1);
- cogl_material_set_layer_matrix (state->material1, 2, &state->tex_matrix1);
-}
-
-static void
-material_rectangle_paint (ClutterActor *actor,
- ClutterPaintContext *paint_context,
- gpointer data)
-{
- TestMultiLayerMaterialState *state = data;
- 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
-animation_completed_cb (ClutterAnimation *animation,
- TestMultiLayerMaterialState *state)
-{
- static gboolean go_back = FALSE;
- gdouble new_rotation_y;
-
- if (go_back)
- new_rotation_y = 30;
- else
- new_rotation_y = -30;
- go_back = !go_back;
-
- clutter_actor_animate_with_timeline (state->group,
- CLUTTER_LINEAR,
- state->timeline,
- "rotation-angle-y", new_rotation_y,
- "signal-after::completed",
- animation_completed_cb, state,
- NULL);
-
-
-}
-
-G_MODULE_EXPORT int
-test_cogl_multitexture_main (int argc, char *argv[])
-{
- GError *error = NULL;
- ClutterActor *stage;
- ClutterColor stage_color = { 0x61, 0x56, 0x56, 0xff };
- g_autofree TestMultiLayerMaterialState *state = g_new0 (TestMultiLayerMaterialState, 1);
- gfloat stage_w, stage_h;
- gchar **files;
- gfloat tex_coords[] =
- {
- /* tx1 ty1 tx2 ty2 */
- 0, 0, 1, 1,
- 0, 0, 1, 1,
- 0, 0, 1, 1
- };
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_actor_get_size (stage, &stage_w, &stage_h);
-
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl: Multi-texturing");
- clutter_actor_set_background_color (CLUTTER_ACTOR (stage), &stage_color);
-
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- /* We create a non-descript actor that we know doesn't have a
- * default paint handler, so that we can easily control
- * painting in a paint signal handler, without having to
- * sub-class anything etc. */
- state->group = clutter_actor_new ();
- clutter_actor_set_position (state->group, stage_w / 2, stage_h / 2);
- g_signal_connect (state->group, "paint",
- G_CALLBACK(material_rectangle_paint), state);
-
- files = g_new (gchar*, 4);
- files[0] = g_build_filename (TESTS_DATADIR, "redhand_alpha.png", NULL);
- files[1] = g_build_filename (TESTS_DATADIR, "redhand.png", NULL);
- files[2] = g_build_filename (TESTS_DATADIR, "light0.png", NULL);
- files[3] = NULL;
-
- state->alpha_tex =
- cogl_texture_new_from_file (files[0],
- COGL_TEXTURE_NO_SLICING,
- COGL_PIXEL_FORMAT_ANY,
- &error);
- if (!state->alpha_tex)
- g_critical ("Failed to load redhand_alpha.png: %s", error->message);
-
- state->redhand_tex =
- cogl_texture_new_from_file (files[1],
- COGL_TEXTURE_NO_SLICING,
- COGL_PIXEL_FORMAT_ANY,
- &error);
- if (!state->redhand_tex)
- g_critical ("Failed to load redhand.png: %s", error->message);
-
- state->light_tex0 =
- cogl_texture_new_from_file (files[2],
- COGL_TEXTURE_NO_SLICING,
- COGL_PIXEL_FORMAT_ANY,
- &error);
- if (!state->light_tex0)
- g_critical ("Failed to load light0.png: %s", error->message);
-
- state->light_tex1 =
- cogl_texture_new_from_file (files[2],
- COGL_TEXTURE_NO_SLICING,
- COGL_PIXEL_FORMAT_ANY,
- &error);
- if (!state->light_tex1)
- g_critical ("Failed to load light0.png: %s", error->message);
-
- g_strfreev (files);
-
- state->material0 = cogl_material_new ();
- cogl_material_set_layer (state->material0, 0, state->alpha_tex);
- cogl_material_set_layer (state->material0, 1, state->redhand_tex);
- cogl_material_set_layer (state->material0, 2, state->light_tex0);
-
- state->material1 = cogl_material_new ();
- cogl_material_set_layer (state->material1, 0, state->alpha_tex);
- cogl_material_set_layer (state->material1, 1, state->redhand_tex);
- cogl_material_set_layer (state->material1, 2, state->light_tex1);
-
- state->tex_coords = tex_coords;
-
- graphene_matrix_init_identity (&state->tex_matrix0);
- graphene_matrix_init_identity (&state->tex_matrix1);
- graphene_matrix_init_identity (&state->rot_matrix0);
- graphene_matrix_init_identity (&state->rot_matrix1);
-
- graohene_matrix_translate (&state->rot_matrix0,
- &GRAPHENE_POINT3D_INIT (-0.5, -0.5, 0));
- graohene_matrix_rotate (&state->rot_matrix0, 10.0, graphene_vec3_z_axis ());
- graphene_matrix_translate (&state->rot_matrix0,
- &GRAPHENE_POINT3D_INIT (0.5, 0.5, 0));
-
- graphene_matrix_translate (&state->rot_matrix1,
- &GRAPHENE_POINT3D_INIT (-0.5, -0.5, 0));
- graohene_matrix_rotate (&state->rot_matrix1, -10.0, graphene_vec3_z_axis ());
- graphene_matrix_translate (&state->rot_matrix1,
- &GRAPHENE_POINT3D_INIT (0.5, 0.5, 0));
-
- clutter_actor_set_translation (data->parent_container, -86.f, -125.f, 0.f);
- clutter_container_add_actor (CLUTTER_CONTAINER(stage),
- state->group);
-
- state->timeline = clutter_timeline_new_for_actor (stage, 2812);
-
- g_signal_connect (state->timeline, "new-frame", G_CALLBACK (frame_cb), state);
-
- clutter_actor_animate_with_timeline (state->group,
- CLUTTER_LINEAR,
- state->timeline,
- "rotation-angle-y", 30.0,
- "signal-after::completed",
- animation_completed_cb, state,
- NULL);
-
- /* start the timeline and thus the animations */
- clutter_timeline_start (state->timeline);
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- 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;
-}
-
-G_MODULE_EXPORT const char *
-test_cogl_multitexture_describe (void)
-{
- return "Multi-texturing support in Cogl.";
-}
diff --git a/src/tests/clutter/interactive/test-cogl-offscreen.c b/src/tests/clutter/interactive/test-cogl-offscreen.c
deleted file mode 100644
index 4f2e6bddb..000000000
--- a/src/tests/clutter/interactive/test-cogl-offscreen.c
+++ /dev/null
@@ -1,353 +0,0 @@
-#include <glib.h>
-#include <gmodule.h>
-#include <stdlib.h>
-#include <clutter/clutter.h>
-#include <cogl/cogl.h>
-
-#include "tests/clutter-test-utils.h"
-
-/* 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, TestCoglbox))
-
-#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;
-
-int
-test_cogl_offscreen_main (int argc, char *argv[]);
-
-const char *
-test_cogl_offscreen_describe (void);
-
-G_END_DECLS
-
-/* Coglbox private declaration
- *--------------------------------------------------*/
-
-struct _TestCoglboxPrivate
-{
- CoglHandle texhand_id;
- CoglHandle texture_id;
- CoglFramebuffer *framebuffer;
-};
-
-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,
- 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 };
- 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->framebuffer, pipeline,
- 20, 20, 20 + 100, 20 + 100);
-
- cogl_pipeline_set_color4ub (pipeline, 0, 0xff, 0, 0xff);
- cogl_framebuffer_draw_rectangle (priv->framebuffer, 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
-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_object_unref (priv->texture_id);
- g_object_unref (priv->framebuffer);
-
- G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object);
-}
-
-/* A newly created Cogl framebuffer will be initialized with a
- * viewport covering the size of the viewport i.e. equavalent to:
- *
- * calling cogl_framebuffer_set_viewport (
- * fb,
- * 0, 0,
- * cogl_framebuffer_get_viewport_width (fb),
- * cogl_framebuffer_get_viewport_width (fb));
- *
- * The projection matrix will be an identity matrix.
- *
- * The modelview matrix will be an identity matrix, and this will
- * create a coordinate system - like OpenGL - with the viewport
- * being mapped to a unit cube with the origin (0, 0, 0) in the
- * center, x, y and z ranging from -1 to 1 with (-1, -1) being top
- * left and (1, 1) bottom right.
- *
- * This sets up a Clutter like coordinate system for a Cogl
- * framebuffer
- */
-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;
- graphene_matrix_t projection_matrix;
- graphene_matrix_t mv_matrix;
-
- 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_framebuffer_perspective (framebuffer, fovy, aspect, z_near, z_far);
-
- /*
- * In theory, we can compute the camera distance from screen as:
- *
- * 0.5 * tan (FOV)
- *
- * However, it's better to compute the z_camera from our projection
- * matrix so that we get a 1:1 mapping at the screen distance. Consider
- * the upper-left corner of the screen. It has object coordinates
- * (0,0,0), so by the transform below, ends up with eye coordinate
- *
- * x_eye = x_object / width - 0.5 = - 0.5
- * y_eye = (height - y_object) / width - 0.5 = 0.5
- * z_eye = z_object / width - z_camera = - z_camera
- *
- * From cogl_perspective(), we know that the projection matrix has
- * the form:
- *
- * (x, 0, 0, 0)
- * (0, y, 0, 0)
- * (0, 0, c, d)
- * (0, 0, -1, 0)
- *
- * Applied to the above, we get clip coordinates of
- *
- * x_clip = x * (- 0.5)
- * y_clip = y * 0.5
- * w_clip = - 1 * (- z_camera) = z_camera
- *
- * Dividing through by w to get normalized device coordinates, we
- * have, x_nd = x * 0.5 / z_camera, y_nd = - y * 0.5 / z_camera.
- * The upper left corner of the screen has normalized device coordinates,
- * (-1, 1), so to have the correct 1:1 mapping, we have to have:
- *
- * z_camera = 0.5 * x = 0.5 * y
- *
- * If x != y, then we have a non-uniform aspect ration, and a 1:1 mapping
- * doesn't make sense.
- */
-
- cogl_framebuffer_get_projection_matrix (framebuffer, &projection_matrix);
- z_camera = 0.5 * graphene_matrix_get_value (&projection_matrix, 0, 0);
-
- graphene_matrix_init_translate (&mv_matrix,
- &GRAPHENE_POINT3D_INIT (0.0f,
- -1.0 * height,
- 0.0f));
- graphene_matrix_scale (&mv_matrix, 1.0f / width, -1.0f / height, 1.0f / width);
- graphene_matrix_translate (&mv_matrix,
- &GRAPHENE_POINT3D_INIT (-0.5f, -0.5f, -z_camera));
- cogl_framebuffer_set_modelview_matrix (framebuffer, &mv_matrix);
-}
-
-static void
-test_coglbox_map (ClutterActor *actor)
-{
- TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (actor);
- ClutterActor *stage;
- ClutterPerspective perspective;
- float stage_width;
- float stage_height;
- GError *error = NULL;
-
- CLUTTER_ACTOR_CLASS (test_coglbox_parent_class)->map (actor);
-
- printf ("Creating offscreen\n");
- priv->framebuffer =
- COGL_FRAMEBUFFER (cogl_offscreen_new_with_texture (priv->texture_id));
- if (!cogl_framebuffer_allocate (priv->framebuffer, &error))
- g_error ("Failed to allocate framebuffer: %s", error->message);
-
- stage = clutter_actor_get_stage (actor);
- clutter_stage_get_perspective (CLUTTER_STAGE (stage), &perspective);
- clutter_actor_get_size (stage, &stage_width, &stage_height);
-
- setup_viewport (priv->framebuffer,
- stage_width, stage_height,
- perspective.fovy,
- perspective.aspect,
- perspective.z_near,
- perspective.z_far);
-
- if (!priv->framebuffer)
- printf ("Failed creating offscreen to texture!\n");
-}
-
-static void
-test_coglbox_init (TestCoglbox *self)
-{
- TestCoglboxPrivate *priv;
- gchar *file;
-
- self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self);
-
- printf ("Loading redhand.png\n");
- file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL);
- priv->texhand_id = cogl_texture_new_from_file (file,
- COGL_TEXTURE_NONE,
- COGL_PIXEL_FORMAT_ANY,
- NULL);
- 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 == NULL)
- printf ("Failed creating texture with size!\n");
-}
-
-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->map = test_coglbox_map;
- actor_class->paint = test_coglbox_paint;
-}
-
-static ClutterActor*
-test_coglbox_new (void)
-{
- return g_object_new (TEST_TYPE_COGLBOX, NULL);
-}
-
-G_MODULE_EXPORT int
-test_cogl_offscreen_main (int argc, char *argv[])
-{
- ClutterActor *stage;
- ClutterActor *coglbox;
-
- clutter_test_init (&argc, &argv);
-
- /* Stage */
- stage = clutter_test_get_stage ();
- clutter_actor_set_size (stage, 400, 400);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Offscreen Buffers");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- /* Cogl Box */
- coglbox = test_coglbox_new ();
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), coglbox);
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return 0;
-}
-
-G_MODULE_EXPORT const char *
-test_cogl_offscreen_describe (void)
-{
- return "Offscreen buffer support in Cogl.";
-}
diff --git a/src/tests/clutter/interactive/test-cogl-point-sprites.c b/src/tests/clutter/interactive/test-cogl-point-sprites.c
deleted file mode 100644
index 9d6027274..000000000
--- a/src/tests/clutter/interactive/test-cogl-point-sprites.c
+++ /dev/null
@@ -1,282 +0,0 @@
-#include <stdlib.h>
-#include <clutter/clutter.h>
-#include <math.h>
-#include <gmodule.h>
-#include <string.h>
-
-#include "tests/clutter-test-utils.h"
-
-#define N_FIREWORKS 32
-/* Units per second per second */
-#define GRAVITY -1.5f
-
-#define N_SPARKS (N_FIREWORKS * 32) /* Must be a power of two */
-#define TIME_PER_SPARK 0.01f /* in seconds */
-
-#define TEXTURE_SIZE 32
-
-typedef struct _Firework Firework;
-
-struct _Firework
-{
- float size;
- float x, y;
- float start_x, start_y;
- ClutterColor color;
-
- /* Velocities are in units per second */
- float initial_x_velocity;
- float initial_y_velocity;
-
- GTimer *timer;
-};
-
-typedef struct _Spark Spark;
-
-struct _Spark
-{
- float x, y;
- ClutterColor color;
- ClutterColor base_color;
-};
-
-typedef struct _Data Data;
-
-struct _Data
-{
- Firework fireworks[N_FIREWORKS];
-
- int next_spark_num;
- Spark sparks[N_SPARKS];
- GTimer *last_spark_time;
-
- 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)
-{
- guint8 *p, *data;
- int x, y;
- CoglHandle tex;
-
- 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++)
- for (x = 0; x < TEXTURE_SIZE; x++)
- {
- int dx = x - TEXTURE_SIZE / 2;
- int dy = y - TEXTURE_SIZE / 2;
- float value = sqrtf (dx * dx + dy * dy) * 255.0 / (TEXTURE_SIZE / 2);
- if (value > 255.0f)
- value = 255.0f;
- value = 255.0f - value;
- *(p++) = value;
- *(p++) = value;
- *(p++) = value;
- *(p++) = value;
- }
-
- tex = cogl_texture_new_from_data (TEXTURE_SIZE, TEXTURE_SIZE,
- COGL_TEXTURE_NO_SLICING,
- COGL_PIXEL_FORMAT_RGBA_8888_PRE,
- COGL_PIXEL_FORMAT_ANY,
- TEXTURE_SIZE * 4,
- data);
-
- g_free (data);
-
- return tex;
-}
-
-static void
-on_after_paint (ClutterActor *stage,
- ClutterPaintContext *paint_context,
- Data *data)
-{
- CoglFramebuffer *framebuffer =
- clutter_paint_context_get_framebuffer (paint_context);
- graphene_matrix_t old_matrix, new_matrix;
- int i;
- float diff_time;
-
- cogl_framebuffer_get_projection_matrix (framebuffer, &old_matrix);
- /* Use an orthogonal projection from -1 -> 1 in both axes */
- graphene_matrix_init_identity (&new_matrix);
- cogl_framebuffer_set_projection_matrix (framebuffer, &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++)
- {
- Firework *firework = data->fireworks + i;
-
- if ((fabsf (firework->x - firework->start_x) > 2.0f) ||
- firework->y < -1.0f)
- {
- firework->size = g_random_double_range (0.001f, 0.1f);
- firework->start_x = 1.0f + firework->size;
- firework->start_y = -1.0f;
- firework->initial_x_velocity = g_random_double_range (-0.1f, -2.0f);
- firework->initial_y_velocity = g_random_double_range (0.1f, 4.0f);
- g_timer_reset (firework->timer);
-
- /* Pick a random color out of six */
- if (g_random_boolean ())
- {
- memset (&firework->color, 0, sizeof (ClutterColor));
- ((guint8 *) &firework->color)[g_random_int_range (0, 3)] = 255;
- }
- else
- {
- memset (&firework->color, 255, sizeof (ClutterColor));
- ((guint8 *) &firework->color)[g_random_int_range (0, 3)] = 0;
- }
- firework->color.alpha = 255;
-
- /* Fire some of the fireworks from the other side */
- if (g_random_boolean ())
- {
- firework->start_x = -firework->start_x;
- firework->initial_x_velocity = -firework->initial_x_velocity;
- }
- }
-
- diff_time = g_timer_elapsed (firework->timer, NULL);
-
- firework->x = (firework->start_x +
- firework->initial_x_velocity * diff_time);
-
- firework->y = ((firework->initial_y_velocity * diff_time +
- 0.5f * GRAVITY * diff_time * diff_time) +
- firework->start_y);
- }
-
- diff_time = g_timer_elapsed (data->last_spark_time, NULL);
- if (diff_time < 0.0f || diff_time >= TIME_PER_SPARK)
- {
- /* Add a new spark for each firework, overwriting the oldest ones */
- for (i = 0; i < N_FIREWORKS; i++)
- {
- Spark *spark = data->sparks + data->next_spark_num;
- Firework *firework = data->fireworks + i;
-
- spark->x = (firework->x +
- g_random_double_range (-firework->size / 2.0f,
- firework->size / 2.0f));
- spark->y = (firework->y +
- g_random_double_range (-firework->size / 2.0f,
- firework->size / 2.0f));
- spark->base_color = firework->color;
-
- data->next_spark_num = (data->next_spark_num + 1) & (N_SPARKS - 1);
- }
-
- /* Update the colour of each spark */
- for (i = 0; i < N_SPARKS; i++)
- {
- float color_value;
-
- /* First spark is the oldest */
- Spark *spark = data->sparks + ((data->next_spark_num + i)
- & (N_SPARKS - 1));
-
- color_value = i / (N_SPARKS - 1.0f);
- spark->color.red = spark->base_color.red * color_value;
- spark->color.green = spark->base_color.green * color_value;
- spark->color.blue = spark->base_color.blue * color_value;
- spark->color.alpha = 255.0f * color_value;
- }
-
- g_timer_reset (data->last_spark_time);
- }
-
- cogl_framebuffer_set_projection_matrix (framebuffer, &old_matrix);
- cogl_framebuffer_pop_matrix (framebuffer);
-}
-
-static gboolean
-idle_cb (gpointer data)
-{
- clutter_actor_queue_redraw (data);
-
- return G_SOURCE_CONTINUE;
-}
-
-G_MODULE_EXPORT int
-test_cogl_point_sprites_main (int argc, char *argv[])
-{
- ClutterActor *stage;
- CoglHandle tex;
- Data data;
- GError *error = NULL;
- int i;
-
- clutter_test_init (&argc, &argv);
-
- data.material = cogl_material_new ();
- data.last_spark_time = g_timer_new ();
- data.next_spark_num = 0;
- cogl_material_set_point_size (data.material, TEXTURE_SIZE);
-
- tex = generate_round_texture ();
- cogl_material_set_layer (data.material, 0, tex);
- cogl_object_unref (tex);
-
- if (!cogl_material_set_layer_point_sprite_coords_enabled (data.material,
- 0, TRUE,
- &error))
- {
- g_warning ("Failed to enable point sprite coords: %s", error->message);
- g_clear_error (&error);
- }
-
- for (i = 0; i < N_FIREWORKS; i++)
- {
- data.fireworks[i].x = -FLT_MAX;
- data.fireworks[i].y = FLT_MAX;
- data.fireworks[i].size = 0.0f;
- data.fireworks[i].timer = g_timer_new ();
- }
-
- for (i = 0; i < N_SPARKS; i++)
- {
- data.sparks[i].x = 2.0f;
- data.sparks[i].y = 2.0f;
- }
-
- stage = clutter_test_get_stage ();
- clutter_actor_set_background_color (CLUTTER_ACTOR (stage), CLUTTER_COLOR_Black);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Point Sprites");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
- g_signal_connect (CLUTTER_STAGE (stage), "after-paint", G_CALLBACK (on_after_paint), &data);
-
- clutter_actor_show (stage);
-
- clutter_threads_add_idle (idle_cb, stage);
-
- clutter_test_main ();
-
- cogl_object_unref (data.material);
- g_timer_destroy (data.last_spark_time);
-
- for (i = 0; i < N_FIREWORKS; i++)
- g_timer_destroy (data.fireworks[i].timer);
-
- return 0;
-}
-
-G_MODULE_EXPORT const char *
-test_cogl_point_sprites_describe (void)
-{
- return "Point sprites support in Cogl.";
-}
diff --git a/src/tests/clutter/interactive/test-cogl-shader-glsl.c b/src/tests/clutter/interactive/test-cogl-shader-glsl.c
deleted file mode 100644
index 62b16e772..000000000
--- a/src/tests/clutter/interactive/test-cogl-shader-glsl.c
+++ /dev/null
@@ -1,350 +0,0 @@
-#include <clutter/clutter.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <glib.h>
-#include <gmodule.h>
-
-#include "tests/clutter-test-utils.h"
-
-typedef struct
-{
- 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
- */
-
-/* FRAGMENT_SHADER_BEGIN: generate boilerplate with a local vec4 color already
- * initialized, from a sampler2D in a variable tex.
- */
-#define FRAGMENT_SHADER_VARS \
- "uniform sampler2D tex;" \
- "uniform float x_step, y_step;"
-
-#define FRAGMENT_SHADER_BEGIN \
- "void main (){" \
- " vec4 color = texture2D (tex, vec2(cogl_tex_coord_in[0]));"
-
-/* FRAGMENT_SHADER_END: apply the changed color to the output buffer correctly
- * blended with the gl specified color (makes the opacity of actors work
- * correctly).
- */
-#define FRAGMENT_SHADER_END \
- " cogl_color_out = color;" \
- " cogl_color_out = cogl_color_out * cogl_color_in;" \
- "}"
-
-static ShaderSource shaders[]=
- {
- {"brightness-contrast",
- FRAGMENT_SHADER_VARS
- "uniform float brightness, contrast;"
- FRAGMENT_SHADER_BEGIN
- " color.rgb /= color.a;"
- " color.rgb = (color.rgb - vec3(0.5, 0.5, 0.5)) * contrast + "
- "vec3 (brightness + 0.5, brightness + 0.5, brightness + 0.5);"
- " color.rgb *= color.a;"
- FRAGMENT_SHADER_END
- },
-
- {"box-blur",
- FRAGMENT_SHADER_VARS
-
- "vec4 get_rgba_rel(sampler2D tex, float dx, float dy)"
- "{"
- " return texture2D (tex, cogl_tex_coord_in[0].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
- },
-
- {"invert",
- FRAGMENT_SHADER_VARS
- FRAGMENT_SHADER_BEGIN
- " color.rgb /= color.a;"
- " color.rgb = vec3(1.0, 1.0, 1.0) - color.rgb;\n"
- " color.rgb *= color.a;"
- FRAGMENT_SHADER_END
- },
-
- {"brightness-contrast",
- FRAGMENT_SHADER_VARS
- "uniform float brightness;"
- "uniform float contrast;"
- FRAGMENT_SHADER_BEGIN
- " color.rgb /= color.a;"
- " color.r = (color.r - 0.5) * contrast + brightness + 0.5;"
- " color.g = (color.g - 0.5) * contrast + brightness + 0.5;"
- " color.b = (color.b - 0.5) * contrast + brightness + 0.5;"
- " color.rgb *= color.a;"
- FRAGMENT_SHADER_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
- },
-
- {"combined-mirror",
- FRAGMENT_SHADER_VARS
- FRAGMENT_SHADER_BEGIN
- " vec4 colorB = texture2D (tex, vec2(cogl_tex_coord_in[0].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
- },
-
- {"edge-detect",
- FRAGMENT_SHADER_VARS
- "float get_avg_rel(sampler2D texB, float dx, float dy)"
- "{"
- " vec4 colorB = texture2D (texB, cogl_tex_coord_in[0].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
- }
-};
-
-static CoglHandle redhand;
-static CoglMaterial *material;
-static unsigned int timeout_id = 0;
-static int shader_no = 0;
-
-static void
-on_after_paint (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_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
-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);
- 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);
-
- program = cogl_create_program ();
- cogl_program_attach_shader (program, shader);
- cogl_object_unref (shader);
- cogl_program_link (program);
-
- uniform_no = cogl_program_get_uniform_location (program, "tex");
- cogl_program_set_uniform_1i (program, uniform_no, 0);
- uniform_no = cogl_program_get_uniform_location (program, "radius");
- cogl_program_set_uniform_1f (program, uniform_no, 3.0);
- uniform_no = cogl_program_get_uniform_location (program, "brightness");
- cogl_program_set_uniform_1f (program, uniform_no, 0.4);
- uniform_no = cogl_program_get_uniform_location (program, "contrast");
- cogl_program_set_uniform_1f (program, uniform_no, -1.9);
-
- uniform_no = cogl_program_get_uniform_location (program, "x_step");
- cogl_program_set_uniform_1f (program, uniform_no, 1.0f / image_width);
- uniform_no = cogl_program_get_uniform_location (program, "y_step");
- cogl_program_set_uniform_1f (program, uniform_no, 1.0f / image_height);
-
- cogl_material_set_user_program (material, program);
- cogl_object_unref (program);
-
- shader_no = new_no;
-}
-
-static gboolean
-button_release_cb (ClutterActor *actor,
- ClutterEvent *event,
- gpointer data)
-{
- int new_no;
-
- /* Stop the automatic cycling if the user want to manually control
- * which shader to display */
- g_clear_handle_id (&timeout_id, g_source_remove);
-
- 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_test_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,
- gpointer user_data)
-{
- clutter_test_quit ();
-
- return CLUTTER_EVENT_STOP;
-}
-
-G_MODULE_EXPORT int
-test_cogl_shader_glsl_main (int argc, char *argv[])
-{
- ClutterActor *stage;
- char *file;
- GError *error;
- ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff };
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
-
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Assembly Shader Test");
- clutter_actor_set_background_color (CLUTTER_ACTOR (stage), &stage_color);
-
- file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL);
- error = NULL;
- redhand = cogl_texture_new_from_file (file,
- COGL_TEXTURE_NO_ATLAS,
- COGL_PIXEL_FORMAT_ANY,
- &error);
- if (redhand == NULL)
- 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 (CLUTTER_STAGE (stage), "after-paint", G_CALLBACK (on_after_paint), 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_test_main ();
-
- return EXIT_SUCCESS;
-}
-
diff --git a/src/tests/clutter/interactive/test-cogl-tex-convert.c b/src/tests/clutter/interactive/test-cogl-tex-convert.c
deleted file mode 100644
index c098ff6a3..000000000
--- a/src/tests/clutter/interactive/test-cogl-tex-convert.c
+++ /dev/null
@@ -1,245 +0,0 @@
-#include <glib.h>
-#include <gmodule.h>
-#include <stdlib.h>
-#include <clutter/clutter.h>
-#include <cogl/cogl.h>
-
-#include "tests/clutter-test-utils.h"
-
-/* 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, TestCoglbox))
-
-#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;
-
-int
-test_cogl_tex_convert_main (int argc, char *argv[]);
-
-const char *
-test_cogl_tex_convert_describe (void);
-
-G_END_DECLS
-
-/* Coglbox private declaration
- *--------------------------------------------------*/
-
-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,
- 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);
-
- 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
-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_object_unref (priv->cogl_tex_id);
-
- G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object);
-}
-
-static void
-test_coglbox_init (TestCoglbox *self)
-{
- TestCoglboxPrivate *priv;
- gchar *file;
-
- self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self);
-
- file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL);
-
- priv->cogl_tex_id[0] =
- cogl_texture_new_from_file (file,
- 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);
-
- g_free (file);
-}
-
-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;
-}
-
-static ClutterActor*
-test_coglbox_new (void)
-{
- return g_object_new (TEST_TYPE_COGLBOX, NULL);
-}
-
-G_MODULE_EXPORT int
-test_cogl_tex_convert_main (int argc, char *argv[])
-{
- ClutterActor *stage;
- ClutterActor *coglbox;
-
- clutter_test_init (&argc, &argv);
-
- /* Stage */
- stage = clutter_test_get_stage ();
- clutter_actor_set_size (stage, 400, 400);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Texture Conversion");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- /* Cogl Box */
- coglbox = test_coglbox_new ();
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), coglbox);
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return 0;
-}
-
-G_MODULE_EXPORT const char *
-test_cogl_tex_convert_describe (void)
-{
- return "Pixel format conversion of Cogl textures.";
-}
diff --git a/src/tests/clutter/interactive/test-cogl-tex-polygon.c b/src/tests/clutter/interactive/test-cogl-tex-polygon.c
deleted file mode 100644
index 2479a3d7c..000000000
--- a/src/tests/clutter/interactive/test-cogl-tex-polygon.c
+++ /dev/null
@@ -1,455 +0,0 @@
-#include <glib.h>
-#include <gmodule.h>
-#include <stdlib.h>
-#include <clutter/clutter.h>
-#include <cogl/cogl.h>
-
-#include "tests/clutter-test-utils.h"
-
-/* 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, TestCoglbox))
-
-#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;
-
-int
-test_cogl_tex_polygon_main (int argc, char *argv[]);
-
-const char *
-test_cogl_tex_polygon_describe (void);
-
-G_END_DECLS
-
-/* Coglbox private declaration
- *--------------------------------------------------*/
-
-struct _TestCoglboxPrivate
-{
- CoglHandle sliced_tex, not_sliced_tex;
- gint frame;
- gboolean use_sliced;
- 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 (CoglFramebuffer *framebuffer,
- CoglPipeline *pipeline,
- float x1,
- float y1,
- float x2,
- float y2,
- float tx1,
- float ty1,
- float tx2,
- float ty2)
-{
- CoglVertexP3T2C4 vertices[4];
- CoglPrimitive *primitive;
- int i;
-
- vertices[0].x = x1;
- vertices[0].y = y1;
- vertices[0].z = 0;
- vertices[0].s = tx1;
- vertices[0].t = ty1;
- vertices[1].x = x1;
- vertices[1].y = y2;
- vertices[1].z = 0;
- vertices[1].s = tx1;
- vertices[1].t = ty2;
- vertices[2].x = x2;
- vertices[2].y = y2;
- vertices[2].z = 0;
- vertices[2].s = tx2;
- vertices[2].t = ty2;
- vertices[3].x = x2;
- vertices[3].y = y1;
- vertices[3].z = 0;
- vertices[3].s = tx2;
- vertices[3].t = ty1;
-
- for (i = 0; i < 4; i++)
- {
- CoglColor cogl_color;
-
- cogl_color_init_from_4ub (&cogl_color,
- 255,
- 255,
- 255,
- ((i ^ (i >> 1)) & 1) ? 0 : 128);
- 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);
- }
-
- 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 (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)
-{
- 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].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].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].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,
- 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);
-
- cogl_material_set_layer_filters (material, 0,
- priv->use_linear_filtering
- ? COGL_MATERIAL_FILTER_LINEAR :
- COGL_MATERIAL_FILTER_NEAREST,
- priv->use_linear_filtering
- ? COGL_MATERIAL_FILTER_LINEAR :
- COGL_MATERIAL_FILTER_NEAREST);
-
- 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 reflect it */
- 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_framebuffer_pop_matrix (framebuffer);
-
- 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 (framebuffer, material,
- tex_width, tex_height,
- 0, 0,
- 0, 0,
- 0, 1,
- 1, 1);
- test_coglbox_triangle_texture (framebuffer, material,
- tex_width, tex_height,
- 20, 0,
- 0, 0,
- 1, 0,
- 1, 1);
-
- cogl_framebuffer_pop_matrix (framebuffer);
-
- cogl_object_unref (material);
-}
-
-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_object_unref (priv->not_sliced_tex);
- cogl_object_unref (priv->sliced_tex);
-
- G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object);
-}
-
-static void
-test_coglbox_init (TestCoglbox *self)
-{
- TestCoglboxPrivate *priv;
- GError *error = NULL;
- gchar *file;
-
- self->priv = priv = TEST_COGLBOX_GET_PRIVATE (self);
-
- priv->use_linear_filtering = FALSE;
- priv->use_sliced = FALSE;
-
- file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL);
- priv->sliced_tex =
- cogl_texture_new_from_file (file,
- COGL_TEXTURE_NONE,
- COGL_PIXEL_FORMAT_ANY,
- &error);
- if (priv->sliced_tex == NULL)
- {
- if (error)
- {
- g_warning ("Texture loading failed: %s", error->message);
- g_error_free (error);
- error = NULL;
- }
- else
- g_warning ("Texture loading failed: <unknown>");
- }
-
- priv->not_sliced_tex =
- cogl_texture_new_from_file (file,
- COGL_TEXTURE_NO_SLICING,
- COGL_PIXEL_FORMAT_ANY,
- &error);
- if (priv->not_sliced_tex == NULL)
- {
- if (error)
- {
- g_warning ("Texture loading failed: %s", error->message);
- g_error_free (error);
- }
- else
- g_warning ("Texture loading failed: <unknown>");
- }
-
- g_free (file);
-}
-
-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;
-}
-
-static ClutterActor*
-test_coglbox_new (void)
-{
- return g_object_new (TEST_TYPE_COGLBOX, NULL);
-}
-
-static void
-frame_cb (ClutterTimeline *timeline,
- gint elapsed_msecs,
- gpointer data)
-{
- TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (data);
- gdouble progress = clutter_timeline_get_progress (timeline);
-
- priv->frame = 360.0 * progress;
- clutter_actor_queue_redraw (CLUTTER_ACTOR (data));
-}
-
-static void
-update_toggle_text (ClutterText *button, gboolean val)
-{
- clutter_text_set_text (button, val ? "Enabled" : "Disabled");
-}
-
-static gboolean
-on_toggle_click (ClutterActor *button, ClutterEvent *event,
- gboolean *toggle_val)
-{
- update_toggle_text (CLUTTER_TEXT (button), *toggle_val = !*toggle_val);
-
- return TRUE;
-}
-
-static ClutterActor *
-make_toggle (const char *label_text, gboolean *toggle_val)
-{
- ClutterActor *group = clutter_actor_new ();
- ClutterActor *label = clutter_text_new_with_text ("Sans 14", label_text);
- ClutterActor *button = clutter_text_new_with_text ("Sans 14", "");
-
- clutter_actor_set_reactive (button, TRUE);
-
- update_toggle_text (CLUTTER_TEXT (button), *toggle_val);
-
- clutter_actor_set_position (button, clutter_actor_get_width (label) + 10, 0);
- clutter_container_add (CLUTTER_CONTAINER (group), label, button, NULL);
-
- g_signal_connect (button, "button-press-event", G_CALLBACK (on_toggle_click),
- toggle_val);
-
- return group;
-}
-
-G_MODULE_EXPORT int
-test_cogl_tex_polygon_main (int argc, char *argv[])
-{
- ClutterActor *stage;
- ClutterActor *coglbox;
- ClutterActor *filtering_toggle;
- ClutterActor *slicing_toggle;
- ClutterActor *note;
- ClutterTimeline *timeline;
- ClutterColor blue = { 0x30, 0x30, 0xff, 0xff };
-
- clutter_test_init (&argc, &argv);
-
- /* Stage */
- stage = clutter_test_get_stage ();
- clutter_actor_set_background_color (CLUTTER_ACTOR (stage), &blue);
- clutter_actor_set_size (stage, 640, 480);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Texture Polygon");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- /* Cogl Box */
- coglbox = test_coglbox_new ();
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), coglbox);
-
- /* Timeline for animation */
- timeline = clutter_timeline_new_for_actor (stage, 6000);
- clutter_timeline_set_repeat_count (timeline, -1);
- g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), coglbox);
- clutter_timeline_start (timeline);
-
- /* Labels for toggling settings */
- slicing_toggle = make_toggle ("Texture slicing: ",
- &(TEST_COGLBOX_GET_PRIVATE (coglbox)
- ->use_sliced));
- clutter_actor_set_position (slicing_toggle, 0,
- clutter_actor_get_height (stage)
- - clutter_actor_get_height (slicing_toggle));
- filtering_toggle = make_toggle ("Linear filtering: ",
- &(TEST_COGLBOX_GET_PRIVATE (coglbox)
- ->use_linear_filtering));
- clutter_actor_set_position (filtering_toggle, 0,
- clutter_actor_get_y (slicing_toggle)
- - clutter_actor_get_height (filtering_toggle));
- note = clutter_text_new_with_text ("Sans 10", "<- Click to change");
- clutter_actor_set_position (note,
- clutter_actor_get_width (filtering_toggle) + 10,
- (clutter_actor_get_height (stage)
- + clutter_actor_get_y (filtering_toggle)) / 2
- - clutter_actor_get_height (note) / 2);
-
- clutter_container_add (CLUTTER_CONTAINER (stage),
- slicing_toggle,
- filtering_toggle,
- note,
- NULL);
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return 0;
-}
-
-G_MODULE_EXPORT const char *
-test_cogl_tex_polygon_describe (void)
-{
- return "Texture polygon primitive.";
-}
diff --git a/src/tests/clutter/interactive/test-cogl-tex-tile.c b/src/tests/clutter/interactive/test-cogl-tex-tile.c
deleted file mode 100644
index d51522491..000000000
--- a/src/tests/clutter/interactive/test-cogl-tex-tile.c
+++ /dev/null
@@ -1,235 +0,0 @@
-#include <glib.h>
-#include <gmodule.h>
-#include <stdlib.h>
-#include <math.h>
-#include <clutter/clutter.h>
-#include <cogl/cogl.h>
-
-#include "tests/clutter-test-utils.h"
-
-/* 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, TestCoglbox))
-
-#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;
-
-int
-test_cogl_tex_tile_main (int argc, char *argv[]);
-
-const char *
-test_cogl_tex_tile_describe (void);
-
-G_END_DECLS
-
-/* Coglbox private declaration
- *--------------------------------------------------*/
-
-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,
- 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;
- gint t;
-
- angle = priv->animation_progress * 2 * G_PI;
-
- frac = ((priv->animation_progress <= 0.5f
- ? priv->animation_progress
- : 1.0f - priv->animation_progress) + 0.5f) * 2.0f;
-
- for (t=0; t<4; t+=2)
- {
- texcoords[t] += cos (angle);
- texcoords[t+1] += sin (angle);
-
- texcoords[t] *= frac;
- texcoords[t+1] *= frac;
- }
-
- priv = TEST_COGLBOX_GET_PRIVATE (self);
-
- cogl_framebuffer_push_matrix (framebuffer);
-
- 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_framebuffer_translate (framebuffer, 100, 100, 0);
-
- 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
-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_object_unref (priv->cogl_tex_id);
-
- G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object);
-}
-
-static void
-test_coglbox_init (TestCoglbox *self)
-{
- TestCoglboxPrivate *priv;
- gchar *file;
-
- self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self);
-
- file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL);
- priv->cogl_tex_id = cogl_texture_new_from_file (file,
- COGL_TEXTURE_NONE,
- COGL_PIXEL_FORMAT_ANY,
- NULL);
- g_free (file);
-}
-
-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;
-}
-
-static ClutterActor*
-test_coglbox_new (void)
-{
- return g_object_new (TEST_TYPE_COGLBOX, NULL);
-}
-
-static void
-frame_cb (ClutterTimeline *timeline,
- gint msecs,
- gpointer data)
-{
- TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (data);
-
- priv->animation_progress = clutter_timeline_get_progress (timeline);
- clutter_actor_queue_redraw (CLUTTER_ACTOR (data));
-}
-
-G_MODULE_EXPORT int
-test_cogl_tex_tile_main (int argc, char *argv[])
-{
- ClutterActor *stage;
- ClutterActor *coglbox;
- ClutterTimeline *timeline;
-
- clutter_test_init (&argc, &argv);
-
- /* Stage */
- stage = clutter_test_get_stage ();
- clutter_actor_set_size (stage, 400, 400);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Texture Tiling");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- /* Cogl Box */
- coglbox = test_coglbox_new ();
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), coglbox);
-
- /* Timeline for animation */
- timeline = clutter_timeline_new_for_actor (stage, 6000); /* 6 second duration */
- clutter_timeline_set_repeat_count (timeline, -1);
- g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), coglbox);
- clutter_timeline_start (timeline);
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return 0;
-}
-
-G_MODULE_EXPORT const char *
-test_cogl_tex_tile_describe (void)
-{
- return "Texture tiling.";
-}
diff --git a/src/tests/clutter/interactive/test-content.c b/src/tests/clutter/interactive/test-content.c
deleted file mode 100644
index fbeebaba3..000000000
--- a/src/tests/clutter/interactive/test-content.c
+++ /dev/null
@@ -1,242 +0,0 @@
-#include <stdlib.h>
-#include <gmodule.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-typedef struct _ColorContent {
- GObject parent_instance;
-
- double red;
- double green;
- double blue;
- double alpha;
-
- float padding;
-} ColorContent;
-
-typedef struct _ColorContentClass {
- GObjectClass parent_class;
-} ColorContentClass;
-
-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,
- ClutterPaintContext *paint_context)
-{
- ColorContent *self = (ColorContent *) content;
- ClutterActorBox box, content_box;
- ClutterColor color;
- PangoLayout *layout;
- PangoRectangle logical;
- ClutterPaintNode *node;
-
-#if 0
- g_debug ("Painting content [%p] "
- "{ r:%.2f, g:%.2f, b:%.2f, a:%.2f } "
- "for actor [%p] (context: [%p])",
- content,
- self->red,
- self->green,
- self->blue,
- self->alpha,
- actor, context);
-#endif
-
- clutter_actor_get_content_box (actor, &content_box);
-
- box = content_box;
- box.x1 += self->padding;
- box.y1 += self->padding;
- box.x2 -= self->padding;
- box.y2 -= self->padding;
-
- color.alpha = self->alpha * 255;
-
- color.red = self->red * 255;
- color.green = self->green * 255;
- color.blue = self->blue * 255;
-
- node = clutter_color_node_new (&color);
- clutter_paint_node_add_rectangle (node, &box);
- clutter_paint_node_add_child (root, node);
- clutter_paint_node_unref (node);
-
- color.red = (1.0 - self->red) * 255;
- color.green = (1.0 - self->green) * 255;
- color.blue = (1.0 - self->blue) * 255;
-
- layout = clutter_actor_create_pango_layout (actor, "A");
- pango_layout_get_pixel_extents (layout, NULL, &logical);
-
- node = clutter_text_node_new (layout, &color);
-
- /* top-left */
- box.x1 = clutter_actor_box_get_x (&content_box);
- box.y1 = clutter_actor_box_get_y (&content_box);
- box.x2 = box.x1 + logical.width;
- box.y2 = box.y1 + logical.height;
- clutter_paint_node_add_rectangle (node, &box);
-
- /* top-right */
- box.x1 = clutter_actor_box_get_x (&content_box)
- + clutter_actor_box_get_width (&content_box)
- - logical.width;
- box.y1 = clutter_actor_box_get_y (&content_box);
- box.x2 = box.x1 + logical.width;
- box.y2 = box.y1 + logical.height;
- clutter_paint_node_add_rectangle (node, &box);
-
- /* bottom-right */
- box.x1 = clutter_actor_box_get_x (&content_box)
- + clutter_actor_box_get_width (&content_box)
- - logical.width;
- box.y1 = clutter_actor_box_get_y (&content_box)
- + clutter_actor_box_get_height (&content_box)
- - logical.height;
- box.x2 = box.x1 + logical.width;
- box.y2 = box.y1 + logical.height;
- clutter_paint_node_add_rectangle (node, &box);
-
- /* bottom-left */
- box.x1 = clutter_actor_box_get_x (&content_box);
- box.y1 = clutter_actor_box_get_y (&content_box)
- + clutter_actor_box_get_height (&content_box)
- - logical.height;
- box.x2 = box.x1 + logical.width;
- box.y2 = box.y1 + logical.height;
- clutter_paint_node_add_rectangle (node, &box);
-
- /* center */
- box.x1 = clutter_actor_box_get_x (&content_box)
- + (clutter_actor_box_get_width (&content_box) - logical.width) / 2.0;
- box.y1 = clutter_actor_box_get_y (&content_box)
- + (clutter_actor_box_get_height (&content_box) - logical.height) / 2.0;
- box.x2 = box.x1 + logical.width;
- box.y2 = box.y1 + logical.height;
- clutter_paint_node_add_rectangle (node, &box);
-
- clutter_paint_node_add_child (root, node);
- clutter_paint_node_unref (node);
-
- g_object_unref (layout);
-}
-
-static void
-clutter_content_iface_init (ClutterContentInterface *iface)
-{
- iface->paint_content = color_content_paint_content;
-}
-
-static void
-color_content_class_init (ColorContentClass *klass)
-{
-}
-
-static void
-color_content_init (ColorContent *self)
-{
-}
-
-static ClutterContent *
-color_content_new (double red,
- double green,
- double blue,
- double alpha,
- float padding)
-{
- ColorContent *self = g_object_new (color_content_get_type (), NULL);
-
- self->red = red;
- self->green = green;
- self->blue = blue;
- self->alpha = alpha;
- self->padding = padding;
-
- return (ClutterContent *) self;
-}
-
-G_MODULE_EXPORT int
-test_content_main (int argc, char *argv[])
-{
- ClutterActor *stage, *grid;
- ClutterContent *content;
- int i, n_rects;
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_actor_set_name (stage, "Stage");
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Content");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
- clutter_actor_show (stage);
-
- grid = clutter_actor_new ();
- clutter_actor_set_name (grid, "Grid");
- clutter_actor_set_margin_top (grid, 12);
- clutter_actor_set_margin_right (grid, 12);
- clutter_actor_set_margin_bottom (grid, 12);
- clutter_actor_set_margin_left (grid, 12);
- clutter_actor_set_layout_manager (grid, clutter_flow_layout_new (CLUTTER_FLOW_HORIZONTAL));
- clutter_actor_add_constraint (grid, clutter_bind_constraint_new (stage, CLUTTER_BIND_SIZE, 0.0));
- clutter_actor_add_child (stage, grid);
-
- content = color_content_new (g_random_double_range (0.0, 1.0),
- g_random_double_range (0.0, 1.0),
- g_random_double_range (0.0, 1.0),
- 1.0,
- 2.0);
-
- n_rects = g_random_int_range (12, 24);
- for (i = 0; i < n_rects; i++)
- {
- ClutterActor *box = clutter_actor_new ();
- ClutterColor bg_color = {
- g_random_int_range (0, 255),
- g_random_int_range (0, 255),
- g_random_int_range (0, 255),
- 255
- };
- char *name, *color;
-
- color = clutter_color_to_string (&bg_color);
- name = g_strconcat ("Box <", color, ">", NULL);
- clutter_actor_set_name (box, name);
-
- g_free (name);
- g_free (color);
-
- clutter_actor_set_background_color (box, &bg_color);
- clutter_actor_set_content (box, content);
- clutter_actor_set_size (box, 64, 64);
-
- clutter_actor_add_child (grid, box);
- }
-
- clutter_test_main ();
-
- g_object_unref (content);
-
- return EXIT_SUCCESS;
-}
-
-G_MODULE_EXPORT const char *
-test_content_describe (void)
-{
- return "A simple test for ClutterContent";
-}
diff --git a/src/tests/clutter/interactive/test-devices.c b/src/tests/clutter/interactive/test-devices.c
deleted file mode 100644
index 7e2b11eb3..000000000
--- a/src/tests/clutter/interactive/test-devices.c
+++ /dev/null
@@ -1,234 +0,0 @@
-#include <stdlib.h>
-#include <gmodule.h>
-#include <clutter/clutter.h>
-
-#include "test-utils.h"
-#include "tests/clutter-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)
-{
- ClutterInputDeviceType d_type;
-
- d_type = clutter_input_device_get_device_type (device);
- switch (d_type)
- {
- case CLUTTER_POINTER_DEVICE:
- return "Pointer";
-
- case CLUTTER_KEYBOARD_DEVICE:
- return "Keyboard";
-
- case CLUTTER_EXTENSION_DEVICE:
- return "Extension";
-
- case CLUTTER_PEN_DEVICE:
- return "Pen";
-
- case CLUTTER_ERASER_DEVICE:
- return "Eraser";
-
- case CLUTTER_CURSOR_DEVICE:
- return "Cursor";
-
- default:
- return "Unknown";
- }
-}
-
-static gboolean
-stage_button_event_cb (ClutterActor *actor,
- ClutterEvent *event,
- TestDevicesApp *app)
-{
- ClutterInputDevice *device;
- ClutterInputDevice *source_device;
- ClutterActor *hand = NULL;
-
- device = clutter_event_get_device (event);
- source_device = clutter_event_get_source_device (event);
-
- hand = g_hash_table_lookup (app->devices, device);
-
- g_print ("Device: '%s' (type: %s, source: '%s')\n",
- clutter_input_device_get_device_name (device),
- device_type_name (device),
- source_device != device
- ? clutter_input_device_get_device_name (source_device)
- : "<same>");
-
- if (hand != NULL)
- {
- gfloat event_x, event_y;
-
- clutter_event_get_coords (event, &event_x, &event_y);
- clutter_actor_set_position (hand, event_x, event_y);
- }
-
- return FALSE;
-}
-
-static gboolean
-stage_motion_event_cb (ClutterActor *actor,
- ClutterEvent *event,
- TestDevicesApp *app)
-{
- ClutterInputDevice *device;
- ClutterActor *hand = NULL;
-
- device = clutter_event_get_device (event);
-
- hand = g_hash_table_lookup (app->devices, device);
- if (hand != NULL)
- {
- gfloat event_x, event_y;
-
- clutter_event_get_coords (event, &event_x, &event_y);
- clutter_actor_set_position (hand, event_x, event_y);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-seat_device_added_cb (ClutterSeat *seat,
- ClutterInputDevice *device,
- TestDevicesApp *app)
-{
- ClutterInputDeviceType device_type;
- ClutterActor *hand = NULL;
-
- g_print ("got a %s device '%s'\n",
- device_type_name (device),
- clutter_input_device_get_device_name (device));
-
- device_type = clutter_input_device_get_device_type (device);
- if (device_type == CLUTTER_POINTER_DEVICE ||
- device_type == CLUTTER_PEN_DEVICE ||
- device_type == CLUTTER_POINTER_DEVICE)
- {
- g_print ("*** enabling device '%s' ***\n",
- clutter_input_device_get_device_name (device));
-
- 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);
- }
-}
-
-static void
-seat_device_removed_cb (ClutterSeat *seat,
- ClutterInputDevice *device,
- TestDevicesApp *app)
-{
- ClutterInputDeviceType device_type;
- ClutterActor *hand = NULL;
-
- g_print ("removed a %s device '%s'\n",
- device_type_name (device),
- clutter_input_device_get_device_name (device));
-
- device_type = clutter_input_device_get_device_type (device);
- if (device_type == CLUTTER_POINTER_DEVICE ||
- device_type == CLUTTER_PEN_DEVICE ||
- device_type == CLUTTER_POINTER_DEVICE)
- {
- hand = g_hash_table_lookup (app->devices, device);
- if (hand != NULL)
- clutter_container_add_actor (CLUTTER_CONTAINER (app->stage), hand);
-
- g_hash_table_remove (app->devices, device);
- }
-}
-
-G_MODULE_EXPORT int
-test_devices_main (int argc, char **argv)
-{
- ClutterActor *stage;
- TestDevicesApp *app;
- ClutterSeat *seat;
- GList *stage_devices, *l;
-
- clutter_test_init (&argc, &argv);
-
- app = g_new0 (TestDevicesApp, 1);
- app->devices = g_hash_table_new (g_direct_hash, g_direct_equal) ;
-
- stage = clutter_test_get_stage ();
- clutter_actor_set_background_color (stage, CLUTTER_COLOR_LightSkyBlue);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Devices");
- g_signal_connect (stage,
- "destroy", G_CALLBACK (clutter_test_quit),
- NULL);
- g_signal_connect (stage,
- "motion-event", G_CALLBACK (stage_motion_event_cb),
- app);
- g_signal_connect (stage,
- "button-press-event", G_CALLBACK (stage_button_event_cb),
- app);
- app->stage = stage;
-
- clutter_actor_show (stage);
-
- 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 (seat,
- "device-removed", G_CALLBACK (seat_device_removed_cb),
- app);
-
- stage_devices = clutter_seat_list_devices (seat);
-
- if (stage_devices == NULL)
- g_error ("No input devices found.");
-
- for (l = stage_devices; l != NULL; l = l->next)
- {
- ClutterInputDevice *device = l->data;
- ClutterInputDeviceType device_type;
- ClutterActor *hand = NULL;
-
- g_print ("got a %s device '%s'\n",
- device_type_name (device),
- clutter_input_device_get_device_name (device));
-
- device_type = clutter_input_device_get_device_type (device);
- if (device_type == CLUTTER_POINTER_DEVICE ||
- device_type == CLUTTER_PEN_DEVICE ||
- device_type == CLUTTER_POINTER_DEVICE)
- {
- g_print ("*** enabling device '%s' ***\n",
- clutter_input_device_get_device_name (device));
-
- 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_test_main ();
-
- return EXIT_SUCCESS;
-}
diff --git a/src/tests/clutter/interactive/test-easing.c b/src/tests/clutter/interactive/test-easing.c
deleted file mode 100644
index 9af10bee7..000000000
--- a/src/tests/clutter/interactive/test-easing.c
+++ /dev/null
@@ -1,252 +0,0 @@
-#include <stdlib.h>
-#include <gmodule.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-/* 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 },
-};
-
-#define HELP_TEXT "Easing mode: %s (%d of %d)\n" \
- "Left click to tween\n" \
- "Right click to change the easing mode"
-
-static const gint n_easing_modes = G_N_ELEMENTS (easing_modes);
-static gint current_mode = 0;
-
-#define DURATION 1
-
-static ClutterActor *main_stage = NULL;
-static ClutterActor *easing_mode_label = 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
- */
-static void
-recenter_bouncer (ClutterActor *rectangle)
-{
- gfloat base_x, base_y;
- gint cur_mode;
-
-
- cur_mode = easing_modes[current_mode].mode;
- base_x = clutter_actor_get_width (main_stage) / 2;
- base_y = clutter_actor_get_height (main_stage) / 2;
-
- clutter_actor_set_easing_duration (rectangle, 250);
- clutter_actor_set_easing_mode (rectangle, cur_mode);
- clutter_actor_set_position (rectangle, base_x, base_y);
-
- g_signal_connect_after (rectangle, "transition-completed",
- G_CALLBACK (clutter_actor_restore_easing_state),
- 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_text (CLUTTER_TEXT (easing_mode_label), text);
- g_free (text);
- }
- else if (event->button == CLUTTER_BUTTON_PRIMARY)
- {
- ClutterAnimationMode cur_mode;
-
- cur_mode = easing_modes[current_mode].mode;
-
- clutter_actor_save_easing_state (rectangle);
- clutter_actor_set_easing_duration (rectangle, DURATION * 1000);
- clutter_actor_set_easing_mode (rectangle, cur_mode);
- clutter_actor_set_position (rectangle, event->x, event->y);
-
- /* if we were asked to, recenter the bouncer at the end of the
- * animation. we keep track of the animation to avoid connecting
- * the signal handler to the same Animation twice.
- */
- g_signal_connect_after (rectangle, "transition-completed",
- G_CALLBACK (recenter_bouncer),
- rectangle);
- }
-
- return TRUE;
-}
-
-static gboolean
-draw_bouncer (ClutterCanvas *canvas,
- cairo_t *cr,
- int width,
- int height)
-{
- const ClutterColor *bouncer_color;
- cairo_pattern_t *pattern;
- float radius;
-
- radius = MAX (width, height);
-
- 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);
-
- 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)
-{
- ClutterContent *canvas;
- ClutterActor *retval;
-
- 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_translation (retval, -width / 2.f, -height / 2.f, 0.f);
- clutter_actor_set_reactive (retval, TRUE);
-
- clutter_content_invalidate (canvas);
-
- return retval;
-}
-
-G_MODULE_EXPORT int
-test_easing_main (int argc, char *argv[])
-{
- ClutterActor *stage, *rect, *label;
- gchar *text;
- gfloat stage_width, stage_height;
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- 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_test_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_container_add_actor (CLUTTER_CONTAINER (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_container_add_actor (CLUTTER_CONTAINER (stage), label);
- clutter_text_set_text (CLUTTER_TEXT (label), text);
- 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;
-
- g_free (text);
-
- g_signal_connect (stage,
- "button-press-event", G_CALLBACK (on_button_press),
- rect);
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return EXIT_SUCCESS;
-}
-
-G_MODULE_EXPORT const char *
-test_easing_describe (void)
-{
- return "Visualize all easing modes provided by Clutter";
-}
diff --git a/src/tests/clutter/interactive/test-events.c b/src/tests/clutter/interactive/test-events.c
deleted file mode 100644
index e8408b5e2..000000000
--- a/src/tests/clutter/interactive/test-events.c
+++ /dev/null
@@ -1,477 +0,0 @@
-#include <gmodule.h>
-#include <clutter/clutter.h>
-#include <string.h>
-
-#include "tests/clutter-test-utils.h"
-
-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)
-{
- switch (event->type)
- {
- case CLUTTER_BUTTON_PRESS:
- return "BUTTON PRESS";
-
- case CLUTTER_BUTTON_RELEASE:
- return "BUTTON_RELEASE";
-
- case CLUTTER_KEY_PRESS:
- return "KEY PRESS";
-
- case CLUTTER_KEY_RELEASE:
- return "KEY RELEASE";
-
- case CLUTTER_ENTER:
- return "ENTER";
-
- case CLUTTER_LEAVE:
- return "LEAVE";
-
- case CLUTTER_MOTION:
- return "MOTION";
-
- case CLUTTER_TOUCH_BEGIN:
- return "TOUCH BEGIN";
-
- case CLUTTER_TOUCH_UPDATE:
- return "TOUCH UPDATE";
-
- case CLUTTER_TOUCH_END:
- return "TOUCH END";
-
- case CLUTTER_TOUCH_CANCEL:
- return "TOUCH CANCEL";
-
- default:
- return "EVENT";
- }
-}
-
-static gchar *
-get_event_state_string (const ClutterEvent *event)
-{
- const char *mods[18];
- int i = 0;
- ClutterModifierType state = clutter_event_get_state (event);
-
- if (state & CLUTTER_SHIFT_MASK)
- mods[i++] = "shift";
- if (state & CLUTTER_LOCK_MASK)
- mods[i++] = "lock";
- if (state & CLUTTER_CONTROL_MASK)
- mods[i++] = "ctrl";
- if (state & CLUTTER_MOD1_MASK)
- mods[i++] = "mod1";
- if (state & CLUTTER_MOD2_MASK)
- mods[i++] = "mod2";
- if (state & CLUTTER_MOD3_MASK)
- mods[i++] = "mod3";
- if (state & CLUTTER_MOD4_MASK)
- mods[i++] = "mod4";
- if (state & CLUTTER_MOD5_MASK)
- mods[i++] = "mod5";
- if (state & CLUTTER_BUTTON1_MASK)
- mods[i++] = "btn1";
- if (state & CLUTTER_BUTTON2_MASK)
- mods[i++] = "btn2";
- if (state & CLUTTER_BUTTON3_MASK)
- mods[i++] = "btn3";
- if (state & CLUTTER_BUTTON4_MASK)
- mods[i++] = "btn4";
- if (state & CLUTTER_BUTTON5_MASK)
- mods[i++] = "btn5";
- if (state & CLUTTER_SUPER_MASK)
- mods[i++] = "super";
- if (state & CLUTTER_HYPER_MASK)
- mods[i++] = "hyper";
- if (state & CLUTTER_META_MASK)
- mods[i++] = "meta";
- if (state & CLUTTER_RELEASE_MASK)
- mods[i++] = "release";
-
- if (i == 0)
- mods[i++] = "-";
-
- mods[i] = NULL;
- return g_strjoinv (",", (char **) mods);
-}
-
-static gboolean
-red_button_cb (ClutterActor *actor,
- ClutterEvent *event,
- gpointer data)
-{
- ClutterActor *stage;
-
- if (IsMotion)
- IsMotion = FALSE;
- else
- IsMotion = TRUE;
-
- stage = clutter_actor_get_stage (actor);
- clutter_stage_set_motion_events_enabled (CLUTTER_STAGE (stage),
- IsMotion);
-
- g_print ("*** Per actor motion events %s ***\n",
- IsMotion ? "enabled" : "disabled");
-
- return FALSE;
-}
-
-static gboolean
-capture_cb (ClutterActor *actor,
- ClutterEvent *event,
- gpointer data)
-{
- g_print ("* captured event '%s' for type '%s' *\n",
- get_event_type_name (event),
- G_OBJECT_TYPE_NAME (actor));
-
- return FALSE;
-}
-
-static void
-key_focus_in_cb (ClutterActor *actor,
- gpointer data)
-{
- ClutterActor *focus_box = CLUTTER_ACTOR (data);
-
- if (CLUTTER_IS_STAGE (actor))
- clutter_actor_hide (focus_box);
- else
- {
- clutter_actor_set_position (focus_box,
- clutter_actor_get_x (actor) - 5,
- clutter_actor_get_y (actor) - 5);
-
- clutter_actor_set_size (focus_box,
- clutter_actor_get_width (actor) + 10,
- clutter_actor_get_height (actor) + 10);
- clutter_actor_show (focus_box);
- }
-}
-
-static void
-fill_keybuf (char *keybuf, ClutterKeyEvent *event)
-{
- char utf8[6];
- int len;
-
- /* printable character, if any (ß, ∑) */
- len = g_unichar_to_utf8 (event->unicode_value, utf8);
- utf8[len] = '\0';
- sprintf (keybuf, "'%s' ", utf8);
-
- /* key combination (<Mod1>s, <Shift><Mod1>S, <Ctrl><Mod1>Delete) */
- len = g_unichar_to_utf8 (clutter_keysym_to_unicode (event->keyval), utf8);
- utf8[len] = '\0';
-
- if (event->modifier_state & CLUTTER_SHIFT_MASK)
- strcat (keybuf, "<Shift>");
-
- if (event->modifier_state & CLUTTER_LOCK_MASK)
- strcat (keybuf, "<Lock>");
-
- if (event->modifier_state & CLUTTER_CONTROL_MASK)
- strcat (keybuf, "<Control>");
-
- if (event->modifier_state & CLUTTER_MOD1_MASK)
- strcat (keybuf, "<Mod1>");
-
- if (event->modifier_state & CLUTTER_MOD2_MASK)
- strcat (keybuf, "<Mod2>");
-
- if (event->modifier_state & CLUTTER_MOD3_MASK)
- strcat (keybuf, "<Mod3>");
-
- if (event->modifier_state & CLUTTER_MOD4_MASK)
- strcat (keybuf, "<Mod4>");
-
- if (event->modifier_state & CLUTTER_MOD5_MASK)
- strcat (keybuf, "<Mod5>");
-
- strcat (keybuf, utf8);
-}
-
-static gboolean
-input_cb (ClutterActor *actor,
- ClutterEvent *event,
- gpointer data)
-{
- ClutterActor *stage = clutter_actor_get_stage (actor);
- ClutterActor *source_actor = clutter_event_get_source (event);
- graphene_point_t position;
- gchar *state;
- gchar keybuf[128];
- ClutterInputDevice *device, *source;
- const gchar *device_name, *source_name = NULL;
-
- device = clutter_event_get_device (event);
- device_name = clutter_input_device_get_device_name (device);
-
- source = clutter_event_get_source_device (event);
- if (source)
- source_name = clutter_input_device_get_device_name (source);
- else
- source_name = "None";
-
- state = get_event_state_string (event);
-
- switch (event->type)
- {
- case CLUTTER_KEY_PRESS:
- fill_keybuf (keybuf, &event->key);
- printf ("[%s] KEY PRESS %s",
- clutter_actor_get_name (source_actor),
- keybuf);
- break;
- case CLUTTER_KEY_RELEASE:
- fill_keybuf (keybuf, &event->key);
- printf ("[%s] KEY RELEASE %s",
- clutter_actor_get_name (source_actor),
- keybuf);
- break;
- case CLUTTER_MOTION:
- clutter_event_get_position (event, &position);
- g_print ("[%s] MOTION (coords:%.02f,%.02f device:%s/%s state:%s)",
- clutter_actor_get_name (source_actor), position.x, position.y,
- device_name, source_name, state);
- break;
- case CLUTTER_ENTER:
- g_print ("[%s] ENTER (from:%s device:%s/%s state:%s)",
- clutter_actor_get_name (source_actor),
- clutter_event_get_related (event) != NULL
- ? clutter_actor_get_name (clutter_event_get_related (event))
- : "<out of stage>",
- device_name, source_name, state);
- break;
- case CLUTTER_LEAVE:
- g_print ("[%s] LEAVE (to:%s device:%s/%s state:%s)",
- clutter_actor_get_name (source_actor),
- clutter_event_get_related (event) != NULL
- ? clutter_actor_get_name (clutter_event_get_related (event))
- : "<out of stage>",
- device_name, source_name, state);
- break;
- case CLUTTER_BUTTON_PRESS:
- clutter_event_get_position (event, &position);
- g_print ("[%s] BUTTON PRESS (button:%i, click count:%i coords:%.02f,%.02f device:%s/%s, state:%s)",
- clutter_actor_get_name (source_actor),
- clutter_event_get_button (event),
- clutter_event_get_click_count (event),
- position.x, position.y,
- device_name, source_name, state);
- break;
- case CLUTTER_BUTTON_RELEASE:
- clutter_event_get_position (event, &position);
- g_print ("[%s] BUTTON RELEASE (button:%i, click count:%i coords:%.02f,%.02f device:%s/%s state:%s)",
- clutter_actor_get_name (source_actor),
- clutter_event_get_button (event),
- clutter_event_get_click_count (event),
- position.x, position.y,
- device_name, source_name, state);
-
- if (source_actor == stage)
- clutter_stage_set_key_focus (CLUTTER_STAGE (stage), NULL);
- else if (source_actor == actor &&
- clutter_actor_get_parent (actor) == stage)
- clutter_stage_set_key_focus (CLUTTER_STAGE (stage), actor);
- break;
- case CLUTTER_TOUCH_BEGIN:
- clutter_event_get_position (event, &position);
- g_print ("[%s] TOUCH BEGIN (seq:%p coords:%.02f,%.02f device:%s/%s state:%s)",
- clutter_actor_get_name (source_actor),
- clutter_event_get_event_sequence (event),
- position.x, position.y,
- device_name, source_name, state);
- break;
- case CLUTTER_TOUCH_UPDATE:
- clutter_event_get_position (event, &position);
- g_print ("[%s] TOUCH UPDATE (seq:%p coords:%.02f,%.02f device:%s/%s state:%s)",
- clutter_actor_get_name (source_actor),
- clutter_event_get_event_sequence (event),
- position.x, position.y,
- device_name, source_name, state);
- break;
- case CLUTTER_TOUCH_END:
- clutter_event_get_position (event, &position);
- g_print ("[%s] TOUCH END (seq:%p coords:%.02f,%.02f device:%s/%s state:%s)",
- clutter_actor_get_name (source_actor),
- clutter_event_get_event_sequence (event),
- position.x, position.y,
- device_name, source_name, state);
- break;
- case CLUTTER_TOUCH_CANCEL:
- clutter_event_get_position (event, &position);
- g_print ("[%s] TOUCH CANCEL (seq:%p coords:%.02f,%.02f device:%s/%s state:%s)",
- clutter_actor_get_name (source_actor),
- clutter_event_get_event_sequence (event),
- position.x, position.y,
- device_name, source_name, state);
- break;
- case CLUTTER_SCROLL:
- {
- ClutterScrollDirection dir = clutter_event_get_scroll_direction (event);
-
- if (dir == CLUTTER_SCROLL_SMOOTH)
- {
- gdouble dx, dy;
- clutter_event_get_scroll_delta (event, &dx, &dy);
- g_print ("[%s] BUTTON SCROLL (direction:smooth %.02f,%.02f state:%s)",
- clutter_actor_get_name (source_actor), dx, dy, state);
- }
- else
- g_print ("[%s] BUTTON SCROLL (direction:%s state:%s)",
- clutter_actor_get_name (source_actor),
- dir == CLUTTER_SCROLL_UP ? "up" :
- dir == CLUTTER_SCROLL_DOWN ? "down" :
- dir == CLUTTER_SCROLL_LEFT ? "left" :
- dir == CLUTTER_SCROLL_RIGHT ? "right" : "?",
- state);
- }
- 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;
- }
-
- g_free (state);
-
- if (source_actor == actor)
- g_print (" *source*");
-
- g_print ("\n");
-
- return FALSE;
-}
-
-G_MODULE_EXPORT int
-test_events_main (int argc, char *argv[])
-{
- ClutterActor *stage, *actor, *focus_box, *group;
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Events");
- clutter_actor_set_name (stage, "Stage");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
- g_signal_connect (stage, "event", G_CALLBACK (input_cb), (char *) "stage");
-
- focus_box = clutter_actor_new ();
- clutter_actor_set_background_color (focus_box, CLUTTER_COLOR_Black);
- clutter_actor_set_name (focus_box, "Focus Box");
- clutter_container_add (CLUTTER_CONTAINER(stage), focus_box, NULL);
-
- actor = clutter_actor_new ();
- clutter_actor_set_background_color (actor, CLUTTER_COLOR_Red);
- clutter_actor_set_name (actor, "Red Box");
- 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 (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 */
- g_signal_connect (actor, "button-press-event",
- G_CALLBACK (red_button_cb), NULL);
-
- clutter_stage_set_key_focus (CLUTTER_STAGE (stage), actor);
-
- actor = clutter_actor_new ();
- clutter_actor_set_background_color (actor, CLUTTER_COLOR_Green);
- clutter_actor_set_name (actor, "Green Box");
- clutter_actor_set_size (actor, 100, 100);
- 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), (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);
-
- /* non reactive */
- actor = clutter_actor_new ();
- clutter_actor_set_background_color (actor, 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), (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),
- focus_box);
-
- /* non reactive group, with reactive child */
- actor = clutter_actor_new ();
- clutter_actor_set_background_color (actor, CLUTTER_COLOR_Yellow);
- clutter_actor_set_name (actor, "Yellow Box");
- clutter_actor_set_size (actor, 100, 100);
- clutter_actor_set_reactive (actor, TRUE);
-
- g_signal_connect (actor, "event", G_CALLBACK (input_cb), (char *) "yellow box");
-
- /* note group not reactive */
- group = clutter_actor_new ();
- clutter_container_add (CLUTTER_CONTAINER (group), actor, NULL);
- clutter_container_add (CLUTTER_CONTAINER (stage), group, NULL);
- clutter_actor_set_position (group, 100, 350);
-
- /* border actor */
- actor = clutter_actor_new ();
- clutter_actor_set_background_color (actor, CLUTTER_COLOR_Magenta);
- clutter_actor_set_name (actor, "Border Box");
- clutter_actor_set_size (actor, 100, 100);
- clutter_actor_set_position (actor,
- (clutter_actor_get_width (stage) - 100) / 2,
- clutter_actor_get_height (stage) - 100);
- clutter_actor_set_reactive (actor, TRUE);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
- g_signal_connect (actor, "event", G_CALLBACK (input_cb), NULL);
-
- clutter_actor_show (CLUTTER_ACTOR (stage));
-
- clutter_test_main ();
-
- return 0;
-}
-
-G_MODULE_EXPORT const char *
-test_events_describe (void)
-{
- return "Event handling and propagation.";
-}
diff --git a/src/tests/clutter/interactive/test-grab.c b/src/tests/clutter/interactive/test-grab.c
deleted file mode 100644
index 1de60985b..000000000
--- a/src/tests/clutter/interactive/test-grab.c
+++ /dev/null
@@ -1,283 +0,0 @@
-#include <gmodule.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-int
-test_grab_main (int argc, char *argv[]);
-
-const char *
-test_grab_describe (void);
-
-static gboolean
-debug_event_cb (ClutterActor *actor,
- ClutterEvent *event,
- gpointer data)
-{
- gchar keybuf[9], *source = (gchar*)data;
- int len = 0;
-
- switch (event->type)
- {
- case CLUTTER_KEY_PRESS:
- len = g_unichar_to_utf8 (clutter_keysym_to_unicode (event->key.keyval),
- keybuf);
- keybuf[len] = '\0';
- printf ("[%s] KEY PRESS '%s'", source, keybuf);
- break;
- case CLUTTER_KEY_RELEASE:
- len = g_unichar_to_utf8 (clutter_keysym_to_unicode (event->key.keyval),
- keybuf);
- keybuf[len] = '\0';
- printf ("[%s] KEY RELEASE '%s'", source, keybuf);
- break;
- case CLUTTER_MOTION:
- printf("[%s] MOTION", source);
- break;
- case CLUTTER_ENTER:
- printf("[%s] ENTER", source);
- break;
- case CLUTTER_LEAVE:
- printf("[%s] LEAVE", source);
- break;
- case CLUTTER_BUTTON_PRESS:
- printf("[%s] BUTTON PRESS (click count:%i)",
- source, event->button.click_count);
- break;
- case CLUTTER_BUTTON_RELEASE:
- printf("[%s] BUTTON RELEASE", source);
- break;
- case CLUTTER_SCROLL:
- printf("[%s] BUTTON SCROLL", 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;
- }
-
- if (clutter_event_get_source (event) == actor)
- printf(" *source*");
-
- printf("\n");
-
- return FALSE;
-}
-
-static gboolean
-grab_pointer_cb (ClutterActor *actor,
- ClutterEvent *event,
- gpointer data)
-{
- ClutterInputDevice *device = clutter_event_get_device (event);
-
- clutter_input_device_grab (device, actor);
- return FALSE;
-}
-
-static gboolean
-red_release_cb (ClutterActor *actor,
- ClutterEvent *event,
- gpointer data)
-{
- ClutterInputDevice *device = clutter_event_get_device (event);
-
- clutter_input_device_ungrab (device);
- return FALSE;
-}
-
-static gboolean
-blue_release_cb (ClutterActor *actor,
- ClutterEvent *event,
- gpointer data)
-{
- clutter_actor_destroy (actor);
- return FALSE;
-}
-
-static gboolean
-green_press_cb (ClutterActor *actor,
- ClutterEvent *event,
- gpointer data)
-{
- ClutterActor *stage;
- gboolean enabled;
-
- stage = clutter_actor_get_stage (actor);
- enabled = !clutter_stage_get_motion_events_enabled (CLUTTER_STAGE (stage));
-
- clutter_stage_set_motion_events_enabled (CLUTTER_STAGE (stage), enabled);
-
- g_print ("per actor motion events are now %s\n",
- enabled ? "enabled" : "disabled");
-
- return FALSE;
-}
-
-static gboolean
-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_input_device_get_grabbed_actor (device) != NULL)
- clutter_input_device_ungrab (device);
- else
- clutter_input_device_grab (device, actor);
- }
-
- return FALSE;
-}
-
-static gboolean
-cyan_press_cb (ClutterActor *actor,
- ClutterEvent *event,
- gpointer data)
-{
- 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_input_device_grab (device, actor);
-
- return FALSE;
-}
-
-
-
-G_MODULE_EXPORT int
-test_grab_main (int argc, char *argv[])
-{
- ClutterActor *stage, *actor;
- ClutterColor rcol = { 0xff, 0, 0, 0xff},
- bcol = { 0, 0, 0xff, 0xff },
- gcol = { 0, 0xff, 0, 0xff },
- ccol = { 0, 0xff, 0xff, 0xff },
- ycol = { 0xff, 0xff, 0, 0xff };
-
- clutter_test_init (&argc, &argv);
-
- g_print ("Red box: acquire grab on press, releases it on next button release\n");
- g_print ("Blue box: acquire grab on press, destroys the blue box actor on release\n");
- g_print ("Yellow box: acquire grab on press, releases grab on next press on yellow box\n");
- g_print ("Green box: toggle per actor motion events.\n\n");
- g_print ("Cyan box: toggle grab (from cyan box) for keyboard events.\n\n");
-
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Grabs");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
- g_signal_connect (stage, "event",
- G_CALLBACK (debug_event_cb), (char *) "stage");
-
- actor = clutter_actor_new ();
- clutter_actor_set_background_color (actor, &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), (char *) "red box");
- g_signal_connect (actor, "button-press-event",
- G_CALLBACK (grab_pointer_cb), NULL);
- g_signal_connect (actor, "button-release-event",
- G_CALLBACK (red_release_cb), NULL);
-
- actor = clutter_actor_new ();
- clutter_actor_set_background_color (actor, &ycol);
- clutter_actor_set_size (actor, 100, 100);
- 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), (char *) "yellow box");
- g_signal_connect (actor, "button-press-event",
- G_CALLBACK (toggle_grab_pointer_cb), NULL);
-
- actor = clutter_actor_new ();
- clutter_actor_set_background_color (actor, &bcol);
- clutter_actor_set_size (actor, 100, 100);
- clutter_actor_set_position (actor, 300, 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), (char *) "blue box");
- g_signal_connect (actor, "button-press-event",
- G_CALLBACK (grab_pointer_cb), NULL);
- g_signal_connect (actor, "button-release-event",
- G_CALLBACK (blue_release_cb), NULL);
-
- actor = clutter_actor_new ();
- clutter_actor_set_background_color (actor, &gcol);
- clutter_actor_set_size (actor, 100, 100);
- clutter_actor_set_position (actor, 300, 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), (char *) "green box");
- g_signal_connect (actor, "button-press-event",
- G_CALLBACK (green_press_cb), NULL);
-
-
- actor = clutter_actor_new ();
- clutter_actor_set_background_color (actor, &ccol);
- clutter_actor_set_size (actor, 100, 100);
- clutter_actor_set_position (actor, 500, 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), (char *) "cyan box");
- g_signal_connect (actor, "button-press-event",
- G_CALLBACK (cyan_press_cb), NULL);
-
- clutter_actor_show (CLUTTER_ACTOR (stage));
-
- clutter_test_main ();
-
- return 0;
-}
-
-G_MODULE_EXPORT const char *
-test_grab_describe (void)
-{
- return "Examples of using actor grabs";
-}
diff --git a/src/tests/clutter/interactive/test-image.c b/src/tests/clutter/interactive/test-image.c
deleted file mode 100644
index 11c07e64b..000000000
--- a/src/tests/clutter/interactive/test-image.c
+++ /dev/null
@@ -1,261 +0,0 @@
-#include <stdlib.h>
-#include <gmodule.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-typedef struct _SolidContent {
- GObject parent_instance;
-
- double red;
- double green;
- double blue;
- double alpha;
-
- float padding;
-} SolidContent;
-
-typedef struct _SolidContentClass {
- GObjectClass parent_class;
-} SolidContentClass;
-
-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,
- ClutterPaintContext *paint_context)
-{
- SolidContent *self = (SolidContent *) content;
- ClutterActorBox box, content_box;
- ClutterColor color;
- PangoLayout *layout;
- PangoRectangle logical;
- ClutterPaintNode *node;
-
-#if 0
- g_debug ("Painting content [%p] "
- "{ r:%.2f, g:%.2f, b:%.2f, a:%.2f } "
- "for actor [%p] (context: [%p])",
- content,
- self->red,
- self->green,
- self->blue,
- self->alpha,
- actor, context);
-#endif
-
- clutter_actor_get_content_box (actor, &content_box);
-
- box = content_box;
- box.x1 += self->padding;
- box.y1 += self->padding;
- box.x2 -= self->padding;
- box.y2 -= self->padding;
-
- color.alpha = self->alpha * 255;
-
- color.red = self->red * 255;
- color.green = self->green * 255;
- color.blue = self->blue * 255;
-
- node = clutter_color_node_new (&color);
- clutter_paint_node_add_rectangle (node, &box);
- clutter_paint_node_add_child (root, node);
- clutter_paint_node_unref (node);
-
- color.red = (1.0 - self->red) * 255;
- color.green = (1.0 - self->green) * 255;
- color.blue = (1.0 - self->blue) * 255;
-
- layout = clutter_actor_create_pango_layout (actor, "A");
- pango_layout_get_pixel_extents (layout, NULL, &logical);
-
- node = clutter_text_node_new (layout, &color);
-
- /* top-left */
- box.x1 = clutter_actor_box_get_x (&content_box);
- box.y1 = clutter_actor_box_get_y (&content_box);
- box.x2 = box.x1 + logical.width;
- box.y2 = box.y1 + logical.height;
- clutter_paint_node_add_rectangle (node, &box);
-
- /* top-right */
- box.x1 = clutter_actor_box_get_x (&content_box)
- + clutter_actor_box_get_width (&content_box)
- - logical.width;
- box.y1 = clutter_actor_box_get_y (&content_box);
- box.x2 = box.x1 + logical.width;
- box.y2 = box.y1 + logical.height;
- clutter_paint_node_add_rectangle (node, &box);
-
- /* bottom-right */
- box.x1 = clutter_actor_box_get_x (&content_box)
- + clutter_actor_box_get_width (&content_box)
- - logical.width;
- box.y1 = clutter_actor_box_get_y (&content_box)
- + clutter_actor_box_get_height (&content_box)
- - logical.height;
- box.x2 = box.x1 + logical.width;
- box.y2 = box.y1 + logical.height;
- clutter_paint_node_add_rectangle (node, &box);
-
- /* bottom-left */
- box.x1 = clutter_actor_box_get_x (&content_box);
- box.y1 = clutter_actor_box_get_y (&content_box)
- + clutter_actor_box_get_height (&content_box)
- - logical.height;
- box.x2 = box.x1 + logical.width;
- box.y2 = box.y1 + logical.height;
- clutter_paint_node_add_rectangle (node, &box);
-
- /* center */
- box.x1 = clutter_actor_box_get_x (&content_box)
- + (clutter_actor_box_get_width (&content_box) - logical.width) / 2.0;
- box.y1 = clutter_actor_box_get_y (&content_box)
- + (clutter_actor_box_get_height (&content_box) - logical.height) / 2.0;
- box.x2 = box.x1 + logical.width;
- box.y2 = box.y1 + logical.height;
- clutter_paint_node_add_rectangle (node, &box);
-
- clutter_paint_node_add_child (root, node);
- clutter_paint_node_unref (node);
-
- g_object_unref (layout);
-}
-
-static void
-clutter_content_iface_init (ClutterContentInterface *iface)
-{
- iface->paint_content = solid_content_paint_content;
-}
-
-static void
-solid_content_class_init (SolidContentClass *klass)
-{
-}
-
-static void
-solid_content_init (SolidContent *self)
-{
-}
-
-static ClutterContent *
-solid_content_new (double red,
- double green,
- double blue,
- double alpha,
- float padding)
-{
- SolidContent *self = g_object_new (solid_content_get_type (), NULL);
-
- self->red = red;
- self->green = green;
- self->blue = blue;
- self->alpha = alpha;
- self->padding = padding;
-
- return (ClutterContent *) self;
-}
-
-G_MODULE_EXPORT const char *
-test_image_describe (void)
-{
- return "A test with image content.";
-}
-
-G_MODULE_EXPORT int
-test_image_main (int argc, char *argv[])
-{
- ClutterActor *stage, *grid;
- ClutterContent *color, *image;
- GdkPixbuf *pixbuf;
- int i, n_rects;
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_actor_set_name (stage, "Stage");
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Content");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
- clutter_actor_show (stage);
-
- grid = clutter_actor_new ();
- clutter_actor_set_name (grid, "Grid");
- clutter_actor_set_margin_top (grid, 12);
- clutter_actor_set_margin_right (grid, 12);
- clutter_actor_set_margin_bottom (grid, 12);
- clutter_actor_set_margin_left (grid, 12);
- clutter_actor_set_layout_manager (grid, clutter_flow_layout_new (CLUTTER_FLOW_HORIZONTAL));
- clutter_actor_add_constraint (grid, clutter_bind_constraint_new (stage, CLUTTER_BIND_SIZE, 0.0));
- clutter_actor_add_child (stage, grid);
-
- color = solid_content_new (g_random_double_range (0.0, 1.0),
- g_random_double_range (0.0, 1.0),
- g_random_double_range (0.0, 1.0),
- 1.0,
- 2.0);
-
- pixbuf = gdk_pixbuf_new_from_file (TESTS_DATADIR G_DIR_SEPARATOR_S "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);
-
- n_rects = g_random_int_range (12, 24);
- for (i = 0; i < n_rects; i++)
- {
- ClutterActor *box = clutter_actor_new ();
- ClutterColor bg_color = {
- g_random_int_range (0, 255),
- g_random_int_range (0, 255),
- g_random_int_range (0, 255),
- 255
- };
- char *name, *str;
-
- str = clutter_color_to_string (&bg_color);
- name = g_strconcat ("Box <", color, ">", NULL);
- clutter_actor_set_name (box, name);
-
- g_free (name);
- g_free (str);
-
- if ((i % 2) == 0)
- clutter_actor_set_content (box, color);
- else
- clutter_actor_set_content (box, image);
-
- clutter_actor_set_size (box, 64, 64);
-
- clutter_actor_add_child (grid, box);
- }
-
- clutter_test_main ();
-
- g_object_unref (color);
- g_object_unref (image);
-
- return EXIT_SUCCESS;
-}
diff --git a/src/tests/clutter/interactive/test-keyframe-transition.c b/src/tests/clutter/interactive/test-keyframe-transition.c
deleted file mode 100644
index 3deabc2f7..000000000
--- a/src/tests/clutter/interactive/test-keyframe-transition.c
+++ /dev/null
@@ -1,115 +0,0 @@
-#include <stdlib.h>
-#include <gmodule.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-static const ClutterColor colors[] = {
- { 255, 0, 0, 255 },
- { 0, 255, 0, 255 },
- { 0, 0, 255, 255 },
-};
-
-#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,
- gboolean is_finished)
-{
- g_print ("%s: transition stopped: %s (finished: %s)\n",
- clutter_actor_get_name (actor),
- transition_name,
- is_finished ? "yes" : "no");
-}
-
-G_MODULE_EXPORT const char *
-test_keyframe_transition_describe (void)
-{
- return "Demonstrate the keyframe transition.";
-}
-
-G_MODULE_EXPORT int
-test_keyframe_transition_main (int argc, char *argv[])
-{
- ClutterActor *stage;
- int i;
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Keyframe Transitions");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- for (i = 0; i < 3; i++)
- {
- ClutterTransition *transition, *group;
- ClutterActor *rect;
- float cur_x, cur_y;
- float new_x, new_y;
- gchar *name;
-
- cur_x = PADDING;
- cur_y = PADDING + ((SIZE + PADDING) * i);
-
- new_x = clutter_actor_get_width (stage) - PADDING - SIZE;
- new_y = g_random_double_range (PADDING, clutter_actor_get_height (stage) - PADDING - SIZE);
-
- name = g_strdup_printf ("rect%02d", i);
-
- rect = clutter_actor_new ();
-
- clutter_actor_set_name (rect, name);
- clutter_actor_set_background_color (rect, &colors[i]);
- clutter_actor_set_size (rect, SIZE, SIZE);
- clutter_actor_set_position (rect, PADDING, cur_y);
- clutter_actor_add_child (stage, rect);
-
- group = clutter_transition_group_new ();
- clutter_timeline_set_duration (CLUTTER_TIMELINE (group), 2000);
- clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (group), 1);
- clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (group), TRUE);
-
- transition = clutter_keyframe_transition_new ("x");
- clutter_transition_set_from (transition, G_TYPE_FLOAT, cur_x);
- clutter_transition_set_to (transition, G_TYPE_FLOAT, new_x);
-
- clutter_keyframe_transition_set (CLUTTER_KEYFRAME_TRANSITION (transition),
- G_TYPE_FLOAT, 1,
- 0.5, new_x / 2.0f, CLUTTER_EASE_OUT_EXPO);
- clutter_transition_group_add_transition (CLUTTER_TRANSITION_GROUP (group), transition);
- g_object_unref (transition);
-
- transition = clutter_keyframe_transition_new ("y");
- clutter_transition_set_from (transition, G_TYPE_FLOAT, cur_y);
- clutter_transition_set_to (transition, G_TYPE_FLOAT, cur_y);
-
- clutter_keyframe_transition_set (CLUTTER_KEYFRAME_TRANSITION (transition),
- G_TYPE_FLOAT, 1,
- 0.5, new_y, CLUTTER_EASE_OUT_EXPO);
- clutter_transition_group_add_transition (CLUTTER_TRANSITION_GROUP (group), transition);
- g_object_unref (transition);
-
- clutter_actor_add_transition (rect, "rectAnimation", group);
-
- g_signal_connect (rect, "transition-stopped",
- G_CALLBACK (on_transition_stopped),
- NULL);
- g_object_unref (group);
-
- g_free (name);
- }
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return EXIT_SUCCESS;
-}
diff --git a/src/tests/clutter/interactive/test-layout.c b/src/tests/clutter/interactive/test-layout.c
deleted file mode 100644
index ce8202cfd..000000000
--- a/src/tests/clutter/interactive/test-layout.c
+++ /dev/null
@@ -1,684 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <gmodule.h>
-#include <cogl/cogl.h>
-
-#include <clutter/clutter.h>
-#include "test-utils.h"
-#include "tests/clutter-test-utils.h"
-
-/* layout actor, by Lucas Rocha */
-
-#define MY_TYPE_THING (my_thing_get_type ())
-#define MY_THING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MY_TYPE_THING, MyThing))
-#define MY_IS_THING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MY_TYPE_THING))
-#define MY_THING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MY_TYPE_THING, MyThingClass))
-#define MY_IS_THING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MY_TYPE_THING))
-#define MY_THING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MY_TYPE_THING, MyThingClass))
-
-typedef struct _MyThing MyThing;
-typedef struct _MyThingPrivate MyThingPrivate;
-typedef struct _MyThingClass MyThingClass;
-
-struct _MyThing
-{
- ClutterActor parent_instance;
-
- MyThingPrivate *priv;
-};
-
-struct _MyThingClass
-{
- ClutterActorClass parent_class;
-};
-
-enum
-{
- PROP_0,
-
- PROP_SPACING,
- PROP_PADDING,
- PROP_USE_TRANSFORMED_BOX
-};
-
-struct _MyThingPrivate
-{
- gfloat spacing;
- gfloat padding;
-
- 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,
- const GValue *value,
- GParamSpec *pspec)
-{
- MyThingPrivate *priv = MY_THING (gobject)->priv;
- gboolean needs_relayout = TRUE;
-
- switch (prop_id)
- {
- case PROP_SPACING:
- priv->spacing = g_value_get_float (value);
- break;
-
- case PROP_PADDING:
- priv->padding = g_value_get_float (value);
- break;
-
- case PROP_USE_TRANSFORMED_BOX:
- priv->use_transformed_box = g_value_get_boolean (value);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
- needs_relayout = FALSE;
- break;
- }
-
- /* setting spacing or padding queues a relayout
- because they are supposed to change the internal
- allocation of children */
- if (needs_relayout)
- clutter_actor_queue_relayout (CLUTTER_ACTOR (gobject));
-}
-
-static void
-my_thing_get_property (GObject *gobject,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MyThingPrivate *priv = MY_THING (gobject)->priv;
-
- switch (prop_id)
- {
- case PROP_SPACING:
- g_value_set_float (value, priv->spacing);
- break;
-
- case PROP_PADDING:
- g_value_set_float (value, priv->padding);
- break;
-
- case PROP_USE_TRANSFORMED_BOX:
- g_value_set_boolean (value, priv->use_transformed_box);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
- break;
- }
-}
-
-static void
-my_thing_get_preferred_width (ClutterActor *self,
- gfloat for_height,
- gfloat *min_width_p,
- gfloat *natural_width_p)
-{
- ClutterActorIter iter;
- ClutterActor *child;
- gfloat min_left, min_right;
- gfloat natural_left, natural_right;
-
- min_left = 0;
- min_right = 0;
- natural_left = 0;
- natural_right = 0;
-
- clutter_actor_iter_init (&iter, self);
- while (clutter_actor_iter_next (&iter, &child))
- {
- gfloat child_x, child_min, child_natural;
-
- child_x = clutter_actor_get_x (child);
-
- clutter_actor_get_preferred_size (child,
- &child_min, NULL,
- &child_natural, NULL);
-
- if (child == clutter_actor_get_first_child (self))
- {
- /* First child */
- min_left = child_x;
- natural_left = child_x;
- min_right = min_left + child_min;
- natural_right = natural_left + child_natural;
- }
- else
- {
- /* Union of extents with previous children */
- if (child_x < min_left)
- min_left = child_x;
-
- if (child_x < natural_left)
- natural_left = child_x;
-
- if (child_x + child_min > min_right)
- min_right = child_x + child_min;
-
- if (child_x + child_natural > natural_right)
- natural_right = child_x + child_natural;
- }
- }
-
- if (min_left < 0)
- min_left = 0;
-
- if (natural_left < 0)
- natural_left = 0;
-
- if (min_right < 0)
- min_right = 0;
-
- if (natural_right < 0)
- natural_right = 0;
-
- g_assert (min_right >= min_left);
- g_assert (natural_right >= natural_left);
-
- if (min_width_p)
- *min_width_p = min_right - min_left;
-
- if (natural_width_p)
- *natural_width_p = natural_right - min_left;
-}
-
-static void
-my_thing_get_preferred_height (ClutterActor *self,
- gfloat for_width,
- gfloat *min_height_p,
- gfloat *natural_height_p)
-{
- ClutterActorIter iter;
- ClutterActor *child;
- gfloat min_top, min_bottom;
- gfloat natural_top, natural_bottom;
-
- min_top = 0;
- min_bottom = 0;
- natural_top = 0;
- natural_bottom = 0;
-
- clutter_actor_iter_init (&iter, self);
- while (clutter_actor_iter_next (&iter, &child))
- {
- gfloat child_y, child_min, child_natural;
-
- child_y = clutter_actor_get_y (child);
-
- clutter_actor_get_preferred_size (child,
- NULL, &child_min,
- NULL, &child_natural);
-
- if (child == clutter_actor_get_first_child (self))
- {
- /* First child */
- min_top = child_y;
- natural_top = child_y;
- min_bottom = min_top + child_min;
- natural_bottom = natural_top + child_natural;
- }
- else
- {
- /* Union of extents with previous children */
- if (child_y < min_top)
- min_top = child_y;
-
- if (child_y < natural_top)
- natural_top = child_y;
-
- if (child_y + child_min > min_bottom)
- min_bottom = child_y + child_min;
-
- if (child_y + child_natural > natural_bottom)
- natural_bottom = child_y + child_natural;
- }
- }
-
- if (min_top < 0)
- min_top = 0;
-
- if (natural_top < 0)
- natural_top = 0;
-
- if (min_bottom < 0)
- min_bottom = 0;
-
- if (natural_bottom < 0)
- natural_bottom = 0;
-
- g_assert (min_bottom >= min_top);
- g_assert (natural_bottom >= natural_top);
-
- if (min_height_p)
- *min_height_p = min_bottom - min_top;
-
- if (natural_height_p)
- *natural_height_p = natural_bottom - min_top;
-}
-
-static void
-my_thing_allocate (ClutterActor *self,
- const ClutterActorBox *box)
-{
- MyThingPrivate *priv;
- gfloat current_x, current_y, max_row_height;
- ClutterActorIter iter;
- ClutterActor *child;
-
- clutter_actor_set_allocation (self, box);
-
- priv = MY_THING (self)->priv;
-
- current_x = priv->padding;
- current_y = priv->padding;
- max_row_height = 0;
-
- /* The allocation logic here is to horizontally place children
- * side-by-side and reflow into a new row when we run out of
- * space
- */
- clutter_actor_iter_init (&iter, self);
- while (clutter_actor_iter_next (&iter, &child))
- {
- gfloat natural_width, natural_height;
- ClutterActorBox child_box;
-
- clutter_actor_get_preferred_size (child,
- NULL, NULL,
- &natural_width,
- &natural_height);
-
- /* if it fits in the current row, keep it there; otherwise
- * reflow into another row
- */
- if (current_x + natural_width > box->x2 - box->x1 - priv->padding)
- {
- current_x = priv->padding;
- current_y += max_row_height + priv->spacing;
- max_row_height = 0;
- }
-
- child_box.x1 = current_x;
- child_box.y1 = current_y;
- child_box.x2 = child_box.x1 + natural_width;
- child_box.y2 = child_box.y1 + natural_height;
-
- clutter_actor_allocate (child, &child_box);
-
- /* if we take into account the transformation of the children
- * then we first check if it's transformed; then we get the
- * onscreen coordinates of the two points of the bounding box
- * of the actor (origin(x, y) and (origin + size)(x,y)) and
- * we update the coordinates and area given to the next child
- */
- if (priv->use_transformed_box)
- {
- if (clutter_actor_is_scaled (child) ||
- clutter_actor_is_rotated (child))
- {
- graphene_point3d_t v1 = { 0, }, v2 = { 0, };
- ClutterActorBox transformed_box = { 0, };
-
- v1.x = box->x1;
- v1.y = box->y1;
-
- clutter_actor_apply_transform_to_point (child, &v1, &v2);
- transformed_box.x1 = v2.x;
- transformed_box.y1 = v2.y;
-
- /* size */
- v1.x = natural_width;
- v1.y = natural_height;
- clutter_actor_apply_transform_to_point (child, &v1, &v2);
- transformed_box.x2 = v2.x;
- transformed_box.y2 = v2.y;
-
- natural_width = transformed_box.x2 - transformed_box.x1;
- natural_height = transformed_box.y2 - transformed_box.y1;
- }
- }
-
- /* Record the maximum child height on current row to know
- * what's the increment that should be used for the next
- * row
- */
- if (natural_height > max_row_height)
- max_row_height = natural_height;
-
- current_x += natural_width + priv->spacing;
- }
-}
-
-#define MIN_SIZE 24
-#define MAX_SIZE 64
-
-static void
-my_thing_class_init (MyThingClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
-
- gobject_class->set_property = my_thing_set_property;
- gobject_class->get_property = my_thing_get_property;
-
- actor_class->get_preferred_width = my_thing_get_preferred_width;
- actor_class->get_preferred_height = my_thing_get_preferred_height;
- actor_class->allocate = my_thing_allocate;
-
- g_object_class_install_property (gobject_class,
- PROP_SPACING,
- g_param_spec_float ("spacing",
- "Spacing",
- "Spacing of the thing",
- 0, G_MAXFLOAT,
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class,
- PROP_PADDING,
- g_param_spec_float ("padding",
- "Padding",
- "Padding around the thing",
- 0, G_MAXFLOAT,
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class,
- PROP_USE_TRANSFORMED_BOX,
- g_param_spec_boolean ("use-transformed-box",
- "Use Transformed Box",
- "Use transformed box when allocating",
- FALSE,
- G_PARAM_READWRITE));
-}
-
-static void
-my_thing_init (MyThing *thing)
-{
- thing->priv = MY_THING_GET_PRIVATE (thing);
-}
-
-static ClutterActor *
-my_thing_new (gfloat padding,
- gfloat spacing)
-{
- return g_object_new (MY_TYPE_THING,
- "padding", padding,
- "spacing", spacing,
- NULL);
-}
-
-/* test code */
-
-static ClutterActor *box = NULL;
-static ClutterActor *icon = NULL;
-static ClutterTimeline *main_timeline = NULL;
-
-static void
-toggle_property_value (ClutterActor *actor,
- const gchar *property_name)
-{
- gboolean value;
-
- g_object_get (actor, property_name, &value, NULL);
-
- value = !value;
-
- g_object_set (box, property_name, value, NULL);
-}
-
-static void
-increase_property_value (ClutterActor *actor,
- const char *property_name)
-{
- gfloat value;
-
- g_object_get (actor, property_name, &value, NULL);
-
- value = value + 10.0;
-
- g_object_set (box, property_name, value, NULL);
-}
-
-static void
-decrease_property_value (ClutterActor *actor,
- const char *property_name)
-{
- gfloat value;
-
- g_object_get (actor, property_name, &value, NULL);
-
- value = MAX (0, value - 10.0);
-
- g_object_set (box, property_name, value, NULL);
-}
-
-static ClutterActor *
-create_item (void)
-{
- ClutterActor *clone = clutter_clone_new (icon);
-
- gint32 size = g_random_int_range (MIN_SIZE, MAX_SIZE);
-
- clutter_actor_set_size (clone, size, size);
- clutter_actor_animate_with_timeline (clone, CLUTTER_EASE_OUT_CUBIC,
- main_timeline,
- "scale-x", 2.0,
- "scale-y", 2.0,
- "fixed::scale-gravity", CLUTTER_GRAVITY_CENTER,
- NULL);
-
- return clone;
-}
-
-static gboolean
-keypress_cb (ClutterActor *actor,
- ClutterEvent *event,
- gpointer data)
-{
- switch (clutter_event_get_key_symbol (event))
- {
- case CLUTTER_KEY_q:
- clutter_test_quit ();
- break;
-
- case CLUTTER_KEY_a:
- {
- if (icon != NULL)
- {
- ClutterActor *clone = create_item ();
-
- /* Add one item to container */
- clutter_actor_add_child (box, clone);
- }
- break;
- }
-
- case CLUTTER_KEY_d:
- {
- ClutterActor *last_child;
-
- last_child = clutter_actor_get_last_child (box);
- if (last_child != NULL)
- {
- /* Remove last item on container */
- clutter_actor_remove_child (box, last_child);
- }
- break;
- }
-
- case CLUTTER_KEY_w:
- {
- decrease_property_value (box, "padding");
- break;
- }
-
- case CLUTTER_KEY_e:
- {
- increase_property_value (box, "padding");
- break;
- }
-
- case CLUTTER_KEY_r:
- {
- decrease_property_value (box, "spacing");
- break;
- }
-
- case CLUTTER_KEY_s:
- {
- toggle_property_value (box, "use-transformed-box");
- break;
- }
-
- case CLUTTER_KEY_t:
- {
- increase_property_value (box, "spacing");
- break;
- }
-
- case CLUTTER_KEY_z:
- {
- if (clutter_timeline_is_playing (main_timeline))
- clutter_timeline_pause (main_timeline);
- else
- clutter_timeline_start (main_timeline);
-
- break;
- }
-
- default:
- break;
- }
-
- return FALSE;
-}
-
-static void
-relayout_on_frame (ClutterTimeline *timeline)
-{
- gboolean use_transformed_box;
-
- /* if we care about transformations updating the layout, we need to inform
- * the layout that a transformation is happening; this is either done by
- * attaching a notification on the transformation properties or by simply
- * queuing a relayout on each frame of the timeline used to drive the
- * behaviour. for simplicity's sake, we used the latter
- */
-
- g_object_get (G_OBJECT (box),
- "use-transformed-box", &use_transformed_box,
- NULL);
-
- if (use_transformed_box)
- clutter_actor_queue_relayout (box);
-}
-
-G_MODULE_EXPORT int
-test_layout_main (int argc, char *argv[])
-{
- ClutterActor *stage, *instructions;
- gint i, size;
- GError *error = NULL;
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_actor_set_size (stage, 800, 600);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Layout");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- main_timeline = clutter_timeline_new_for_actor (stage, 2000);
- clutter_timeline_set_repeat_count (main_timeline, -1);
- clutter_timeline_set_auto_reverse (main_timeline, TRUE);
- g_signal_connect (main_timeline, "new-frame",
- G_CALLBACK (relayout_on_frame),
- NULL);
-
-
- box = my_thing_new (10, 10);
-
- clutter_actor_set_position (box, 20, 20);
- clutter_actor_set_size (box, 350, -1);
-
- 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);
-
- size = g_random_int_range (MIN_SIZE, MAX_SIZE);
- clutter_actor_set_size (icon, size, size);
- clutter_actor_add_child (box, icon);
- clutter_actor_animate_with_timeline (icon, CLUTTER_EASE_OUT_CUBIC,
- main_timeline,
- "scale-x", 2.0,
- "scale-y", 2.0,
- "fixed::scale-gravity", CLUTTER_GRAVITY_CENTER,
- NULL);
-
- for (i = 1; i < 33; i++)
- {
- ClutterActor *clone = create_item ();
-
- clutter_actor_add_child (box, clone);
- }
-
- clutter_actor_add_child (stage, box);
-
- instructions = clutter_text_new_with_text (NULL,
- "<b>Instructions:</b>\n"
- "a - add a new item\n"
- "d - remove last item\n"
- "z - start/pause behaviour\n"
- "w - decrease padding\n"
- "e - increase padding\n"
- "r - decrease spacing\n"
- "t - increase spacing\n"
- "s - use transformed box\n"
- "q - quit");
-
- clutter_text_set_use_markup (CLUTTER_TEXT (instructions), TRUE);
- clutter_actor_set_position (instructions, 450, 10);
- clutter_actor_add_child (stage, instructions);
-
- g_signal_connect (stage, "key-release-event",
- G_CALLBACK (keypress_cb),
- NULL);
-
- clutter_timeline_stop (main_timeline);
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- g_object_unref (main_timeline);
-
- return EXIT_SUCCESS;
-}
-
-G_MODULE_EXPORT const char *
-test_layout_describe (void)
-{
- return "Container implementing a layout policy.";
-}
diff --git a/src/tests/clutter/interactive/test-main.c b/src/tests/clutter/interactive/test-main.c
deleted file mode 100644
index 29fc82a6a..000000000
--- a/src/tests/clutter/interactive/test-main.c
+++ /dev/null
@@ -1,227 +0,0 @@
-#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 "meta-test/meta-context-test.h"
-#include "tests/clutter-test-utils.h"
-
-#include "test-unit-names.h"
-
-#define MAX_DESC_SIZE 72
-
-static GModule *module = NULL;
-
-static gpointer
-get_symbol_with_suffix (const char *unit_name,
- const char *suffix)
-{
- char *main_symbol_name;
- gpointer func;
-
- main_symbol_name = g_strconcat (unit_name, "_", suffix, NULL);
- main_symbol_name = g_strdelimit (main_symbol_name, "-", '_');
-
- g_module_symbol (module, main_symbol_name, &func);
-
- g_free (main_symbol_name);
-
- return func;
-}
-
-static gpointer
-get_unit_name_main (const char *unit_name)
-{
- return get_symbol_with_suffix (unit_name, "main");
-}
-static char *
-get_unit_name_description (const char *unit_name,
- gssize max_len)
-{
- const char *description;
- gpointer func;
- char *retval;
-
- func = get_symbol_with_suffix (unit_name, "describe");
- if (func == NULL)
- description = "No description found";
- else
- {
- const char *(* unit_test_describe) (void);
-
- unit_test_describe = func;
-
- description = unit_test_describe ();
- }
-
- if (max_len > 0 && strlen (description) >= max_len)
- {
- GString *buf = g_string_sized_new (max_len);
- char *newline;
-
- newline = strchr (description, '\n');
- if (newline != NULL)
- {
- g_string_append_len (buf, description,
- MIN (newline - description - 1, max_len - 3));
- }
- else
- g_string_append_len (buf, description, max_len - 3);
-
- g_string_append (buf, "...");
-
- retval = g_string_free (buf, FALSE);
- }
- else
- retval = g_strdup (description);
-
- return retval;
-}
-
-static gboolean list_all = FALSE;
-static gboolean describe = FALSE;
-static char **unit_names = NULL;
-
-static GOptionEntry entries[] = {
- {
- "describe", 'd',
- 0,
- G_OPTION_ARG_NONE, &describe,
- "Describe the interactive unit test", NULL,
- },
- {
- "list-all", 'l',
- 0,
- G_OPTION_ARG_NONE, &list_all,
- "List all available units", NULL,
- },
- {
- G_OPTION_REMAINING, 0,
- 0,
- G_OPTION_ARG_STRING_ARRAY, &unit_names,
- "The interactive unit test", "UNIT_NAME"
- },
- { NULL }
-};
-
-int
-main (int argc, char **argv)
-{
- int ret, i, n_unit_names;
- GOptionContext *context;
-
- context = g_option_context_new (" - Interactive test suite");
- g_option_context_add_main_entries (context, entries, NULL);
- g_option_context_set_help_enabled (context, TRUE);
- g_option_context_set_ignore_unknown_options (context, TRUE);
- if (!g_option_context_parse (context, &argc, &argv, NULL))
- {
- g_print ("Usage: test-interactive <unit_test>\n");
- return EXIT_FAILURE;
- }
-
- g_option_context_free (context);
-
- module = g_module_open (NULL, 0);
- if (!module)
- g_error ("*** Failed to open self for symbol lookup");
-
- ret = EXIT_SUCCESS;
-
- if (list_all)
- {
- g_print ("* Available unit tests:\n");
-
- for (i = 0; i < G_N_ELEMENTS (test_unit_names); i++)
- {
- char *str;
- gsize len;
-
- len = MAX_DESC_SIZE - strlen (test_unit_names[i]);
- str = get_unit_name_description (test_unit_names[i], len - 2);
-
- g_print (" - %s:%*s%s\n",
- test_unit_names[i],
- (int) (len - strlen (str)), " ",
- str);
-
- g_free (str);
- }
-
- ret = EXIT_SUCCESS;
- goto out;
- }
-
- if (unit_names != NULL)
- n_unit_names = g_strv_length (unit_names);
- else
- {
- g_print ("Usage: test-interactive <unit_test>\n");
- ret = EXIT_FAILURE;
- goto out;
- }
-
- for (i = 0; i < n_unit_names; i++)
- {
- const char *unit_name = unit_names[i];
- char *unit_test = NULL;
- gboolean found;
- int j;
-
- unit_test = g_path_get_basename (unit_name);
-
- found = FALSE;
- for (j = 0; j < G_N_ELEMENTS (test_unit_names); j++)
- {
- if (strcmp (test_unit_names[j], unit_test) == 0)
- {
- found = TRUE;
- break;
- }
- }
-
- if (!found)
- g_error ("*** Unit '%s' does not exist", unit_test);
-
- if (describe)
- {
- char *str;
-
- str = get_unit_name_description (unit_test, -1);
-
- g_print ("* %s:\n%s\n\n", unit_test, str);
-
- g_free (str);
-
- ret = EXIT_SUCCESS;
- }
- else
- {
- int (* unit_test_main) (int argc, char **argv);
- gpointer func;
-
- func = get_unit_name_main (unit_test);
- if (func == NULL)
- g_error ("*** Unable to find the main entry point for '%s'", unit_test);
-
- unit_test_main = func;
-
- ret = unit_test_main (n_unit_names, unit_names);
-
- g_free (unit_test);
-
- break;
- }
-
- g_free (unit_test);
- }
-
-out:
- g_module_close (module);
-
- return ret;
-}
-
diff --git a/src/tests/clutter/interactive/test-path-constraint.c b/src/tests/clutter/interactive/test-path-constraint.c
deleted file mode 100644
index baa1ea790..000000000
--- a/src/tests/clutter/interactive/test-path-constraint.c
+++ /dev/null
@@ -1,138 +0,0 @@
-#include <stdlib.h>
-#include <gmodule.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-#define PATH_DESCRIPTION \
- "M 0, 0 " \
- "L 0, 300 " \
- "L 300, 300 " \
- "L 300, 0 " \
- "L 0, 0"
-
-static gboolean toggled = FALSE;
-
-int
-test_path_constraint_main (int argc,
- char *argv[]);
-
-static gboolean
-on_button_press (ClutterActor *actor,
- const ClutterEvent *event,
- gpointer dummy G_GNUC_UNUSED)
-{
- if (!toggled)
- clutter_actor_animate (actor, CLUTTER_EASE_OUT_CUBIC, 500,
- "@constraints.path.offset", 1.0,
- NULL);
- else
- clutter_actor_animate (actor, CLUTTER_EASE_OUT_CUBIC, 500,
- "@constraints.path.offset", 0.0,
- NULL);
-
- toggled = !toggled;
-
- return TRUE;
-}
-
-static gchar *
-node_to_string (const ClutterPathNode *node)
-{
- GString *buffer = g_string_sized_new (256);
- gsize len = 0, i;
-
- switch (node->type)
- {
- case CLUTTER_PATH_MOVE_TO:
- g_string_append (buffer, "move-to ");
- len = 1;
- break;
-
- case CLUTTER_PATH_LINE_TO:
- g_string_append (buffer, "line-to ");
- len = 1;
- break;
-
- case CLUTTER_PATH_CURVE_TO:
- g_string_append (buffer, "curve-to ");
- len = 3;
- break;
-
- case CLUTTER_PATH_CLOSE:
- g_string_append (buffer, "close");
- len = 0;
- break;
-
- default:
- break;
- }
-
- for (i = 0; i < len; i++)
- {
- if (i == 0)
- g_string_append (buffer, "[ ");
-
- g_string_append_printf (buffer, "[ %d, %d ]",
- node->points[i].x,
- node->points[i].y);
-
- if (i == len - 1)
- g_string_append (buffer, " ]");
- }
-
- return g_string_free (buffer, FALSE);
-}
-
-static void
-on_node_reached (ClutterPathConstraint *constraint,
- ClutterActor *actor,
- guint index_)
-{
- ClutterPath *path = clutter_path_constraint_get_path (constraint);
- ClutterPathNode node;
- gchar *str;
-
- clutter_path_get_node (path, index_, &node);
-
- str = node_to_string (&node);
- g_print ("Node %d reached: %s\n", index_, str);
- g_free (str);
-}
-
-G_MODULE_EXPORT int
-test_path_constraint_main (int argc,
- char *argv[])
-{
- ClutterActor *stage, *rect;
- ClutterPath *path;
- ClutterColor rect_color = { 0xcc, 0x00, 0x00, 0xff };
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Path Constraint");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- path = clutter_path_new ();
- clutter_path_set_description (path, PATH_DESCRIPTION);
-
- rect = clutter_actor_new ();
- clutter_actor_set_background_color (rect, &rect_color);
- clutter_actor_set_size (rect, 128, 128);
- clutter_actor_set_reactive (rect, TRUE);
- clutter_actor_add_constraint_with_name (rect, "path", clutter_path_constraint_new (path, 0.0));
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
-
- g_signal_connect (rect, "button-press-event", G_CALLBACK (on_button_press), NULL);
- g_signal_connect (clutter_actor_get_constraint (rect, "path"),
- "node-reached",
- G_CALLBACK (on_node_reached),
- NULL);
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return EXIT_SUCCESS;
-}
diff --git a/src/tests/clutter/interactive/test-rotate-zoom.c b/src/tests/clutter/interactive/test-rotate-zoom.c
deleted file mode 100644
index f21492158..000000000
--- a/src/tests/clutter/interactive/test-rotate-zoom.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2013 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 <stdlib.h>
-#include <math.h>
-#include <cairo.h>
-#include <glib.h>
-#include <clutter/clutter.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
-#include "tests/clutter-test-utils.h"
-
-#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)
-{
- GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (TESTS_DATADIR G_DIR_SEPARATOR_S "redhand.png", NULL);
- ClutterContent *image = clutter_image_new ();
- ClutterActor *actor = clutter_actor_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);
- clutter_actor_set_content (actor, image);
- clutter_actor_set_size (actor,
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf));
- clutter_actor_set_reactive (actor, TRUE);
-
- g_object_unref (pixbuf);
-
- return actor;
-}
-
-G_MODULE_EXPORT int
-test_rotate_zoom_main (int argc, char *argv[])
-{
- ClutterActor *stage, *actor;
- gfloat width, height;
-
- /* initialize Clutter */
- clutter_test_init (&argc, &argv);
-
- /* create a resizable stage */
- stage = clutter_test_get_stage ();
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Rotate and Zoom actions");
- clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
- clutter_actor_set_reactive (stage, FALSE);
- clutter_actor_show (stage);
-
- actor = create_hand ();
- clutter_actor_add_action (actor, clutter_rotate_action_new ());
- clutter_actor_add_action (actor, clutter_zoom_action_new ());
- clutter_actor_add_child (stage, actor);
-
- clutter_actor_get_size (actor, &width, &height);
- clutter_actor_set_position (actor,
- STAGE_WIDTH / 2 - width / 2,
- STAGE_HEIGHT / 2 - height / 2);
-
- clutter_test_main ();
-
- return EXIT_SUCCESS;
-}
-
-G_MODULE_EXPORT const char *
-test_rotate_zoom_describe (void)
-{
- return "Rotates and zooms an actor using touch events";
-}
diff --git a/src/tests/clutter/interactive/test-script.c b/src/tests/clutter/interactive/test-script.c
deleted file mode 100644
index e15ff32b4..000000000
--- a/src/tests/clutter/interactive/test-script.c
+++ /dev/null
@@ -1,154 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <math.h>
-
-#include <glib.h>
-#include <gmodule.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-static ClutterScript *script = NULL;
-static guint merge_id = 0;
-
-int
-test_script_main (int argc, char *argv[]);
-
-static const gchar *test_unmerge =
-"["
-" {"
-" \"id\" : \"main-stage\","
-" \"type\" : \"ClutterStage\","
-" \"children\" : [ \"blue-button\" ]"
-" },"
-" {"
-" \"id\" : \"blue-button\","
-" \"type\" : \"ClutterActor\","
-" \"background-color\" : \"#0000ffff\","
-" \"x\" : 350,"
-" \"y\" : 50,"
-" \"width\" : 100,"
-" \"height\" : 100,"
-" \"visible\" : true,"
-" \"reactive\" : true"
-" }"
-"]";
-
-static const gchar *test_behaviour =
-"["
-" {"
-" \"id\" : \"main-timeline\","
-" \"type\" : \"ClutterTimeline\","
-" \"duration\" : 5000,"
-" \"loop\" : true"
-" }"
-"]";
-
-static gboolean
-blue_button_press (ClutterActor *actor,
- ClutterButtonEvent *event,
- gpointer data)
-{
- g_print ("[*] Pressed '%s'\n", clutter_get_script_id (G_OBJECT (actor)));
- g_print ("[*] Unmerging objects with merge id: %d\n", merge_id);
-
- clutter_script_unmerge_objects (script, merge_id);
-
- return TRUE;
-}
-
-static gboolean
-red_button_press (ClutterActor *actor,
- ClutterButtonEvent *event,
- gpointer data)
-{
- GObject *timeline;
-
- g_print ("[*] Pressed '%s'\n", clutter_get_script_id (G_OBJECT (actor)));
-
- timeline = clutter_script_get_object (script, "main-timeline");
- g_assert (CLUTTER_IS_TIMELINE (timeline));
-
- if (!clutter_timeline_is_playing (CLUTTER_TIMELINE (timeline)))
- clutter_timeline_start (CLUTTER_TIMELINE (timeline));
- else
- clutter_timeline_pause (CLUTTER_TIMELINE (timeline));
-
- return TRUE;
-}
-
-G_MODULE_EXPORT int
-test_script_main (int argc, char *argv[])
-{
- GObject *stage, *blue_button, *red_button;
- GError *error = NULL;
- gchar *file;
- gint res;
-
- clutter_test_init (&argc, &argv);
-
- script = clutter_script_new ();
- g_assert (CLUTTER_IS_SCRIPT (script));
-
- clutter_script_load_from_data (script, test_behaviour, -1, &error);
- if (error)
- {
- g_print ("*** Error:\n"
- "*** %s\n", error->message);
- g_error_free (error);
- g_object_unref (script);
- return EXIT_FAILURE;
- }
-
- file = g_build_filename (TESTS_DATADIR, "test-script.json", NULL);
- clutter_script_load_from_file (script, file, &error);
- if (error)
- {
- g_print ("*** Error:\n"
- "*** %s\n", error->message);
- g_error_free (error);
- g_object_unref (script);
- g_free (file);
- return EXIT_FAILURE;
- }
-
- g_free (file);
-
- merge_id = clutter_script_load_from_data (script, test_unmerge, -1, &error);
- if (error)
- {
- g_print ("*** Error:\n"
- "*** %s\n", error->message);
- g_error_free (error);
- g_object_unref (script);
- return EXIT_FAILURE;
- }
-
- clutter_script_connect_signals (script, NULL);
-
- res = clutter_script_get_objects (script,
- "main-stage", &stage,
- "red-button", &red_button,
- "blue-button", &blue_button,
- NULL);
- g_assert (res == 3);
-
- clutter_actor_show (CLUTTER_ACTOR (stage));
-
- g_signal_connect (red_button,
- "button-press-event",
- G_CALLBACK (red_button_press),
- NULL);
-
- g_signal_connect (blue_button,
- "button-press-event",
- G_CALLBACK (blue_button_press),
- NULL);
-
- clutter_test_main ();
-
- g_object_unref (script);
-
- return EXIT_SUCCESS;
-}
diff --git a/src/tests/clutter/interactive/test-script.json b/src/tests/clutter/interactive/test-script.json
deleted file mode 100644
index b958315ae..000000000
--- a/src/tests/clutter/interactive/test-script.json
+++ /dev/null
@@ -1,54 +0,0 @@
-{
- "My Scene" : {
- "id" : "main-stage",
- "type" : "ClutterStage",
- "title" : { "translatable" : true, "string" : "ClutterScript test" },
- "color" : "white",
- "signals" : [
- { "name" : "key-press-event", "handler" : "clutter_test_quit" },
- { "name" : "destroy", "handler" : "clutter_test_quit" }
- ],
- "children" : [
- {
- "id" : "red-button",
- "type" : "ClutterActor",
- "background-color" : "#ff0000ff",
- "x" : 50, "y" : 50, "width" : 100, "height" : 100,
- "reactive" : true,
- "rotation" : [
- { "z-axis" : [ 45.0, [ 75, 75 ] ] }
- ]
- },
- {
- "id" : "green-button",
- "type" : "ClutterActor",
- "background-color" : "#00ff00ff",
- "border-width" : 5,
- "border-color" : "#00cc00ff",
- "position" : [ 200.0, 50.0 ],
- "size" : { "width" : 100.0, "height" : 100.0 },
- "depth" : -200.0,
- "reactive" : true,
- "signals" : [
- { "name" : "button-press-event", "handler" : "clutter_test_quit" }
- ]
- },
- {
- "id" : "label",
- "type" : "ClutterText",
- "x" : 50,
- "y" : 200,
- "text" : { "translatable" : true, "string" : "Clutter Script" },
- "font-name" : "Sans 24px",
- "color" : "black",
- "line-alignment" : "center",
- "line-wrap" : false,
- "ellipsize" : "none",
- "rotation" : [
- { "y-axis" : [ 60.0, [ 275, 100 ] ] },
- { "z-axis" : [ 45.0, [ 75, 75 ] ] }
- ]
- }
- ]
- }
-}
diff --git a/src/tests/clutter/interactive/test-shader-effects.c b/src/tests/clutter/interactive/test-shader-effects.c
deleted file mode 100644
index 992587c58..000000000
--- a/src/tests/clutter/interactive/test-shader-effects.c
+++ /dev/null
@@ -1,88 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-#include <gmodule.h>
-
-#include <clutter/clutter.h>
-#include "test-utils.h"
-#include "tests/clutter-test-utils.h"
-
-int
-test_shader_effects_main (int argc, char *argv[]);
-
-G_MODULE_EXPORT int
-test_shader_effects_main (int argc, char *argv[])
-{
- ClutterTimeline *timeline;
- ClutterActor *stage, *hand, *label, *rect;
- gchar *file;
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Rotations");
- clutter_actor_set_background_color (stage, CLUTTER_COLOR_Aluminium3);
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- /* Make a timeline */
- timeline = clutter_timeline_new_for_actor (stage, 7692);
- clutter_timeline_set_repeat_count (timeline, -1);
-
- /* Make a hand */
- file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL);
- hand = clutter_test_utils_create_texture_from_file (file, NULL);
- if (!hand)
- g_error("Unable to load '%s'", 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));
- clutter_actor_add_effect_with_name (hand, "blur", clutter_blur_effect_new ());
- clutter_actor_animate_with_timeline (hand, CLUTTER_LINEAR, timeline,
- "@effects.desaturate.factor", 1.0,
- "rotation-angle-z", 360.0,
- "fixed::anchor-x", 86.0,
- "fixed::anchor-y", 125.0,
- "opacity", 128,
- NULL);
-
- rect = clutter_actor_new ();
- clutter_actor_set_background_color (rect, CLUTTER_COLOR_DarkOrange);
- clutter_actor_add_effect_with_name (rect, "blur", clutter_blur_effect_new ());
- clutter_actor_set_position (rect, 415, 215);
- clutter_actor_set_size (rect, 150, 150);
- clutter_actor_animate_with_timeline (rect, CLUTTER_LINEAR, timeline,
- "rotation-angle-z", 360.0,
- "fixed::anchor-x", 75.0,
- "fixed::anchor-y", 75.0,
- NULL);
-
- label = clutter_text_new_with_text ("Mono 16",
- "The Wonder\n"
- "of the\n"
- "Spinning Hand");
- clutter_text_set_line_alignment (CLUTTER_TEXT (label), PANGO_ALIGN_CENTER);
- clutter_actor_set_position (label, 336, 275);
- clutter_actor_set_size (label, 500, 100);
- clutter_actor_animate_with_timeline (label, CLUTTER_LINEAR, timeline,
- "rotation-angle-z", 360.0,
- "fixed::anchor-x", 86.0,
- "fixed::anchor-y", 125.0,
- NULL);
-
- clutter_container_add (CLUTTER_CONTAINER (stage), rect, hand, label, NULL);
-
- /* start the timeline and thus the animations */
- clutter_timeline_start (timeline);
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- g_object_unref (timeline);
-
- return 0;
-}
diff --git a/src/tests/clutter/interactive/test-stage-sizing.c b/src/tests/clutter/interactive/test-stage-sizing.c
deleted file mode 100644
index 020b4be86..000000000
--- a/src/tests/clutter/interactive/test-stage-sizing.c
+++ /dev/null
@@ -1,89 +0,0 @@
-#include <stdlib.h>
-#include <gmodule.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-int
-test_stage_sizing_main (int argc, char *argv[]);
-
-const char *
-test_stage_sizing_describe (void);
-
-static gboolean
-shrink_clicked_cb (ClutterActor *stage)
-{
- gfloat width, height;
- clutter_actor_get_size (stage, &width, &height);
- clutter_actor_set_size (stage, MAX (0, width - 10.f), MAX (0, height - 10.f));
- return CLUTTER_EVENT_STOP;
-}
-
-static gboolean
-expand_clicked_cb (ClutterActor *stage)
-{
- gfloat width, height;
- clutter_actor_get_size (stage, &width, &height);
- clutter_actor_set_size (stage, width + 10.f, height + 10.f);
- return CLUTTER_EVENT_STOP;
-}
-
-G_MODULE_EXPORT int
-test_stage_sizing_main (int argc, char *argv[])
-{
- ClutterActor *stage, *rect, *label, *box;
- ClutterMargin margin = { 12.f, 12.f, 6.f, 6.f };
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Stage Sizing");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), 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_SkyBlue);
- clutter_actor_set_reactive (rect, TRUE);
- g_signal_connect_swapped (rect, "button-press-event",
- G_CALLBACK (shrink_clicked_cb), stage);
- label = clutter_text_new_with_text ("Sans 16", "Shrink");
- 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_Butter);
- clutter_actor_set_reactive (rect, TRUE);
- g_signal_connect_swapped (rect, "button-press-event",
- G_CALLBACK (expand_clicked_cb), stage);
- label = clutter_text_new_with_text ("Sans 16", "Expand");
- clutter_actor_set_margin (label, &margin);
- clutter_actor_add_child (rect, label);
- clutter_actor_add_child (box, rect);
-
- clutter_stage_set_minimum_size (CLUTTER_STAGE (stage),
- clutter_actor_get_width (box),
- clutter_actor_get_height (box));
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return EXIT_SUCCESS;
-}
-
-G_MODULE_EXPORT const char *
-test_stage_sizing_describe (void)
-{
- return "Check stage sizing policies.";
-}
diff --git a/src/tests/clutter/interactive/test-state-script.c b/src/tests/clutter/interactive/test-state-script.c
deleted file mode 100644
index 5905704f0..000000000
--- a/src/tests/clutter/interactive/test-state-script.c
+++ /dev/null
@@ -1,46 +0,0 @@
-#include <stdlib.h>
-
-#include <gmodule.h>
-
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-#define TEST_STATE_SCRIPT_FILE "test-script-signals.json"
-
-int
-test_state_script_main (int argc, char *argv[]);
-
-G_MODULE_EXPORT int
-test_state_script_main (int argc, char *argv[])
-{
- ClutterActor *stage, *button;
- ClutterScript *script;
- GError *error = NULL;
-
- clutter_test_init (&argc, &argv);
-
- script = clutter_script_new ();
- clutter_script_load_from_file (script, TEST_STATE_SCRIPT_FILE, &error);
- if (error != NULL)
- g_error ("Unable to load '%s': %s\n",
- TEST_STATE_SCRIPT_FILE,
- error->message);
-
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "State Script");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
- clutter_actor_show (stage);
-
- button = CLUTTER_ACTOR (clutter_script_get_object (script, "button"));
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), button);
- clutter_actor_add_constraint (button, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5));
-
- clutter_script_connect_signals (script, NULL);
-
- clutter_test_main ();
-
- g_object_unref (script);
-
- return EXIT_SUCCESS;
-}
diff --git a/src/tests/clutter/interactive/test-swipe-action.c b/src/tests/clutter/interactive/test-swipe-action.c
deleted file mode 100644
index d160ff288..000000000
--- a/src/tests/clutter/interactive/test-swipe-action.c
+++ /dev/null
@@ -1,199 +0,0 @@
-#include <stdlib.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-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,
- ClutterSwipeDirection direction,
- gpointer data_)
-{
- guint axis = GPOINTER_TO_UINT (data_);
- gchar *direction_str = g_strdup ("");
-
- if (axis == HORIZONTAL &&
- ((direction & CLUTTER_SWIPE_DIRECTION_UP) != 0 ||
- (direction & CLUTTER_SWIPE_DIRECTION_DOWN) != 0))
- {
- g_print ("discarding non-horizontal swipe on '%s'\n",
- clutter_actor_get_name (actor));
- return;
- }
-
- if (axis == VERTICAL &&
- ((direction & CLUTTER_SWIPE_DIRECTION_LEFT) != 0 ||
- (direction & CLUTTER_SWIPE_DIRECTION_RIGHT) != 0))
- {
- g_print ("discarding non-vertical swipe on '%s'\n",
- clutter_actor_get_name (actor));
- return;
- }
-
- if (direction & CLUTTER_SWIPE_DIRECTION_UP)
- {
- char *old_str = direction_str;
-
- direction_str = g_strconcat (direction_str, " up", NULL);
- g_free (old_str);
- }
-
- if (direction & CLUTTER_SWIPE_DIRECTION_DOWN)
- {
- char *old_str = direction_str;
-
- direction_str = g_strconcat (direction_str, " down", NULL);
- g_free (old_str);
- }
-
- if (direction & CLUTTER_SWIPE_DIRECTION_LEFT)
- {
- char *old_str = direction_str;
-
- direction_str = g_strconcat (direction_str, " left", NULL);
- g_free (old_str);
- }
-
- if (direction & CLUTTER_SWIPE_DIRECTION_RIGHT)
- {
- char *old_str = direction_str;
-
- direction_str = g_strconcat (direction_str, " right", NULL);
- g_free (old_str);
- }
-
- g_print ("swept: '%s': %s\n", clutter_actor_get_name (actor), direction_str);
-
- g_free (direction_str);
-}
-
-static void
-gesture_cancel_cb (ClutterSwipeAction *action,
- ClutterActor *actor,
- gpointer user_data)
-{
- g_debug ("gesture cancelled: '%s'", clutter_actor_get_name (actor));
-}
-
-static void
-attach_action (ClutterActor *actor, guint axis)
-{
- ClutterAction *action;
-
- action = g_object_new (CLUTTER_TYPE_SWIPE_ACTION, NULL);
- clutter_actor_add_action (actor, action);
- g_signal_connect (action, "swept", G_CALLBACK (swept_cb), GUINT_TO_POINTER (axis));
- g_signal_connect (action, "gesture-cancel", G_CALLBACK (gesture_cancel_cb), NULL);
-}
-
-static ClutterActor *
-create_label (const char *markup)
-{
- return CLUTTER_ACTOR (g_object_new (CLUTTER_TYPE_TEXT,
- "text", markup,
- "use-markup", TRUE,
- "x-expand", TRUE,
- "y-expand", TRUE,
- "x-align", CLUTTER_ACTOR_ALIGN_START,
- "y-align", CLUTTER_ACTOR_ALIGN_CENTER,
- NULL));
-}
-
-G_MODULE_EXPORT int
-test_swipe_action_main (int argc, char *argv[])
-{
- ClutterActor *stage, *rect;
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Swipe action");
- clutter_actor_set_size (stage, 640, 480);
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- rect = clutter_actor_new ();
- clutter_actor_set_background_color (rect, CLUTTER_COLOR_Red);
- clutter_actor_set_name (rect, "Vertical swipes");
- clutter_actor_set_size (rect, 150, 150);
- clutter_actor_set_position (rect, 10, 100);
- clutter_actor_set_reactive (rect, TRUE);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
- attach_action (rect, VERTICAL);
-
- rect = clutter_actor_new ();
- clutter_actor_set_background_color (rect, CLUTTER_COLOR_Blue);
- clutter_actor_set_name (rect, "Horizontal swipes");
- clutter_actor_set_size (rect, 150, 150);
- clutter_actor_set_position (rect, 170, 100);
- clutter_actor_set_reactive (rect, TRUE);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
- attach_action (rect, HORIZONTAL);
-
- rect = clutter_actor_new ();
- clutter_actor_set_background_color (rect, CLUTTER_COLOR_Green);
- clutter_actor_set_name (rect, "All swipes");
- clutter_actor_set_size (rect, 150, 150);
- clutter_actor_set_position (rect, 330, 100);
- clutter_actor_set_reactive (rect, TRUE);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
- attach_action (rect, BOTH);
-
- {
- ClutterLayoutManager *layout = clutter_box_layout_new ();
- ClutterActor *box;
- float offset;
-
- clutter_box_layout_set_orientation (CLUTTER_BOX_LAYOUT (layout),
- CLUTTER_ORIENTATION_VERTICAL);
- clutter_box_layout_set_spacing (CLUTTER_BOX_LAYOUT (layout), 6);
-
- box = clutter_actor_new ();
- clutter_actor_set_layout_manager (box, layout);
-
- clutter_actor_add_child (box,
- create_label ("<b>Red</b>: vertical swipes only"));
-
- clutter_actor_add_child (box,
- create_label ("<b>Blue</b>: horizontal swipes only"));
-
- clutter_actor_add_child (box,
- create_label ("<b>Green</b>: both"));
-
- offset = clutter_actor_get_height (stage)
- - clutter_actor_get_height (box)
- - 12.0;
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), box);
- clutter_actor_add_constraint (box, clutter_bind_constraint_new (stage,
- CLUTTER_BIND_X,
- 12.0));
- clutter_actor_add_constraint (box, clutter_bind_constraint_new (stage,
- CLUTTER_BIND_Y,
- offset));
- }
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return EXIT_SUCCESS;
-}
-
-G_MODULE_EXPORT const char *
-test_swipe_action_describe (void)
-{
- return "Swipe gesture recognizer.";
-}
diff --git a/src/tests/clutter/interactive/test-text-field.c b/src/tests/clutter/interactive/test-text-field.c
deleted file mode 100644
index a145b6758..000000000
--- a/src/tests/clutter/interactive/test-text-field.c
+++ /dev/null
@@ -1,339 +0,0 @@
-#include <stdlib.h>
-#include <gmodule.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.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)
-{
- g_print ("Text activated: %s (cursor: %d, selection at: %d)\n",
- clutter_text_get_text (text),
- clutter_text_get_cursor_position (text),
- clutter_text_get_selection_bound (text));
-}
-
-#define is_hex_digit(c) (((c) >= '0' && (c) <= '9') || \
- ((c) >= 'a' && (c) <= 'f') || \
- ((c) >= 'A' && (c) <= 'F'))
-#define to_hex_digit(c) (((c) <= '9') ? (c) - '0' : ((c) & 7) + 9)
-
-static gboolean
-on_captured_event (ClutterText *text,
- ClutterEvent *event,
- gpointer dummy G_GNUC_UNUSED)
-{
- gboolean is_unicode_mode = FALSE;
- gunichar c;
- guint keyval;
-
- if (event->type != CLUTTER_KEY_PRESS)
- return FALSE;
-
- is_unicode_mode = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (text),
- "unicode-mode"));
-
- c = clutter_event_get_key_unicode (event);
- keyval = clutter_event_get_key_symbol (event);
- if (keyval == CLUTTER_KEY_U)
- {
- if (is_unicode_mode)
- {
- GString *str = g_object_get_data (G_OBJECT (text), "unicode-str");
-
- clutter_text_set_preedit_string (text, NULL, NULL, 0);
-
- g_object_set_data (G_OBJECT (text), "unicode-mode",
- GINT_TO_POINTER (FALSE));
- g_object_set_data (G_OBJECT (text), "unicode-str",
- NULL);
-
- g_string_free (str, TRUE);
-
- return FALSE;
- }
-
- if (clutter_event_has_control_modifier (event))
- {
- PangoAttrList *attrs;
- PangoAttribute *a;
- GString *str = g_string_sized_new (5);
-
- g_string_append (str, "u");
-
- g_object_set_data (G_OBJECT (text),
- "unicode-mode",
- GINT_TO_POINTER (TRUE));
- g_object_set_data (G_OBJECT (text),
- "unicode-str",
- str);
-
- attrs = pango_attr_list_new ();
-
- a = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
- a->start_index = 0;
- a->end_index = str->len;
- pango_attr_list_insert (attrs, a);
-
- clutter_text_set_preedit_string (text, str->str, attrs, str->len);
-
- pango_attr_list_unref (attrs);
-
- return TRUE;
- }
-
- return FALSE;
- }
- else if (is_unicode_mode && is_hex_digit (c))
- {
- GString *str = g_object_get_data (G_OBJECT (text), "unicode-str");
- PangoAttrList *attrs;
- PangoAttribute *a;
- gchar buf[8];
- gsize len;
-
- len = g_unichar_to_utf8 (c, buf);
- buf[len] = '\0';
-
- g_string_append (str, buf);
-
- g_print ("added '%s' to '%s' (len:%d)\n",
- buf,
- str->str,
- (int) str->len);
-
- attrs = pango_attr_list_new ();
-
- a = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
- a->start_index = 0;
- a->end_index = str->len;
- pango_attr_list_insert (attrs, a);
-
- clutter_text_set_preedit_string (text, str->str, attrs, str->len);
-
- pango_attr_list_unref (attrs);
-
- return TRUE;
- }
- else if (is_unicode_mode && (keyval == CLUTTER_KEY_BackSpace))
- {
- GString *str = g_object_get_data (G_OBJECT (text), "unicode-str");
- PangoAttrList *attrs;
- PangoAttribute *a;
-
- g_string_truncate (str, str->len - 1);
-
- attrs = pango_attr_list_new ();
-
- a = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
- a->start_index = 0;
- a->end_index = str->len;
- pango_attr_list_insert (attrs, a);
-
- clutter_text_set_preedit_string (text, str->str, attrs, str->len);
-
- pango_attr_list_unref (attrs);
-
- return TRUE;
- }
- else if (is_unicode_mode &&
- (keyval == CLUTTER_KEY_Return ||
- keyval == CLUTTER_KEY_KP_Enter ||
- keyval == CLUTTER_KEY_ISO_Enter ||
- keyval == CLUTTER_KEY_KP_Space))
- {
- GString *str = g_object_get_data (G_OBJECT (text), "unicode-str");
- const gchar *contents = clutter_text_get_text (text);
- gunichar uchar = 0;
- gchar ch;
- gint i;
-
- clutter_text_set_preedit_string (text, NULL, NULL, 0);
-
- g_object_set_data (G_OBJECT (text), "unicode-mode",
- GINT_TO_POINTER (FALSE));
- g_object_set_data (G_OBJECT (text), "unicode-str",
- NULL);
-
- for (i = 0; i < str->len; i++)
- {
- ch = str->str[i];
-
- if (is_hex_digit (ch))
- uchar += ((gunichar) to_hex_digit (ch) << ((4 - i) * 4));
- }
-
- g_assert (g_unichar_validate (uchar));
-
- g_string_overwrite (str, 0, contents);
- g_string_insert_unichar (str,
- clutter_text_get_cursor_position (text),
- uchar);
-
- i = clutter_text_get_cursor_position (text);
- clutter_text_set_text (text, str->str);
-
- if (i >= 0)
- i += 1;
- else
- i = -1;
-
- clutter_text_set_cursor_position (text, i);
- clutter_text_set_selection_bound (text, i);
-
- g_string_free (str, TRUE);
-
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static ClutterActor *
-create_label (const ClutterColor *color,
- const gchar *text)
-{
- ClutterActor *retval = clutter_text_new ();
-
- clutter_text_set_color (CLUTTER_TEXT (retval), color);
- clutter_text_set_markup (CLUTTER_TEXT (retval), text);
- clutter_text_set_editable (CLUTTER_TEXT (retval), FALSE);
- clutter_text_set_selectable (CLUTTER_TEXT (retval), FALSE);
- clutter_text_set_single_line_mode (CLUTTER_TEXT (retval), TRUE);
- clutter_text_set_ellipsize (CLUTTER_TEXT (retval), PANGO_ELLIPSIZE_END);
-
- return retval;
-}
-
-static ClutterActor *
-create_entry (const ClutterColor *color,
- const gchar *text,
- PangoAttrList *attrs,
- gunichar password_char,
- gint max_length)
-{
- ClutterActor *retval = clutter_text_new_full (NULL, text, color);
- ClutterColor selection = { 0, };
- ClutterColor selected_text = { 0x00, 0x00, 0xff, 0xff };
-
- clutter_actor_set_reactive (retval, TRUE);
-
- clutter_color_darken (color, &selection);
-
- clutter_text_set_editable (CLUTTER_TEXT (retval), TRUE);
- clutter_text_set_selectable (CLUTTER_TEXT (retval), TRUE);
- clutter_text_set_activatable (CLUTTER_TEXT (retval), TRUE);
- clutter_text_set_single_line_mode (CLUTTER_TEXT (retval), TRUE);
- clutter_text_set_password_char (CLUTTER_TEXT (retval), password_char);
- clutter_text_set_cursor_color (CLUTTER_TEXT (retval), &selection);
- clutter_text_set_max_length (CLUTTER_TEXT (retval), max_length);
- clutter_text_set_selected_text_color (CLUTTER_TEXT (retval), &selected_text);
- clutter_actor_set_background_color (retval, CLUTTER_COLOR_LightGray);
- if (attrs)
- clutter_text_set_attributes (CLUTTER_TEXT (retval), attrs);
-
- g_signal_connect (retval, "activate",
- G_CALLBACK (on_entry_activate),
- NULL);
- g_signal_connect (retval, "captured-event",
- G_CALLBACK (on_captured_event),
- NULL);
-
- return retval;
-}
-
-G_MODULE_EXPORT gint
-test_text_field_main (gint argc,
- gchar **argv)
-{
- ClutterActor *stage;
- ClutterActor *box, *label, *entry;
- ClutterLayoutManager *grid;
- PangoAttrList *entry_attrs;
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Text Fields");
- clutter_actor_set_background_color (stage, CLUTTER_COLOR_Black);
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- 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, 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);
- clutter_actor_add_child (stage, box);
-
- 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 (grid, CLUTTER_CONTAINER (box), label,
- "row", 0,
- "column", 0,
- "x-expand", FALSE,
- "y-expand", FALSE,
- NULL);
-
- entry_attrs = pango_attr_list_new ();
- pango_attr_list_insert (entry_attrs, pango_attr_underline_new (PANGO_UNDERLINE_ERROR));
- 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 (grid, CLUTTER_CONTAINER (box), entry,
- "row", 0,
- "column", 1,
- "x-expand", TRUE,
- "x-fill", TRUE,
- "y-expand", FALSE,
- NULL);
- clutter_actor_grab_key_focus (entry);
-
- label = create_label (CLUTTER_COLOR_White, "<b>A very long password field:</b>");
- clutter_actor_add_child (box, label);
- clutter_layout_manager_child_set (grid, CLUTTER_CONTAINER (box), label,
- "row", 1,
- "column", 0,
- "x-expand", FALSE,
- "y-expand", FALSE,
- NULL);
-
- entry = create_entry (CLUTTER_COLOR_Black, "password", NULL, '*', 8);
- clutter_actor_add_child (box, entry);
- clutter_layout_manager_child_set (grid, CLUTTER_CONTAINER (box), entry,
- "row", 1,
- "column", 1,
- "x-expand", TRUE,
- "x-fill", TRUE,
- "y-expand", FALSE,
- NULL);
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return EXIT_SUCCESS;
-}
-
-G_MODULE_EXPORT const char *
-test_text_field_describe (void)
-{
- return
-"Text actor single-line and password mode support\n"
-"\n"
-"This test checks the :single-line-mode and :password-char properties of\n"
-"the ClutterText actor, plus the password hint feature and the :max-length\n"
-"property.";
-}
diff --git a/src/tests/clutter/interactive/test-text.c b/src/tests/clutter/interactive/test-text.c
deleted file mode 100644
index 308482d73..000000000
--- a/src/tests/clutter/interactive/test-text.c
+++ /dev/null
@@ -1,102 +0,0 @@
-#include <stdlib.h>
-
-#include <gmodule.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-#define FONT "Mono Bold 24px"
-
-static const gchar *runes =
-"ᚠᛇᚻ᛫ᛒᛦᚦ᛫ᚠᚱᚩᚠᚢᚱ᛫ᚠᛁᚱᚪ᛫ᚷᛖᚻᚹᛦᛚᚳᚢᛗ\n"
-"ᛋᚳᛖᚪᛚ᛫ᚦᛖᚪᚻ᛫ᛗᚪᚾᚾᚪ᛫ᚷᛖᚻᚹᛦᛚᚳ᛫ᛗᛁᚳᛚᚢᚾ᛫ᚻᛦᛏ᛫ᛞᚫᛚᚪᚾ\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)
-{
- ClutterActor *stage;
- ClutterActor *text, *text2;
- ClutterColor text_color = { 0x33, 0xff, 0x33, 0xff };
- ClutterColor cursor_color = { 0xff, 0x33, 0x33, 0xff };
- ClutterTextBuffer *buffer;
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Text Editing");
- clutter_actor_set_background_color (stage, CLUTTER_COLOR_Black);
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- buffer = clutter_text_buffer_new_with_text ("·", -1);
-
- text = clutter_text_new_with_buffer (buffer);
- clutter_text_set_font_name (CLUTTER_TEXT (text), FONT);
- clutter_text_set_color (CLUTTER_TEXT (text), &text_color);
-
- clutter_container_add (CLUTTER_CONTAINER (stage), text, NULL);
- clutter_actor_set_position (text, 40, 30);
- clutter_actor_set_width (text, 1024);
- clutter_text_set_line_wrap (CLUTTER_TEXT (text), TRUE);
-
- clutter_actor_set_reactive (text, TRUE);
- clutter_stage_set_key_focus (CLUTTER_STAGE (stage), text);
-
- clutter_text_set_editable (CLUTTER_TEXT (text), TRUE);
- clutter_text_set_selectable (CLUTTER_TEXT (text), TRUE);
- clutter_text_set_cursor_color (CLUTTER_TEXT (text), &cursor_color);
- clutter_text_set_selected_text_color (CLUTTER_TEXT (text), CLUTTER_COLOR_Blue);
-
- text2 = clutter_text_new_with_buffer (buffer);
- clutter_text_set_color (CLUTTER_TEXT (text2), &text_color);
- clutter_container_add (CLUTTER_CONTAINER (stage), text2, NULL);
- clutter_actor_set_position (text2, 40, 300);
- clutter_actor_set_width (text2, 1024);
- clutter_text_set_line_wrap (CLUTTER_TEXT (text2), TRUE);
-
- clutter_actor_set_reactive (text2, TRUE);
- clutter_text_set_editable (CLUTTER_TEXT (text2), TRUE);
- clutter_text_set_selectable (CLUTTER_TEXT (text2), TRUE);
- clutter_text_set_cursor_color (CLUTTER_TEXT (text2), &cursor_color);
- clutter_text_set_selected_text_color (CLUTTER_TEXT (text2), CLUTTER_COLOR_Green);
-
- if (argv[1])
- {
- GError *error = NULL;
- gchar *utf8;
-
- g_file_get_contents (argv[1], &utf8, NULL, &error);
- if (error)
- {
- utf8 = g_strconcat ("Unable to open '", argv[1], "':\n",
- error->message,
- NULL);
- g_error_free (error);
- }
-
- clutter_text_set_text (CLUTTER_TEXT (text), utf8);
- }
- else
- clutter_text_set_text (CLUTTER_TEXT (text), runes);
-
- clutter_actor_set_size (stage, 1024, 768);
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- return EXIT_SUCCESS;
-}
-
-G_MODULE_EXPORT const char *
-test_text_describe (void)
-{
- return "Multi-line text editing.";
-}
diff --git a/src/tests/clutter/interactive/test-touch-events.c b/src/tests/clutter/interactive/test-touch-events.c
deleted file mode 100644
index 6dd2befa3..000000000
--- a/src/tests/clutter/interactive/test-touch-events.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2012 Collabora Ltd.
- *
- * 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 <stdlib.h>
-#include <math.h>
-#include <cairo.h>
-#include <glib.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-#define STAGE_WIDTH 800
-#define STAGE_HEIGHT 550
-#define NUM_COLORS 10
-#define NUM_ACTORS 10
-
-static GQueue events = G_QUEUE_INIT;
-static GQueue all_events = G_QUEUE_INIT;
-static gboolean new_surface = TRUE;
-
-static const ClutterColor static_colors[] = {
- { 0xff, 0x00, 0x00, 0xff }, /* red */
- { 0x80, 0x00, 0x00, 0xff }, /* dark red */
- { 0x00, 0xff, 0x00, 0xff }, /* green */
- { 0x00, 0x80, 0x00, 0xff }, /* dark green */
- { 0x00, 0x00, 0xff, 0xff }, /* blue */
- { 0x00, 0x00, 0x80, 0xff }, /* dark blue */
- { 0x00, 0xff, 0xff, 0xff }, /* cyan */
- { 0x00, 0x80, 0x80, 0xff }, /* dark cyan */
- { 0xff, 0x00, 0xff, 0xff }, /* magenta */
- { 0xff, 0xff, 0x00, 0xff }, /* yellow */
-};
-static GHashTable *sequence_to_color = NULL;
-
-int
-test_touch_events_main (int argc, char *argv[]);
-
-const char *
-test_touch_events_describe (void);
-
-static void
-draw_touch (ClutterEvent *event,
- cairo_t *cr)
-{
- ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
- const ClutterColor *color;
-
- color = g_hash_table_lookup (sequence_to_color, sequence);
- if (color == NULL)
- {
- color = &static_colors[g_random_int_range (0, NUM_COLORS)];
- g_hash_table_insert (sequence_to_color, (gpointer) sequence, (gpointer) color);
- }
-
- cairo_set_source_rgba (cr, color->red / 255,
- color->green / 255,
- color->blue / 255,
- color->alpha / 255);
- cairo_arc (cr, event->touch.x, event->touch.y, 5, 0, 2 * G_PI);
- cairo_fill (cr);
-}
-
-static gboolean
-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);
-
- new_surface = FALSE;
-
- return TRUE;
-}
-
-static gboolean
-event_cb (ClutterActor *actor, ClutterEvent *event, ClutterActor *canvas)
-{
- ClutterEvent *copy;
-
- if (event->type != CLUTTER_TOUCH_UPDATE)
- return FALSE;
-
- copy = clutter_event_copy (event);
- g_queue_push_tail (&events, copy);
- g_queue_push_tail (&all_events, copy);
- clutter_actor_queue_redraw (canvas);
-
- return TRUE;
-}
-
-static gboolean
-rect_event_cb (ClutterActor *actor, ClutterEvent *event, gpointer data)
-{
- ClutterColor color;
-
- if (event->type != CLUTTER_TOUCH_BEGIN)
- return FALSE;
-
- color = static_colors[g_random_int_range (0, NUM_COLORS)];
- clutter_actor_set_background_color (actor, &color);
-
- return TRUE;
-}
-
-G_MODULE_EXPORT int
-test_touch_events_main (int argc, char *argv[])
-{
- ClutterActor *stage, *canvas_actor;
- ClutterContent *canvas;
- int i;
-
- /* initialize Clutter */
- clutter_test_init (&argc, &argv);
-
- /* create a resizable stage */
- stage = clutter_test_get_stage ();
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Touch events");
- 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_canvas_new ();
- clutter_canvas_set_size (CLUTTER_CANVAS (canvas), STAGE_WIDTH, STAGE_HEIGHT);
- g_signal_connect (canvas, "draw", G_CALLBACK (draw_touches), NULL);
-
- 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++)
- {
- gfloat size = STAGE_HEIGHT / NUM_ACTORS;
- ClutterColor color = static_colors[i % NUM_COLORS];
- ClutterActor *rectangle = clutter_actor_new ();
-
- clutter_actor_set_background_color (rectangle, &color);
-
- /* Test that event delivery to actors work */
- g_signal_connect (rectangle, "event", G_CALLBACK (rect_event_cb), NULL);
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), rectangle);
- clutter_actor_set_size (rectangle, size, size);
- clutter_actor_set_position (rectangle, 0, i * size);
- clutter_actor_set_reactive (rectangle, TRUE);
- }
-
- sequence_to_color = g_hash_table_new (NULL, NULL);
-
- clutter_test_main ();
-
- g_queue_foreach (&all_events, (GFunc) clutter_event_free, NULL);
- g_queue_clear (&events);
- g_queue_clear (&all_events);
- g_hash_table_destroy (sequence_to_color);
-
- return EXIT_SUCCESS;
-}
-
-G_MODULE_EXPORT const char *
-test_touch_events_describe (void)
-{
- return "Draw shapes based on touch events";
-}
diff --git a/src/tests/clutter/interactive/wrapper.sh.in b/src/tests/clutter/interactive/wrapper.sh.in
deleted file mode 100755
index 90aa4e1b6..000000000
--- a/src/tests/clutter/interactive/wrapper.sh.in
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-UNIT_TEST=$1
-
-shift
-
-echo "Running ./test-interactive $UNIT_TEST $@"
-echo ""
-echo "NOTE: For debugging purposes, you can run this single test as follows:"
-echo "$ libtool --mode=execute \\"
-echo " gdb --eval-command=\"b `echo $UNIT_TEST|tr '-' '_'`_main\" \\"
-echo " --args ./test-interactive $UNIT_TEST"
-
-@abs_builddir@/test-interactive $UNIT_TEST "$@"
-
diff --git a/src/tests/clutter/meson.build b/src/tests/clutter/meson.build
deleted file mode 100644
index ae05ae064..000000000
--- a/src/tests/clutter/meson.build
+++ /dev/null
@@ -1,11 +0,0 @@
-clutter_tests_includepath = include_directories('.')
-clutter_tests_includes = [
- tests_includepath,
- clutter_tests_includepath,
-]
-
-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
deleted file mode 100644
index 7fa2a8fca..000000000
--- a/src/tests/clutter/micro-bench/meson.build
+++ /dev/null
@@ -1,31 +0,0 @@
-clutter_tests_micro_bench_c_args = [
- '-DG_DISABLE_SINGLE_INCLUDES',
- '-DGLIB_DISABLE_DEPRECATION_WARNINGS',
- '-DCOGL_DISABLE_DEPRECATION_WARNINGS',
- '-DCLUTTER_DISABLE_DEPRECATION_WARNINGS',
- '-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()),
-]
-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),
- clutter_test_utils,
- ],
- include_directories: clutter_includes,
- c_args: clutter_tests_micro_bench_c_args,
- dependencies: [
- libmutter_test_dep,
- ],
- install: false,
- )
-endforeach
diff --git a/src/tests/clutter/micro-bench/test-cogl-perf.c b/src/tests/clutter/micro-bench/test-cogl-perf.c
deleted file mode 100644
index 3f3f29843..000000000
--- a/src/tests/clutter/micro-bench/test-cogl-perf.c
+++ /dev/null
@@ -1,150 +0,0 @@
-#include <clutter-build-config.h>
-#include <glib.h>
-#include <gmodule.h>
-#include <stdlib.h>
-#include <clutter/clutter.h>
-#include <cogl/cogl.h>
-#include <math.h>
-
-#include "tests/clutter-test-utils.h"
-
-#define STAGE_WIDTH 800
-#define STAGE_HEIGHT 600
-
-typedef struct _TestState
-{
- ClutterActor *stage;
- int current_test;
-} TestState;
-
-typedef void (*TestCallback) (TestState *state,
- ClutterPaintContext *paint_context);
-
-static void
-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?
- *
- * 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.
- *
- */
-
- pipeline = cogl_pipeline_new (ctx);
-
- for (y = 0; y < STAGE_HEIGHT; y += RECT_HEIGHT)
- {
- for (x = 0; x < STAGE_WIDTH; x += RECT_WIDTH)
- {
- 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);
- }
- }
-
- for (y = 0; y < STAGE_HEIGHT; y += RECT_HEIGHT)
- {
- for (x = 0; x < STAGE_WIDTH; x += RECT_WIDTH)
- {
- 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);
- }
- }
-}
-
-TestCallback tests[] =
-{
- test_rectangles
-};
-
-static void
-on_after_paint (ClutterActor *actor,
- ClutterPaintContext *paint_context,
- TestState *state)
-{
- tests[state->current_test] (state, paint_context);
-}
-
-static gboolean
-queue_redraw (gpointer stage)
-{
- clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
-
- return TRUE;
-}
-
-int
-main (int argc, char *argv[])
-{
- TestState state;
- ClutterActor *stage;
-
- g_setenv ("CLUTTER_VBLANK", "none", FALSE);
- g_setenv ("CLUTTER_SHOW_FPS", "1", FALSE);
-
- clutter_test_init (&argc, &argv);
-
- state.current_test = 0;
-
- state.stage = stage = clutter_test_get_stage ();
-
- clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
- clutter_actor_set_background_color (CLUTTER_ACTOR (stage), CLUTTER_COLOR_White);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Performance Test");
-
- /* We want continuous redrawing of the stage... */
- clutter_threads_add_idle (queue_redraw, stage);
-
- g_signal_connect (CLUTTER_STAGE (stage), "after-paint", G_CALLBACK (on_after_paint), &state);
-
- clutter_actor_show (stage);
-
- clutter_test_main ();
-
- clutter_actor_destroy (stage);
-
- return 0;
-}
-
diff --git a/src/tests/clutter/micro-bench/test-picking.c b/src/tests/clutter/micro-bench/test-picking.c
deleted file mode 100644
index 2e02671ba..000000000
--- a/src/tests/clutter/micro-bench/test-picking.c
+++ /dev/null
@@ -1,119 +0,0 @@
-
-#include <math.h>
-#include <stdlib.h>
-#include <clutter/clutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-#define N_ACTORS 100
-#define N_EVENTS 5
-
-static gboolean
-motion_event_cb (ClutterActor *actor, ClutterEvent *event, gpointer user_data)
-{
- return FALSE;
-}
-
-static void
-do_events (ClutterActor *stage)
-{
- glong i;
- static gdouble angle = 0;
-
- for (i = 0; i < N_EVENTS; i++)
- {
- angle += (2.0 * G_PI) / (double) N_ACTORS;
- while (angle > G_PI * 2.0)
- angle -= G_PI * 2.0;
-
- /* If we synthesized events, they would be motion compressed;
- * calling get_actor_at_position() doesn't have that problem
- */
- clutter_stage_get_actor_at_pos (CLUTTER_STAGE (stage),
- CLUTTER_PICK_REACTIVE,
- 256.0 + 206.0 * cos (angle),
- 256.0 + 206.0 * sin (angle));
- }
-}
-
-static void
-on_after_paint (ClutterActor *stage,
- ClutterPaintContext *paint_context,
- gconstpointer *data)
-{
- do_events (stage);
-}
-
-static gboolean
-queue_redraw (gpointer stage)
-{
- clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
-
- return TRUE;
-}
-
-int
-main (int argc, char **argv)
-{
- glong i;
- gdouble angle;
- ClutterColor color = { 0x00, 0x00, 0x00, 0xff };
- ClutterActor *stage, *rect;
-
- g_setenv ("CLUTTER_VBLANK", "none", FALSE);
- g_setenv ("CLUTTER_DEFAULT_FPS", "1000", FALSE);
- g_setenv ("CLUTTER_SHOW_FPS", "1", FALSE);
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_actor_set_size (stage, 512, 512);
- clutter_actor_set_background_color (CLUTTER_ACTOR (stage), CLUTTER_COLOR_Black);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Picking");
-
- printf ("Picking performance test with "
- "%d actors and %d events per frame\n",
- N_ACTORS,
- N_EVENTS);
-
- for (i = N_ACTORS - 1; i >= 0; i--)
- {
- angle = ((2.0 * G_PI) / (double) N_ACTORS) * i;
-
- color.red = (1.0 - ABS ((MAX (0, MIN (N_ACTORS / 2.0 + 0, i))) /
- (double) (N_ACTORS / 4.0) - 1.0)) * 255.0;
- color.green = (1.0 - ABS ((MAX (0, MIN (N_ACTORS / 2.0 + 0,
- fmod (i + (N_ACTORS / 3.0) * 2, N_ACTORS)))) /
- (double) (N_ACTORS / 4) - 1.0)) * 255.0;
- color.blue = (1.0 - ABS ((MAX (0, MIN (N_ACTORS / 2.0 + 0,
- fmod ((i + (N_ACTORS / 3.0)), N_ACTORS)))) /
- (double) (N_ACTORS / 4.0) - 1.0)) * 255.0;
-
- rect = clutter_actor_new ();
- clutter_actor_set_background_color (rect, &color);
- clutter_actor_set_size (rect, 100, 100);
- clutter_actor_set_translation (rect, -50.f, -50.f, 0.f);
- clutter_actor_set_position (rect,
- 256 + 206 * cos (angle),
- 256 + 206 * sin (angle));
- clutter_actor_set_reactive (rect, TRUE);
- g_signal_connect (rect, "motion-event",
- G_CALLBACK (motion_event_cb), NULL);
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
- }
-
- clutter_actor_show (stage);
-
- clutter_threads_add_idle (queue_redraw, stage);
-
- g_signal_connect (CLUTTER_STAGE (stage), "after-paint", G_CALLBACK (on_after_paint), NULL);
-
- clutter_test_main ();
-
- clutter_actor_destroy (stage);
-
- return 0;
-}
-
-
diff --git a/src/tests/clutter/micro-bench/test-random-text.c b/src/tests/clutter/micro-bench/test-random-text.c
deleted file mode 100644
index c5612924f..000000000
--- a/src/tests/clutter/micro-bench/test-random-text.c
+++ /dev/null
@@ -1,106 +0,0 @@
-#include <gmodule.h>
-#include <clutter/clutter.h>
-#include <stdlib.h>
-
-#include "tests/clutter-test-utils.h"
-
-#define MAX_TEXT_LEN 10
-#define MIN_FONT_SIZE 10
-#define MAX_FONT_SIZE 30
-
-static const char * const font_names[] =
- {
- "Sans", "Sans Italic", "Serif", "Serif Bold", "Times", "Monospace"
- };
-#define FONT_NAME_COUNT 6
-
-static gboolean
-on_idle (gpointer data)
-{
- ClutterActor *stage = CLUTTER_ACTOR (data);
- int line_height = 0, xpos = 0, ypos = 0;
- int stage_width = clutter_actor_get_width (stage);
- int stage_height = clutter_actor_get_height (stage);
- char text[MAX_TEXT_LEN + 1];
- char font_name[64];
- int i;
- GList *children, *node;
- static GTimer *timer = NULL;
- static int frame_count = 0;
-
- /* Remove all of the children of the stage */
- children = clutter_container_get_children (CLUTTER_CONTAINER (stage));
- for (node = children; node; node = node->next)
- clutter_container_remove_actor (CLUTTER_CONTAINER (stage),
- CLUTTER_ACTOR (node->data));
- g_list_free (children);
-
- /* Fill the stage with new random labels */
- while (ypos < stage_height)
- {
- int text_len = rand () % MAX_TEXT_LEN + 1;
- ClutterActor *label;
-
- for (i = 0; i < text_len; i++)
- text[i] = rand () % (128 - 32) + 32;
- text[text_len] = '\0';
-
- sprintf (font_name, "%s %i",
- font_names[rand () % FONT_NAME_COUNT],
- rand () % (MAX_FONT_SIZE - MIN_FONT_SIZE) + MIN_FONT_SIZE);
-
- label = clutter_text_new_with_text (font_name, text);
-
- if (clutter_actor_get_height (label) > line_height)
- line_height = clutter_actor_get_height (label);
-
- if (xpos + clutter_actor_get_width (label) > stage_width)
- {
- xpos = 0;
- ypos += line_height;
- line_height = 0;
- }
-
- clutter_actor_set_position (label, xpos, ypos);
-
- clutter_container_add (CLUTTER_CONTAINER (stage), label, NULL);
-
- xpos += clutter_actor_get_width (label);
- }
-
- if (timer == NULL)
- timer = g_timer_new ();
- else
- {
- if (++frame_count >= 10)
- {
- printf ("10 frames in %f seconds\n",
- g_timer_elapsed (timer, NULL));
- g_timer_start (timer);
- frame_count = 0;
- }
- }
-
- return TRUE;
-}
-
-int
-main (int argc, char *argv[])
-{
- ClutterActor *stage;
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Random Text");
-
- clutter_actor_show (stage);
-
- clutter_threads_add_idle (on_idle, stage);
-
- clutter_test_main ();
-
- clutter_actor_destroy (stage);
-
- return 0;
-}
diff --git a/src/tests/clutter/micro-bench/test-text-perf.c b/src/tests/clutter/micro-bench/test-text-perf.c
deleted file mode 100644
index 4f302870d..000000000
--- a/src/tests/clutter/micro-bench/test-text-perf.c
+++ /dev/null
@@ -1,190 +0,0 @@
-#include <clutter/clutter.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "tests/clutter-test-utils.h"
-
-#define STAGE_WIDTH 800
-#define STAGE_HEIGHT 600
-
-static int font_size;
-static int n_chars;
-static int rows, cols;
-
-static void
-on_after_paint (ClutterActor *actor,
- ClutterPaintContext *paint_context,
- gconstpointer *data)
-{
- static GTimer *timer = NULL;
- static int fps = 0;
-
- if (!timer)
- {
- timer = g_timer_new ();
- g_timer_start (timer);
- }
-
- if (g_timer_elapsed (timer, NULL) >= 1)
- {
- printf ("fps=%d, strings/sec=%d, chars/sec=%d\n",
- fps,
- fps * rows * cols,
- fps * rows * cols * n_chars);
- g_timer_start (timer);
- fps = 0;
- }
-
- ++fps;
-}
-
-static gboolean
-queue_redraw (gpointer stage)
-{
- clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
-
- return G_SOURCE_CONTINUE;
-}
-
-static gunichar
-get_character (int ch)
-{
- int total_letters = 0;
- int i;
-
- static const struct
- {
- gunichar first_letter;
- int n_letters;
- }
- ranges[] =
- {
- { 'a', 26 }, /* lower case letters */
- { 'A', 26 }, /* upper case letters */
- { '0', 10 }, /* digits */
- { 0x410, 0x40 }, /* cyrillic alphabet */
- { 0x3b1, 18 } /* greek alphabet */
- };
-
- for (i = 0; i < G_N_ELEMENTS (ranges); i++)
- total_letters += ranges[i].n_letters;
-
- ch %= total_letters;
-
- for (i = 0; i < G_N_ELEMENTS (ranges) - 1; i++)
- if (ch < ranges[i].n_letters)
- return ch + ranges[i].first_letter;
- else
- ch -= ranges[i].n_letters;
-
- return ch + ranges[i].first_letter;
-}
-
-static ClutterActor *
-create_label (void)
-{
- ClutterColor label_color = { 0xff, 0xff, 0xff, 0xff };
- ClutterActor *label;
- char *font_name;
- GString *str;
- int i;
-
- font_name = g_strdup_printf ("Monospace %dpx", font_size);
-
- str = g_string_new (NULL);
- for (i = 0; i < n_chars; i++)
- g_string_append_unichar (str, get_character (i));
-
- label = clutter_text_new_with_text (font_name, str->str);
- clutter_text_set_color (CLUTTER_TEXT (label), &label_color);
-
- g_free (font_name);
- g_string_free (str, TRUE);
-
- return label;
-}
-
-int
-main (int argc, char *argv[])
-{
- ClutterActor *stage;
- ClutterActor *label;
- int w, h;
- int row, col;
- float scale = 1.0f;
-
- g_setenv ("CLUTTER_VBLANK", "none", FALSE);
- g_setenv ("CLUTTER_DEFAULT_FPS", "1000", FALSE);
-
- clutter_test_init (&argc, &argv);
-
- if (argc != 3)
- {
- g_printerr ("Usage test-text-perf FONT_SIZE N_CHARS\n");
- exit (1);
- }
-
- font_size = atoi (argv[1]);
- n_chars = atoi (argv[2]);
-
- g_print ("Monospace %dpx, string length = %d\n", font_size, n_chars);
-
- stage = clutter_test_get_stage ();
- clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
- clutter_actor_set_background_color (CLUTTER_ACTOR (stage), CLUTTER_COLOR_Black);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Text Performance");
-
- g_signal_connect (CLUTTER_STAGE (stage), "after-paint", G_CALLBACK (on_after_paint), NULL);
-
- label = create_label ();
- w = clutter_actor_get_width (label);
- h = clutter_actor_get_height (label);
-
- /* If the label is too big to fit on the stage then scale it so that
- it will fit */
- if (w > STAGE_WIDTH || h > STAGE_HEIGHT)
- {
- float x_scale = STAGE_WIDTH / (float) w;
- float y_scale = STAGE_HEIGHT / (float) h;
-
- if (x_scale < y_scale)
- {
- scale = x_scale;
- cols = 1;
- rows = STAGE_HEIGHT / (h * scale);
- }
- else
- {
- scale = y_scale;
- cols = STAGE_WIDTH / (w * scale);
- rows = 1;
- }
-
- g_print ("Text scaled by %f to fit on the stage\n", scale);
- }
- else
- {
- cols = STAGE_WIDTH / w;
- rows = STAGE_HEIGHT / h;
- }
-
- clutter_actor_destroy (label);
-
- for (row=0; row<rows; row++)
- for (col=0; col<cols; col++)
- {
- label = create_label();
- clutter_actor_set_scale (label, scale, scale);
- clutter_actor_set_position (label, w * col * scale, h * row * scale);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), label);
- }
-
- clutter_actor_show (stage);
-
- clutter_threads_add_idle (queue_redraw, stage);
-
- clutter_test_main ();
-
- return 0;
-}
diff --git a/src/tests/clutter/micro-bench/test-text.c b/src/tests/clutter/micro-bench/test-text.c
deleted file mode 100644
index 0afb58bf6..000000000
--- a/src/tests/clutter/micro-bench/test-text.c
+++ /dev/null
@@ -1,123 +0,0 @@
-#include <clutter/clutter.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "tests/clutter-test-utils.h"
-
-#define STAGE_WIDTH 640
-#define STAGE_HEIGHT 480
-
-#define COLS 18
-#define ROWS 20
-
-static void
-on_after_paint (ClutterActor *actor,
- ClutterPaintContext *paint_context,
- gconstpointer *data)
-{
- static GTimer *timer = NULL;
- static int fps = 0;
-
- if (!timer)
- {
- timer = g_timer_new ();
- g_timer_start (timer);
- }
-
- if (g_timer_elapsed (timer, NULL) >= 1)
- {
- printf ("fps: %d\n", fps);
- g_timer_start (timer);
- fps = 0;
- }
-
- ++fps;
-}
-
-static gboolean
-queue_redraw (gpointer stage)
-{
- clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
-
- return G_SOURCE_CONTINUE;
-}
-
-int
-main (int argc, char *argv[])
-{
- ClutterActor *stage;
- ClutterActor *group;
-
- g_setenv ("CLUTTER_VBLANK", "none", FALSE);
- g_setenv ("CLUTTER_DEFAULT_FPS", "1000", FALSE);
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
- clutter_actor_set_background_color (CLUTTER_ACTOR (stage), CLUTTER_COLOR_Black);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Text");
-
- group = clutter_actor_new ();
- clutter_actor_set_size (group, STAGE_WIDTH, STAGE_WIDTH);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
-
- clutter_threads_add_idle (queue_redraw, stage);
-
- g_signal_connect (CLUTTER_STAGE (stage), "after-paint", G_CALLBACK (on_after_paint), NULL);
-
- {
- gint row, col;
-
- for (row=0; row<ROWS; row++)
- for (col=0; col<COLS; col++)
- {
- ClutterActor *label;
- gchar font_name[64];
- gchar text[64];
- gint font_size = row+10;
- gdouble scale = 0.17 + (1.5 * col / COLS);
-
- sprintf (font_name, "Sans %ipx", font_size);
- sprintf (text, "OH");
-
- if (row==0)
- {
- sprintf (font_name, "Sans 10px");
- sprintf (text, "%1.2f", scale);
- font_size = 10;
- scale = 1.0;
- }
- if (col==0)
- {
- sprintf (font_name, "Sans 10px");
- sprintf (text, "%ipx", font_size);
- if (row == 0)
- strcpy (text, "");
- font_size = 10;
- scale = 1.0;
- }
-
- label = clutter_text_new_with_text (font_name, text);
- clutter_text_set_color (CLUTTER_TEXT (label), CLUTTER_COLOR_White);
- clutter_actor_set_position (label, (1.0*STAGE_WIDTH/COLS)*col,
- (1.0*STAGE_HEIGHT/ROWS)*row);
- /*clutter_actor_set_clip (label, 0,0, (1.0*STAGE_WIDTH/COLS),
- (1.0*STAGE_HEIGHT/ROWS));*/
- clutter_actor_set_scale (label, scale, scale);
- clutter_text_set_line_wrap (CLUTTER_TEXT (label), FALSE);
- clutter_container_add_actor (CLUTTER_CONTAINER (group), label);
- }
- }
- clutter_actor_show (stage);
-
- g_signal_connect (stage, "key-press-event",
- G_CALLBACK (clutter_test_quit), NULL);
-
- clutter_test_main ();
-
- clutter_actor_destroy (stage);
-
- return 0;
-}
diff --git a/src/tests/clutter/performance/create-report.rb b/src/tests/clutter/performance/create-report.rb
deleted file mode 100755
index 9a58fdb89..000000000
--- a/src/tests/clutter/performance/create-report.rb
+++ /dev/null
@@ -1,179 +0,0 @@
-#!/usr/bin/env ruby
-#
-# ruby program to generate a performance report in PDF/png over git revisions, based on work
-# originally done for gegl by pippin@gimp.org, the original program is in the public domain.
-
-require 'cairo'
-
-def cairo_surface(w,h)
- surface = Cairo::PDFSurface.new("report.pdf", w,h)
- cr = Cairo::Context.new(surface)
- yield(cr)
-end
-
-class Database
-
- def initialize()
- @vals = Hash.new
- @runs = Array.new
- @colors = [
- [0,1,0, 0.8],
- [0,1,1, 0.8],
- [1,0,0, 0.8],
- [1,0,1, 0.8],
- [1,1,0, 0.8],
- #[0.5,0.5,0.5,0.8],
- # gray doesn't have sufficient contrast against background
- [0.5,0.5,1, 0.8],
- [0.5,1,0.5, 0.8],
- [0.5,1,1, 0.8],
- [1,0.5,0.5, 0.8],
- [1,0.5,1, 0.8],
- [1,1,0.5, 0.8],
- [1,1,1, 0.8],
- ]
- @width = 1800
- @height = 500
-
- @marginlx = 10
- @marginrx = 180
- @rgap = 40
- @marginy = 10
- end
- def val_max(key)
- max=0
- @runs.each { |run|
- val = @vals[key][run]
- if val and val > max
- max = val
- end
- }
- max
- end
- def val_min(key)
- min=9999990
- @runs.each { |run|
- val = @vals[key][run]
- min = val if val and val < min
- }
- #min
- 0 # this shows the relative noise in measurements better
- end
- def add_run(run)
- @runs = @runs + [run]
- end
- def add_entry(run, name, val)
- if !@vals[name]
- @vals[name]=Hash.new
- end
- # check if there is an existing value,
- # and perhaps have different behaviors
- # associated with
- @vals[name][run] = val.to_f
- end
-
- def drawbg cr
- cr.set_source_rgba(0.2, 0.2, 0.2, 1)
- cr.paint
-
- i=0
- @runs.each { |run|
- if i % 2 == 1
- cr.move_to 1.0 * i / @runs.length * (@width - @marginlx-@marginrx) + @marginlx, 0 * (@height - @marginy*2) + @marginy
- cr.line_to 1.0 * i / @runs.length * (@width - @marginlx-@marginrx) + @marginlx, 1.0 * (@height - @marginy*2) + @marginy
- cr.rel_line_to(1.0 / @runs.length * (@width - @marginlx-@marginrx), 0)
- cr.rel_line_to(0, -(@height - @marginy*2))
-
- cr.set_source_rgba([0.25,0.25,0.25,1])
- cr.fill
- end
- i+=1
- }
- end
-
- def drawtext cr
- i = 0
- @runs.each { |run|
- y = i * 10 + 20
- while y > @height - @marginy
- y = y - @height + @marginy + 10
- end
- cr.move_to 1.0 * i / @runs.length * (@width - @marginlx-@marginrx) + @marginlx, y
-
- cr.set_source_rgba(0.6,0.6,0.6,1)
- cr.show_text(run[0..6])
- i+=1
- }
- end
-
- def draw_limits cr, key
- cr.move_to @width - @marginrx + @rgap, 20
- cr.set_source_rgba(1.0, 1.0, 1.0, 1.0)
- cr.show_text(" #{val_max(key)} ")
- cr.move_to @width - @marginrx + @rgap, @height - @marginy
- cr.show_text(" #{val_min(key)} ")
- end
-
- def draw_val cr, key, valno
- min = val_min(key)
- max = val_max(key)
-
- cr.set_source_rgba(@colors[valno])
- cr.move_to(@width - @marginrx + @rgap, valno * 14 + @marginy + 20)
- cr.show_text(key)
-
- cr.line_width = 2
- cr.new_path
-
- i = 0
- @runs.each { |run|
- val = @vals[key][run]
- if val
- cr.line_to 1.0 * (i+0.5) / @runs.length * (@width - @marginlx-@marginrx) + @marginlx,
- (1.0 - ((val-min) * 1.0 / (max - min))) * (@height - @marginy*2) + @marginy
- end
- i = i + 1
- }
- cr.stroke
- end
-
- def create_report
- cairo_surface(@width, @height) { |cr|
- drawbg cr
- valno = 0
- @vals.each { |key, value|
- draw_val cr, key, valno
- valno += 1
- }
- drawtext cr
- cr.target.write_to_png("report.png")
-
- valno = 0
- @vals.each { |key, value|
- cr.show_page
- drawbg cr
- draw_val cr, key, valno
- drawtext cr
- draw_limits cr, key
- valno += 1
- }
- }
- end
-end
-
-generator = Database.new
-
-items = File.open('jobs').each { |rev|
- rev.strip!
- generator.add_run(rev)
- filename = "reports/" + rev;
- if File.exist?(filename)
- File.open(filename).each { |line|
- if line =~ /^@ (.*):(.*)/
- generator.add_entry(rev, $1, $2)
- end
- }
- end
-}
-
-generator.create_report
diff --git a/src/tests/clutter/performance/joblist b/src/tests/clutter/performance/joblist
deleted file mode 100644
index ce046cc71..000000000
--- a/src/tests/clutter/performance/joblist
+++ /dev/null
@@ -1,27 +0,0 @@
-# This file lists the commits that we want to do retrospective testing
-# of, aborting the retrospective testing and adjusting this file will
-# add the commit range to be tested without having to redo the initial one
-# thus allowing a sparse distributed range to first be tested, with
-# detailed ranges added in later.
-
-master~500..master % 32 # every 32th commit, to provide context
-
-# various spans of commits around which "interesting things happen"
-
-#eeac7~1..985a4
-#6c6e93d~1..3142b15
-#0486c56..88b026
-#732eecf..8cfb158
-#b499696..b77d9a6
-#ba09e9c..7bdbbe6
-#b424bd7..c1878
-#bc58de4..d03c3a6
-#5640a6..a29623e
-#6fd2663..6ec9c32
-# 012e4ab..1a8d577 #
-#120d759~4..2235e70
-
-# ef8be9e25ebe77fc63055191cc48af53d731c108 - actor: Use paint volumes to always queue clipped redraws
-
-# 5d16000 going up, and 3b78949 going down,. was a case of clipped redraws being broken
-
diff --git a/src/tests/clutter/performance/makejobs.rb b/src/tests/clutter/performance/makejobs.rb
deleted file mode 100755
index 79499df9b..000000000
--- a/src/tests/clutter/performance/makejobs.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env ruby
-
-# this ruby script generates a chronologically sorted
-
-res = ""
-input = File.read(ARGV[0])
-input = input.gsub(/#.*/, "")
-input.split("\n").each {|a|
- if a =~ /([^ ]*)\.\.([^ ]*) %(.*)/
- res += `git log #{$1}..#{$2} | grep '^commit' | sed 's/commit //' | sed -n '0~#{$3}p'`
- elsif a =~ /([^ ]*)\.\.([^ ]*)/
- res += `git log #{$1}..#{$2} | grep '^commit' | sed 's/commit //'`
- else
- res += `echo #{a}`
- end
-}
-
-all = `git log | grep '^commit' | sed 's/commit//' `
-all.split("\n").reverse.each {|a|
- if res.match(a.strip) != nil
- puts "#{a.strip}"
- end
-}
-
diff --git a/src/tests/clutter/performance/meson.build b/src/tests/clutter/performance/meson.build
deleted file mode 100644
index 2c7637bad..000000000
--- a/src/tests/clutter/performance/meson.build
+++ /dev/null
@@ -1,34 +0,0 @@
-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',
- '-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()),
-]
-
-clutter_tests_performance_c_args += clutter_debug_c_args
-
-clutter_tests_performance_tests = [
- 'test-picking',
- 'test-text-perf',
-]
-
-foreach test : clutter_tests_performance_tests
- executable(test,
- sources: [
- '@0@.c'.format(test),
- 'test-common.h',
- clutter_test_utils,
- ],
- include_directories: [
- clutter_includes,
- clutter_tests_includes,
- ],
- c_args: clutter_tests_performance_c_args,
- dependencies: [
- libmutter_test_dep,
- ],
- install: false,
- )
-endforeach
diff --git a/src/tests/clutter/performance/test-common.h b/src/tests/clutter/performance/test-common.h
deleted file mode 100644
index ea4210ddc..000000000
--- a/src/tests/clutter/performance/test-common.h
+++ /dev/null
@@ -1,144 +0,0 @@
-#include <stdlib.h>
-#include <glib.h>
-#include <clutter/clutter.h>
-#include <clutter/clutter-mutter.h>
-
-#include "tests/clutter-test-utils.h"
-
-static GTimer *testtimer = NULL;
-static gint testframes = 0;
-static float testmaxtime = 1.0;
-
-/* initialize environment to be suitable for fps testing */
-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);
- g_setenv ("CLUTTER_VBLANK", "none", FALSE);
-
- /* also override internal default FPS */
- g_setenv ("CLUTTER_DEFAULT_FPS", "1000", FALSE);
-
- if (g_getenv ("CLUTTER_PERFORMANCE_TEST_DURATION"))
- testmaxtime = atof(g_getenv("CLUTTER_PERFORMANCE_TEST_DURATION"));
- else
- testmaxtime = 10.0;
-
- g_random_set_seed (12345678);
-}
-
-static void perf_stage_after_paint_cb (ClutterStage *stage,
- ClutterPaintContext *paint_context,
- gpointer *data);
-static gboolean perf_fake_mouse_cb (gpointer stage);
-
-static inline void
-clutter_perf_fps_start (ClutterStage *stage)
-{
- g_signal_connect (stage, "after-paint", G_CALLBACK (perf_stage_after_paint_cb), NULL);
-}
-
-static inline void
-clutter_perf_fake_mouse (ClutterStage *stage)
-{
- clutter_threads_add_timeout (1000/60, perf_fake_mouse_cb, stage);
-}
-
-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_after_paint_cb (ClutterStage *stage,
- ClutterPaintContext *paint_context,
- gpointer *data)
-{
- if (!testtimer)
- testtimer = g_timer_new ();
- testframes ++;
- if (g_timer_elapsed (testtimer, NULL) > testmaxtime)
- {
- clutter_test_quit ();
- }
-}
-
-static void wrap (gfloat *value, gfloat min, gfloat max)
-{
- if (*value > max)
- *value = min;
- else if (*value < min)
- *value = max;
-}
-
-static gboolean perf_fake_mouse_cb (gpointer stage)
-{
- ClutterEvent *event = clutter_event_new (CLUTTER_MOTION);
- static ClutterInputDevice *device = NULL;
- int i;
- static float x = 0.0;
- static float y = 0.0;
- static float xd = 0.0;
- static float yd = 0.0;
- static gboolean inited = FALSE;
-
- gfloat w, h;
-
- if (!inited) /* XXX:
- force clutter to do handle our motion events,
- by forcibly updating the input device's state
- this should be possible to do in a better
- manner in the future, a versioning check
- will have to be added when this is possible
- without a hack... and the means to do the
- hack is deprecated
- */
- {
- ClutterEvent *event2 = clutter_event_new (CLUTTER_ENTER);
- 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.related = NULL;
-
- clutter_event_set_device (event2, device);
-
- clutter_event_put (event2);
- clutter_event_free (event2);
- inited = TRUE;
- }
-
- clutter_actor_get_size (stage, &w, &h);
- event->motion.stage = stage;
- clutter_event_set_device (event, device);
-
- /* called about every 60fps, and do 10 picks per stage */
- for (i = 0; i < 10; i++)
- {
- event->motion.x = x;
- event->motion.y = y;
-
- clutter_event_put (event);
-
- x += xd;
- y += yd;
- xd += g_random_double_range (-0.1, 0.1);
- yd += g_random_double_range (-0.1, 0.1);
-
- wrap (&x, 0, w);
- wrap (&y, 0, h);
-
- xd = CLAMP(xd, -1.3, 1.3);
- yd = CLAMP(yd, -1.3, 1.3);
- }
- clutter_event_free (event);
- return G_SOURCE_CONTINUE;
-}
diff --git a/src/tests/clutter/performance/test-picking.c b/src/tests/clutter/performance/test-picking.c
deleted file mode 100644
index a65132559..000000000
--- a/src/tests/clutter/performance/test-picking.c
+++ /dev/null
@@ -1,109 +0,0 @@
-
-#include <math.h>
-#include <stdlib.h>
-#include <clutter/clutter.h>
-#include "test-common.h"
-
-#define N_ACTORS 100
-#define N_EVENTS 5
-
-static gint n_actors = N_ACTORS;
-static gint n_events = N_EVENTS;
-
-static gboolean
-motion_event_cb (ClutterActor *actor, ClutterEvent *event, gpointer user_data)
-{
- return FALSE;
-}
-
-static void
-do_events (ClutterActor *stage)
-{
- glong i;
- static gdouble angle = 0;
-
- for (i = 0; i < n_events; i++)
- {
- angle += (2.0 * G_PI) / (gdouble)n_actors;
- while (angle > G_PI * 2.0)
- angle -= G_PI * 2.0;
-
- /* If we synthesized events, they would be motion compressed;
- * calling get_actor_at_position() doesn't have that problem
- */
- clutter_stage_get_actor_at_pos (CLUTTER_STAGE (stage),
- CLUTTER_PICK_REACTIVE,
- 256.0 + 206.0 * cos (angle),
- 256.0 + 206.0 * sin (angle));
- }
-}
-
-static gboolean queue_redraw (gpointer data)
-{
- ClutterActor *stage = CLUTTER_ACTOR (data);
- clutter_actor_queue_redraw (stage);
- do_events (stage);
- return TRUE;
-}
-
-int
-main (int argc, char **argv)
-{
- glong i;
- gdouble angle;
- ClutterColor color = { 0x00, 0x00, 0x00, 0xff };
- ClutterActor *stage, *rect;
-
- clutter_perf_fps_init ();
-
- clutter_test_init (&argc, &argv);
-
- stage = clutter_test_get_stage ();
- clutter_actor_set_size (stage, 512, 512);
- clutter_actor_set_background_color (CLUTTER_ACTOR (stage), CLUTTER_COLOR_Black);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Picking Performance");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- printf ("Picking performance test with "
- "%d actors and %d events per frame\n",
- n_actors,
- n_events);
-
- for (i = n_actors - 1; i >= 0; i--)
- {
- angle = ((2.0 * G_PI) / (gdouble) n_actors) * i;
-
- color.red = (1.0 - ABS ((MAX (0, MIN (n_actors/2.0 + 0, i))) /
- (gdouble)(n_actors/4.0) - 1.0)) * 255.0;
- color.green = (1.0 - ABS ((MAX (0, MIN (n_actors/2.0 + 0,
- fmod (i + (n_actors/3.0)*2, n_actors)))) /
- (gdouble)(n_actors/4) - 1.0)) * 255.0;
- color.blue = (1.0 - ABS ((MAX (0, MIN (n_actors/2.0 + 0,
- fmod ((i + (n_actors/3.0)), n_actors)))) /
- (gdouble)(n_actors/4.0) - 1.0)) * 255.0;
-
- rect = clutter_actor_new ();
- clutter_actor_set_background_color (rect, &color);
- clutter_actor_set_size (rect, 100, 100);
- clutter_actor_set_translation (rect, -50.f, -50.f, 0.f);
- clutter_actor_set_position (rect,
- 256 + 206 * cos (angle),
- 256 + 206 * sin (angle));
- clutter_actor_set_reactive (rect, TRUE);
- g_signal_connect (rect, "motion-event",
- G_CALLBACK (motion_event_cb), NULL);
-
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
- }
-
- clutter_actor_show (stage);
-
- clutter_perf_fps_start (CLUTTER_STAGE (stage));
- clutter_threads_add_idle (queue_redraw, stage);
- clutter_test_main ();
- clutter_perf_fps_report ("test-picking");
-
- return 0;
-}
-
-
diff --git a/src/tests/clutter/performance/test-text-perf.c b/src/tests/clutter/performance/test-text-perf.c
deleted file mode 100644
index bce727f38..000000000
--- a/src/tests/clutter/performance/test-text-perf.c
+++ /dev/null
@@ -1,166 +0,0 @@
-#include <clutter/clutter.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include "test-common.h"
-
-#define STAGE_WIDTH 800
-#define STAGE_HEIGHT 600
-
-static int font_size;
-static int n_chars;
-static int rows, cols;
-
-static gboolean
-queue_redraw (gpointer stage)
-{
- clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
-
- return G_SOURCE_CONTINUE;
-}
-
-static gunichar
-get_character (int ch)
-{
- int total_letters = 0;
- int i;
-
- static const struct
- {
- gunichar first_letter;
- int n_letters;
- }
- ranges[] =
- {
- { 'a', 26 }, /* lower case letters */
- { 'A', 26 }, /* upper case letters */
- { '0', 10 }, /* digits */
- { 0x410, 0x40 }, /* cyrillic alphabet */
- { 0x3b1, 18 } /* greek alphabet */
- };
-
- for (i = 0; i < G_N_ELEMENTS (ranges); i++)
- total_letters += ranges[i].n_letters;
-
- ch %= total_letters;
-
- for (i = 0; i < G_N_ELEMENTS (ranges) - 1; i++)
- if (ch < ranges[i].n_letters)
- return ch + ranges[i].first_letter;
- else
- ch -= ranges[i].n_letters;
-
- return ch + ranges[i].first_letter;
-}
-
-static ClutterActor *
-create_label (void)
-{
- ClutterColor label_color = { 0xff, 0xff, 0xff, 0xff };
- ClutterActor *label;
- char *font_name;
- GString *str;
- int i;
-
- font_name = g_strdup_printf ("Monospace %dpx", font_size);
-
- str = g_string_new (NULL);
- for (i = 0; i < n_chars; i++)
- g_string_append_unichar (str, get_character (i));
-
- label = clutter_text_new_with_text (font_name, str->str);
- clutter_text_set_color (CLUTTER_TEXT (label), &label_color);
-
- g_free (font_name);
- g_string_free (str, TRUE);
-
- return label;
-}
-
-int
-main (int argc, char *argv[])
-{
- ClutterActor *stage;
- ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff };
- ClutterActor *label;
- int w, h;
- int row, col;
- float scale = 1.0f;
-
- clutter_perf_fps_init ();
-
- clutter_test_init (&argc, &argv);
-
- if (argc != 3)
- {
- //g_printerr ("Usage test-text-perf FONT_SIZE N_CHARS\n");
- //exit (1);
- font_size = 30;
- n_chars = 400;
- }
- else
- {
- font_size = atoi (argv[1]);
- n_chars = atoi (argv[2]);
- }
-
- g_print ("Monospace %dpx, string length = %d\n", font_size, n_chars);
-
- stage = clutter_test_get_stage ();
- clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
- clutter_actor_set_background_color (CLUTTER_ACTOR (stage), &stage_color);
- clutter_stage_set_title (CLUTTER_STAGE (stage), "Text Performance");
- g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL);
-
- label = create_label ();
- w = clutter_actor_get_width (label);
- h = clutter_actor_get_height (label);
-
- /* If the label is too big to fit on the stage then scale it so that
- it will fit */
- if (w > STAGE_WIDTH || h > STAGE_HEIGHT)
- {
- float x_scale = STAGE_WIDTH / (float) w;
- float y_scale = STAGE_HEIGHT / (float) h;
-
- if (x_scale < y_scale)
- {
- scale = x_scale;
- cols = 1;
- rows = STAGE_HEIGHT / (h * scale);
- }
- else
- {
- scale = y_scale;
- cols = STAGE_WIDTH / (w * scale);
- rows = 1;
- }
-
- g_print ("Text scaled by %f to fit on the stage\n", scale);
- }
- else
- {
- cols = STAGE_WIDTH / w;
- rows = STAGE_HEIGHT / h;
- }
-
- clutter_actor_destroy (label);
-
- for (row=0; row<rows; row++)
- for (col=0; col<cols; col++)
- {
- label = create_label();
- clutter_actor_set_scale (label, scale, scale);
- clutter_actor_set_position (label, w * col * scale, h * row * scale);
- clutter_container_add_actor (CLUTTER_CONTAINER (stage), label);
- }
-
- clutter_actor_show (stage);
-
- clutter_perf_fps_start (CLUTTER_STAGE (stage));
- clutter_threads_add_idle (queue_redraw, stage);
- clutter_test_main ();
- clutter_perf_fps_report ("test-text-perf");
-
- return 0;
-}
diff --git a/src/tests/clutter/test-utils.h b/src/tests/clutter/test-utils.h
deleted file mode 100644
index 6ed1a938b..000000000
--- a/src/tests/clutter/test-utils.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#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
deleted file mode 100644
index 85f1b8ee2..000000000
--- a/src/tests/headless-start-test.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/* -*- 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 "core/display-private.h"
-#include "meta-test/meta-context-test.h"
-#include "tests/meta-monitor-manager-test.h"
-
-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;
- g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL;
- MetaCrtcMode *crtc_mode;
- MetaGpu *gpu;
- MetaCrtc *crtc;
- MetaCrtc **possible_crtcs;
- g_autoptr (MetaOutputInfo) output_info = NULL;
- MetaOutput *output;
- GList *logical_monitors;
- ClutterActor *stage;
-
- test_setup = g_new0 (MetaMonitorTestSetup, 1);
-
- crtc_mode_info = meta_crtc_mode_info_new ();
- crtc_mode_info->width = 1024;
- crtc_mode_info->height = 768;
- crtc_mode_info->refresh_rate = 60.0;
-
- crtc_mode = g_object_new (META_TYPE_CRTC_MODE,
- "id", (uint64_t) 1,
- "info", crtc_mode_info,
- NULL);
- test_setup->modes = g_list_append (NULL, crtc_mode);
-
- gpu = META_GPU (meta_backend_get_gpus (meta_get_backend ())->data);
- crtc = g_object_new (META_TYPE_CRTC_TEST,
- "id", (uint64_t) 1,
- "gpu", gpu,
- NULL);
- 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_info = meta_output_info_new ();
-
- output_info->name = g_strdup ("DP-1");
- output_info->vendor = g_strdup ("MetaProduct's Inc.");
- output_info->product = g_strdup ("MetaMonitor");
- output_info->serial = g_strdup ("0x987654");
- output_info->preferred_mode = modes[0];
- output_info->n_modes = 1;
- output_info->modes = modes;
- output_info->n_possible_crtcs = 1;
- output_info->possible_crtcs = possible_crtcs;
- output_info->connector_type = META_CONNECTOR_TYPE_DisplayPort;
-
- output = g_object_new (META_TYPE_OUTPUT_TEST,
- "id", (uint64_t) 1,
- "gpu", gpu,
- "info", output_info,
- NULL);
-
- 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 (void)
-{
- meta_monitor_manager_test_init_test_setup (create_headless_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[])
-{
- g_autoptr (MetaContext) context = NULL;
-
- context = meta_create_test_context (META_CONTEXT_TEST_TYPE_NESTED,
- META_CONTEXT_TEST_FLAG_NO_X11);
- g_assert (meta_context_configure (context, &argc, &argv, NULL));
-
- init_tests ();
-
- return meta_context_test_run_tests (META_CONTEXT_TEST (context));
-}
diff --git a/src/tests/kms-utils-unit-tests.c b/src/tests/kms-utils-unit-tests.c
deleted file mode 100644
index 40b768b3e..000000000
--- a/src/tests/kms-utils-unit-tests.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2021 Akihiko Odaki <akihiko.odaki@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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 "backends/native/meta-kms-utils.h"
-#include "backends/native/meta-kms-update.h"
-
-typedef struct {
- drmModeModeInfo drm_mode;
- float expected_refresh_rate;
-} RefreshRateTestCase;
-
-static const RefreshRateTestCase refresh_rate_test_cases[] = {
- /* "cvt 640 480" */
- {
- .drm_mode = {
- .clock = 23975,
- .hdisplay = 640,
- .hsync_start = 664,
- .hsync_end = 720,
- .htotal = 800,
- .vdisplay = 480,
- .vsync_start = 483,
- .vsync_end = 487,
- .vtotal = 500,
- .vscan = 0,
- .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
- },
- .expected_refresh_rate = 59.9375,
- },
-
- /* "cvt 640 480" with htotal 0 */
- {
- .drm_mode = {
- .clock = 23975,
- .hdisplay = 640,
- .hsync_start = 664,
- .hsync_end = 720,
- .htotal = 0,
- .vdisplay = 480,
- .vsync_start = 483,
- .vsync_end = 487,
- .vtotal = 500,
- .vscan = 0,
- .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
- },
- .expected_refresh_rate = 0.0,
- },
-
- /* "cvt 640 480" with vtotal 0 */
- {
- .drm_mode = {
- .clock = 23975,
- .hdisplay = 640,
- .hsync_start = 664,
- .hsync_end = 720,
- .htotal = 800,
- .vdisplay = 480,
- .vsync_start = 483,
- .vsync_end = 487,
- .vtotal = 0,
- .vscan = 0,
- .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
- },
- .expected_refresh_rate = 0.0,
- },
-
- /* "cvt 320 240" with doubled clock and vscan 2 */
- {
- .drm_mode = {
- .clock = 12062,
- .hdisplay = 320,
- .hsync_start = 336,
- .hsync_end = 360,
- .htotal = 400,
- .vdisplay = 240,
- .vsync_start = 243,
- .vsync_end = 247,
- .vtotal = 252,
- .vscan = 2,
- .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
- },
- .expected_refresh_rate = 59.8313,
- },
-
- /* "cvt 15360 8640 180" */
- {
- .drm_mode = {
- .clock = 37793603,
- .hdisplay = 15360,
- .hsync_start = 16880,
- .hsync_end = 18624,
- .htotal = 21888,
- .vdisplay = 8640,
- .vsync_start = 8643,
- .vsync_end = 8648,
- .vtotal = 9593,
- .vscan = 0,
- .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
- },
- .expected_refresh_rate = 179.9939,
- },
-};
-
-static void
-meta_test_kms_refresh_rate (void)
-{
- size_t index;
-
- for (index = 0; index < G_N_ELEMENTS (refresh_rate_test_cases); index++)
- {
- const RefreshRateTestCase *test_case = refresh_rate_test_cases + index;
- float refresh_rate;
-
- refresh_rate =
- meta_calculate_drm_mode_refresh_rate (&test_case->drm_mode);
- g_assert_cmpfloat_with_epsilon (refresh_rate,
- test_case->expected_refresh_rate,
- 0.0001);
- }
-}
-
-typedef struct
-{
- drmModeModeInfo drm_mode;
- int64_t expected_vblank_duration_us;
-} VblankDurationTestCase;
-
-static const VblankDurationTestCase vblank_duration_test_cases[] = {
- /* "cvt 640 480" */
- {
- .drm_mode = {
- .clock = 23975,
- .hdisplay = 640,
- .hsync_start = 664,
- .hsync_end = 720,
- .htotal = 800,
- .vdisplay = 480,
- .vsync_start = 483,
- .vsync_end = 487,
- .vtotal = 500,
- .vscan = 0,
- .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
- },
- .expected_vblank_duration_us = 668,
- },
-
- /* "cvt 640 480" with htotal 0 */
- {
- .drm_mode = {
- .clock = 23975,
- .hdisplay = 640,
- .hsync_start = 664,
- .hsync_end = 720,
- .htotal = 0,
- .vdisplay = 480,
- .vsync_start = 483,
- .vsync_end = 487,
- .vtotal = 500,
- .vscan = 0,
- .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
- },
- .expected_vblank_duration_us = 0,
- },
-
- /* "cvt 640 480" with vtotal 0 */
- {
- .drm_mode = {
- .clock = 23975,
- .hdisplay = 640,
- .hsync_start = 664,
- .hsync_end = 720,
- .htotal = 800,
- .vdisplay = 480,
- .vsync_start = 483,
- .vsync_end = 487,
- .vtotal = 0,
- .vscan = 0,
- .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
- },
- .expected_vblank_duration_us = 0,
- },
-
- /* "cvt 640 480" with DBLSCAN */
- {
- .drm_mode = {
- .clock = 23975,
- .hdisplay = 640,
- .hsync_start = 664,
- .hsync_end = 720,
- .htotal = 800,
- .vdisplay = 480,
- .vsync_start = 483,
- .vsync_end = 487,
- .vtotal = 500,
- .vscan = 0,
- .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC |
- DRM_MODE_FLAG_DBLSCAN,
- },
- .expected_vblank_duration_us = 1335,
- },
-};
-
-static void
-meta_test_kms_vblank_duration (void)
-{
- size_t index;
-
- for (index = 0; index < G_N_ELEMENTS (vblank_duration_test_cases); index++)
- {
- const VblankDurationTestCase *test_case = vblank_duration_test_cases + index;
- int64_t vblank_duration_us;
-
- vblank_duration_us =
- meta_calculate_drm_mode_vblank_duration_us (&test_case->drm_mode);
- g_assert_cmpint (vblank_duration_us,
- ==,
- test_case->expected_vblank_duration_us);
- }
-}
-
-static void
-meta_test_kms_update_fixed16 (void)
-{
- g_assert_cmpint (meta_fixed_16_from_int (12345), ==, 809041920);
- g_assert_cmpint (meta_fixed_16_to_int (809041920), ==, 12345);
- g_assert_cmpint (meta_fixed_16_from_int (-12345), ==, -809041920);
- g_assert_cmpint (meta_fixed_16_to_int (-809041920), ==, -12345);
-}
-
-static void
-init_kms_utils_tests (void)
-{
- g_test_add_func ("/backends/native/kms/refresh-rate",
- meta_test_kms_refresh_rate);
- g_test_add_func ("/backends/native/kms/vblank-duration",
- meta_test_kms_vblank_duration);
- g_test_add_func ("/backends/native/kms/update/fixed16",
- meta_test_kms_update_fixed16);
-}
-
-int
-main (int argc,
- char **argv)
-{
- g_test_init (&argc, &argv, NULL);
- init_kms_utils_tests ();
- return g_test_run ();
-}
diff --git a/src/tests/meson.build b/src/tests/meson.build
deleted file mode 100644
index a809cef8a..000000000
--- a/src/tests/meson.build
+++ /dev/null
@@ -1,351 +0,0 @@
-mutter_test_sources = [
- 'meta-backend-test.c',
- 'meta-backend-test.h',
- 'meta-context-test.c',
- 'meta-gpu-test.c',
- 'meta-gpu-test.h',
- 'meta-monitor-manager-test.c',
- 'meta-monitor-manager-test.h',
- 'monitor-test-utils.c',
- 'monitor-test-utils.h',
- 'meta-test-utils.c',
- 'meta-test-utils.h',
-]
-
-libmutter_test_name = 'mutter-test-' + libmutter_api_version
-
-clutter_test_utils = files (
- 'clutter-test-utils.c',
- 'clutter-test-utils.h',
-)
-
-tests_includepath = include_directories('.')
-tests_includes = mutter_includes
-tests_c_args = mutter_c_args
-
-tests_deps = [
- mutter_deps,
- libmutter_dep,
- libmutter_cogl_dep,
- libmutter_clutter_dep,
-]
-
-libmutter_test = shared_library(libmutter_test_name,
- mutter_test_sources,
- gnu_symbol_visibility: 'hidden',
- include_directories: tests_includes,
- c_args: tests_c_args,
- dependencies: tests_deps,
- install_rpath: pkglibdir,
- install_dir: libdir,
- install: true,
-)
-
-libmutter_test_dep = declare_dependency(
- link_with: libmutter_test,
- include_directories: tests_includes,
- dependencies: tests_deps,
-)
-
-pkg.generate(libmutter_test,
- name: 'Meta (test framework)',
- filebase: 'libmutter-test-' + libmutter_api_version,
- description: 'Mutter test framework',
- subdirs: pkgname,
- requires: ['libmutter-' + libmutter_api_version],
- version: meson.project_version(),
- variables: [
- 'apiversion=' + libmutter_api_version,
- ],
- install_dir: pcdir,
-)
-
-if have_clutter_tests
- subdir('clutter')
-endif
-
-subdir('meta-test')
-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_includes,
- 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-runner.c',
- ],
- include_directories: tests_includes,
- c_args: tests_c_args,
- dependencies: libmutter_test_dep,
- install: have_installed_tests,
- install_dir: mutter_installed_tests_libexecdir,
-)
-
-unit_tests = executable('mutter-test-unit-tests',
- sources: [
- 'unit-tests.c',
- 'boxes-tests.c',
- 'boxes-tests.h',
- 'meta-wayland-test-driver.c',
- 'meta-wayland-test-driver.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_includes,
- c_args: tests_c_args,
- dependencies: libmutter_test_dep,
- install: have_installed_tests,
- install_dir: mutter_installed_tests_libexecdir,
-)
-
-headless_start_test = executable('mutter-headless-start-test',
- sources: [
- 'headless-start-test.c',
- ],
- include_directories: tests_includes,
- c_args: tests_c_args,
- dependencies: libmutter_test_dep,
- install: have_installed_tests,
- install_dir: mutter_installed_tests_libexecdir,
-)
-
-stage_view_tests = executable('mutter-stage-view-tests',
- sources: [
- 'monitor-test-utils.c',
- 'monitor-test-utils.h',
- 'stage-view-tests.c',
- ],
- include_directories: tests_includes,
- c_args: tests_c_args,
- dependencies: libmutter_test_dep,
- install: have_installed_tests,
- install_dir: mutter_installed_tests_libexecdir,
-)
-
-anonymous_file_test = executable('anonymous-file-tests',
- sources: [
- 'anonymous-file.c',
- ],
- include_directories: tests_includes,
- c_args: tests_c_args,
- dependencies: [tests_deps],
- install: have_installed_tests,
- install_dir: mutter_installed_tests_libexecdir,
-)
-
-ref_test_sources = [
- 'meta-ref-test.c',
- 'meta-ref-test.h',
-]
-
-if have_native_tests
- native_kms_utils_tests = executable('mutter-native-kms-utils-tests',
- sources: [
- 'kms-utils-unit-tests.c',
- ],
- include_directories: tests_includepath,
- c_args: tests_c_args,
- dependencies: [tests_deps],
- install: have_installed_tests,
- install_dir: mutter_installed_tests_libexecdir,
- )
-
- native_headless_tests = executable('mutter-native-headless-tests',
- sources: [
- 'native-headless.c',
- 'native-screen-cast.c',
- 'native-screen-cast.h',
- 'native-virtual-monitor.c',
- 'native-virtual-monitor.h',
- ref_test_sources,
- ],
- include_directories: tests_includes,
- c_args: tests_c_args,
- dependencies: libmutter_test_dep,
- install: have_installed_tests,
- install_dir: mutter_installed_tests_libexecdir,
- )
-
- ref_test_sanity = executable('mutter-ref-test-sanity',
- sources: [
- 'ref-test-sanity.c',
- ref_test_sources,
- ],
- include_directories: tests_includes,
- c_args: tests_c_args,
- dependencies: libmutter_test_dep,
- install: have_installed_tests,
- install_dir: mutter_installed_tests_libexecdir,
- )
-
- screen_cast_client = executable('mutter-screen-cast-client',
- sources: [
- 'screen-cast-client.c',
- dbus_screen_cast_built_sources,
- ],
- include_directories: tests_includes,
- c_args: tests_c_args,
- dependencies: [
- gio_dep,
- libpipewire_dep,
- ],
- install: have_installed_tests,
- install_dir: mutter_installed_tests_libexecdir,
- )
-
- native_persistent_virtual_monitor = executable(
- 'mutter-persistent-virtual-monitor',
- sources: [
- 'native-persistent-virtual-monitor.c',
- ],
- include_directories: tests_includes,
- c_args: tests_c_args,
- dependencies: libmutter_test_dep,
- install: have_installed_tests,
- install_dir: mutter_installed_tests_libexecdir,
- )
-endif
-
-stacking_tests = [
- 'basic-x11',
- 'basic-wayland',
- 'client-side-decorated',
- 'closed-transient',
- 'closed-transient-no-default-focus',
- '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',
- 'restore-size',
- 'unmaximize-new-size',
- 'fullscreen-maximize',
- 'restore-position',
- 'default-size',
- 'modals',
- 'map-fixed-size',
-]
-
-foreach stacking_test: stacking_tests
- test(stacking_test, test_runner,
- suite: ['core', 'mutter/stacking'],
- 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,
-)
-
-test('stage-view', stage_view_tests,
- suite: ['core', 'mutter/unit'],
- env: test_env,
- is_parallel: false,
- timeout: 60,
-)
-
-test('anonymous-file', anonymous_file_test,
- suite: ['core', 'mutter/unit'],
- env: test_env,
- is_parallel: false,
- timeout: 60,
-)
-
-if have_native_tests
- test('native-kms-utils', native_kms_utils_tests,
- suite: ['core', 'mutter/native/kms'],
- env: test_env,
- is_parallel: false,
- timeout: 60,
- )
-
- test('native-headless', native_headless_tests,
- suite: ['core', 'mutter/native/headless'],
- env: test_env,
- is_parallel: false,
- timeout: 60,
- )
-
- test('ref-test-sanity', ref_test_sanity,
- suite: ['core', 'mutter/ref-test/sanity'],
- env: test_env,
- is_parallel: false,
- timeout: 60,
- )
-
- test('native-persistent-virtual-monitor', native_persistent_virtual_monitor,
- suite: ['core', 'mutter/native/persistent-virtual-monitor'],
- env: test_env,
- is_parallel: false,
- timeout: 60,
- )
-endif
diff --git a/src/tests/meta-backend-test.c b/src/tests/meta-backend-test.c
deleted file mode 100644
index 0bc30d04d..000000000
--- a/src/tests/meta-backend-test.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- 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
deleted file mode 100644
index ad57a42e8..000000000
--- a/src/tests/meta-backend-test.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- 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 ())
-META_EXPORT
-G_DECLARE_FINAL_TYPE (MetaBackendTest, meta_backend_test,
- META, BACKEND_TEST, MetaBackendX11Nested)
-
-META_EXPORT
-void meta_backend_test_set_is_lid_closed (MetaBackendTest *backend_test,
- gboolean is_lid_closed);
-
-META_EXPORT
-MetaGpu * meta_backend_test_get_gpu (MetaBackendTest *backend_test);
-
-#endif /* META_BACKEND_TEST_H */
diff --git a/src/tests/meta-context-test.c b/src/tests/meta-context-test.c
deleted file mode 100644
index 7ba6c6b51..000000000
--- a/src/tests/meta-context-test.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (C) 2021 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 "meta-test/meta-context-test.h"
-
-#include <glib.h>
-#include <gio/gio.h>
-
-#include "core/meta-context-private.h"
-#include "tests/meta-backend-test.h"
-#include "tests/meta-test-utils-private.h"
-#include "wayland/meta-wayland.h"
-#include "wayland/meta-xwayland.h"
-
-#ifdef HAVE_NATIVE_BACKEND
-#include "backends/native/meta-backend-native.h"
-#endif
-
-enum
-{
- BEFORE_TESTS,
- RUN_TESTS,
- AFTER_TESTS,
- N_SIGNALS
-};
-
-static guint signals[N_SIGNALS];
-
-typedef struct _MetaContextTestPrivate
-{
- MetaContextTestType type;
- MetaContextTestFlag flags;
-} MetaContextTestPrivate;
-
-struct _MetaContextTestClass
-{
- MetaContextClass parent_class;
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE (MetaContextTest, meta_context_test,
- META_TYPE_CONTEXT)
-
-static gboolean
-meta_context_test_configure (MetaContext *context,
- int *argc,
- char ***argv,
- GError **error)
-{
- MetaContextTest *context_test = META_CONTEXT_TEST (context);
- MetaContextTestPrivate *priv =
- meta_context_test_get_instance_private (context_test);
- MetaContextClass *context_class =
- META_CONTEXT_CLASS (meta_context_test_parent_class);
- const char *plugin_name;
-
- if (!context_class->configure (context, argc, argv, error))
- return FALSE;
-
- g_test_init (argc, argv, NULL);
- g_test_bug_base ("https://gitlab.gnome.org/GNOME/mutter/issues/");
-
- if (priv->flags & META_CONTEXT_TEST_FLAG_TEST_CLIENT)
- meta_ensure_test_client_path (*argc, *argv);
-
- meta_wayland_override_display_name ("mutter-test-display");
- meta_xwayland_override_display_number (512);
-
- plugin_name = g_getenv ("MUTTER_TEST_PLUGIN_PATH");
- if (!plugin_name)
- plugin_name = "libdefault";
- meta_context_set_plugin_name (context, plugin_name);
-
- return TRUE;
-}
-
-static MetaCompositorType
-meta_context_test_get_compositor_type (MetaContext *context)
-{
- return META_COMPOSITOR_TYPE_WAYLAND;
-}
-
-static MetaX11DisplayPolicy
-meta_context_test_get_x11_display_policy (MetaContext *context)
-{
- MetaContextTest *context_test = META_CONTEXT_TEST (context);
- MetaContextTestPrivate *priv =
- meta_context_test_get_instance_private (context_test);
-
- if (priv->flags & META_CONTEXT_TEST_FLAG_NO_X11)
- return META_X11_DISPLAY_POLICY_DISABLED;
- else
- return META_X11_DISPLAY_POLICY_ON_DEMAND;
-}
-
-static gboolean
-meta_context_test_is_replacing (MetaContext *context)
-{
- return FALSE;
-}
-
-static gboolean
-meta_context_test_setup (MetaContext *context,
- GError **error)
-{
- MetaBackend *backend;
- MetaSettings *settings;
-
- if (!META_CONTEXT_CLASS (meta_context_test_parent_class)->setup (context,
- error))
- return FALSE;
-
- backend = meta_get_backend ();
- settings = meta_backend_get_settings (backend);
- meta_settings_override_experimental_features (settings);
- meta_settings_enable_experimental_feature (
- settings,
- META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
-
- meta_set_syncing (!!g_getenv ("MUTTER_SYNC"));
-
- return TRUE;
-}
-
-static MetaBackend *
-create_nested_backend (MetaContext *context,
- GError **error)
-{
- return g_initable_new (META_TYPE_BACKEND_TEST,
- NULL, error,
- "context", context,
- NULL);
-}
-
-#ifdef HAVE_NATIVE_BACKEND
-static MetaBackend *
-create_headless_backend (MetaContext *context,
- GError **error)
-{
- return g_initable_new (META_TYPE_BACKEND_NATIVE,
- NULL, error,
- "context", context,
- "headless", TRUE,
- NULL);
-}
-#endif /* HAVE_NATIVE_BACKEND */
-
-static MetaBackend *
-meta_context_test_create_backend (MetaContext *context,
- GError **error)
-{
- MetaContextTest *context_test = META_CONTEXT_TEST (context);
- MetaContextTestPrivate *priv =
- meta_context_test_get_instance_private (context_test);
-
- switch (priv->type)
- {
- case META_CONTEXT_TEST_TYPE_NESTED:
- return create_nested_backend (context, error);
-#ifdef HAVE_NATIVE_BACKEND
- case META_CONTEXT_TEST_TYPE_HEADLESS:
- return create_headless_backend (context, error);
-#endif /* HAVE_NATIVE_BACKEND */
- }
-
- g_assert_not_reached ();
-}
-
-static void
-meta_context_test_notify_ready (MetaContext *context)
-{
-}
-
-static gboolean
-run_tests_idle (gpointer user_data)
-{
- MetaContext *context = user_data;
- int ret;
-
- g_signal_emit (context, signals[BEFORE_TESTS], 0);
- if (g_signal_has_handler_pending (context, signals[RUN_TESTS], 0, TRUE))
- {
- g_signal_emit (context, signals[RUN_TESTS], 0, &ret);
- g_assert (ret == 1 || ret == 0);
- }
- else
- {
- ret = g_test_run ();
- }
- g_signal_emit (context, signals[AFTER_TESTS], 0);
-
- if (ret != 0)
- {
- GError *error;
-
- error = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED,
- "One or more tests failed");
- meta_context_terminate_with_error (context, error);
- }
- else
- {
- meta_context_terminate (context);
- }
-
- return G_SOURCE_REMOVE;
-}
-
-int
-meta_context_test_run_tests (MetaContextTest *context_test)
-{
- MetaContext *context = META_CONTEXT (context_test);
- g_autoptr (GError) error = NULL;
-
- if (!meta_context_setup (context, &error))
- {
- g_printerr ("Test case failed to start: %s\n", error->message);
- return EXIT_FAILURE;
- }
-
- if (!meta_context_start (context, &error))
- {
- g_printerr ("Test case failed to start: %s\n", error->message);
- return EXIT_FAILURE;
- }
-
- g_idle_add (run_tests_idle, context_test);
-
- meta_context_notify_ready (context);
-
- if (!meta_context_run_main_loop (context, &error))
- {
- g_printerr ("Test case failed: %s\n", error->message);
- return EXIT_FAILURE;
- }
- else
- {
- return EXIT_SUCCESS;
- }
-}
-
-void
-meta_context_test_wait_for_x11_display (MetaContextTest *context_test)
-{
- MetaDisplay *display = meta_context_get_display (META_CONTEXT (context_test));
-
- while (!meta_display_get_x11_display (display))
- g_main_context_iteration (NULL, TRUE);
-
- g_assert_nonnull (meta_display_get_x11_display (display));
-}
-
-/**
- * meta_create_test_context: (skip)
- */
-MetaContext *
-meta_create_test_context (MetaContextTestType type,
- MetaContextTestFlag flags)
-{
- MetaContextTest *context_test;
- MetaContextTestPrivate *priv;
-
- context_test = g_object_new (META_TYPE_CONTEXT_TEST,
- "name", "Mutter Test",
- NULL);
- priv = meta_context_test_get_instance_private (context_test);
- priv->type = type;
- priv->flags = flags;
-
- return META_CONTEXT (context_test);
-}
-
-static void
-meta_context_test_class_init (MetaContextTestClass *klass)
-{
- MetaContextClass *context_class = META_CONTEXT_CLASS (klass);
-
- context_class->configure = meta_context_test_configure;
- context_class->get_compositor_type = meta_context_test_get_compositor_type;
- context_class->get_x11_display_policy =
- meta_context_test_get_x11_display_policy;
- context_class->is_replacing = meta_context_test_is_replacing;
- context_class->setup = meta_context_test_setup;
- context_class->create_backend = meta_context_test_create_backend;
- context_class->notify_ready = meta_context_test_notify_ready;
-
- signals[BEFORE_TESTS] =
- g_signal_new ("before-tests",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE,
- 0);
- signals[RUN_TESTS] =
- g_signal_new ("run-tests",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_INT,
- 0);
- signals[AFTER_TESTS] =
- g_signal_new ("after-tests",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE,
- 0);
-}
-
-static void
-meta_context_test_init (MetaContextTest *context_test)
-{
-}
diff --git a/src/tests/meta-gpu-test.c b/src/tests/meta-gpu-test.c
deleted file mode 100644
index d483fd211..000000000
--- a/src/tests/meta-gpu-test.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 46bbc80e2..000000000
--- a/src/tests/meta-gpu-test.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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
deleted file mode 100644
index e3b4f46cf..000000000
--- a/src/tests/meta-monitor-manager-test.c
+++ /dev/null
@@ -1,490 +0,0 @@
-/* -*- 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"
-#include "tests/monitor-test-utils.h"
-
-G_DEFINE_TYPE (MetaCrtcTest, meta_crtc_test, META_TYPE_CRTC)
-G_DEFINE_TYPE (MetaOutputTest, meta_output_test, META_TYPE_OUTPUT)
-
-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 CreateTestSetupFunc initial_setup_func;
-
-void
-meta_monitor_manager_test_init_test_setup (CreateTestSetupFunc func)
-{
- initial_setup_func = func;
-}
-
-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_reload (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);
-
- g_assert (manager_test->test_setup);
-
- 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,
- MetaCrtcAssignment **crtcs,
- unsigned int n_crtcs,
- MetaOutputAssignment **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);
- g_autoptr (GList) to_configure_outputs = NULL;
- g_autoptr (GList) to_configure_crtcs = NULL;
- unsigned int i;
-
- to_configure_outputs = g_list_copy (meta_gpu_get_outputs (gpu));
- to_configure_crtcs = g_list_copy (meta_gpu_get_crtcs (gpu));
-
- for (i = 0; i < n_crtcs; i++)
- {
- MetaCrtcAssignment *crtc_assignment = crtcs[i];
- MetaCrtc *crtc = crtc_assignment->crtc;
-
- to_configure_crtcs = g_list_remove (to_configure_crtcs, crtc);
-
- if (crtc_assignment->mode == NULL)
- {
- meta_crtc_unset_config (crtc);
- }
- else
- {
- unsigned int j;
-
- meta_crtc_set_config (crtc,
- &crtc_assignment->layout,
- crtc_assignment->mode,
- crtc_assignment->transform);
-
- for (j = 0; j < crtc_assignment->outputs->len; j++)
- {
- MetaOutput *output;
- MetaOutputAssignment *output_assignment;
-
- output = ((MetaOutput**) crtc_assignment->outputs->pdata)[j];
-
- to_configure_outputs = g_list_remove (to_configure_outputs,
- output);
-
- output_assignment = meta_find_output_assignment (outputs,
- n_outputs,
- output);
- meta_output_assign_crtc (output, crtc, output_assignment);
- }
- }
- }
-
- g_list_foreach (to_configure_crtcs,
- (GFunc) meta_crtc_unset_config,
- NULL);
- g_list_foreach (to_configure_outputs,
- (GFunc) meta_output_unassign_crtc,
- NULL);
-}
-
-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_assignments;
- GPtrArray *output_assignments;
-
- 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_assignments,
- &output_assignments,
- error))
- return FALSE;
-
- if (method == META_MONITORS_CONFIG_METHOD_VERIFY)
- {
- g_ptr_array_free (crtc_assignments, TRUE);
- g_ptr_array_free (output_assignments, TRUE);
- return TRUE;
- }
-
- apply_crtc_assignments (manager,
- (MetaCrtcAssignment **) crtc_assignments->pdata,
- crtc_assignments->len,
- (MetaOutputAssignment **) output_assignments->pdata,
- output_assignments->len);
-
- g_ptr_array_free (crtc_assignments, TRUE);
- g_ptr_array_free (output_assignments, 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,
- MetaMonitor *monitor,
- MetaMonitorMode *monitor_mode)
-{
- MetaOutput *output;
- MetaOutputTest *output_test;
-
- output = meta_monitor_get_main_output (monitor);
- output_test = META_OUTPUT_TEST (output);
-
- 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:
- 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 =
- META_MONITOR_MANAGER_CAPABILITY_NONE;
-
- 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);
-
- G_OBJECT_CLASS (meta_monitor_manager_test_parent_class)->dispose (object);
-}
-
-static MonitorTestCaseSetup default_test_case_setup = {
- .modes = {
- {
- .width = 800,
- .height = 600,
- .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
- },
-
- },
- .n_outputs = 1,
- .crtcs = {
- {
- .current_mode = 0
- },
- },
- .n_crtcs = 1,
-};
-
-static MetaMonitorTestSetup *
-create_default_test_setup (void)
-{
- return create_monitor_test_setup (&default_test_case_setup,
- MONITOR_TEST_FLAG_NO_STORED);
-}
-
-static void
-meta_monitor_manager_test_constructed (GObject *object)
-{
- MetaMonitorManagerTest *manager_test = META_MONITOR_MANAGER_TEST (object);
-
- if (initial_setup_func)
- manager_test->test_setup = initial_setup_func ();
- else
- manager_test->test_setup = create_default_test_setup ();
-
- G_OBJECT_CLASS (meta_monitor_manager_test_parent_class)->constructed (object);
-}
-
-static void
-meta_monitor_manager_test_init (MetaMonitorManagerTest *manager_test)
-{
- manager_test->handles_transforms = TRUE;
-}
-
-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;
- object_class->constructed = meta_monitor_manager_test_constructed;
-
- 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;
-}
-
-static void
-meta_output_test_init (MetaOutputTest *output_test)
-{
- output_test->scale = 1;
-}
-
-static void
-meta_output_test_class_init (MetaOutputTestClass *klass)
-{
-}
-
-static void
-meta_crtc_test_init (MetaCrtcTest *crtc_test)
-{
-}
-
-static void
-meta_crtc_test_class_init (MetaCrtcTestClass *klass)
-{
-}
diff --git a/src/tests/meta-monitor-manager-test.h b/src/tests/meta-monitor-manager-test.h
deleted file mode 100644
index 5b0b6d8e7..000000000
--- a/src/tests/meta-monitor-manager-test.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- 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-crtc.h"
-#include "backends/meta-monitor-manager-private.h"
-#include "backends/meta-output.h"
-
-typedef struct _MetaMonitorTestSetup
-{
- GList *modes;
- GList *outputs;
- GList *crtcs;
-} MetaMonitorTestSetup;
-
-struct _MetaCrtcTest
-{
- MetaCrtc parent;
-};
-
-struct _MetaOutputTest
-{
- MetaOutput parent;
-
- float scale;
-};
-
-typedef MetaMonitorTestSetup * (* CreateTestSetupFunc) (void);
-
-#define META_TYPE_CRTC_TEST (meta_crtc_test_get_type ())
-META_EXPORT
-G_DECLARE_FINAL_TYPE (MetaCrtcTest, meta_crtc_test,
- META, CRTC_TEST,
- MetaCrtc)
-
-#define META_TYPE_OUTPUT_TEST (meta_output_test_get_type ())
-META_EXPORT
-G_DECLARE_FINAL_TYPE (MetaOutputTest, meta_output_test,
- META, OUTPUT_TEST,
- MetaOutput)
-
-#define META_TYPE_MONITOR_MANAGER_TEST (meta_monitor_manager_test_get_type ())
-META_EXPORT
-G_DECLARE_FINAL_TYPE (MetaMonitorManagerTest, meta_monitor_manager_test,
- META, MONITOR_MANAGER_TEST, MetaMonitorManager)
-
-META_EXPORT
-void meta_monitor_manager_test_init_test_setup (CreateTestSetupFunc func);
-
-void meta_monitor_manager_test_read_current (MetaMonitorManager *manager);
-
-META_EXPORT
-void meta_monitor_manager_test_emulate_hotplug (MetaMonitorManagerTest *manager_test,
- MetaMonitorTestSetup *test_setup);
-
-META_EXPORT
-void meta_monitor_manager_test_set_handles_transforms (MetaMonitorManagerTest *manager_test,
- gboolean handles_transforms);
-
-META_EXPORT
-int meta_monitor_manager_test_get_tiled_monitor_count (MetaMonitorManagerTest *manager_test);
-
-#endif /* META_MONITOR_MANAGER_TEST_H */
diff --git a/src/tests/meta-ref-test.c b/src/tests/meta-ref-test.c
deleted file mode 100644
index 84ac8876d..000000000
--- a/src/tests/meta-ref-test.c
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
- * Copyright (C) 2021 Red Hat Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * The image difference code is originally a reformatted and simplified
- * copy of weston-test-client-helper.c from the weston repository, with
- * the following copyright and license note:
- *
- * Copyright © 2012 Intel Corporation
- * Copyright © 2015 Samsung Electronics Co., Ltd
- * Copyright 2016, 2017 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.
- */
-
-/*
- * To update or initialize reference images for tests, set the
- * MUTTER_REF_TEST_UPDATE environment variable.
- *
- * The MUTTER_REF_TEST_UPDATE is interpreted as a comma seperated list of
- * regular expressions. If the test path matches any of the regular
- * expressions, the test reference image will be updated, unless the
- * existing reference image is pixel identical to the newly created one.
- *
- * Updating test reference images also requires using a software OpenGL
- * renderer, which can be achieved using LIBGL_ALWAYS_SOFTWARE=1
- *
- * For example, for the test case '/path/to/test/case', run the test
- * inside
- *
- * ```
- * env LIBGL_ALWAYS_SOFTWARE=1 MUTTER_REF_TEST_UPDATE='/path/to/test/case`
- * ```
- *
- */
-
-#include "config.h"
-
-#include "tests/meta-ref-test.h"
-
-#include <cairo.h>
-#include <glib.h>
-
-#include "backends/meta-backend-private.h"
-#include "backends/meta-stage-private.h"
-#include "clutter/clutter/clutter-stage-view-private.h"
-
-typedef struct _Range
-{
- int a;
- int b;
-} Range;
-
-typedef struct _ImageIterator
-{
- uint8_t *data;
- int stride;
-} ImageIterator;
-
-typedef struct _PixelDiffStat
-{
- /* Pixel diff stat channel */
- struct {
- int min_diff;
- int max_diff;
- } ch[4];
-} PixelDiffStat;
-
-/**
- * range_get:
- * @range: Range to validate or NULL.
- *
- * Validate and get range.
- *
- * Returns the given range, or {0, 0} for NULL.
- *
- * Will abort if range is invalid, that is a > b.
- */
-static Range
-range_get (const Range *range)
-{
- if (!range)
- return (Range) { 0, 0 };
-
- g_assert_cmpint (range->a, <=, range->b);
- return *range;
-}
-
-static void
-image_iterator_init (ImageIterator *it,
- cairo_surface_t *image)
-{
- it->stride = cairo_image_surface_get_stride (image);
- it->data = cairo_image_surface_get_data (image);
-
- g_assert_cmpint (cairo_image_surface_get_format (image), ==,
- CAIRO_FORMAT_ARGB32);
-}
-
-static uint32_t *
-image_iterator_get_row (ImageIterator *it,
- int y)
-{
- return (uint32_t *) (it->data + y * it->stride);
-}
-
-static gboolean
-fuzzy_match_pixels (uint32_t pix_a,
- uint32_t pix_b,
- const Range *fuzz,
- PixelDiffStat *diff_stat)
-{
- gboolean ret = TRUE;
- int shift;
- int i;
-
- for (shift = 0, i = 0; i < 4; shift += 8, i++)
- {
- int val_a = (pix_a >> shift) & 0xffu;
- int val_b = (pix_b >> shift) & 0xffu;
- int d = val_b - val_a;
-
- if (diff_stat)
- {
- diff_stat->ch[i].min_diff = MIN (diff_stat->ch[i].min_diff, d);
- diff_stat->ch[i].max_diff = MAX (diff_stat->ch[i].max_diff, d);
- }
-
- if (d < fuzz->a || d > fuzz->b)
- ret = FALSE;
- }
-
- return ret;
-}
-
-static gboolean
-compare_images (cairo_surface_t *ref_image,
- cairo_surface_t *result_image,
- const Range *precision,
- PixelDiffStat *diff_stat)
-{
- Range fuzz = range_get (precision);
- ImageIterator it_ref;
- ImageIterator it_result;
- int x, y;
- uint32_t *pix_ref;
- uint32_t *pix_result;
-
- g_assert_cmpint (cairo_image_surface_get_width (ref_image), ==,
- cairo_image_surface_get_width (result_image));
- g_assert_cmpint (cairo_image_surface_get_height (ref_image), ==,
- cairo_image_surface_get_height (result_image));
-
- image_iterator_init (&it_ref, ref_image);
- image_iterator_init (&it_result, result_image);
-
- for (y = 0; y < cairo_image_surface_get_height (ref_image); y++)
- {
- pix_ref = image_iterator_get_row (&it_ref, y);
- pix_result = image_iterator_get_row (&it_result, y);
-
- for (x = 0; x < cairo_image_surface_get_width (ref_image); x++)
- {
- if (!fuzzy_match_pixels (*pix_ref, *pix_result,
- &fuzz, diff_stat))
- return FALSE;
-
- pix_ref++;
- pix_result++;
- }
- }
-
- return TRUE;
-}
-
-static void
-assert_software_rendered (void)
-{
- MetaBackend *backend = meta_get_backend ();
-
- g_assert_false (meta_backend_is_rendering_hardware_accelerated (backend));
-}
-
-static void
-capture_view_into (ClutterStageView *view,
- MetaRectangle *rect,
- uint8_t *buffer,
- int stride)
-{
- CoglFramebuffer *framebuffer;
- ClutterBackend *backend;
- CoglContext *context;
- CoglBitmap *bitmap;
- cairo_rectangle_int_t view_layout;
- float view_scale;
- float texture_width;
- float texture_height;
- int x, y;
-
- framebuffer = clutter_stage_view_get_framebuffer (view);
-
- view_scale = clutter_stage_view_get_scale (view);
- texture_width = roundf (rect->width * view_scale);
- texture_height = roundf (rect->height * view_scale);
-
- backend = clutter_get_default_backend ();
- context = clutter_backend_get_cogl_context (backend);
- bitmap = cogl_bitmap_new_for_data (context,
- texture_width, texture_height,
- CLUTTER_CAIRO_FORMAT_ARGB32,
- stride,
- buffer);
-
- clutter_stage_view_get_layout (view, &view_layout);
-
- x = roundf ((rect->x - view_layout.x) * view_scale);
- y = roundf ((rect->y - view_layout.y) * view_scale);
- cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
- x, y,
- COGL_READ_PIXELS_COLOR_BUFFER,
- bitmap);
-
- cogl_object_unref (bitmap);
-}
-
-typedef struct
-{
- MetaStageWatch *watch;
- GMainLoop *loop;
-
- cairo_surface_t *out_image;
-} CaptureViewData;
-
-static void
-on_after_paint (MetaStage *stage,
- ClutterStageView *view,
- ClutterPaintContext *paint_context,
- gpointer user_data)
-{
- CaptureViewData *data = user_data;
- MetaRectangle rect;
- float view_scale;
- int texture_width, texture_height;
- cairo_surface_t *image;
- uint8_t *buffer;
- int stride;
-
- meta_stage_remove_watch (stage, data->watch);
- data->watch = NULL;
-
- clutter_stage_view_get_layout (view, &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,
- texture_width, texture_height);
- cairo_surface_set_device_scale (image, view_scale, view_scale);
-
- buffer = cairo_image_surface_get_data (image);
- stride = cairo_image_surface_get_stride (image);
-
- capture_view_into (view, &rect, buffer, stride);
-
- data->out_image = image;
-
- cairo_surface_mark_dirty (data->out_image);
-
- g_main_loop_quit (data->loop);
-}
-
-static cairo_surface_t *
-capture_view (ClutterStageView *view)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaStage *stage = META_STAGE (meta_backend_get_stage (backend));
- CaptureViewData data = { 0 };
-
- data.loop = g_main_loop_new (NULL, FALSE);
- data.watch = meta_stage_watch_view (stage, view,
- META_STAGE_WATCH_AFTER_PAINT,
- on_after_paint,
- &data);
- clutter_stage_view_add_redraw_clip (view, NULL);
- clutter_stage_view_schedule_update (view);
-
- g_main_loop_run (data.loop);
- g_main_loop_unref (data.loop);
-
- g_assert_null (data.watch);
- g_assert_nonnull (data.out_image);
-
- return data.out_image;
-}
-
-static void
-depathify (char *path)
-{
- int len = strlen (path);
- int i;
-
- for (i = 0; i < len; i++)
- {
- if (path[i] == '/')
- path[i] = '_';
- }
-}
-
-static void
-ensure_expected_format (cairo_surface_t **ref_image)
-{
- int width, height;
- cairo_surface_t *target;
- cairo_t *cr;
-
- if (cairo_image_surface_get_format (*ref_image) ==
- CAIRO_FORMAT_ARGB32)
- return;
-
- width = cairo_image_surface_get_width (*ref_image);
- height = cairo_image_surface_get_height (*ref_image);
- target = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
-
- cr = cairo_create (target);
- cairo_set_source_surface (cr, *ref_image, 0.0, 0.0);
- cairo_paint (cr);
- cairo_destroy (cr);
-
- cairo_surface_destroy (*ref_image);
- *ref_image = target;
-}
-
-/**
- * Tint a color:
- * @src Source pixel as x8r8g8b8.
- * @add The tint as x8r8g8b8, x8 must be zero; r8, g8 and b8 must be
- * no greater than 0xc0 to avoid overflow to another channel.
- * Returns: The tinted pixel color as x8r8g8b8, x8 guaranteed to be 0xff.
- *
- * The source pixel RGB values are divided by 4, and then the tint is added.
- * To achieve colors outside of the range of src, a tint color channel must be
- * at least 0x40. (0xff / 4 = 0x3f, 0xff - 0x3f = 0xc0)
- */
-static uint32_t
-tint (uint32_t src,
- uint32_t add)
-{
- uint32_t v;
-
- v = ((src & 0xfcfcfcfc) >> 2) | 0xff000000;
-
- return v + add;
-}
-
-static cairo_surface_t *
-visualize_difference (cairo_surface_t *ref_image,
- cairo_surface_t *result_image,
- const Range *precision)
-{
- Range fuzz = range_get (precision);
- int width, height;
- cairo_surface_t *diff_image;
- cairo_t *cr;
- ImageIterator it_ref;
- ImageIterator it_result;
- ImageIterator it_diff;
- int y;
-
- width = cairo_image_surface_get_width (ref_image);
- height = cairo_image_surface_get_height (ref_image);
-
- diff_image = cairo_surface_create_similar_image (ref_image,
- CAIRO_FORMAT_ARGB32,
- width,
- height);
- cr = cairo_create (diff_image);
- cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
- cairo_paint (cr);
- cairo_set_source_surface (cr, ref_image, 0.0, 0.0);
- cairo_set_operator (cr, CAIRO_OPERATOR_HSL_LUMINOSITY);
- cairo_paint (cr);
- cairo_destroy (cr);
-
- image_iterator_init (&it_ref, ref_image);
- image_iterator_init (&it_result, result_image);
- image_iterator_init (&it_diff, diff_image);
-
- for (y = 0; y < cairo_image_surface_get_height (ref_image); y++)
- {
- uint32_t *ref_pixel;
- uint32_t *result_pixel;
- uint32_t *diff_pixel;
- int x;
-
- ref_pixel = image_iterator_get_row (&it_ref, y);
- result_pixel = image_iterator_get_row (&it_result, y);
- diff_pixel = image_iterator_get_row (&it_diff, y);
-
- for (x = 0; x < cairo_image_surface_get_width (ref_image); x++)
- {
- if (fuzzy_match_pixels (*ref_pixel, *result_pixel,
- &fuzz, NULL))
- *diff_pixel = tint (*diff_pixel, 0x00008000); /* green */
- else
- *diff_pixel = tint (*diff_pixel, 0x00c00000); /* red */
-
- ref_pixel++;
- result_pixel++;
- diff_pixel++;
- }
- }
-
- return diff_image;
-}
-
-void
-meta_ref_test_verify_view (ClutterStageView *view,
- const char *test_name_unescaped,
- int test_seq_no,
- MetaReftestFlag flags)
-{
- cairo_surface_t *view_image;
- const char *dist_dir;
- g_autofree char *test_name = NULL;
- g_autofree char *ref_image_path = NULL;
- cairo_surface_t *ref_image;
- cairo_status_t ref_status;
-
- if (flags & META_REFTEST_FLAG_UPDATE_REF)
- assert_software_rendered ();
-
- view_image = capture_view (view);
-
- test_name = g_strdup (test_name_unescaped + 1);
- depathify (test_name);
-
- dist_dir = g_test_get_dir (G_TEST_DIST);
- ref_image_path = g_strdup_printf ("%s/tests/ref-tests/%s_%d.ref.png",
- dist_dir,
- test_name, test_seq_no);
-
- ref_image = cairo_image_surface_create_from_png (ref_image_path);
- g_assert_nonnull (ref_image);
- ref_status = cairo_surface_status (ref_image);
-
- if (flags & META_REFTEST_FLAG_UPDATE_REF)
- {
- g_assert (ref_status == CAIRO_STATUS_FILE_NOT_FOUND ||
- ref_status == CAIRO_STATUS_SUCCESS);
-
- if (ref_status == CAIRO_STATUS_SUCCESS)
- ensure_expected_format (&ref_image);
-
- if (ref_status == CAIRO_STATUS_SUCCESS &&
- cairo_image_surface_get_width (ref_image) ==
- cairo_image_surface_get_width (view_image) &&
- cairo_image_surface_get_height (ref_image) ==
- cairo_image_surface_get_height (view_image) &&
- compare_images (ref_image, view_image, NULL, NULL))
- {
- g_message ("Not updating '%s', it didn't change.", ref_image_path);
- }
- else
- {
- g_message ("Updating '%s'.", ref_image_path);
- g_assert_cmpint (cairo_surface_write_to_png (view_image, ref_image_path),
- ==,
- CAIRO_STATUS_SUCCESS);
- }
- }
- else
- {
- const Range gl_fuzz = { -3, 4 };
- PixelDiffStat diff_stat = {};
-
- g_assert_cmpint (ref_status, ==, CAIRO_STATUS_SUCCESS);
- ensure_expected_format (&ref_image);
-
- if (!compare_images (ref_image, view_image, &gl_fuzz,
- &diff_stat))
- {
- cairo_surface_t *diff_image;
- const char *build_dir;
- g_autofree char *ref_image_copy_path = NULL;
- g_autofree char *result_image_path = NULL;
- g_autofree char *diff_image_path = NULL;
-
- diff_image = visualize_difference (ref_image, view_image,
- &gl_fuzz);
-
- build_dir = g_test_get_dir (G_TEST_BUILT);
- ref_image_copy_path =
- g_strdup_printf ("%s/meson-logs/tests/ref-tests/%s_%d.ref.png",
- build_dir,
- test_name, test_seq_no);
- result_image_path =
- g_strdup_printf ("%s/meson-logs/tests/ref-tests/%s_%d.result.png",
- build_dir,
- test_name, test_seq_no);
- diff_image_path =
- g_strdup_printf ("%s/meson-logs/tests/ref-tests/%s_%d.diff.png",
- build_dir,
- test_name, test_seq_no);
-
- g_mkdir_with_parents (g_path_get_dirname (ref_image_copy_path),
- 0755);
-
- g_assert_cmpint (cairo_surface_write_to_png (ref_image,
- ref_image_copy_path),
- ==,
- CAIRO_STATUS_SUCCESS);
- g_assert_cmpint (cairo_surface_write_to_png (view_image,
- result_image_path),
- ==,
- CAIRO_STATUS_SUCCESS);
- g_assert_cmpint (cairo_surface_write_to_png (diff_image,
- diff_image_path),
- ==,
- CAIRO_STATUS_SUCCESS);
-
- g_critical ("Pixel difference exceeds limits "
- "(min: [%d, %d, %d, %d], "
- "max: [%d, %d, %d, %d])\n"
- "See %s, %s, and %s for details.",
- diff_stat.ch[0].min_diff,
- diff_stat.ch[1].min_diff,
- diff_stat.ch[2].min_diff,
- diff_stat.ch[3].min_diff,
- diff_stat.ch[0].max_diff,
- diff_stat.ch[1].max_diff,
- diff_stat.ch[2].max_diff,
- diff_stat.ch[3].max_diff,
- ref_image_copy_path,
- result_image_path,
- diff_image_path);
- }
- }
-
- cairo_surface_destroy (view_image);
- cairo_surface_destroy (ref_image);
-}
-
-MetaReftestFlag
-meta_ref_test_determine_ref_test_flag (void)
-{
- const char *update_tests;
- char **update_test_rules;
- int n_update_test_rules;
- MetaReftestFlag flags;
- int i;
-
- update_tests = g_getenv ("MUTTER_REF_TEST_UPDATE");
- if (!update_tests)
- return META_REFTEST_FLAG_NONE;
-
- if (strcmp (update_tests, "all") == 0)
- return META_REFTEST_FLAG_UPDATE_REF;
-
- update_test_rules = g_strsplit (update_tests, ",", -1);
- n_update_test_rules = g_strv_length (update_test_rules);
- g_assert_cmpint (n_update_test_rules, >, 0);
-
- flags = META_REFTEST_FLAG_NONE;
- for (i = 0; i < n_update_test_rules; i++)
- {
- char *rule = update_test_rules[i];
-
- if (g_regex_match_simple (rule, g_test_get_path (), 0, 0))
- {
- flags |= META_REFTEST_FLAG_UPDATE_REF;
- break;
- }
- }
-
- g_strfreev (update_test_rules);
-
- return flags;
-}
diff --git a/src/tests/meta-ref-test.h b/src/tests/meta-ref-test.h
deleted file mode 100644
index 7a71e388f..000000000
--- a/src/tests/meta-ref-test.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 Red Hat Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef META_REF_TEST_H
-#define META_REF_TEST_H
-
-#include <glib.h>
-
-#include "clutter/clutter/clutter.h"
-#include "meta/boxes.h"
-
-typedef enum _MetaReftestFlag
-{
- META_REFTEST_FLAG_NONE = 0,
- META_REFTEST_FLAG_UPDATE_REF = 1 << 0,
-} MetaReftestFlag;
-
-void meta_ref_test_verify_view (ClutterStageView *view,
- const char *test_name,
- int test_seq_no,
- MetaReftestFlag flags);
-
-MetaReftestFlag meta_ref_test_determine_ref_test_flag (void);
-
-#endif /* META_REF_TEST_H */
diff --git a/src/tests/meta-test-utils-private.h b/src/tests/meta-test-utils-private.h
deleted file mode 100644
index 2b36c58b4..000000000
--- a/src/tests/meta-test-utils-private.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2017-2021 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_TEST_UTILS_PRIVATE_H
-#define META_TEST_UTILS_PRIVATE_H
-
-#include "tests/meta-test-utils.h"
-
-void meta_ensure_test_client_path (int argc,
- char **argv);
-
-#endif /* META_TEST_UTILS_PRIVATE_H */
diff --git a/src/tests/meta-test-utils.c b/src/tests/meta-test-utils.c
deleted file mode 100644
index 24b7106d1..000000000
--- a/src/tests/meta-test-utils.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/* -*- 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/meta-test-utils-private.h"
-
-#include <gio/gio.h>
-#include <string.h>
-#include <X11/Xlib-xcb.h>
-
-#include "core/display-private.h"
-#include "core/window-private.h"
-#include "meta-test/meta-context-test.h"
-#include "wayland/meta-wayland.h"
-#include "wayland/meta-xwayland.h"
-#include "x11/meta-x11-display-private.h"
-
-struct _MetaTestClient
-{
- char *id;
- MetaWindowClientType type;
- GSubprocess *subprocess;
- GCancellable *cancellable;
- GMainLoop *loop;
- GDataOutputStream *in;
- GDataInputStream *out;
-
- char *line;
- GError **error;
-
- MetaAsyncWaiter *waiter;
-};
-
-struct _MetaAsyncWaiter {
- XSyncCounter counter;
- int counter_value;
- XSyncAlarm alarm;
-
- GMainLoop *loop;
- int counter_wait_value;
-};
-
-G_DEFINE_QUARK (meta-test-client-error-quark, meta_test_client_error)
-
-static char *test_client_path;
-
-void
-meta_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");
-}
-
-MetaAsyncWaiter *
-meta_async_waiter_new (void)
-{
- MetaAsyncWaiter *waiter = g_new0 (MetaAsyncWaiter, 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
-meta_async_waiter_destroy (MetaAsyncWaiter *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
-meta_async_waiter_next_value (MetaAsyncWaiter *waiter)
-{
- return waiter->counter_value + 1;
-}
-
-static void
-meta_async_waiter_wait (MetaAsyncWaiter *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
-meta_async_waiter_set_and_wait (MetaAsyncWaiter *waiter)
-{
- MetaDisplay *display = meta_get_display ();
- Display *xdisplay = display->x11_display->xdisplay;
- int wait_value = meta_async_waiter_next_value (waiter);
-
- XSyncValue sync_value;
- XSyncIntToValue (&sync_value, wait_value);
-
- XSyncSetCounter (xdisplay, waiter->counter, sync_value);
- meta_async_waiter_wait (waiter, wait_value);
-}
-
-gboolean
-meta_async_waiter_process_x11_event (MetaAsyncWaiter *waiter,
- MetaX11Display *x11_display,
- XSyncAlarmNotifyEvent *event)
-{
-
- 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 *
-meta_test_client_get_id (MetaTestClient *client)
-{
- return client->id;
-}
-
-static void
-test_client_line_read (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- MetaTestClient *client = user_data;
-
- client->line = g_data_input_stream_read_line_finish_utf8 (client->out,
- result,
- NULL,
- client->error);
- g_main_loop_quit (client->loop);
-}
-
-gboolean
-meta_test_client_do (MetaTestClient *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,
- META_TEST_CLIENT_ERROR,
- META_TEST_CLIENT_ERROR_RUNTIME_ERROR,
- "test client exited");
- }
- goto out;
- }
-
- if (strcmp (line, "OK") != 0)
- {
- g_set_error (error,
- META_TEST_CLIENT_ERROR,
- META_TEST_CLIENT_ERROR_RUNTIME_ERROR,
- "%s", line);
- goto out;
- }
-
- out:
- g_string_free (command, TRUE);
- g_free (line);
-
- return *error == NULL;
-}
-
-gboolean
-meta_test_client_wait (MetaTestClient *client,
- GError **error)
-{
- if (client->type == META_WINDOW_CLIENT_TYPE_WAYLAND)
- {
- return meta_test_client_do (client, error, "sync", NULL);
- }
- else
- {
- int wait_value = meta_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 = meta_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;
-
- meta_async_waiter_wait (client->waiter, wait_value);
- return TRUE;
- }
-}
-
-MetaWindow *
-meta_test_client_find_window (MetaTestClient *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,
- META_TEST_CLIENT_ERROR,
- META_TEST_CLIENT_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
-meta_test_client_wait_for_window_shown (MetaTestClient *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
-meta_test_client_process_x11_event (MetaTestClient *client,
- MetaX11Display *x11_display,
- XSyncAlarmNotifyEvent *event)
-{
- if (client->waiter)
- {
- return meta_async_waiter_process_x11_event (client->waiter,
- x11_display,
- event);
- }
- else
- {
- return FALSE;
- }
-}
-
-static gpointer
-spawn_xwayland (gpointer user_data)
-{
- xcb_connection_t *connection;
-
- connection = xcb_connect (NULL, NULL);
- g_assert_nonnull (connection);
- xcb_disconnect (connection);
-
- return NULL;
-}
-
-MetaTestClient *
-meta_test_client_new (MetaContext *context,
- const char *id,
- MetaWindowClientType type,
- GError **error)
-{
- MetaTestClient *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_context_get_wayland_compositor (context);
- wayland_display_name = meta_wayland_get_wayland_display_name (compositor);
- x11_display_name = meta_wayland_get_public_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 (MetaTestClient, 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)
- {
- MetaDisplay *display = meta_get_display ();
-
- if (!display->x11_display)
- {
- GThread *thread;
-
- thread = g_thread_new ("Mutter Spawn Xwayland Thread",
- spawn_xwayland,
- NULL);
- meta_context_test_wait_for_x11_display (META_CONTEXT_TEST (context));
- g_thread_join (thread);
- }
-
- client->waiter = meta_async_waiter_new ();
- }
-
- return client;
-}
-
-gboolean
-meta_test_client_quit (MetaTestClient *client,
- GError **error)
-{
- if (!meta_test_client_do (client, error, "destroy_all", NULL))
- return FALSE;
-
- if (!meta_test_client_wait (client, error))
- return FALSE;
-
- return TRUE;
-}
-
-void
-meta_test_client_destroy (MetaTestClient *client)
-{
- GError *error = NULL;
-
- if (client->waiter)
- meta_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 *
-meta_test_get_plugin_name (void)
-{
- const char *name;
-
- name = g_getenv ("MUTTER_TEST_PLUGIN_PATH");
- if (name)
- return name;
- else
- return "libdefault";
-}
diff --git a/src/tests/meta-test-utils.h b/src/tests/meta-test-utils.h
deleted file mode 100644
index 2d8673e13..000000000
--- a/src/tests/meta-test-utils.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* -*- 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_TEST_UTILS_H
-#define META_TEST_UTILS_H
-
-#include <glib.h>
-#include <X11/Xlib.h>
-#include <X11/extensions/sync.h>
-
-#include "meta/window.h"
-
-#define META_TEST_CLIENT_ERROR meta_test_client_error_quark ()
-
-typedef enum _MetaClientError
-{
- META_TEST_CLIENT_ERROR_BAD_COMMAND,
- META_TEST_CLIENT_ERROR_RUNTIME_ERROR,
- META_TEST_CLIENT_ERROR_ASSERTION_FAILED
-} MetaClientError;
-
-META_EXPORT
-GQuark meta_test_client_error_quark (void);
-
-typedef struct _MetaAsyncWaiter MetaAsyncWaiter;
-typedef struct _MetaTestClient MetaTestClient;
-
-META_EXPORT
-gboolean meta_async_waiter_process_x11_event (MetaAsyncWaiter *waiter,
- MetaX11Display *display,
- XSyncAlarmNotifyEvent *event);
-
-META_EXPORT
-void meta_async_waiter_set_and_wait (MetaAsyncWaiter *waiter);
-
-META_EXPORT
-MetaAsyncWaiter * meta_async_waiter_new (void);
-
-META_EXPORT
-void meta_async_waiter_destroy (MetaAsyncWaiter *waiter);
-
-META_EXPORT
-char * meta_test_client_get_id (MetaTestClient *client);
-
-META_EXPORT
-gboolean meta_test_client_process_x11_event (MetaTestClient *client,
- MetaX11Display *x11_display,
- XSyncAlarmNotifyEvent *event);
-
-META_EXPORT
-gboolean meta_test_client_wait (MetaTestClient *client,
- GError **error);
-
-META_EXPORT
-gboolean meta_test_client_do (MetaTestClient *client,
- GError **error,
- ...) G_GNUC_NULL_TERMINATED;
-
-META_EXPORT
-MetaWindow * meta_test_client_find_window (MetaTestClient *client,
- const char *window_id,
- GError **error);
-
-META_EXPORT
-void meta_test_client_wait_for_window_shown (MetaTestClient *client,
- MetaWindow *window);
-
-META_EXPORT
-gboolean meta_test_client_quit (MetaTestClient *client,
- GError **error);
-
-META_EXPORT
-MetaTestClient * meta_test_client_new (MetaContext *context,
- const char *id,
- MetaWindowClientType type,
- GError **error);
-
-META_EXPORT
-void meta_test_client_destroy (MetaTestClient *client);
-
-META_EXPORT
-const char * meta_test_get_plugin_name (void);
-
-#endif /* TEST_UTILS_H */
diff --git a/src/tests/meta-test/meson.build b/src/tests/meta-test/meson.build
deleted file mode 100644
index 8cb4e9a9e..000000000
--- a/src/tests/meta-test/meson.build
+++ /dev/null
@@ -1,9 +0,0 @@
-mutter_test_includesubdir = join_paths(pkgname, 'meta-test')
-
-mutter_test_public_headers = [
- 'meta-context-test.h',
-]
-
-install_headers(mutter_test_public_headers,
- subdir: mutter_test_includesubdir
-)
diff --git a/src/tests/meta-test/meta-context-test.h b/src/tests/meta-test/meta-context-test.h
deleted file mode 100644
index b1f678030..000000000
--- a/src/tests/meta-test/meta-context-test.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2021 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_CONTEXT_TEST_H
-#define META_CONTEXT_TEST_H
-
-#include <meta/common.h>
-#include <meta/meta-context.h>
-
-typedef enum _MetaContextTestType
-{
- META_CONTEXT_TEST_TYPE_HEADLESS,
- META_CONTEXT_TEST_TYPE_NESTED,
-} MetaContextTestType;
-
-typedef enum _MetaContextTestFlag
-{
- META_CONTEXT_TEST_FLAG_NONE = 0,
- META_CONTEXT_TEST_FLAG_TEST_CLIENT = 1 << 0,
- META_CONTEXT_TEST_FLAG_NO_X11 = 1 << 1,
-} MetaContextTestFlag;
-
-#define META_TYPE_CONTEXT_TEST (meta_context_test_get_type ())
-META_EXPORT
-G_DECLARE_DERIVABLE_TYPE (MetaContextTest, meta_context_test,
- META, CONTEXT_TEST,
- MetaContext)
-
-META_EXPORT
-MetaContext * meta_create_test_context (MetaContextTestType type,
- MetaContextTestFlag flags);
-
-META_EXPORT
-int meta_context_test_run_tests (MetaContextTest *context_test);
-
-META_EXPORT
-void meta_context_test_wait_for_x11_display (MetaContextTest *context_test);
-
-#endif /* META_CONTEXT_TEST_H */
diff --git a/src/tests/meta-wayland-test-driver.c b/src/tests/meta-wayland-test-driver.c
deleted file mode 100644
index 0eecf8d45..000000000
--- a/src/tests/meta-wayland-test-driver.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * 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/meta-wayland-test-driver.h"
-
-#include <wayland-server.h>
-
-#include "wayland/meta-wayland-actor-surface.h"
-#include "wayland/meta-wayland-private.h"
-
-#include "test-driver-server-protocol.h"
-
-enum
-{
- SYNC_POINT,
-
- N_SIGNALS
-};
-
-static int signals[N_SIGNALS];
-
-struct _MetaWaylandTestDriver
-{
- GObject parent;
-
- struct wl_global *test_driver;
-};
-
-G_DEFINE_TYPE (MetaWaylandTestDriver, meta_wayland_test_driver,
- G_TYPE_OBJECT)
-
-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 void
-sync_point (struct wl_client *client,
- struct wl_resource *resource,
- uint32_t sequence)
-{
- MetaWaylandTestDriver *test_driver = wl_resource_get_user_data (resource);
-
- g_signal_emit (test_driver, signals[SYNC_POINT], 0,
- sequence,
- client);
-}
-
-static const struct test_driver_interface meta_test_driver_interface = {
- sync_actor_destroy,
- sync_point,
-};
-
-static void
-bind_test_driver (struct wl_client *client,
- void *user_data,
- uint32_t version,
- uint32_t id)
-{
- MetaWaylandTestDriver *test_driver = user_data;
- struct wl_resource *resource;
-
- resource = wl_resource_create (client, &test_driver_interface,
- version, id);
- wl_resource_set_implementation (resource, &meta_test_driver_interface,
- test_driver, NULL);
-}
-
-static void
-meta_wayland_test_driver_finalize (GObject *object)
-{
- MetaWaylandTestDriver *test_driver = META_WAYLAND_TEST_DRIVER (object);
-
- g_clear_pointer (&test_driver->test_driver, wl_global_destroy);
-
- G_OBJECT_CLASS (meta_wayland_test_driver_parent_class)->finalize (object);
-}
-
-static void
-meta_wayland_test_driver_class_init (MetaWaylandTestDriverClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = meta_wayland_test_driver_finalize;
-
- signals[SYNC_POINT] =
- g_signal_new ("sync-point",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 2,
- G_TYPE_UINT,
- G_TYPE_POINTER);
-}
-
-static void
-meta_wayland_test_driver_init (MetaWaylandTestDriver *test_driver)
-{
-}
-
-MetaWaylandTestDriver *
-meta_wayland_test_driver_new (MetaWaylandCompositor *compositor)
-{
- MetaWaylandTestDriver *test_driver;
-
- test_driver = g_object_new (META_TYPE_WAYLAND_TEST_DRIVER, NULL);
- test_driver->test_driver = wl_global_create (compositor->wayland_display,
- &test_driver_interface,
- 1,
- test_driver, bind_test_driver);
- if (!test_driver->test_driver)
- g_error ("Failed to register a global wl-subcompositor object");
-
- return test_driver;
-}
diff --git a/src/tests/meta-wayland-test-driver.h b/src/tests/meta-wayland-test-driver.h
deleted file mode 100644
index ccbfe1312..000000000
--- a/src/tests/meta-wayland-test-driver.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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_WAYLAND_TEST_DRIVER_H
-#define META_WAYLAND_TEST_DRIVER_H
-
-#include "wayland/meta-wayland.h"
-
-#define META_TYPE_WAYLAND_TEST_DRIVER (meta_wayland_test_driver_get_type ())
-G_DECLARE_FINAL_TYPE (MetaWaylandTestDriver, meta_wayland_test_driver,
- META, WAYLAND_TEST_DRIVER,
- GObject)
-
-MetaWaylandTestDriver * meta_wayland_test_driver_new (MetaWaylandCompositor *compositor);
-
-#endif /* META_WAYLAND_TEST_DRIVER_H */
diff --git a/src/tests/migration/basic-new.xml b/src/tests/migration/basic-new.xml
deleted file mode 100644
index 569d1e7cd..000000000
--- a/src/tests/migration/basic-new.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<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
deleted file mode 100644
index c47dc55c1..000000000
--- a/src/tests/migration/basic-old.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<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
deleted file mode 100644
index 9f875c21f..000000000
--- a/src/tests/migration/first-rotated-new.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<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
deleted file mode 100644
index b00a35963..000000000
--- a/src/tests/migration/first-rotated-old.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<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
deleted file mode 100644
index 9e71069de..000000000
--- a/src/tests/migration/oneoff-new-finished.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<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&apos;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&apos;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
deleted file mode 100644
index 02d85f4de..000000000
--- a/src/tests/migration/oneoff-new.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<monitors version="2">
- <configuration>
- <migrated/>
- <logicalmonitor>
- <x>0</x>
- <y>0</y>
- <primary>yes</primary>
- <monitor>
- <monitorspec>
- <connector>DP-1</connector>
- <vendor>MetaProduct&apos;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&apos;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
deleted file mode 100644
index 229379146..000000000
--- a/src/tests/migration/oneoff-old.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<monitors version="1">
- <configuration>
- <clone>no</clone>
- <output name="DP-1">
- <vendor>MetaProduct&apos;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&apos;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
deleted file mode 100644
index a67c376dc..000000000
--- a/src/tests/migration/rotated-new-finished.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<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&apos;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
deleted file mode 100644
index f41964546..000000000
--- a/src/tests/migration/rotated-new.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<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&apos;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
deleted file mode 100644
index d252f0117..000000000
--- a/src/tests/migration/rotated-old.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<monitors version="1">
- <configuration>
- <clone>no</clone>
- <output name="DP-1">
- <vendor>MetaProduct&apos;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
deleted file mode 100644
index 9fe285ac8..000000000
--- a/src/tests/migration/tiled-new.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<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
deleted file mode 100644
index 8235b31e3..000000000
--- a/src/tests/migration/tiled-old.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<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
deleted file mode 100644
index fa4090a11..000000000
--- a/src/tests/migration/wiggle-new-discarded.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<monitors version="2">
-</monitors>
diff --git a/src/tests/migration/wiggle-new-finished.xml b/src/tests/migration/wiggle-new-finished.xml
deleted file mode 100644
index c4a56556f..000000000
--- a/src/tests/migration/wiggle-new-finished.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<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&apos;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
deleted file mode 100644
index cd1acf717..000000000
--- a/src/tests/migration/wiggle-new.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<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&apos;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
deleted file mode 100644
index b0c996c03..000000000
--- a/src/tests/migration/wiggle-old.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<monitors version="1">
- <configuration>
- <clone>no</clone>
- <output name="DP-1">
- <vendor>MetaProduct&apos;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
deleted file mode 100644
index bb2ac62cc..000000000
--- a/src/tests/monitor-config-migration-unit-tests.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* -*- 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_cmpstr (expected_data, ==, migrated_data);
-
- 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
deleted file mode 100644
index a8d18de9a..000000000
--- a/src/tests/monitor-config-migration-unit-tests.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 59a42bef5..000000000
--- a/src/tests/monitor-configs/first-rotated.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<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&apos;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&apos;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
deleted file mode 100644
index 991a47d14..000000000
--- a/src/tests/monitor-configs/fractional-scale.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<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&apos;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
deleted file mode 100644
index 2a0d43912..000000000
--- a/src/tests/monitor-configs/high-precision-fractional-scale.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<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&apos;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
deleted file mode 100644
index b02f1cf94..000000000
--- a/src/tests/monitor-configs/interlaced.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<monitors version="2">
- <configuration>
- <logicalmonitor>
- <x>0</x>
- <y>0</y>
- <primary>yes</primary>
- <monitor>
- <monitorspec>
- <connector>DP-1</connector>
- <vendor>MetaProduct&apos;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
deleted file mode 100644
index d5bfecb11..000000000
--- a/src/tests/monitor-configs/lid-scale.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<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&apos;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
deleted file mode 100644
index 1d43c98bd..000000000
--- a/src/tests/monitor-configs/lid-switch.xml
+++ /dev/null
@@ -1,91 +0,0 @@
-<monitors version="2">
- <configuration>
- <logicalmonitor>
- <x>0</x>
- <y>0</y>
- <primary>yes</primary>
- <monitor>
- <monitorspec>
- <connector>eDP-1</connector>
- <vendor>MetaProduct&apos;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&apos;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&apos;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&apos;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
deleted file mode 100644
index 7866b4aae..000000000
--- a/src/tests/monitor-configs/mirrored.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<monitors version="2">
- <configuration>
- <logicalmonitor>
- <x>0</x>
- <y>0</y>
- <primary>yes</primary>
- <monitor>
- <monitorspec>
- <connector>DP-1</connector>
- <vendor>MetaProduct&apos;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&apos;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
deleted file mode 100644
index 5f46583eb..000000000
--- a/src/tests/monitor-configs/non-preferred-tiled-custom-resolution.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<monitors version="2">
- <configuration>
- <logicalmonitor>
- <x>0</x>
- <y>0</y>
- <primary>yes</primary>
- <monitor>
- <monitorspec>
- <connector>DP-2</connector>
- <vendor>MetaProduct&apos;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
deleted file mode 100644
index 63e641cf0..000000000
--- a/src/tests/monitor-configs/oneoff.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<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&apos;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&apos;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
deleted file mode 100644
index ce78b1099..000000000
--- a/src/tests/monitor-configs/primary.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<monitors version="2">
- <configuration>
- <logicalmonitor>
- <x>0</x>
- <y>0</y>
- <primary>no</primary>
- <monitor>
- <monitorspec>
- <connector>DP-1</connector>
- <vendor>MetaProduct&apos;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&apos;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
deleted file mode 100644
index c011900ef..000000000
--- a/src/tests/monitor-configs/scale.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<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&apos;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
deleted file mode 100644
index 14ba91b4e..000000000
--- a/src/tests/monitor-configs/second-rotated-tiled.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<monitors version="2">
- <configuration>
- <logicalmonitor>
- <x>0</x>
- <y>256</y>
- <primary>yes</primary>
- <monitor>
- <monitorspec>
- <connector>DP-1</connector>
- <vendor>MetaProduct&apos;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&apos;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
deleted file mode 100644
index 885b2bf83..000000000
--- a/src/tests/monitor-configs/second-rotated.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<monitors version="2">
- <configuration>
- <logicalmonitor>
- <x>0</x>
- <y>256</y>
- <primary>yes</primary>
- <monitor>
- <monitorspec>
- <connector>DP-1</connector>
- <vendor>MetaProduct&apos;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&apos;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
deleted file mode 100644
index cc01b4a63..000000000
--- a/src/tests/monitor-configs/single.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<monitors version="2">
- <configuration>
- <logicalmonitor>
- <x>0</x>
- <y>0</y>
- <primary>yes</primary>
- <monitor>
- <monitorspec>
- <connector>DP-1</connector>
- <vendor>MetaProduct&apos;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
deleted file mode 100644
index 85939dd1f..000000000
--- a/src/tests/monitor-configs/tiled-custom-resolution.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<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&apos;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
deleted file mode 100644
index 0ed149ffc..000000000
--- a/src/tests/monitor-configs/tiled.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<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&apos;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
deleted file mode 100644
index 3ab02476d..000000000
--- a/src/tests/monitor-configs/underscanning.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<monitors version="2">
- <configuration>
- <logicalmonitor>
- <x>0</x>
- <y>0</y>
- <primary>yes</primary>
- <monitor>
- <monitorspec>
- <connector>DP-1</connector>
- <vendor>MetaProduct&apos;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
deleted file mode 100644
index 0546b055c..000000000
--- a/src/tests/monitor-configs/vertical.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<monitors version="2">
- <configuration>
- <logicalmonitor>
- <x>0</x>
- <y>0</y>
- <primary>yes</primary>
- <monitor>
- <monitorspec>
- <connector>DP-1</connector>
- <vendor>MetaProduct&apos;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&apos;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
deleted file mode 100644
index b9d5622b7..000000000
--- a/src/tests/monitor-store-unit-tests.c
+++ /dev/null
@@ -1,864 +0,0 @@
-/* -*- 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 _MonitorStoreTestCaseMonitorMode
-{
- int width;
- int height;
- float refresh_rate;
- MetaCrtcModeFlag flags;
-} MonitorStoreTestCaseMonitorMode;
-
-typedef struct _MonitorStoreTestCaseMonitor
-{
- const char *connector;
- const char *vendor;
- const char *product;
- const char *serial;
- MonitorStoreTestCaseMonitorMode mode;
- gboolean is_underscanning;
-} MonitorStoreTestCaseMonitor;
-
-typedef struct _MonitorStoreTestCaseLogicalMonitor
-{
- MetaRectangle layout;
- float scale;
- MetaMonitorTransform transform;
- gboolean is_primary;
- gboolean is_presentation;
- MonitorStoreTestCaseMonitor monitors[MAX_N_MONITORS];
- int n_monitors;
-} MonitorStoreTestCaseLogicalMonitor;
-
-typedef struct _MonitorStoreTestConfiguration
-{
- MonitorStoreTestCaseLogicalMonitor 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;
- MonitorStoreTestCaseMonitor *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_store_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;
- MonitorStoreTestCaseMonitor *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_store_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_store_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_store_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_store_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_store_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_store_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_store_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_store_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_store_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_store_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_store_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_store_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_store_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
deleted file mode 100644
index 2e9496d32..000000000
--- a/src/tests/monitor-store-unit-tests.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 933b8912a..000000000
--- a/src/tests/monitor-test-utils.c
+++ /dev/null
@@ -1,780 +0,0 @@
-/* -*- 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-crtc.h"
-#include "backends/meta-logical-monitor.h"
-#include "backends/meta-monitor-config-manager.h"
-#include "backends/meta-monitor-config-store.h"
-#include "backends/meta-output.h"
-#include "tests/meta-test-utils.h"
-#include "meta-backend-test.h"
-
-MetaGpu *
-test_get_gpu (void)
-{
- return META_GPU (meta_backend_get_gpus (meta_get_backend ())->data);
-}
-
-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);
-}
-
-static MetaOutput *
-output_from_winsys_id (MetaBackend *backend,
- uint64_t output_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 (meta_output_get_id (output) == output_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)
- {
- const MetaCrtcModeInfo *crtc_mode_info =
- meta_crtc_mode_get_info (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_info->refresh_rate);
- g_assert_cmpint (flags, ==, (crtc_mode_info->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
- {
- const MetaCrtcConfig *crtc_config;
- MetaLogicalMonitor *logical_monitor;
-
- g_assert_nonnull (crtc);
-
- crtc_config = meta_crtc_get_config (crtc);
- 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 (MetaMonitorManager *monitor_manager,
- MonitorTestCaseLogicalMonitor *test_logical_monitor,
- GList **all_crtcs)
-{
- 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;
-
- g_assert (meta_output_get_monitor (output) == monitor);
-
- if (meta_output_is_primary (output))
- {
- g_assert_null (primary_output);
- primary_output = output;
- }
-
- crtc = meta_output_get_assigned_crtc (output);
- if (crtc)
- {
- g_assert (meta_monitor_get_logical_monitor (monitor) ==
- logical_monitor);
- g_assert (g_list_find ((GList *) meta_crtc_get_outputs (crtc),
- output));
- *all_crtcs = g_list_remove (*all_crtcs, crtc);
- }
- else
- {
- g_assert_null (crtc);
- }
-
- g_assert_cmpint (logical_monitor->is_presentation,
- ==,
- meta_output_is_presentation (output));
- }
- }
-
- if (logical_monitor == monitor_manager->primary_logical_monitor)
- g_assert_nonnull (primary_output);
-}
-
-void
-check_monitor_configuration (MonitorTestCaseExpect *expect)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaRenderer *renderer = meta_backend_get_renderer (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 *all_crtcs;
- GList *l;
- int i;
-
- g_assert_cmpint (monitor_manager->screen_width,
- ==,
- expect->screen_width);
- g_assert_cmpint (monitor_manager->screen_height,
- ==,
- expect->screen_height);
- g_assert_cmpint ((int) g_list_length (meta_gpu_get_outputs (gpu)),
- ==,
- expect->n_outputs);
- g_assert_cmpint ((int) g_list_length (meta_gpu_get_crtcs (gpu)),
- ==,
- expect->n_crtcs);
-
- tiled_monitor_count =
- meta_monitor_manager_test_get_tiled_monitor_count (monitor_manager_test);
- g_assert_cmpint (tiled_monitor_count,
- ==,
- expect->n_tiled_monitors);
-
- monitors = meta_monitor_manager_get_monitors (monitor_manager);
- g_assert_cmpint ((int) g_list_length (monitors),
- ==,
- expect->n_monitors);
- for (l = monitors, i = 0; l; l = l->next, i++)
- {
- MetaMonitor *monitor = l->data;
- MetaOutput *main_output;
- const MetaOutputInfo *main_output_info;
- 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),
- ==,
- 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 = expect->monitors[i].outputs[j];
-
- g_assert (output == output_from_winsys_id (backend, winsys_id));
- g_assert_cmpint (expect->monitors[i].is_underscanning,
- ==,
- meta_output_is_underscanning (output));
- }
-
- meta_monitor_get_physical_dimensions (monitor, &width_mm, &height_mm);
- g_assert_cmpint (width_mm,
- ==,
- expect->monitors[i].width_mm);
- g_assert_cmpint (height_mm,
- ==,
- expect->monitors[i].height_mm);
-
- main_output = meta_monitor_get_main_output (monitor);
- main_output_info = meta_output_get_info (main_output);
- g_assert_cmpstr (meta_monitor_get_connector (monitor), ==,
- main_output_info->name);
- g_assert_cmpstr (meta_monitor_get_vendor (monitor), ==,
- main_output_info->vendor);
- g_assert_cmpstr (meta_monitor_get_product (monitor), ==,
- main_output_info->product);
- g_assert_cmpstr (meta_monitor_get_serial (monitor), ==,
- main_output_info->serial);
- g_assert_cmpint (meta_monitor_get_connector_type (monitor), ==,
- main_output_info->connector_type);
-
- modes = meta_monitor_get_modes (monitor);
- g_assert_cmpint (g_list_length (modes),
- ==,
- 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,
- ==,
- expect->monitors[i].modes[j].width);
- g_assert_cmpint (height,
- ==,
- expect->monitors[i].modes[j].height);
- g_assert_cmpfloat (refresh_rate,
- ==,
- expect->monitors[i].modes[j].refresh_rate);
- g_assert_cmpint (flags,
- ==,
- expect->monitors[i].modes[j].flags);
-
- data = (CheckMonitorModeData) {
- .backend = backend,
- .expect_crtc_mode_iter =
- 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 = 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 =
- 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,
- ==,
- 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 (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 =
- &expect->logical_monitors[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);
- }
-
- all_crtcs = NULL;
- for (l = meta_backend_get_gpus (backend); l; l = l->next)
- {
- MetaGpu *gpu = l->data;
-
- all_crtcs = g_list_concat (all_crtcs,
- g_list_copy (meta_gpu_get_crtcs (gpu)));
- }
-
- for (i = 0; i < expect->n_logical_monitors; i++)
- {
- MonitorTestCaseLogicalMonitor *test_logical_monitor =
- &expect->logical_monitors[i];
-
- check_logical_monitor (monitor_manager, test_logical_monitor, &all_crtcs);
- }
- g_assert_cmpint (n_logical_monitors, ==, i);
-
- for (l = all_crtcs; l; l = l->next)
- {
- MetaCrtc *crtc = l->data;
-
- g_assert_null (meta_crtc_get_outputs (crtc));
- }
- g_list_free (all_crtcs);
-
- crtcs = meta_gpu_get_crtcs (gpu);
- for (l = crtcs, i = 0; l; l = l->next, i++)
- {
- MetaCrtc *crtc = l->data;
- const MetaCrtcConfig *crtc_config = meta_crtc_get_config (crtc);
-
- if (expect->crtcs[i].current_mode == -1)
- {
- g_assert_null (meta_crtc_get_outputs (crtc));
- g_assert_null (crtc_config);
- }
- else
- {
- MetaCrtcMode *expected_current_mode;
- const GList *l_output;
- MetaRendererView *view;
- cairo_rectangle_int_t view_layout;
-
- for (l_output = meta_crtc_get_outputs (crtc);
- l_output;
- l_output = l_output->next)
- {
- MetaOutput *output = l_output->data;
-
- g_assert (meta_output_get_assigned_crtc (output) == crtc);
- g_assert_null (g_list_find (l_output->next, output));
- }
-
- g_assert_nonnull (crtc_config);
-
- expected_current_mode =
- g_list_nth_data (meta_gpu_get_modes (gpu),
- expect->crtcs[i].current_mode);
- g_assert (crtc_config->mode == expected_current_mode);
-
- g_assert_cmpuint (crtc_config->transform,
- ==,
- expect->crtcs[i].transform);
-
- g_assert_cmpfloat_with_epsilon (crtc_config->layout.origin.x,
- expect->crtcs[i].x,
- FLT_EPSILON);
- g_assert_cmpfloat_with_epsilon (crtc_config->layout.origin.y,
- expect->crtcs[i].y,
- FLT_EPSILON);
-
- view = meta_renderer_get_view_for_crtc (renderer, crtc);
- g_assert_nonnull (view);
- clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (view),
- &view_layout);
- g_assert_cmpfloat_with_epsilon (crtc_config->layout.origin.x,
- view_layout.x,
- FLT_EPSILON);
- g_assert_cmpfloat_with_epsilon (crtc_config->layout.origin.y,
- view_layout.y,
- FLT_EPSILON);
- g_assert_cmpfloat_with_epsilon (crtc_config->layout.size.width,
- view_layout.width,
- FLT_EPSILON);
- g_assert_cmpfloat_with_epsilon (crtc_config->layout.size.height,
- view_layout.height,
- FLT_EPSILON);
- }
- }
-}
-
-MetaMonitorTestSetup *
-create_monitor_test_setup (MonitorTestCaseSetup *setup,
- MonitorTestFlag flags)
-{
- MetaMonitorTestSetup *test_setup;
- int i;
- int n_laptop_panels = 0;
- int n_normal_panels = 0;
-
- test_setup = g_new0 (MetaMonitorTestSetup, 1);
-
- test_setup->modes = NULL;
- for (i = 0; i < setup->n_modes; i++)
- {
- g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL;
- MetaCrtcMode *mode;
-
- crtc_mode_info = meta_crtc_mode_info_new ();
- crtc_mode_info->width = setup->modes[i].width;
- crtc_mode_info->height = setup->modes[i].height;
- crtc_mode_info->refresh_rate = setup->modes[i].refresh_rate;
- crtc_mode_info->flags = setup->modes[i].flags;
-
- mode = g_object_new (META_TYPE_CRTC_MODE,
- "id", (uint64_t) i,
- "info", crtc_mode_info,
- NULL);
-
- test_setup->modes = g_list_append (test_setup->modes, mode);
- }
-
- test_setup->crtcs = NULL;
- for (i = 0; i < setup->n_crtcs; i++)
- {
- MetaCrtc *crtc;
-
- crtc = g_object_new (META_TYPE_CRTC_TEST,
- "id", (uint64_t) i + 1,
- "gpu", test_get_gpu (),
- NULL);
-
- test_setup->crtcs = g_list_append (test_setup->crtcs, crtc);
- }
-
- test_setup->outputs = NULL;
- for (i = 0; i < 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;
- g_autoptr (MetaOutputInfo) output_info = NULL;
-
- crtc_index = setup->outputs[i].crtc;
- if (crtc_index == -1)
- crtc = NULL;
- else
- crtc = g_list_nth_data (test_setup->crtcs, crtc_index);
-
- preferred_mode_index = 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 = setup->outputs[i].n_modes;
- modes = g_new0 (MetaCrtcMode *, n_modes);
- for (j = 0; j < n_modes; j++)
- {
- int mode_index;
-
- mode_index = setup->outputs[i].modes[j];
- modes[j] = g_list_nth_data (test_setup->modes, mode_index);
- }
-
- n_possible_crtcs = 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 = setup->outputs[i].possible_crtcs[j];
- possible_crtcs[j] = g_list_nth_data (test_setup->crtcs,
- possible_crtc_index);
- }
-
- scale = setup->outputs[i].scale;
- if (scale < 1)
- scale = 1;
-
- is_laptop_panel = setup->outputs[i].is_laptop_panel;
-
- serial = setup->outputs[i].serial;
- if (!serial)
- serial = "0x123456";
-
- output_info = meta_output_info_new ();
-
- output_info->name = (is_laptop_panel
- ? g_strdup_printf ("eDP-%d", ++n_laptop_panels)
- : g_strdup_printf ("DP-%d", ++n_normal_panels));
- output_info->vendor = g_strdup ("MetaProduct's Inc.");
- output_info->product = g_strdup ("MetaMonitor");
- output_info->serial = g_strdup (serial);
- if (setup->outputs[i].hotplug_mode)
- {
- output_info->hotplug_mode_update = TRUE;
- output_info->suggested_x = setup->outputs[i].suggested_x;
- output_info->suggested_y = setup->outputs[i].suggested_y;
- }
- else if (flags & MONITOR_TEST_FLAG_NO_STORED)
- {
- output_info->hotplug_mode_update = TRUE;
- output_info->suggested_x = -1;
- output_info->suggested_y = -1;
- }
- output_info->width_mm = setup->outputs[i].width_mm;
- output_info->height_mm = setup->outputs[i].height_mm;
- output_info->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
- output_info->preferred_mode = preferred_mode;
- output_info->n_modes = n_modes;
- output_info->modes = modes;
- output_info->n_possible_crtcs = n_possible_crtcs;
- output_info->possible_crtcs = possible_crtcs;
- output_info->n_possible_clones = 0;
- output_info->possible_clones = NULL;
- output_info->connector_type = (is_laptop_panel ? META_CONNECTOR_TYPE_eDP
- : META_CONNECTOR_TYPE_DisplayPort);
- output_info->tile_info = setup->outputs[i].tile_info;
- output_info->panel_orientation_transform =
- setup->outputs[i].panel_orientation_transform;
-
- output = g_object_new (META_TYPE_OUTPUT_TEST,
- "id", (uint64_t) i,
- "gpu", test_get_gpu (),
- "info", output_info,
- NULL);
-
- output_test = META_OUTPUT_TEST (output);
- output_test->scale = scale;
-
- if (crtc)
- {
- MetaOutputAssignment output_assignment;
-
- output_assignment = (MetaOutputAssignment) {
- .is_underscanning = setup->outputs[i].is_underscanning,
- };
- meta_output_assign_crtc (output, crtc, &output_assignment);
- }
-
- test_setup->outputs = g_list_append (test_setup->outputs, output);
- }
-
- return test_setup;
-}
diff --git a/src/tests/monitor-test-utils.h b/src/tests/monitor-test-utils.h
deleted file mode 100644
index 3ebf1ff79..000000000
--- a/src/tests/monitor-test-utils.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/* -*- 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>
-
-#include "tests/meta-monitor-manager-test.h"
-#include "backends/meta-crtc.h"
-#include "backends/meta-output.h"
-
-#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;
- gboolean hotplug_mode;
- int suggested_x;
- int suggested_y;
-} 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;
-
-struct _MonitorTestCase
-{
- MonitorTestCaseSetup setup;
- MonitorTestCaseExpect expect;
-};
-
-MetaGpu * test_get_gpu (void);
-
-void set_custom_monitor_config (const char *filename);
-
-char * read_file (const char *file_path);
-
-void check_monitor_configuration (MonitorTestCaseExpect *expect);
-
-MetaMonitorTestSetup * create_monitor_test_setup (MonitorTestCaseSetup *setup,
- MonitorTestFlag flags);
-
-#endif /* MONITOR_TEST_UTILS_H */
diff --git a/src/tests/monitor-transform-tests.c b/src/tests/monitor-transform-tests.c
deleted file mode 100644
index 871a06b10..000000000
--- a/src/tests/monitor-transform-tests.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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_invert (META_MONITOR_TRANSFORM_90),
- .expect = META_MONITOR_TRANSFORM_270,
- },
- {
- .transform = META_MONITOR_TRANSFORM_FLIPPED,
- .other = meta_monitor_transform_invert (META_MONITOR_TRANSFORM_90),
- .expect = META_MONITOR_TRANSFORM_FLIPPED_270,
- },
- {
- .transform = META_MONITOR_TRANSFORM_FLIPPED_180,
- .other = meta_monitor_transform_invert (META_MONITOR_TRANSFORM_270),
- .expect = META_MONITOR_TRANSFORM_FLIPPED_270,
- },
- {
- .transform = META_MONITOR_TRANSFORM_FLIPPED_180,
- .other =
- meta_monitor_transform_invert (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
deleted file mode 100644
index f6d019132..000000000
--- a/src/tests/monitor-transform-tests.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 6d6d5fce4..000000000
--- a/src/tests/monitor-unit-tests.c
+++ /dev/null
@@ -1,5868 +0,0 @@
-/* -*- 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/meta-test-utils.h"
-#include "tests/unit-tests.h"
-#include "x11/meta-x11-display-private.h"
-
-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 MetaTestClient *wayland_monitor_test_client = NULL;
-static MetaTestClient *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 meta_test_client_process_x11_event (x11_monitor_test_client,
- x11_display, event);
-}
-
-static void
-create_monitor_test_clients (MetaContext *context)
-{
- GError *error = NULL;
-
- wayland_monitor_test_client = meta_test_client_new (context,
- 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 = meta_test_client_new (context,
- 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);
-
- meta_x11_display_set_alarm_filter (meta_get_display ()->x11_display,
- monitor_tests_alarm_filter, NULL);
-
- if (!meta_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 (!meta_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 (!meta_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 (!meta_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 (MetaTestClient *test_client)
-{
- GError *error = NULL;
-
- if (!meta_test_client_wait (test_client, &error))
- {
- g_error ("Failed to sync test client '%s': %s",
- meta_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 (!meta_test_client_quit (wayland_monitor_test_client, &error))
- g_error ("Failed to quit Wayland test client: %s", error->message);
-
- if (!meta_test_client_quit (x11_monitor_test_client, &error))
- g_error ("Failed to quit X11 test client: %s", error->message);
-
- meta_test_client_destroy (wayland_monitor_test_client);
- meta_test_client_destroy (x11_monitor_test_client);
-
- meta_x11_display_set_alarm_filter (meta_get_display ()->x11_display,
- NULL, NULL);
-}
-
-static void
-meta_test_monitor_initial_linear_config (void)
-{
- check_monitor_configuration (&initial_test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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,
- .hotplug_mode = TRUE,
- .suggested_x = 1024,
- .suggested_y = 758,
- },
- {
- .crtc = 1,
- .modes = { 1 },
- .n_modes = 1,
- .preferred_mode = 1,
- .possible_crtcs = { 1 },
- .n_possible_crtcs = 1,
- .width_mm = 220,
- .height_mm = 124,
- .hotplug_mode = TRUE,
- .suggested_x = 0,
- .suggested_y = 0,
- }
- },
- .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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
-
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- 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.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-
- 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.expect);
- check_monitor_test_clients_state ();
-
- 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.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- 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.expect);
- check_monitor_test_clients_state ();
-
- 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.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- 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.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- 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.expect);
- check_monitor_test_clients_state ();
-
- /* 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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-
- /* 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.setup,
- 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.expect);
- check_monitor_test_clients_state ();
-
- /*
- * 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.setup,
- 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.expect);
- check_monitor_test_clients_state ();
-
- /* 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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-
- /* 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.setup,
- 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.expect);
- check_monitor_test_clients_state ();
-
- /* Lid opened */
-
- test_setup = create_monitor_test_setup (&test_case.setup,
- 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.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("lid-scale.xml");
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-
- 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.expect);
- check_monitor_test_clients_state ();
-
- 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.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
-
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-
- if (!meta_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 (!meta_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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
-
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-static void
-meta_test_monitor_switch_external_without_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
- },
- {
- .crtc = 1,
- .modes = { 0 },
- .n_modes = 1,
- .preferred_mode = 0,
- .possible_crtcs = { 1 },
- .n_possible_crtcs = 1,
- .width_mm = 222,
- .height_mm = 125,
- .is_laptop_panel = TRUE
- }
- },
- .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 = 222,
- .height_mm = 125
- }
- },
- .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 = 2048,
- .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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
-
- meta_monitor_manager_switch_config (monitor_manager,
- META_MONITOR_SWITCH_CONFIG_EXTERNAL);
- check_monitor_configuration (&test_case.expect);
-
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("vertical.xml");
- emulate_hotplug (test_setup);
-
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("primary.xml");
- emulate_hotplug (test_setup);
-
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("underscanning.xml");
- emulate_hotplug (test_setup);
-
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("scale.xml");
- emulate_hotplug (test_setup);
-
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("fractional-scale.xml");
- emulate_hotplug (test_setup);
-
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("high-precision-fractional-scale.xml");
- emulate_hotplug (test_setup);
-
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("tiled.xml");
- emulate_hotplug (test_setup);
-
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("tiled-custom-resolution.xml");
- emulate_hotplug (test_setup);
-
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("non-preferred-tiled-custom-resolution.xml");
- emulate_hotplug (test_setup);
-
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("mirrored.xml");
- emulate_hotplug (test_setup);
-
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("first-rotated.xml");
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("second-rotated.xml");
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("second-rotated-tiled.xml");
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("second-rotated-tiled.xml");
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("second-rotated.xml");
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("interlaced.xml");
- emulate_hotplug (test_setup);
-
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("oneoff.xml");
- emulate_hotplug (test_setup);
-
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- MONITOR_TEST_FLAG_NONE);
- set_custom_monitor_config ("lid-switch.xml");
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-
- /* 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.setup,
- MONITOR_TEST_FLAG_NONE);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-
- /* 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.setup,
- MONITOR_TEST_FLAG_NONE);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-
- /* 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.setup,
- MONITOR_TEST_FLAG_NONE);
- emulate_hotplug (test_setup);
- check_monitor_configuration (&test_case.expect);
- check_monitor_test_clients_state ();
-}
-
-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.setup,
- 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.expect);
- check_monitor_test_clients_state ();
-
- 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.setup,
- 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.expect);
- check_monitor_test_clients_state ();
-
- 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 MetaTestClient *
-create_test_window (MetaContext *context,
- const char *window_name)
-{
- MetaTestClient *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 = meta_test_client_new (context,
- client_name, META_WINDOW_CLIENT_TYPE_WAYLAND,
- &error);
- if (!test_client)
- g_error ("Failed to launch test client: %s", error->message);
-
- if (!meta_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)
-{
- MetaContext *context = test_context;
- MonitorTestCase test_case = initial_test_case;
- MetaMonitorTestSetup *test_setup;
- g_autoptr (GError) error = NULL;
- MetaTestClient *test_client;
-
- test_setup = create_monitor_test_setup (&test_case.setup,
- 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";
- test_client = create_test_window (context, test_window_name);
-
- if (!meta_test_client_do (test_client, &error,
- "show", test_window_name,
- NULL))
- g_error ("Failed to show the window: %s", error->message);
-
- MetaWindow *test_window =
- meta_test_client_find_window (test_client,
- test_window_name,
- &error);
- if (!test_window)
- g_error ("Failed to find the window: %s", error->message);
- meta_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);
-
- test_case.setup.n_outputs = 0;
- test_setup = create_monitor_test_setup (&test_case.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
- test_case.setup.n_outputs = 1;
- test_setup = create_monitor_test_setup (&test_case.setup,
- 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.setup,
- 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.setup,
- MONITOR_TEST_FLAG_NO_STORED);
- emulate_hotplug (test_setup);
-
- meta_window_tile (test_window, META_TILE_MAXIMIZED);
-
- meta_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.setup,
- 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.expect);
- check_monitor_test_clients_state ();
-
- 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);
-}
-
-static MetaMonitorTestSetup *
-create_initial_test_setup (void)
-{
- return create_monitor_test_setup (&initial_test_case.setup,
- MONITOR_TEST_FLAG_NO_STORED);
-}
-
-void
-init_monitor_tests (void)
-{
- meta_monitor_manager_test_init_test_setup (create_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/switch-external-without-external",
- meta_test_monitor_switch_external_without_external);
-
- 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 (MetaContext *context)
-{
- create_monitor_test_clients (context);
-}
-
-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
deleted file mode 100644
index bbf096b39..000000000
--- a/src/tests/monitor-unit-tests.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- 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
-
-#include "core/util-private.h"
-#include "tests/monitor-test-utils.h"
-
-typedef struct _MonitorTestCase MonitorTestCase;
-
-void init_monitor_tests (void);
-
-void pre_run_monitor_tests (MetaContext *context);
-
-void finish_monitor_tests (void);
-
-MonitorTestCase * test_get_initial_monitor_test_case (void);
-
-#endif /* MONITOR_UNIT_TESTS_H */
diff --git a/src/tests/mutter-all.test.in b/src/tests/mutter-all.test.in
deleted file mode 100644
index 6e103c51d..000000000
--- a/src/tests/mutter-all.test.in
+++ /dev/null
@@ -1,6 +0,0 @@
-[Test]
-Description=All Mutter tests
-TestEnvironment=GSETTINGS_BACKEND=memory;
-Exec=sh -c 'env XDG_RUNTIME_DIR="$(mktemp -d -t mutter-@apiversion@-all-tests-XXXXXX)" dbus-run-session -- xvfb-run -a -s "+iglx -noreset" -- @libexecdir@/installed-tests/mutter-@apiversion@/mutter-test-runner --all'
-Type=session
-Output=TAP
diff --git a/src/tests/native-headless.c b/src/tests/native-headless.c
deleted file mode 100644
index 6680ba7b9..000000000
--- a/src/tests/native-headless.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2021 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 "meta-test/meta-context-test.h"
-#include "tests/native-screen-cast.h"
-#include "tests/native-virtual-monitor.h"
-
-static void
-init_tests (void)
-{
- init_virtual_monitor_tests ();
- init_screen_cast_tests ();
-}
-
-int
-main (int argc,
- char **argv)
-{
- g_autoptr (MetaContext) context = NULL;
-
- context = meta_create_test_context (META_CONTEXT_TEST_TYPE_HEADLESS,
- META_CONTEXT_TEST_FLAG_NO_X11);
- g_assert (meta_context_configure (context, &argc, &argv, NULL));
-
- init_tests ();
-
- return meta_context_test_run_tests (META_CONTEXT_TEST (context));
-}
diff --git a/src/tests/native-persistent-virtual-monitor.c b/src/tests/native-persistent-virtual-monitor.c
deleted file mode 100644
index 19a16cc5e..000000000
--- a/src/tests/native-persistent-virtual-monitor.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2021 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-logical-monitor.h"
-#include "backends/meta-monitor-manager-private.h"
-#include "meta/meta-context.h"
-#include "meta/meta-backend.h"
-#include "tests/meta-test-utils.h"
-
-static gboolean
-wait_for_paint (gpointer user_data)
-{
- MetaContext *context = user_data;
- MetaBackend *backend = meta_get_backend ();
- ClutterActor *stage = meta_backend_get_stage (backend);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- GMainLoop *loop;
- GList *monitors;
- GList *logical_monitors;
- MetaLogicalMonitor *logical_monitor;
- MetaRectangle layout;
-
- loop = g_main_loop_new (NULL, FALSE);
- g_signal_connect_swapped (stage, "presented",
- G_CALLBACK (g_main_loop_quit),
- loop);
- clutter_actor_queue_redraw (stage);
-
- monitors = meta_monitor_manager_get_monitors (monitor_manager);
- g_assert_cmpint (g_list_length (monitors), ==, 1);
-
- logical_monitors =
- meta_monitor_manager_get_logical_monitors (monitor_manager);
- g_assert_cmpint (g_list_length (logical_monitors), ==, 1);
-
- logical_monitor = logical_monitors->data;
- g_assert (meta_logical_monitor_get_monitors (logical_monitor)->data ==
- monitors->data);
-
- layout = meta_logical_monitor_get_layout (logical_monitor);
- g_assert_cmpint (layout.x, ==, 0);
- g_assert_cmpint (layout.y, ==, 0);
- g_assert_cmpint (layout.width, ==, 800);
- g_assert_cmpint (layout.height, ==, 600);
-
- g_main_loop_run (loop);
-
- meta_context_terminate (context);
-
- return G_SOURCE_REMOVE;
-}
-
-int
-main (int argc,
- char **argv)
-{
- char *fake_args[] = {
- argv[0],
- (char *) "--wayland",
- (char *) "--headless",
- (char *) "--virtual-monitor",
- (char *) "800x600",
- };
- char **fake_argv = fake_args;
- int fake_argc = G_N_ELEMENTS (fake_args);
- g_autoptr (MetaContext) context = NULL;
- g_autoptr (GError) error = NULL;
-
- context = meta_create_context ("Persistent virtual monitor test");
- g_assert (meta_context_configure (context, &fake_argc, &fake_argv, &error));
- meta_context_set_plugin_name (context, meta_test_get_plugin_name ());
- g_assert (meta_context_setup (context, &error));
- g_assert (meta_context_start (context, &error));
-
- g_idle_add (wait_for_paint, context);
-
- g_assert (meta_context_run_main_loop (context, &error));
-
- return EXIT_SUCCESS;
-}
diff --git a/src/tests/native-screen-cast.c b/src/tests/native-screen-cast.c
deleted file mode 100644
index bcde15665..000000000
--- a/src/tests/native-screen-cast.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2021 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 "tests/native-screen-cast.h"
-
-#include <errno.h>
-#include <gio/gio.h>
-#include <unistd.h>
-
-static void
-test_client_exited (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GError *error = NULL;
-
- if (!g_subprocess_wait_finish (G_SUBPROCESS (source_object),
- result,
- &error))
- g_error ("Screen cast test client exited with an error: %s", error->message);
-
- g_main_loop_quit (user_data);
-}
-
-static void
-meta_test_screen_cast_record_virtual (void)
-{
- GSubprocessLauncher *launcher;
- g_autofree char *test_client_path = NULL;
- GError *error = NULL;
- GSubprocess *subprocess;
- GMainLoop *loop;
-
- launcher = g_subprocess_launcher_new ((G_SUBPROCESS_FLAGS_STDIN_PIPE |
- G_SUBPROCESS_FLAGS_STDOUT_PIPE));
-
- test_client_path = g_test_build_filename (G_TEST_BUILT,
- "src",
- "tests",
- "mutter-screen-cast-client",
- NULL);
- g_subprocess_launcher_setenv (launcher,
- "XDG_RUNTIME_DIR", getenv ("XDG_RUNTIME_DIR"),
- TRUE);
- subprocess = g_subprocess_launcher_spawn (launcher,
- &error,
- test_client_path,
- NULL);
- if (!subprocess)
- g_error ("Failed to launch screen cast test client: %s", error->message);
-
- loop = g_main_loop_new (NULL, FALSE);
- g_subprocess_wait_check_async (subprocess,
- NULL,
- test_client_exited,
- loop);
- g_main_loop_run (loop);
- g_assert_true (g_subprocess_get_successful (subprocess));
- g_object_unref (subprocess);
-}
-
-void
-init_screen_cast_tests (void)
-{
- g_test_add_func ("/backends/native/screen-cast/record-virtual",
- meta_test_screen_cast_record_virtual);
-}
diff --git a/src/tests/native-screen-cast.h b/src/tests/native-screen-cast.h
deleted file mode 100644
index 3c79676c7..000000000
--- a/src/tests/native-screen-cast.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2021 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 NATIVE_SCREEN_CAST_H
-#define NATIVE_SCREEN_CAST_H
-
-void init_screen_cast_tests (void);
-
-#endif /* NATIVE_SCREEN_CAST_H */
diff --git a/src/tests/native-virtual-monitor.c b/src/tests/native-virtual-monitor.c
deleted file mode 100644
index 15fc78f88..000000000
--- a/src/tests/native-virtual-monitor.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2021 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 "tests/native-virtual-monitor.h"
-
-#include "backends/meta-backend-private.h"
-#include "backends/meta-logical-monitor.h"
-#include "backends/meta-monitor-config-manager.h"
-#include "backends/meta-virtual-monitor.h"
-#include "backends/native/meta-renderer-native.h"
-#include "tests/meta-ref-test.h"
-
-static void
-meta_test_virtual_monitor_create (void)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend);
- MetaMonitorConfigManager *config_manager =
- meta_monitor_manager_get_config_manager (monitor_manager);
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
- MetaVirtualMonitor *virtual_monitor;
- g_autoptr (MetaVirtualMonitorInfo) monitor_info = NULL;
- GError *error = NULL;
- GList *monitors;
- MetaMonitor *monitor;
- MetaMonitorsConfig *monitors_config;
- GList *logical_monitors;
- GList *logical_monitor_monitors;
- GList *views;
- int i;
- ClutterActor *actor;
-
- g_assert_null (meta_monitor_config_manager_get_current (config_manager));
- g_assert_null (meta_monitor_manager_get_logical_monitors (monitor_manager));
- g_assert_null (meta_monitor_manager_get_monitors (monitor_manager));
- g_assert_null (meta_renderer_get_views (renderer));
-
- monitor_info = meta_virtual_monitor_info_new (80, 60, 60.0,
- "MetaTestVendor",
- "MetaVirtualMonitor",
- "0x1234");
- virtual_monitor = meta_monitor_manager_create_virtual_monitor (monitor_manager,
- monitor_info,
- &error);
- if (!virtual_monitor)
- g_error ("Failed to create virtual monitor: %s", error->message);
-
- meta_monitor_manager_reload (monitor_manager);
-
- monitors = meta_monitor_manager_get_monitors (monitor_manager);
- g_assert_cmpint (g_list_length (monitors), ==, 1);
- monitor = META_MONITOR (monitors->data);
- g_assert_cmpstr (meta_monitor_get_vendor (monitor), ==, "MetaTestVendor");
- g_assert_cmpstr (meta_monitor_get_product (monitor), ==, "MetaVirtualMonitor");
- g_assert_cmpstr (meta_monitor_get_serial (monitor), ==, "0x1234");
- g_assert (meta_monitor_get_main_output (monitor) ==
- meta_virtual_monitor_get_output (virtual_monitor));
-
- monitors_config = meta_monitor_manager_ensure_configured (monitor_manager);
- g_assert_nonnull (monitors_config);
- g_assert_cmpint (g_list_length (monitors_config->logical_monitor_configs),
- ==,
- 1);
-
- g_assert_cmpint (g_list_length (monitors_config->disabled_monitor_specs),
- ==,
- 0);
-
- logical_monitors =
- meta_monitor_manager_get_logical_monitors (monitor_manager);
- g_assert_cmpint (g_list_length (logical_monitors), ==, 1);
- logical_monitor_monitors =
- meta_logical_monitor_get_monitors (logical_monitors->data);
- g_assert_cmpint (g_list_length (logical_monitor_monitors), ==, 1);
- g_assert (logical_monitor_monitors->data == monitor);
-
- views = meta_renderer_get_views (renderer);
- g_assert_cmpint (g_list_length (views), ==, 1);
-
- for (i = 0; i < 5; i++)
- {
- meta_ref_test_verify_view (CLUTTER_STAGE_VIEW (views->data),
- g_test_get_path (), 0,
- meta_ref_test_determine_ref_test_flag ());
- }
-
- actor = clutter_actor_new ();
- clutter_actor_set_position (actor, 10, 10);
- clutter_actor_set_size (actor, 40, 40);
- clutter_actor_set_background_color (actor, CLUTTER_COLOR_LightSkyBlue);
- clutter_actor_add_child (meta_backend_get_stage (backend), actor);
-
- for (i = 0; i < 5; i++)
- {
- meta_ref_test_verify_view (CLUTTER_STAGE_VIEW (views->data),
- g_test_get_path (), 1,
- meta_ref_test_determine_ref_test_flag ());
- }
-
- g_object_unref (virtual_monitor);
- meta_monitor_manager_reload (monitor_manager);
-
- g_assert_null (meta_monitor_manager_ensure_configured (monitor_manager));
- g_assert_null (meta_monitor_manager_get_logical_monitors (monitor_manager));
- g_assert_null (meta_monitor_manager_get_monitors (monitor_manager));
- g_assert_null (meta_renderer_get_views (renderer));
-
- clutter_actor_destroy (actor);
-}
-
-void
-init_virtual_monitor_tests (void)
-{
- g_test_add_func ("/backends/native/virtual-monitor/create",
- meta_test_virtual_monitor_create);
-}
diff --git a/src/tests/native-virtual-monitor.h b/src/tests/native-virtual-monitor.h
deleted file mode 100644
index 0c4c34f02..000000000
--- a/src/tests/native-virtual-monitor.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2021 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 NATIVE_VIRTUAL_MONITOR_H
-#define NATIVE_VIRTUAL_MONITOR_H
-
-void init_virtual_monitor_tests (void);
-
-#endif /* NATIVE_VIRTUAL_MONITOR_H */
diff --git a/src/tests/ref-test-sanity.c b/src/tests/ref-test-sanity.c
deleted file mode 100644
index 0a9472b13..000000000
--- a/src/tests/ref-test-sanity.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2021 Red Hat Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "config.h"
-
-#include "backends/meta-virtual-monitor.h"
-#include "backends/native/meta-renderer-native.h"
-#include "meta-test/meta-context-test.h"
-#include "tests/meta-ref-test.h"
-
-static MetaVirtualMonitor *virtual_monitor;
-
-static void
-setup_test_environment (void)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaSettings *settings = meta_backend_get_settings (backend);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
- g_autoptr (MetaVirtualMonitorInfo) monitor_info = NULL;
- GError *error = NULL;
- GList *views;
-
- meta_settings_override_experimental_features (settings);
- meta_settings_enable_experimental_feature (
- settings,
- META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
-
- monitor_info = meta_virtual_monitor_info_new (100, 100, 60.0,
- "MetaTestVendor",
- "MetaVirtualMonitor",
- "0x1234");
- virtual_monitor = meta_monitor_manager_create_virtual_monitor (monitor_manager,
- monitor_info,
- &error);
- if (!virtual_monitor)
- g_error ("Failed to create virtual monitor: %s", error->message);
-
- meta_monitor_manager_reload (monitor_manager);
-
- views = meta_renderer_get_views (renderer);
- g_assert_cmpint (g_list_length (views), ==, 1);
-}
-
-static void
-tear_down_test_environment (void)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
-
- g_object_unref (virtual_monitor);
- meta_monitor_manager_reload (monitor_manager);
-}
-
-static ClutterStageView *
-get_view (void)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
-
- return CLUTTER_STAGE_VIEW (meta_renderer_get_views (renderer)->data);
-}
-
-static void
-meta_test_ref_test_sanity (void)
-{
- MetaBackend *backend = meta_get_backend ();
- ClutterActor *stage = meta_backend_get_stage (backend);
- ClutterActor *actor1;
- ClutterActor *actor2;
-
- meta_ref_test_verify_view (get_view (),
- g_test_get_path (), 0,
- meta_ref_test_determine_ref_test_flag ());
-
- actor1 = clutter_actor_new ();
- clutter_actor_set_position (actor1, 10, 10);
- clutter_actor_set_size (actor1, 50, 50);
- clutter_actor_set_background_color (actor1, CLUTTER_COLOR_Orange);
- clutter_actor_add_child (stage, actor1);
-
- meta_ref_test_verify_view (get_view (),
- g_test_get_path (), 1,
- meta_ref_test_determine_ref_test_flag ());
-
- actor2 = clutter_actor_new ();
- clutter_actor_set_position (actor2, 20, 20);
- clutter_actor_set_size (actor2, 50, 50);
- clutter_actor_set_background_color (actor2, CLUTTER_COLOR_SkyBlue);
- clutter_actor_add_child (stage, actor2);
-
- g_test_expect_message (G_LOG_DOMAIN,
- G_LOG_LEVEL_CRITICAL,
- "Pixel difference exceeds limits*");
-
- meta_ref_test_verify_view (get_view (),
- g_test_get_path (), 1,
- meta_ref_test_determine_ref_test_flag ());
-
- g_test_assert_expected_messages ();
-
- clutter_actor_destroy (actor2);
- clutter_actor_destroy (actor1);
-}
-
-static void
-init_ref_test_sanity_tests (void)
-{
- g_test_add_func ("/tests/ref-test/sanity",
- meta_test_ref_test_sanity);
-}
-
-int
-main (int argc,
- char **argv)
-{
- g_autoptr (MetaContext) context = NULL;
-
- context = meta_create_test_context (META_CONTEXT_TEST_TYPE_HEADLESS,
- META_CONTEXT_TEST_FLAG_NO_X11);
- g_assert (meta_context_configure (context, &argc, &argv, NULL));
-
- init_ref_test_sanity_tests ();
-
- g_signal_connect (context, "before-tests",
- G_CALLBACK (setup_test_environment), NULL);
- g_signal_connect (context, "after-tests",
- G_CALLBACK (tear_down_test_environment), NULL);
-
- return meta_context_test_run_tests (META_CONTEXT_TEST (context));
-}
diff --git a/src/tests/ref-tests/backends_native_virtual-monitor_create_0.ref.png b/src/tests/ref-tests/backends_native_virtual-monitor_create_0.ref.png
deleted file mode 100644
index 55ed4d9e0..000000000
--- a/src/tests/ref-tests/backends_native_virtual-monitor_create_0.ref.png
+++ /dev/null
Binary files differ
diff --git a/src/tests/ref-tests/backends_native_virtual-monitor_create_1.ref.png b/src/tests/ref-tests/backends_native_virtual-monitor_create_1.ref.png
deleted file mode 100644
index c75a6e161..000000000
--- a/src/tests/ref-tests/backends_native_virtual-monitor_create_1.ref.png
+++ /dev/null
Binary files differ
diff --git a/src/tests/ref-tests/tests_ref-test_sanity_0.ref.png b/src/tests/ref-tests/tests_ref-test_sanity_0.ref.png
deleted file mode 100644
index f434827f8..000000000
--- a/src/tests/ref-tests/tests_ref-test_sanity_0.ref.png
+++ /dev/null
Binary files differ
diff --git a/src/tests/ref-tests/tests_ref-test_sanity_1.ref.png b/src/tests/ref-tests/tests_ref-test_sanity_1.ref.png
deleted file mode 100644
index 29567348e..000000000
--- a/src/tests/ref-tests/tests_ref-test_sanity_1.ref.png
+++ /dev/null
Binary files differ
diff --git a/src/tests/screen-cast-client.c b/src/tests/screen-cast-client.c
deleted file mode 100644
index cc118f7ae..000000000
--- a/src/tests/screen-cast-client.c
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * Copyright (C) 2021 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 <pipewire/pipewire.h>
-#include <spa/param/format-utils.h>
-#include <spa/param/props.h>
-#include <spa/param/video/format-utils.h>
-#include <spa/utils/result.h>
-#include <stdint.h>
-#include <sys/mman.h>
-
-#include "meta-dbus-screen-cast.h"
-
-typedef struct _Stream
-{
- MetaDBusScreenCastStream *proxy;
- uint32_t pipewire_node_id;
- struct spa_video_info_raw spa_format;
- struct pw_stream *pipewire_stream;
- struct spa_hook pipewire_stream_listener;
- enum pw_stream_state state;
- int buffer_count;
-} Stream;
-
-typedef struct _Session
-{
- MetaDBusScreenCastSession *proxy;
-} Session;
-
-typedef struct _ScreenCast
-{
- MetaDBusScreenCast *proxy;
-} ScreenCast;
-
-typedef struct _PipeWireSource
-{
- GSource base;
-
- struct pw_loop *pipewire_loop;
-} PipeWireSource;
-
-static PipeWireSource *_pipewire_source;
-static struct pw_context *_pipewire_context;
-static struct pw_core *_pipewire_core;
-static struct spa_hook _pipewire_core_listener;
-
-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)
-{
- PipeWireSource *pipewire_source = (PipeWireSource *) source;
- int result;
-
- result = pw_loop_iterate (pipewire_source->pipewire_loop, 0);
- if (result < 0)
- g_error ("pipewire_loop_iterate failed: %s", spa_strerror (result));
-
- return TRUE;
-}
-
-static void
-pipewire_loop_source_finalize (GSource *source)
-{
- PipeWireSource *pipewire_source = (PipeWireSource *) 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 PipeWireSource *
-create_pipewire_source (void)
-{
- PipeWireSource *pipewire_source;
-
- pipewire_source =
- (PipeWireSource *) g_source_new (&pipewire_source_funcs,
- sizeof (PipeWireSource));
- pipewire_source->pipewire_loop = pw_loop_new (NULL);
- g_assert_nonnull (pipewire_source->pipewire_loop);
- 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 void
-on_core_error (void *user_data,
- uint32_t id,
- int seq,
- int res,
- const char *message)
-{
- g_error ("PipeWire core error: id:%u %s", id, message);
-}
-
-static const struct pw_core_events core_events = {
- PW_VERSION_CORE_EVENTS,
- .error = on_core_error,
-};
-
-static void
-init_pipewire (void)
-{
- pw_init (NULL, NULL);
- _pipewire_source = create_pipewire_source ();
- _pipewire_context = pw_context_new (_pipewire_source->pipewire_loop,
- NULL, 0);
- g_assert_nonnull (_pipewire_context);
- _pipewire_core = pw_context_connect (_pipewire_context, NULL, 0);
- g_assert_nonnull (_pipewire_core);
-
- pw_core_add_listener (_pipewire_core,
- &_pipewire_core_listener,
- &core_events,
- NULL);
-}
-
-static void
-release_pipewire (void)
-{
- g_clear_pointer (&_pipewire_core, pw_core_disconnect);
- g_clear_pointer (&_pipewire_context, pw_context_destroy);
- if (_pipewire_source)
- {
- g_source_destroy ((GSource *) _pipewire_source);
- g_source_unref ((GSource *) _pipewire_source);
- _pipewire_source = NULL;
- }
-}
-
-static void
-on_stream_state_changed (void *user_data,
- enum pw_stream_state old,
- enum pw_stream_state state,
- const char *error)
-{
- Stream *stream = user_data;
-
- switch (state)
- {
- case PW_STREAM_STATE_ERROR:
- g_warning ("PipeWire stream error: %s", error);
- break;
- case PW_STREAM_STATE_PAUSED:
- case PW_STREAM_STATE_STREAMING:
- case PW_STREAM_STATE_UNCONNECTED:
- case PW_STREAM_STATE_CONNECTING:
- break;
- }
-
- stream->state = state;
-}
-
-static void
-on_stream_param_changed (void *user_data,
- uint32_t id,
- const struct spa_pod *format)
-{
- Stream *stream = user_data;
- uint8_t params_buffer[1024];
- struct spa_pod_builder pod_builder;
- const struct spa_pod *params[2];
-
- if (!format || id != SPA_PARAM_Format)
- return;
-
- spa_format_video_raw_parse (format, &stream->spa_format);
-
- 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 (8, 1, 8),
- SPA_PARAM_BUFFERS_dataType, SPA_POD_Int ((1 << SPA_DATA_MemPtr) |
- (1 << SPA_DATA_MemFd)),
- 0);
-
- 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_Header),
- SPA_PARAM_META_size, SPA_POD_Int (sizeof (struct spa_meta_header)),
- 0);
-
- pw_stream_update_params (stream->pipewire_stream,
- params, G_N_ELEMENTS (params));
-}
-
-static void
-sanity_check_memfd (struct spa_buffer *buffer)
-{
- size_t size;
- uint8_t *map;
-
- size = buffer->datas[0].maxsize + buffer->datas[0].mapoffset;
- g_assert_cmpint (size, >, 0);
- map = mmap (NULL, size, PROT_READ, MAP_PRIVATE, buffer->datas[0].fd, 0);
- g_assert (map != MAP_FAILED);
- munmap (map, size);
-}
-
-static void
-sanity_check_memptr (struct spa_buffer *buffer)
-{
- size_t size;
-
- size = buffer->datas[0].maxsize + buffer->datas[0].mapoffset;
- g_assert_cmpint (size, >, 0);
-
- g_assert_nonnull (buffer->datas[0].data);
-}
-
-static void
-process_buffer (Stream *stream,
- struct spa_buffer *buffer)
-{
- if (buffer->datas[0].chunk->size == 0)
- g_assert_not_reached ();
- else if (buffer->datas[0].type == SPA_DATA_MemFd)
- sanity_check_memfd (buffer);
- else if (buffer->datas[0].type == SPA_DATA_DmaBuf)
- g_assert_not_reached ();
- else if (buffer->datas[0].type == SPA_DATA_MemPtr)
- sanity_check_memptr (buffer);
- else
- g_assert_not_reached ();
-}
-
-static void
-on_stream_process (void *user_data)
-{
- Stream *stream = user_data;
- struct pw_buffer *next_buffer;
- struct pw_buffer *buffer = NULL;
-
- next_buffer = pw_stream_dequeue_buffer (stream->pipewire_stream);
- while (next_buffer)
- {
- buffer = next_buffer;
- next_buffer = pw_stream_dequeue_buffer (stream->pipewire_stream);
-
- if (next_buffer)
- pw_stream_queue_buffer (stream->pipewire_stream, buffer);
- }
- if (!buffer)
- return;
-
- process_buffer (stream, buffer->buffer);
- pw_stream_queue_buffer (stream->pipewire_stream, buffer);
-
- stream->buffer_count++;
-}
-
-static const struct pw_stream_events stream_events = {
- PW_VERSION_STREAM_EVENTS,
- .state_changed = on_stream_state_changed,
- .param_changed = on_stream_param_changed,
- .process = on_stream_process,
-};
-
-static void
-stream_connect (Stream *stream)
-{
- struct pw_stream *pipewire_stream;
- uint8_t params_buffer[1024];
- struct spa_pod_builder pod_builder;
- struct spa_rectangle min_rect;
- struct spa_rectangle max_rect;
- struct spa_fraction min_framerate;
- struct spa_fraction max_framerate;
- const struct spa_pod *params[2];
- int ret;
-
- pipewire_stream = pw_stream_new (_pipewire_core,
- "mutter-test-pipewire-stream",
- NULL);
-
- min_rect = SPA_RECTANGLE (1, 1);
- max_rect = SPA_RECTANGLE (50 , 50);
- min_framerate = SPA_FRACTION (1, 1);
- max_framerate = SPA_FRACTION (30, 1);
-
- pod_builder = SPA_POD_BUILDER_INIT (params_buffer, sizeof (params_buffer));
- 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_CHOICE_RANGE_Rectangle (&min_rect,
- &min_rect,
- &max_rect),
- SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction (&SPA_FRACTION(0, 1)),
- SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_CHOICE_RANGE_Fraction (&min_framerate,
- &min_framerate,
- &max_framerate),
- 0);
-
- stream->pipewire_stream = pipewire_stream;
-
- pw_stream_add_listener (pipewire_stream,
- &stream->pipewire_stream_listener,
- &stream_events,
- stream);
-
- ret = pw_stream_connect (stream->pipewire_stream,
- PW_DIRECTION_INPUT,
- stream->pipewire_node_id,
- PW_STREAM_FLAG_AUTOCONNECT,
- params, 1);
- if (ret < 0)
- g_error ("Failed to connect PipeWire stream: %s", g_strerror (-ret));
-}
-
-static void
-stream_wait_for_node (Stream *stream)
-{
- while (!stream->pipewire_node_id)
- g_main_context_iteration (NULL, TRUE);
-}
-
-static G_GNUC_UNUSED void
-stream_wait_for_streaming (Stream *stream)
-{
- while (stream->state != PW_STREAM_STATE_STREAMING)
- g_main_context_iteration (NULL, TRUE);
-}
-
-static G_GNUC_UNUSED void
-stream_wait_for_render (Stream *stream)
-{
- while (stream->buffer_count == 0)
- g_main_context_iteration (NULL, TRUE);
-}
-
-static void
-on_pipewire_stream_added (MetaDBusScreenCastStream *proxy,
- unsigned int node_id,
- Stream *stream)
-{
- stream->pipewire_node_id = (uint32_t) node_id;
- stream_connect (stream);
-}
-
-static Stream *
-stream_new (const char *path)
-{
- Stream *stream;
- GError *error = NULL;
-
- stream = g_new0 (Stream, 1);
- stream->proxy = meta_dbus_screen_cast_stream_proxy_new_for_bus_sync (
- G_BUS_TYPE_SESSION,
- G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
- "org.gnome.Mutter.ScreenCast",
- path,
- NULL,
- &error);
- if (!stream->proxy)
- g_error ("Failed to acquire proxy: %s", error->message);
-
- g_signal_connect (stream->proxy, "pipewire-stream-added",
- G_CALLBACK (on_pipewire_stream_added),
- stream);
-
- return stream;
-}
-
-static void
-stream_free (Stream *stream)
-{
- g_clear_pointer (&stream->pipewire_stream, pw_stream_destroy);
- g_clear_object (&stream->proxy);
- g_free (stream);
-}
-
-static void
-session_start (Session *session)
-{
- GError *error = NULL;
-
- if (!meta_dbus_screen_cast_session_call_start_sync (session->proxy,
- NULL,
- &error))
- g_error ("Failed to start session: %s", error->message);
-}
-
-static void
-session_stop (Session *session)
-{
- GError *error = NULL;
-
- if (!meta_dbus_screen_cast_session_call_stop_sync (session->proxy,
- NULL,
- &error))
- g_error ("Failed to stop session: %s", error->message);
-}
-
-static Stream *
-session_record_virtual (Session *session)
-{
- GVariantBuilder properties_builder;
- GVariant *properties_variant;
- GError *error = NULL;
- g_autofree char *stream_path = NULL;
- Stream *stream;
-
- g_variant_builder_init (&properties_builder, G_VARIANT_TYPE ("a{sv}"));
- properties_variant = g_variant_builder_end (&properties_builder);
-
- if (!meta_dbus_screen_cast_session_call_record_virtual_sync (
- session->proxy,
- properties_variant,
- &stream_path,
- NULL,
- &error))
- g_error ("Failed to create session: %s", error->message);
-
- stream = stream_new (stream_path);
- g_assert_nonnull (stream);
- return stream;
-}
-
-static Session *
-session_new (const char *path)
-{
- Session *session;
- GError *error = NULL;
-
- session = g_new0 (Session, 1);
- session->proxy = meta_dbus_screen_cast_session_proxy_new_for_bus_sync (
- G_BUS_TYPE_SESSION,
- G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
- "org.gnome.Mutter.ScreenCast",
- path,
- NULL,
- &error);
- if (!session->proxy)
- g_error ("Failed to acquire proxy: %s", error->message);
-
- return session;
-}
-
-static void
-session_free (Session *session)
-{
- g_clear_object (&session->proxy);
- g_free (session);
-}
-
-static Session *
-screen_cast_create_session (ScreenCast *screen_cast)
-{
- GVariantBuilder properties_builder;
- GVariant *properties_variant;
- GError *error = NULL;
- g_autofree char *session_path = NULL;
- Session *session;
-
- g_variant_builder_init (&properties_builder, G_VARIANT_TYPE ("a{sv}"));
- properties_variant = g_variant_builder_end (&properties_builder);
-
- if (!meta_dbus_screen_cast_call_create_session_sync (screen_cast->proxy,
- properties_variant,
- &session_path,
- NULL,
- &error))
- g_error ("Failed to create session: %s", error->message);
-
- session = session_new (session_path);
- g_assert_nonnull (session);
- return session;
-}
-
-static ScreenCast *
-screen_cast_new (void)
-{
- ScreenCast *screen_cast;
- GError *error = NULL;
-
- screen_cast = g_new0 (ScreenCast, 1);
- screen_cast->proxy = meta_dbus_screen_cast_proxy_new_for_bus_sync (
- G_BUS_TYPE_SESSION,
- G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
- "org.gnome.Mutter.ScreenCast",
- "/org/gnome/Mutter/ScreenCast",
- NULL,
- &error);
- if (!screen_cast->proxy)
- g_error ("Failed to acquire proxy: %s", error->message);
-
- return screen_cast;
-}
-
-static void
-screen_cast_free (ScreenCast *screen_cast)
-{
- g_clear_object (&screen_cast->proxy);
- g_free (screen_cast);
-}
-
-int
-main (int argc,
- char **argv)
-{
- ScreenCast *screen_cast;
- Session *session;
- Stream *stream;
-
- init_pipewire ();
-
- screen_cast = screen_cast_new ();
- session = screen_cast_create_session (screen_cast);
- stream = session_record_virtual (session);
-
- session_start (session);
-
- stream_wait_for_node (stream);
- stream_wait_for_streaming (stream);
- stream_wait_for_render (stream);
-
- session_stop (session);
-
- stream_free (stream);
- session_free (session);
- screen_cast_free (screen_cast);
-
- release_pipewire ();
-
- return EXIT_SUCCESS;
-}
diff --git a/src/tests/stacking/basic-wayland.metatest b/src/tests/stacking/basic-wayland.metatest
deleted file mode 100644
index 63ce6082b..000000000
--- a/src/tests/stacking/basic-wayland.metatest
+++ /dev/null
@@ -1,22 +0,0 @@
-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
deleted file mode 100644
index ee261ece0..000000000
--- a/src/tests/stacking/basic-x11.metatest
+++ /dev/null
@@ -1,19 +0,0 @@
-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
deleted file mode 100644
index 1d5dfc646..000000000
--- a/src/tests/stacking/client-side-decorated.metatest
+++ /dev/null
@@ -1,22 +0,0 @@
-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-default-focus.metatest b/src/tests/stacking/closed-transient-no-default-focus.metatest
deleted file mode 100644
index a2db12d5b..000000000
--- a/src/tests/stacking/closed-transient-no-default-focus.metatest
+++ /dev/null
@@ -1,29 +0,0 @@
-new_client 1 x11
-create 1/1
-accept_focus 1/1 false
-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 1/1 1/2 1/3
-
-destroy 1/3
-wait
-
-assert_focused none
-assert_stacking 1/1 1/2
-
-sleep 150
-wait
-
-assert_focused none
-assert_stacking 1/1 1/2
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
deleted file mode 100644
index 0c0649c07..000000000
--- a/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest
+++ /dev/null
@@ -1,23 +0,0 @@
-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
deleted file mode 100644
index 6556803e1..000000000
--- a/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest
+++ /dev/null
@@ -1,30 +0,0 @@
-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
deleted file mode 100644
index 90a65e659..000000000
--- a/src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest
+++ /dev/null
@@ -1,37 +0,0 @@
-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
-wait
-
-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
-wait
-
-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
deleted file mode 100644
index 5c2be11fb..000000000
--- a/src/tests/stacking/closed-transient-no-input-parent.metatest
+++ /dev/null
@@ -1,31 +0,0 @@
-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
-wait
-
-assert_stacking 2/1 1/1 1/2
-
-sleep 150
-wait
-
-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
deleted file mode 100644
index e361fbdf6..000000000
--- a/src/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest
+++ /dev/null
@@ -1,44 +0,0 @@
-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
-wait
-
-assert_stacking 0/1 1/1 1/2 1/3 1/4
-
-destroy 1/2
-wait
-
-sleep 450
-wait
-
-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
deleted file mode 100644
index 365f6f444..000000000
--- a/src/tests/stacking/closed-transient-no-input-parents.metatest
+++ /dev/null
@@ -1,47 +0,0 @@
-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
-wait
-
-assert_stacking 0/1 1/1 1/2 1/3 1/4
-
-sleep 600
-wait
-
-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
deleted file mode 100644
index 88bf7865c..000000000
--- a/src/tests/stacking/closed-transient-only-take-focus-parents.metatest
+++ /dev/null
@@ -1,36 +0,0 @@
-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
-wait
-
-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
deleted file mode 100644
index 5ca95ba0f..000000000
--- a/src/tests/stacking/closed-transient.metatest
+++ /dev/null
@@ -1,19 +0,0 @@
-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/default-size.metatest b/src/tests/stacking/default-size.metatest
deleted file mode 100644
index d1c692959..000000000
--- a/src/tests/stacking/default-size.metatest
+++ /dev/null
@@ -1,36 +0,0 @@
-new_client x x11
-create x/1 csd
-
-resize x/1 300 400
-show x/1
-wait
-
-assert_size x/1 300 400
-
-resize x/1 200 300
-wait_reconfigure
-assert_size x/1 200 300
-
-hide x/1
-show x/1
-wait
-assert_size x/1 200 300
-
-
-new_client w wayland
-create w/1 csd
-
-resize w/1 300 400
-show w/1
-wait
-
-assert_size w/1 300 400
-
-resize w/1 200 300
-wait_reconfigure
-assert_size w/1 200 300
-
-hide w/1
-show w/1
-wait_reconfigure
-assert_size w/1 200 300
diff --git a/src/tests/stacking/fullscreen-maximize.metatest b/src/tests/stacking/fullscreen-maximize.metatest
deleted file mode 100644
index 433c8b252..000000000
--- a/src/tests/stacking/fullscreen-maximize.metatest
+++ /dev/null
@@ -1,73 +0,0 @@
-# Tests that the following works, both on Wayland and X11
-# 1. Create a window with a known size
-# 2. Maximize window results in maximized size
-# 3. Fullscreen window results in fullscreen size
-# 4. Unfullscreen window results in maximized size
-# 5. Unmaximize window results in original size
-# 6. Toggling fullscreen ends up with original size
-
-new_client w wayland
-create w/1 csd
-
-resize w/1 500 400
-show w/1
-wait
-
-assert_size w/1 500 400
-
-maximize w/1
-wait_reconfigure
-assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-fullscreen w/1
-wait_reconfigure
-assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-unfullscreen w/1
-wait_reconfigure
-assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-unmaximize w/1
-wait_reconfigure
-assert_size w/1 500 400
-
-fullscreen w/1
-wait_reconfigure
-assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-unfullscreen w/1
-wait_reconfigure
-assert_size w/1 500 400
-
-new_client x x11
-create x/1 csd
-
-resize x/1 500 400
-show x/1
-wait
-
-assert_size x/1 500 400
-
-maximize x/1
-wait_reconfigure
-assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-fullscreen x/1
-wait_reconfigure
-assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-unfullscreen x/1
-wait_reconfigure
-assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-unmaximize x/1
-wait_reconfigure
-assert_size x/1 500 400
-
-fullscreen x/1
-wait_reconfigure
-assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-unfullscreen x/1
-wait_reconfigure
-assert_size x/1 500 400
diff --git a/src/tests/stacking/map-fixed-size.metatest b/src/tests/stacking/map-fixed-size.metatest
deleted file mode 100644
index 992de0df7..000000000
--- a/src/tests/stacking/map-fixed-size.metatest
+++ /dev/null
@@ -1,75 +0,0 @@
-# Map an initially maximized window
-
-# Map a Wayland window initially maximized
-
-new_client w wayland
-create w/1 csd
-maximize w/1
-
-wait
-
-assert_stacking
-
-show w/1
-
-wait
-
-assert_stacking w/1
-assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-hide w/1
-
-# Map a Wayland window initially fullscreen
-
-create w/2 csd
-fullscreen w/2
-
-wait
-
-assert_stacking
-
-show w/2
-
-wait
-
-assert_stacking w/2
-assert_size w/2 MONITOR_WIDTH MONITOR_HEIGHT
-
-hide w/2
-
-# Map a X11 window initially maximized
-
-new_client x x11
-create x/1 csd
-maximize x/1
-
-wait
-
-assert_stacking
-
-show x/1
-
-wait
-
-assert_stacking x/1
-assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-hide x/1
-
-# Map a X11 window initially fullscreen
-
-create x/2 csd
-fullscreen x/2
-
-wait
-
-assert_stacking
-
-show x/2
-
-wait
-
-assert_stacking x/2
-assert_size x/2 MONITOR_WIDTH MONITOR_HEIGHT
-
-hide x/2
diff --git a/src/tests/stacking/minimized.metatest b/src/tests/stacking/minimized.metatest
deleted file mode 100644
index 3da236d19..000000000
--- a/src/tests/stacking/minimized.metatest
+++ /dev/null
@@ -1,18 +0,0 @@
-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
deleted file mode 100644
index 38058b582..000000000
--- a/src/tests/stacking/mixed-windows.metatest
+++ /dev/null
@@ -1,26 +0,0 @@
-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/modals.metatest b/src/tests/stacking/modals.metatest
deleted file mode 100644
index 6c76eadf8..000000000
--- a/src/tests/stacking/modals.metatest
+++ /dev/null
@@ -1,32 +0,0 @@
-new_client w wayland
-
-# Create two Wayland windows, and make the second a transient of the
-# first. Then make the parent not actually ever show, but show the
-# transient.
-
-# Then make sure that hiding the transient can hide without causing
-# issues.
-
-# https://gitlab.gnome.org/GNOME/mutter/-/issues/862
-
-create w/1 csd
-create w/2 csd
-
-set_parent w/2 1
-
-freeze w/1
-
-show w/1 async
-show w/2
-
-wait
-
-assert_stacking w/1 w/2
-
-hide w/2
-wait
-
-assert_stacking w/1
-
-hide w/2
-wait
diff --git a/src/tests/stacking/override-redirect.metatest b/src/tests/stacking/override-redirect.metatest
deleted file mode 100644
index b313d240b..000000000
--- a/src/tests/stacking/override-redirect.metatest
+++ /dev/null
@@ -1,19 +0,0 @@
-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/restore-position.metatest b/src/tests/stacking/restore-position.metatest
deleted file mode 100644
index b4e7a7e97..000000000
--- a/src/tests/stacking/restore-position.metatest
+++ /dev/null
@@ -1,73 +0,0 @@
-# X11
-
-new_client x x11
-create x/1 csd
-show x/1
-
-move x/1 100 100
-assert_position x/1 100 100
-
-maximize x/1
-wait_reconfigure
-assert_position x/1 0 0
-
-unmaximize x/1
-wait_reconfigure
-assert_position x/1 100 100
-
-tile x/1 left
-wait_reconfigure
-assert_position x/1 0 0
-
-untile x/1
-wait_reconfigure
-assert_position x/1 100 100
-
-tile x/1 left
-wait
-assert_position x/1 0 0
-
-maximize x/1
-wait_reconfigure
-assert_position x/1 0 0
-
-unmaximize x/1
-wait_reconfigure
-assert_position x/1 100 100
-
-# Wayland
-
-new_client w wayland
-create w/1 csd
-show w/1
-
-move w/1 100 100
-assert_position w/1 100 100
-
-maximize w/1
-wait_reconfigure
-assert_position w/1 0 0
-
-unmaximize w/1
-wait_reconfigure
-assert_position w/1 100 100
-
-tile w/1 left
-wait_reconfigure
-assert_position w/1 0 0
-
-untile w/1
-wait_reconfigure
-assert_position w/1 100 100
-
-tile w/1 left
-wait_reconfigure
-assert_position w/1 0 0
-
-maximize w/1
-wait_reconfigure
-assert_position w/1 0 0
-
-unmaximize w/1
-wait_reconfigure
-assert_position w/1 100 100
diff --git a/src/tests/stacking/restore-size.metatest b/src/tests/stacking/restore-size.metatest
deleted file mode 100644
index 58941b017..000000000
--- a/src/tests/stacking/restore-size.metatest
+++ /dev/null
@@ -1,95 +0,0 @@
-# Check that X11 clients restore to their right size after unmaximize
-# or untile
-
-new_client x x11
-create x/1 csd
-
-resize x/1 500 400
-maximize x/1
-show x/1
-
-wait
-
-assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-unmaximize x/1
-wait
-
-assert_size x/1 500 400
-
-resize x/1 300 200
-wait
-maximize x/1
-wait_reconfigure
-unmaximize x/1
-wait_reconfigure
-
-assert_size x/1 300 200
-
-tile x/1 right
-wait_reconfigure
-assert_size x/1 MONITOR_WIDTH/2 MONITOR_HEIGHT
-
-untile x/1
-wait_reconfigure
-assert_size x/1 300 200
-
-tile x/1 left
-wait_reconfigure
-assert_size x/1 MONITOR_WIDTH/2 MONITOR_HEIGHT
-
-maximize x/1
-wait_reconfigure
-assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-unmaximize x/1
-wait_reconfigure
-assert_size x/1 300 200
-
-# Check that Wayland clients restore to their right size after unmaximize
-# or untile
-
-new_client w wayland
-create w/1 csd
-
-resize w/1 150 300
-maximize w/1
-show w/1
-
-wait
-
-assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-unmaximize w/1
-wait_reconfigure
-
-assert_size w/1 150 300
-
-resize w/1 300 200
-wait
-maximize w/1
-wait_reconfigure
-unmaximize w/1
-wait_reconfigure
-
-assert_size w/1 300 200
-
-tile w/1 right
-wait_reconfigure
-assert_size w/1 MONITOR_WIDTH/2 MONITOR_HEIGHT
-
-untile w/1
-wait_reconfigure
-assert_size w/1 300 200
-
-tile w/1 left
-wait_reconfigure
-assert_size w/1 MONITOR_WIDTH/2 MONITOR_HEIGHT
-
-maximize w/1
-wait_reconfigure
-assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-unmaximize w/1
-wait_reconfigure
-assert_size w/1 300 200
diff --git a/src/tests/stacking/set-override-redirect-parent.metatest b/src/tests/stacking/set-override-redirect-parent.metatest
deleted file mode 100644
index 4c98bee22..000000000
--- a/src/tests/stacking/set-override-redirect-parent.metatest
+++ /dev/null
@@ -1,37 +0,0 @@
-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
deleted file mode 100644
index 8dbb9c932..000000000
--- a/src/tests/stacking/set-parent-exported.metatest
+++ /dev/null
@@ -1,15 +0,0 @@
-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
deleted file mode 100644
index e95eaca29..000000000
--- a/src/tests/stacking/set-parent.metatest
+++ /dev/null
@@ -1,14 +0,0 @@
-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/stacking/unmaximize-new-size.metatest b/src/tests/stacking/unmaximize-new-size.metatest
deleted file mode 100644
index b25922a70..000000000
--- a/src/tests/stacking/unmaximize-new-size.metatest
+++ /dev/null
@@ -1,22 +0,0 @@
-# This is only tested on Wayland since it's broken on X11
-
-new_client w wayland
-create w/1 csd
-
-resize w/1 500 400
-show w/1
-wait
-
-assert_size w/1 500 400
-
-maximize w/1
-wait_reconfigure
-assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-resize w/1 300 500
-wait_reconfigure
-assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
-
-unmaximize w/1
-wait_reconfigure
-assert_size w/1 300 500
diff --git a/src/tests/stage-view-tests.c b/src/tests/stage-view-tests.c
deleted file mode 100644
index 509af37fb..000000000
--- a/src/tests/stage-view-tests.c
+++ /dev/null
@@ -1,1171 +0,0 @@
-/*
- * Copyright (C) 2020 Jonas Dreßler
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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 "clutter/clutter.h"
-#include "clutter/clutter-stage-view-private.h"
-#include "meta-test/meta-context-test.h"
-#include "tests/meta-backend-test.h"
-#include "tests/monitor-test-utils.h"
-
-static MonitorTestCaseSetup 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
-};
-
-static void
-meta_test_stage_views_exist (void)
-{
- MetaBackend *backend = meta_get_backend ();
- ClutterActor *stage;
- GList *stage_views;
-
- stage = meta_backend_get_stage (backend);
- g_assert_cmpint (clutter_actor_get_width (stage), ==, 1024 * 2);
- g_assert_cmpint (clutter_actor_get_height (stage), ==, 768);
-
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
- g_assert_cmpint (g_list_length (stage_views), ==, 2);
-}
-
-static void
-on_after_paint (ClutterStage *stage,
- ClutterStageView *view,
- gboolean *was_painted)
-{
- *was_painted = TRUE;
-}
-
-static void
-wait_for_paint (ClutterActor *stage)
-{
- gboolean was_painted = FALSE;
- gulong was_painted_id;
-
- was_painted_id = g_signal_connect (CLUTTER_STAGE (stage),
- "after-paint",
- G_CALLBACK (on_after_paint),
- &was_painted);
-
- while (!was_painted)
- g_main_context_iteration (NULL, TRUE);
-
- g_signal_handler_disconnect (stage, was_painted_id);
-}
-
-static void
-on_stage_views_changed (ClutterActor *actor,
- gboolean *stage_views_changed)
-{
- *stage_views_changed = TRUE;
-}
-
-static void
-is_on_stage_views (ClutterActor *actor,
- unsigned int n_views,
- ...)
-{
- va_list valist;
- int i = 0;
- GList *stage_views = clutter_actor_peek_stage_views (actor);
-
- va_start (valist, n_views);
- for (i = 0; i < n_views; i++)
- {
- ClutterStageView *view = va_arg (valist, ClutterStageView*);
- g_assert_nonnull (g_list_find (stage_views, view));
- }
-
- va_end (valist);
- g_assert (g_list_length (stage_views) == n_views);
-}
-
-static void
-meta_test_actor_stage_views (void)
-{
- MetaBackend *backend = meta_get_backend ();
- ClutterActor *stage, *container, *test_actor;
- GList *stage_views;
- gboolean stage_views_changed_container = FALSE;
- gboolean stage_views_changed_test_actor = FALSE;
- gboolean *stage_views_changed_container_ptr =
- &stage_views_changed_container;
- gboolean *stage_views_changed_test_actor_ptr =
- &stage_views_changed_test_actor;
-
- stage = meta_backend_get_stage (backend);
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
-
- container = clutter_actor_new ();
- clutter_actor_set_size (container, 100, 100);
- clutter_actor_add_child (stage, container);
-
- test_actor = clutter_actor_new ();
- clutter_actor_set_size (test_actor, 50, 50);
- clutter_actor_add_child (container, test_actor);
-
- g_signal_connect (container, "stage-views-changed",
- G_CALLBACK (on_stage_views_changed),
- stage_views_changed_container_ptr);
- g_signal_connect (test_actor, "stage-views-changed",
- G_CALLBACK (on_stage_views_changed),
- stage_views_changed_test_actor_ptr);
-
- clutter_actor_show (stage);
-
- wait_for_paint (stage);
-
- is_on_stage_views (container, 1, stage_views->data);
- is_on_stage_views (test_actor, 1, stage_views->data);
-
- /* The signal was emitted for the initial change */
- g_assert (stage_views_changed_container);
- g_assert (stage_views_changed_test_actor);
- stage_views_changed_container = FALSE;
- stage_views_changed_test_actor = FALSE;
-
- /* Move the container to the second stage view */
- clutter_actor_set_x (container, 1040);
-
- wait_for_paint (stage);
-
- is_on_stage_views (container, 1, stage_views->next->data);
- is_on_stage_views (test_actor, 1, stage_views->next->data);
-
- /* The signal was emitted again */
- g_assert (stage_views_changed_container);
- g_assert (stage_views_changed_test_actor);
- stage_views_changed_container = FALSE;
- stage_views_changed_test_actor = FALSE;
-
- /* Move the container so it's on both stage views while the test_actor
- * is only on the first one.
- */
- clutter_actor_set_x (container, 940);
-
- wait_for_paint (stage);
-
- is_on_stage_views (container, 2, stage_views->data, stage_views->next->data);
- is_on_stage_views (test_actor, 1, stage_views->data);
-
- /* The signal was emitted again */
- g_assert (stage_views_changed_container);
- g_assert (stage_views_changed_test_actor);
-
- g_signal_handlers_disconnect_by_func (container, on_stage_views_changed,
- stage_views_changed_container_ptr);
- g_signal_handlers_disconnect_by_func (test_actor, on_stage_views_changed,
- stage_views_changed_test_actor_ptr);
- clutter_actor_destroy (container);
-}
-
-static void
-on_relayout_actor_frame (ClutterTimeline *timeline,
- int msec,
- ClutterActor *actor)
-{
- MetaBackend *backend = meta_get_backend ();
- ClutterActor *stage = meta_backend_get_stage (backend);
-
- clutter_stage_clear_stage_views (CLUTTER_STAGE (stage));
-}
-
-static void
-meta_test_actor_stage_views_relayout (void)
-{
- MetaBackend *backend = meta_get_backend ();
- ClutterActor *stage, *actor;
- ClutterTransition *transition;
- GMainLoop *main_loop;
-
- stage = meta_backend_get_stage (backend);
-
- actor = clutter_actor_new ();
- clutter_actor_set_size (actor, 100, 100);
- clutter_actor_set_easing_duration (actor, 100);
- clutter_actor_add_child (stage, actor);
-
- clutter_actor_show (stage);
-
- wait_for_paint (stage);
- clutter_actor_set_position (actor, 1000.0, 0.0);
- transition = clutter_actor_get_transition (actor, "position");
- g_signal_connect_after (transition, "new-frame",
- G_CALLBACK (on_relayout_actor_frame),
- actor);
-
- main_loop = g_main_loop_new (NULL, FALSE);
- g_signal_connect_swapped (transition, "stopped",
- G_CALLBACK (g_main_loop_quit),
- main_loop);
-
- g_main_loop_run (main_loop);
-
- clutter_actor_destroy (actor);
- g_main_loop_unref (main_loop);
-}
-
-static void
-meta_test_actor_stage_views_reparent (void)
-{
- MetaBackend *backend = meta_get_backend ();
- ClutterActor *stage, *container, *test_actor;
- GList *stage_views;
- gboolean stage_views_changed_container = FALSE;
- gboolean stage_views_changed_test_actor = FALSE;
- gboolean *stage_views_changed_container_ptr =
- &stage_views_changed_container;
- gboolean *stage_views_changed_test_actor_ptr =
- &stage_views_changed_test_actor;
-
- stage = meta_backend_get_stage (backend);
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
-
- container = clutter_actor_new ();
- clutter_actor_set_size (container, 100, 100);
- clutter_actor_set_x (container, 1020);
- clutter_actor_add_child (stage, container);
-
- test_actor = clutter_actor_new ();
- clutter_actor_set_size (test_actor, 20, 20);
- clutter_actor_add_child (container, test_actor);
-
- g_signal_connect (container, "stage-views-changed",
- G_CALLBACK (on_stage_views_changed),
- stage_views_changed_container_ptr);
- g_signal_connect (test_actor, "stage-views-changed",
- G_CALLBACK (on_stage_views_changed),
- stage_views_changed_test_actor_ptr);
-
- clutter_actor_show (stage);
-
- wait_for_paint (stage);
-
- is_on_stage_views (container, 2, stage_views->data, stage_views->next->data);
- is_on_stage_views (test_actor, 2, stage_views->data, stage_views->next->data);
-
- /* The signal was emitted for both actors */
- g_assert (stage_views_changed_container);
- g_assert (stage_views_changed_test_actor);
- stage_views_changed_container = FALSE;
- stage_views_changed_test_actor = FALSE;
-
- /* Remove the test_actor from the scene-graph */
- g_object_ref (test_actor);
- clutter_actor_remove_child (container, test_actor);
-
- /* While the test_actor is not on stage, it must be on no stage views */
- is_on_stage_views (test_actor, 0);
-
- /* When the test_actor left the stage, the signal was emitted */
- g_assert (!stage_views_changed_container);
- g_assert (stage_views_changed_test_actor);
- stage_views_changed_test_actor = FALSE;
-
- /* Add the test_actor again as a child of the stage */
- clutter_actor_add_child (stage, test_actor);
- g_object_unref (test_actor);
-
- wait_for_paint (stage);
-
- /* The container is still on both stage views... */
- is_on_stage_views (container, 2, stage_views->data, stage_views->next->data);
-
- /* ...while the test_actor is only on the first one now */
- is_on_stage_views (test_actor, 1, stage_views->data);
-
- /* The signal was emitted for the test_actor again */
- g_assert (!stage_views_changed_container);
- g_assert (stage_views_changed_test_actor);
- stage_views_changed_test_actor = FALSE;
-
- /* Move the container out of the stage... */
- clutter_actor_set_y (container, 2000);
- g_object_ref (test_actor);
- clutter_actor_remove_child (stage, test_actor);
-
- /* When the test_actor left the stage, the signal was emitted */
- g_assert (!stage_views_changed_container);
- g_assert (stage_views_changed_test_actor);
- stage_views_changed_test_actor = FALSE;
-
- /* ...and reparent the test_actor to the container again */
- clutter_actor_add_child (container, test_actor);
- g_object_unref (test_actor);
-
- wait_for_paint (stage);
-
- /* Now both actors are on no stage views */
- is_on_stage_views (container, 0);
- is_on_stage_views (test_actor, 0);
-
- /* The signal was emitted only for the container, the test_actor already
- * has no stage-views.
- */
- g_assert (stage_views_changed_container);
- g_assert (!stage_views_changed_test_actor);
-
- g_signal_handlers_disconnect_by_func (container, on_stage_views_changed,
- stage_views_changed_container_ptr);
- g_signal_handlers_disconnect_by_func (test_actor, on_stage_views_changed,
- stage_views_changed_test_actor_ptr);
- clutter_actor_destroy (container);
-}
-
-static void
-meta_test_actor_stage_views_hide_parent (void)
-{
- MetaBackend *backend = meta_get_backend ();
- ClutterActor *stage, *outer_container, *inner_container, *test_actor;
- GList *stage_views;
- gboolean stage_views_changed_outer_container = FALSE;
- gboolean stage_views_changed_inner_container = FALSE;
- gboolean stage_views_changed_test_actor = FALSE;
- gboolean *stage_views_changed_outer_container_ptr =
- &stage_views_changed_outer_container;
- gboolean *stage_views_changed_inner_container_ptr =
- &stage_views_changed_inner_container;
- gboolean *stage_views_changed_test_actor_ptr =
- &stage_views_changed_test_actor;
-
- stage = meta_backend_get_stage (backend);
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
-
- outer_container = clutter_actor_new ();
- clutter_actor_add_child (stage, outer_container);
-
- inner_container = clutter_actor_new ();
- clutter_actor_add_child (outer_container, inner_container);
-
- test_actor = clutter_actor_new ();
- clutter_actor_set_size (test_actor, 20, 20);
- clutter_actor_add_child (inner_container, test_actor);
-
- g_signal_connect (outer_container, "stage-views-changed",
- G_CALLBACK (on_stage_views_changed),
- stage_views_changed_outer_container_ptr);
- g_signal_connect (inner_container, "stage-views-changed",
- G_CALLBACK (on_stage_views_changed),
- stage_views_changed_inner_container_ptr);
- g_signal_connect (test_actor, "stage-views-changed",
- G_CALLBACK (on_stage_views_changed),
- stage_views_changed_test_actor_ptr);
-
- clutter_actor_show (stage);
-
- wait_for_paint (stage);
-
- /* The containers and the test_actor are on all on the first view */
- is_on_stage_views (outer_container, 1, stage_views->data);
- is_on_stage_views (inner_container, 1, stage_views->data);
- is_on_stage_views (test_actor, 1, stage_views->data);
-
- /* The signal was emitted for all three */
- g_assert (stage_views_changed_outer_container);
- g_assert (stage_views_changed_inner_container);
- g_assert (stage_views_changed_test_actor);
- stage_views_changed_outer_container = FALSE;
- stage_views_changed_inner_container = FALSE;
- stage_views_changed_test_actor = FALSE;
-
- /* Hide the inner_container */
- clutter_actor_hide (inner_container);
-
- /* Move the outer_container so it's still on the first view */
- clutter_actor_set_x (outer_container, 1023);
-
- wait_for_paint (stage);
-
- /* The outer_container is still expanded so it should be on both views */
- is_on_stage_views (outer_container, 2,
- stage_views->data, stage_views->next->data);
-
- /* The inner_container and test_actor aren't updated because they're hidden */
- is_on_stage_views (inner_container, 1, stage_views->data);
- is_on_stage_views (test_actor, 1, stage_views->data);
-
- /* The signal was emitted for the outer_container */
- g_assert (stage_views_changed_outer_container);
- g_assert (!stage_views_changed_inner_container);
- g_assert (!stage_views_changed_test_actor);
- stage_views_changed_outer_container = FALSE;
-
- /* Show the inner_container again */
- clutter_actor_show (inner_container);
-
- wait_for_paint (stage);
-
- /* All actors are on both views now */
- is_on_stage_views (outer_container, 2,
- stage_views->data, stage_views->next->data);
- is_on_stage_views (inner_container, 2,
- stage_views->data, stage_views->next->data);
- is_on_stage_views (test_actor, 2,
- stage_views->data, stage_views->next->data);
-
- /* The signal was emitted for the inner_container and test_actor */
- g_assert (!stage_views_changed_outer_container);
- g_assert (stage_views_changed_inner_container);
- g_assert (stage_views_changed_test_actor);
-
- g_signal_handlers_disconnect_by_func (outer_container, on_stage_views_changed,
- stage_views_changed_outer_container_ptr);
- g_signal_handlers_disconnect_by_func (inner_container, on_stage_views_changed,
- stage_views_changed_inner_container_ptr);
- g_signal_handlers_disconnect_by_func (test_actor, on_stage_views_changed,
- stage_views_changed_test_actor_ptr);
- clutter_actor_destroy (outer_container);
-}
-
-static MetaMonitorTestSetup *
-create_stage_view_test_setup (void)
-{
- return create_monitor_test_setup (&initial_test_case_setup,
- MONITOR_TEST_FLAG_NO_STORED);
-}
-
-static void
-assert_is_stage_view (ClutterStageView *stage_view,
- int x,
- int y,
- int width,
- int height)
-{
- cairo_rectangle_int_t layout;
-
- g_assert_nonnull (stage_view);
- g_assert_true (CLUTTER_IS_STAGE_VIEW (stage_view));
-
- clutter_stage_view_get_layout (stage_view, &layout);
- g_assert_cmpint (layout.x, ==, x);
- g_assert_cmpint (layout.y, ==, y);
- g_assert_cmpint (layout.width, ==, width);
- g_assert_cmpint (layout.height, ==, height);
-}
-
-static void
-meta_test_actor_stage_views_hot_plug (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);
- ClutterActor *stage = meta_backend_get_stage (backend);
- ClutterActor *actor_1;
- ClutterActor *actor_2;
- GList *stage_views;
- GList *prev_stage_views;
- MonitorTestCaseSetup hotplug_test_case_setup = initial_test_case_setup;
- MetaMonitorTestSetup *test_setup;
-
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
- g_assert_cmpint (g_list_length (stage_views), ==, 2);
- assert_is_stage_view (stage_views->data, 0, 0, 1024, 768);
- assert_is_stage_view (stage_views->next->data, 1024, 0, 1024, 768);
-
- actor_1 = clutter_actor_new ();
- clutter_actor_set_size (actor_1, 100, 100);
- clutter_actor_set_position (actor_1, 100, 100);
- clutter_actor_add_child (stage, actor_1);
-
- actor_2 = clutter_actor_new ();
- clutter_actor_set_size (actor_2, 100, 100);
- clutter_actor_set_position (actor_2, 1100, 100);
- clutter_actor_add_child (stage, actor_2);
-
- clutter_actor_show (stage);
-
- wait_for_paint (stage);
-
- is_on_stage_views (actor_1, 1, stage_views->data);
- is_on_stage_views (actor_2, 1, stage_views->next->data);
-
- prev_stage_views = g_list_copy_deep (stage_views,
- (GCopyFunc) g_object_ref, NULL);
-
- test_setup = create_monitor_test_setup (&hotplug_test_case_setup,
- MONITOR_TEST_FLAG_NO_STORED);
- meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup);
-
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
-
- g_assert (stage_views != prev_stage_views);
- g_assert_cmpint (g_list_length (stage_views), ==, 2);
- g_assert (prev_stage_views->data != stage_views->data);
- g_assert (prev_stage_views->next->data != stage_views->next->data);
- assert_is_stage_view (stage_views->data, 0, 0, 1024, 768);
- assert_is_stage_view (stage_views->next->data, 1024, 0, 1024, 768);
-
- g_list_free_full (prev_stage_views, (GDestroyNotify) g_object_unref);
-
- is_on_stage_views (actor_1, 0);
- is_on_stage_views (actor_2, 0);
-
- wait_for_paint (stage);
-
- is_on_stage_views (actor_1, 1, stage_views->data);
- is_on_stage_views (actor_2, 1, stage_views->next->data);
-
- clutter_actor_destroy (actor_1);
- clutter_actor_destroy (actor_2);
-}
-
-static void
-meta_test_actor_stage_views_frame_clock (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);
- ClutterActor *stage = meta_backend_get_stage (backend);
- ClutterActor *actor_1;
- ClutterActor *actor_2;
- ClutterActor *actor_3;
- GList *stage_views;
- MonitorTestCaseSetup frame_clock_test_setup = initial_test_case_setup;
- MetaMonitorTestSetup *test_setup;
- ClutterFrameClock *frame_clock;
-
- frame_clock_test_setup.modes[1].width = 1024;
- frame_clock_test_setup.modes[1].height = 768;
- frame_clock_test_setup.modes[1].refresh_rate = 30.0;
- frame_clock_test_setup.n_modes = 2;
- frame_clock_test_setup.outputs[1].modes[0] = 1;
- frame_clock_test_setup.outputs[1].preferred_mode = 1;
- test_setup = create_monitor_test_setup (&frame_clock_test_setup,
- MONITOR_TEST_FLAG_NO_STORED);
- meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup);
-
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
-
- g_assert_cmpfloat (clutter_stage_view_get_refresh_rate (stage_views->data),
- ==,
- 60.0);
- g_assert_cmpfloat (clutter_stage_view_get_refresh_rate (stage_views->next->data),
- ==,
- 30.0);
-
- actor_1 = clutter_actor_new ();
- clutter_actor_set_size (actor_1, 100, 100);
- clutter_actor_set_position (actor_1, 100, 100);
- clutter_actor_add_child (stage, actor_1);
-
- actor_2 = clutter_actor_new ();
- clutter_actor_set_size (actor_2, 100, 100);
- clutter_actor_set_position (actor_2, 1100, 100);
- clutter_actor_add_child (stage, actor_2);
-
- actor_3 = clutter_actor_new ();
- clutter_actor_set_size (actor_3, 100, 100);
- clutter_actor_set_position (actor_3, 1000, 400);
- clutter_actor_add_child (stage, actor_3);
-
- clutter_actor_show (stage);
-
- wait_for_paint (stage);
-
- is_on_stage_views (actor_1, 1, stage_views->data);
- is_on_stage_views (actor_2, 1, stage_views->next->data);
- is_on_stage_views (actor_3, 2,
- stage_views->data,
- stage_views->next->data);
-
- frame_clock = clutter_actor_pick_frame_clock (actor_1, NULL);
- g_assert_cmpfloat (clutter_frame_clock_get_refresh_rate (frame_clock),
- ==,
- 60.0);
- frame_clock = clutter_actor_pick_frame_clock (actor_2, NULL);
- g_assert_cmpfloat (clutter_frame_clock_get_refresh_rate (frame_clock),
- ==,
- 30.0);
- frame_clock = clutter_actor_pick_frame_clock (actor_3, NULL);
- g_assert_cmpfloat (clutter_frame_clock_get_refresh_rate (frame_clock),
- ==,
- 60.0);
-
- clutter_actor_destroy (actor_1);
- clutter_actor_destroy (actor_2);
- clutter_actor_destroy (actor_3);
-}
-
-typedef struct _TimelineTest
-{
- GMainLoop *main_loop;
- ClutterFrameClock *frame_clock_1;
- ClutterFrameClock *frame_clock_2;
- int phase;
-
- int frame_counter[2];
-} TimelineTest;
-
-static void
-on_transition_stopped (ClutterTransition *transition,
- gboolean is_finished,
- TimelineTest *test)
-{
- g_assert_true (is_finished);
-
- g_assert_cmpint (test->phase, ==, 2);
-
- test->phase = 3;
-
- g_main_loop_quit (test->main_loop);
-}
-
-static void
-on_transition_new_frame (ClutterTransition *transition,
- int elapsed_time_ms,
- TimelineTest *test)
-{
- ClutterTimeline *timeline = CLUTTER_TIMELINE (transition);
-
- if (test->phase == 1)
- {
- g_assert (clutter_timeline_get_frame_clock (timeline) ==
- test->frame_clock_1);
- test->frame_counter[0]++;
- }
- else if (test->phase == 2)
- {
- g_assert (clutter_timeline_get_frame_clock (timeline) ==
- test->frame_clock_2);
- test->frame_counter[1]++;
- }
- else
- {
- g_assert_not_reached ();
- }
-}
-
-static void
-on_transition_frame_clock_changed (ClutterTimeline *timeline,
- GParamSpec *pspec,
- TimelineTest *test)
-{
- ClutterFrameClock *frame_clock;
-
- frame_clock = clutter_timeline_get_frame_clock (timeline);
- g_assert (frame_clock == test->frame_clock_2);
- g_assert_cmpint (test->phase, ==, 1);
-
- test->phase = 2;
-}
-
-static void
-meta_test_actor_stage_views_timeline (void)
-{
- TimelineTest test = { 0 };
- MetaBackend *backend = meta_get_backend ();
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- MetaMonitorManagerTest *monitor_manager_test =
- META_MONITOR_MANAGER_TEST (monitor_manager);
- ClutterActor *stage = meta_backend_get_stage (backend);
- MonitorTestCaseSetup frame_clock_test_setup;
- ClutterActor *actor;
- GList *stage_views;
- ClutterStageView *stage_view_1;
- ClutterStageView *stage_view_2;
- MetaMonitorTestSetup *test_setup;
- ClutterTransition *transition;
-
- frame_clock_test_setup = initial_test_case_setup;
- frame_clock_test_setup.modes[1].width = 1024;
- frame_clock_test_setup.modes[1].height = 768;
- frame_clock_test_setup.modes[1].refresh_rate = 30.0;
- frame_clock_test_setup.n_modes = 2;
- frame_clock_test_setup.outputs[1].modes[0] = 1;
- frame_clock_test_setup.outputs[1].preferred_mode = 1;
- test_setup = create_monitor_test_setup (&frame_clock_test_setup,
- MONITOR_TEST_FLAG_NO_STORED);
- meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup);
-
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
- stage_view_1 = stage_views->data;
- stage_view_2 = stage_views->next->data;
- g_assert_nonnull (stage_view_1);
- g_assert_nonnull (stage_view_2);
- test.frame_clock_1 = clutter_stage_view_get_frame_clock (stage_view_1);
- test.frame_clock_2 = clutter_stage_view_get_frame_clock (stage_view_2);
- g_assert_nonnull (test.frame_clock_1);
- g_assert_nonnull (test.frame_clock_2);
-
- actor = clutter_actor_new ();
- clutter_actor_set_size (actor, 100, 100);
- clutter_actor_set_position (actor, 800, 100);
- clutter_actor_add_child (stage, actor);
-
- clutter_actor_show (stage);
-
- wait_for_paint (stage);
-
- is_on_stage_views (actor, 1, stage_views->data);
-
- clutter_actor_set_easing_duration (actor, 1000);
- clutter_actor_set_position (actor, 1200, 300);
-
- transition = clutter_actor_get_transition (actor, "position");
- g_assert_nonnull (transition);
- g_assert (clutter_timeline_get_frame_clock (CLUTTER_TIMELINE (transition)) ==
- test.frame_clock_1);
-
- test.main_loop = g_main_loop_new (NULL, FALSE);
- g_signal_connect (transition, "stopped",
- G_CALLBACK (on_transition_stopped),
- &test);
- g_signal_connect (transition, "new-frame",
- G_CALLBACK (on_transition_new_frame),
- &test);
- g_signal_connect (transition, "notify::frame-clock",
- G_CALLBACK (on_transition_frame_clock_changed),
- &test);
-
- test.phase = 1;
-
- g_main_loop_run (test.main_loop);
-
- g_assert_cmpint (test.phase, ==, 3);
- g_assert_cmpint (test.frame_counter[0], >, 0);
- g_assert_cmpint (test.frame_counter[1], >, 0);
-
- clutter_actor_destroy (actor);
- g_main_loop_unref (test.main_loop);
-}
-
-static void
-meta_test_actor_stage_views_parent_views_rebuilt (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);
- MonitorTestCaseSetup frame_clock_test_setup;
- MetaMonitorTestSetup *test_setup;
- ClutterActor *stage, *container, *test_actor;
- GList *stage_views;
- ClutterTimeline *timeline;
- ClutterFrameClock *timeline_frame_clock;
- ClutterFrameClock *view_frame_clock;
- ClutterStageView *old_stage_view;
- ClutterFrameClock *old_frame_clock;
-
- stage = meta_backend_get_stage (backend);
-
- frame_clock_test_setup = initial_test_case_setup;
- frame_clock_test_setup.n_outputs = 1;
- frame_clock_test_setup.n_crtcs = 1;
- test_setup = create_monitor_test_setup (&frame_clock_test_setup,
- MONITOR_TEST_FLAG_NO_STORED);
- meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup);
-
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
- g_assert_cmpint (g_list_length (stage_views), ==, 1);
-
- container = clutter_actor_new ();
- clutter_actor_set_size (container, 100, 100);
- clutter_actor_set_position (container, 0, 0);
- clutter_actor_add_child (stage, container);
-
- test_actor = clutter_actor_new ();
- clutter_actor_set_size (test_actor, 0, 0);
- clutter_actor_add_child (container, test_actor);
-
- clutter_actor_show (stage);
- wait_for_paint (stage);
-
- is_on_stage_views (test_actor, 0);
- is_on_stage_views (container, 1, stage_views->data);
- is_on_stage_views (stage, 1, stage_views->data);
-
- timeline = clutter_timeline_new_for_actor (test_actor, 100);
- clutter_timeline_start (timeline);
-
- timeline_frame_clock = clutter_timeline_get_frame_clock (timeline);
- view_frame_clock = clutter_stage_view_get_frame_clock (stage_views->data);
- g_assert_nonnull (timeline_frame_clock);
- g_assert_nonnull (view_frame_clock);
- g_assert (timeline_frame_clock == view_frame_clock);
-
- /* Keep the stage view alive so it can be used to compare with later. */
- old_stage_view = g_object_ref (stage_views->data);
- old_frame_clock =
- g_object_ref (clutter_stage_view_get_frame_clock (old_stage_view));
-
- test_setup = create_monitor_test_setup (&frame_clock_test_setup,
- MONITOR_TEST_FLAG_NO_STORED);
- meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup);
- wait_for_paint (stage);
-
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
- g_assert_cmpint (g_list_length (stage_views), ==, 1);
-
- g_assert (stage_views->data != old_stage_view);
- view_frame_clock = clutter_stage_view_get_frame_clock (stage_views->data);
- g_assert_nonnull (view_frame_clock);
- g_assert (view_frame_clock != old_frame_clock);
-
- timeline_frame_clock = clutter_timeline_get_frame_clock (timeline);
- g_assert_nonnull (timeline_frame_clock);
- g_assert (timeline_frame_clock == view_frame_clock);
-
- g_object_unref (old_stage_view);
- g_object_unref (old_frame_clock);
-
- clutter_actor_destroy (test_actor);
- clutter_actor_destroy (container);
-}
-
-static void
-meta_test_actor_stage_views_parent_views_changed (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);
- MonitorTestCaseSetup frame_clock_test_setup;
- MetaMonitorTestSetup *test_setup;
- ClutterActor *stage, *container, *test_actor;
- GList *stage_views;
- ClutterTimeline *timeline;
- ClutterFrameClock *timeline_frame_clock;
- ClutterFrameClock *first_view_frame_clock;
- ClutterFrameClock *second_view_frame_clock;
-
- stage = meta_backend_get_stage (backend);
-
- frame_clock_test_setup = initial_test_case_setup;
- test_setup = create_monitor_test_setup (&frame_clock_test_setup,
- MONITOR_TEST_FLAG_NO_STORED);
- meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup);
-
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
- g_assert_cmpint (g_list_length (stage_views), ==, 2);
-
- container = clutter_actor_new ();
- clutter_actor_set_size (container, 100, 100);
- clutter_actor_set_position (container, 0, 0);
- clutter_actor_add_child (stage, container);
-
- test_actor = clutter_actor_new ();
- clutter_actor_set_size (test_actor, 0, 0);
- clutter_actor_add_child (container, test_actor);
-
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
- g_assert_cmpint (g_list_length (stage_views), ==, 2);
- clutter_actor_show (stage);
- wait_for_paint (stage);
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
- g_assert_cmpint (g_list_length (stage_views), ==, 2);
-
- is_on_stage_views (test_actor, 0);
- is_on_stage_views (container, 1, stage_views->data);
- is_on_stage_views (stage, 2,
- stage_views->data,
- stage_views->next->data);
-
- timeline = clutter_timeline_new_for_actor (test_actor, 100);
- clutter_timeline_start (timeline);
-
- first_view_frame_clock =
- clutter_stage_view_get_frame_clock (stage_views->data);
- second_view_frame_clock =
- clutter_stage_view_get_frame_clock (stage_views->next->data);
- g_assert_nonnull (first_view_frame_clock);
- g_assert_nonnull (second_view_frame_clock);
-
- timeline_frame_clock = clutter_timeline_get_frame_clock (timeline);
-
- g_assert_nonnull (timeline_frame_clock);
- g_assert (timeline_frame_clock == first_view_frame_clock);
-
- clutter_actor_set_x (container, 1200);
- wait_for_paint (stage);
-
- timeline_frame_clock = clutter_timeline_get_frame_clock (timeline);
- g_assert_nonnull (timeline_frame_clock);
- g_assert (timeline_frame_clock == second_view_frame_clock);
-
- clutter_actor_destroy (test_actor);
- clutter_actor_destroy (container);
-}
-
-static void
-meta_test_actor_stage_views_and_frame_clocks_freed (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);
- ClutterActor *stage = meta_backend_get_stage (backend);
- ClutterActor *actor_1;
- ClutterActor *actor_2;
- GList *stage_views;
- ClutterStageView *first_view;
- ClutterStageView *second_view;
- ClutterTimeline *timeline;
- ClutterFrameClock *timeline_frame_clock;
- ClutterFrameClock *first_view_frame_clock;
- ClutterFrameClock *second_view_frame_clock;
- MonitorTestCaseSetup frame_clock_test_setup;
- MetaMonitorTestSetup *test_setup;
-
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
- first_view = stage_views->data;
- second_view = stage_views->next->data;
-
- g_object_add_weak_pointer (G_OBJECT (first_view), (gpointer *) &first_view);
- g_object_add_weak_pointer (G_OBJECT (second_view), (gpointer *) &second_view);
-
- /* Create two actors, one on the first stage view, another one on the
- * second view.
- */
- actor_1 = clutter_actor_new ();
- clutter_actor_set_size (actor_1, 100, 100);
- clutter_actor_set_position (actor_1, 100, 100);
- clutter_actor_add_child (stage, actor_1);
-
- actor_2 = clutter_actor_new ();
- clutter_actor_set_size (actor_2, 100, 100);
- clutter_actor_set_position (actor_2, 1100, 100);
- clutter_actor_add_child (stage, actor_2);
-
- clutter_actor_show (stage);
-
- wait_for_paint (stage);
-
- is_on_stage_views (actor_1, 1, first_view);
- is_on_stage_views (actor_2, 1, second_view);
-
- /* Now create a timeline for the first actor and make sure its using the
- * frame clock of the first view.
- */
- timeline = clutter_timeline_new_for_actor (actor_1, 100);
- clutter_timeline_start (timeline);
-
- first_view_frame_clock =
- clutter_stage_view_get_frame_clock (first_view);
- second_view_frame_clock =
- clutter_stage_view_get_frame_clock (second_view);
- g_assert_nonnull (first_view_frame_clock);
- g_assert_nonnull (second_view_frame_clock);
-
- g_object_add_weak_pointer (G_OBJECT (first_view_frame_clock),
- (gpointer *) &first_view_frame_clock);
- g_object_add_weak_pointer (G_OBJECT (second_view_frame_clock),
- (gpointer *) &second_view_frame_clock);
-
- timeline_frame_clock = clutter_timeline_get_frame_clock (timeline);
-
- g_assert_nonnull (timeline_frame_clock);
- g_assert (timeline_frame_clock == first_view_frame_clock);
-
- /* Now set the timeline actor to actor_2 and make sure the timeline is
- * using the second frame clock.
- */
- clutter_timeline_set_actor (timeline, actor_2);
-
- timeline_frame_clock = clutter_timeline_get_frame_clock (timeline);
-
- g_assert_nonnull (timeline_frame_clock);
- g_assert (timeline_frame_clock == second_view_frame_clock);
-
- /* Trigger a hotplug and remove both monitors, after that the timeline
- * should have no frame clock set and both stage views and their
- * frame clocks should have been freed.
- */
- frame_clock_test_setup = initial_test_case_setup;
- frame_clock_test_setup.n_outputs = 0;
- frame_clock_test_setup.n_crtcs = 0;
- test_setup = create_monitor_test_setup (&frame_clock_test_setup,
- MONITOR_TEST_FLAG_NO_STORED);
- meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup);
-
- timeline_frame_clock = clutter_timeline_get_frame_clock (timeline);
-
- g_assert_null (timeline_frame_clock);
- g_assert_null (first_view);
- g_assert_null (first_view_frame_clock);
- g_assert_null (second_view);
- g_assert_null (second_view_frame_clock);
-
- clutter_actor_destroy (actor_1);
- clutter_actor_destroy (actor_2);
-}
-
-static void
-ensure_view_count (int n_views)
-{
- MetaBackend *backend = meta_get_backend ();
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- MetaMonitorManagerTest *monitor_manager_test =
- META_MONITOR_MANAGER_TEST (monitor_manager);
- MonitorTestCaseSetup test_case_setup;
- MetaMonitorTestSetup *test_setup;
-
- test_case_setup = initial_test_case_setup;
- test_case_setup.n_outputs = n_views;
- test_case_setup.n_crtcs = n_views;
- test_setup = create_monitor_test_setup (&test_case_setup,
- MONITOR_TEST_FLAG_NO_STORED);
- meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup);
-}
-
-static void
-meta_test_timeline_actor_destroyed (void)
-{
- MetaBackend *backend = meta_get_backend ();
- ClutterActor *stage;
- GList *stage_views;
- ClutterActor *persistent_actor;
- ClutterActor *actor;
- ClutterTimeline *timeline;
- gboolean did_stage_views_changed = FALSE;
-
- ensure_view_count (0);
-
- stage = meta_backend_get_stage (backend);
- clutter_actor_show (stage);
-
- persistent_actor = clutter_actor_new ();
- clutter_actor_add_child (stage, persistent_actor);
-
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
- g_assert_null (stage_views);
- stage_views = clutter_actor_peek_stage_views (stage);
- g_assert_null (stage_views);
- g_assert_null (clutter_actor_pick_frame_clock (stage, NULL));
-
- actor = clutter_actor_new ();
- clutter_actor_add_child (stage, actor);
- g_assert_null (clutter_actor_pick_frame_clock (actor, NULL));
-
- timeline = clutter_timeline_new_for_actor (actor, 100);
- clutter_timeline_start (timeline);
-
- g_signal_connect (stage, "stage-views-changed",
- G_CALLBACK (on_stage_views_changed),
- &did_stage_views_changed);
-
- clutter_actor_destroy (actor);
- g_object_unref (timeline);
-
- ensure_view_count (1);
-
- stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
- g_assert_cmpint (g_list_length (stage_views), ==, 1);
-
- g_assert_false (did_stage_views_changed);
- clutter_actor_queue_redraw (persistent_actor);
- clutter_stage_schedule_update (CLUTTER_STAGE (stage));
- wait_for_paint (stage);
- g_assert_true (did_stage_views_changed);
-
- g_signal_handlers_disconnect_by_func (stage, on_stage_views_changed,
- &did_stage_views_changed);
-
- clutter_actor_destroy (persistent_actor);
-}
-
-static void
-init_tests (void)
-{
- meta_monitor_manager_test_init_test_setup (create_stage_view_test_setup);
-
- g_test_add_func ("/stage-view/stage-views-exist",
- meta_test_stage_views_exist);
- g_test_add_func ("/stage-views/actor-stage-views",
- meta_test_actor_stage_views);
- g_test_add_func ("/stage-views/actor-stage-views-relayout",
- meta_test_actor_stage_views_relayout);
- g_test_add_func ("/stage-views/actor-stage-views-reparent",
- meta_test_actor_stage_views_reparent);
- g_test_add_func ("/stage-views/actor-stage-views-hide-parent",
- meta_test_actor_stage_views_hide_parent);
- g_test_add_func ("/stage-views/actor-stage-views-hot-plug",
- meta_test_actor_stage_views_hot_plug);
- g_test_add_func ("/stage-views/actor-stage-views-frame-clock",
- meta_test_actor_stage_views_frame_clock);
- g_test_add_func ("/stage-views/actor-stage-views-timeline",
- meta_test_actor_stage_views_timeline);
- g_test_add_func ("/stage-views/actor-stage-views-parent-rebuilt",
- meta_test_actor_stage_views_parent_views_rebuilt);
- g_test_add_func ("/stage-views/actor-stage-views-parent-changed",
- meta_test_actor_stage_views_parent_views_changed);
- g_test_add_func ("/stage-views/actor-stage-views-and-frame-clocks-freed",
- meta_test_actor_stage_views_and_frame_clocks_freed);
- g_test_add_func ("/stage-views/timeline/actor-destroyed",
- meta_test_timeline_actor_destroyed);
-}
-
-int
-main (int argc, char *argv[])
-{
- g_autoptr (MetaContext) context = NULL;
-
- context = meta_create_test_context (META_CONTEXT_TEST_TYPE_NESTED,
- META_CONTEXT_TEST_FLAG_NO_X11);
- g_assert (meta_context_configure (context, &argc, &argv, NULL));
-
- init_tests ();
-
- return meta_context_test_run_tests (META_CONTEXT_TEST (context));
-}
diff --git a/src/tests/test-client.c b/src/tests/test-client.c
deleted file mode 100644
index 73931375e..000000000
--- a/src/tests/test-client.c
+++ /dev/null
@@ -1,944 +0,0 @@
-/* -*- 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\n", 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\n", 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 int
-calculate_titlebar_height (GtkWindow *window)
-{
- GtkWidget *titlebar;
- GdkWindow *gdk_window;
-
- gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
- if (gdk_window_get_state (gdk_window) & GDK_WINDOW_STATE_FULLSCREEN)
- return 0;
-
- titlebar = gtk_window_get_titlebar (window);
- if (!titlebar)
- return 0;
-
- return gtk_widget_get_allocated_height (titlebar);
-}
-
-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\n", error->message);
- g_error_free (error);
- return;
- }
-
- if (argc < 1)
- {
- g_print ("Empty command\n");
- goto out;
- }
-
- if (strcmp (argv[0], "create") == 0)
- {
- int i;
-
- if (argc < 2)
- {
- g_print ("usage: create <id> [override|csd]\n");
- goto out;
- }
-
- if (g_hash_table_lookup (windows, argv[1]))
- {
- g_print ("window %s already exists\n", 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 exclusive\n");
- 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>\n");
- goto out;
- }
-
- GtkWidget *window = lookup_window (argv[1]);
- if (!window)
- {
- g_print ("unknown window %s\n", argv[1]);
- goto out;
- }
-
- GtkWidget *parent_window = lookup_window (argv[2]);
- if (!parent_window)
- {
- g_print ("unknown parent window %s\n", 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>\n");
- goto out;
- }
-
- GtkWidget *window = lookup_window (argv[1]);
- if (!window)
- {
- g_print ("unknown window %s\n", argv[1]);
- goto out;
- }
-
- GtkWidget *parent_window = lookup_window (argv[2]);
- if (!parent_window)
- {
- g_print ("unknown parent window %s\n", 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\n", argv[2]);
- }
- else if (strcmp (argv[0], "accept_focus") == 0)
- {
- if (argc != 3)
- {
- g_print ("usage: %s <window-id> [true|false]\n", argv[0]);
- goto out;
- }
-
- GtkWidget *window = lookup_window (argv[1]);
- if (!window)
- {
- g_print ("unknown window %s\n", 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\n",
- 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]\n", argv[0]);
- goto out;
- }
-
- GtkWidget *window = lookup_window (argv[1]);
- if (!window)
- {
- g_print ("unknown window %s\n", argv[1]);
- goto out;
- }
-
- if (wayland)
- {
- g_print ("%s not supported under wayland\n", 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\n",
- 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]\n", argv[0]);
- goto out;
- }
-
- GtkWidget *window = lookup_window (argv[1]);
- if (!window)
- {
- g_print ("unknown window %s\n", argv[1]);
- goto out;
- }
-
- if (wayland)
- {
- g_print ("%s not supported under wayland\n", argv[0]);
- goto out;
- }
-
- if (gtk_window_get_accept_focus (GTK_WINDOW (window)))
- {
- g_print ("%s not supported for input windows\n", 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\n",
- 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>\n");
- 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>\n");
- 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>\n");
- 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>\n");
- goto out;
- }
-
- GtkWidget *window = lookup_window (argv[1]);
- if (!window)
- goto out;
-
- int width = atoi (argv[2]);
- int height = atoi (argv[3]);
- int titlebar_height = calculate_titlebar_height (GTK_WINDOW (window));
- gtk_window_resize (GTK_WINDOW (window),
- width,
- height - titlebar_height);
- }
- else if (strcmp (argv[0], "raise") == 0)
- {
- if (argc != 2)
- {
- g_print ("usage: raise <id>\n");
- 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>\n");
- 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>\n");
- 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\n");
- 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\n");
- 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>\n");
- goto out;
- }
-
- if (wayland)
- {
- g_print ("usage: set_counter can only be used for X11\n");
- 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>\n");
- 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>\n");
- goto out;
- }
-
- GtkWidget *window = lookup_window (argv[1]);
- if (!window)
- goto out;
-
- gtk_window_deiconify (GTK_WINDOW (window));
- }
- else if (strcmp (argv[0], "maximize") == 0)
- {
- if (argc != 2)
- {
- g_print ("usage: maximize <id>\n");
- goto out;
- }
-
- GtkWidget *window = lookup_window (argv[1]);
- if (!window)
- goto out;
-
- gtk_window_maximize (GTK_WINDOW (window));
- }
- else if (strcmp (argv[0], "unmaximize") == 0)
- {
- if (argc != 2)
- {
- g_print ("usage: unmaximize <id>\n");
- goto out;
- }
-
- GtkWidget *window = lookup_window (argv[1]);
- if (!window)
- goto out;
-
- gtk_window_unmaximize (GTK_WINDOW (window));
- }
- else if (strcmp (argv[0], "fullscreen") == 0)
- {
- if (argc != 2)
- {
- g_print ("usage: fullscreen <id>\n");
- goto out;
- }
-
- GtkWidget *window = lookup_window (argv[1]);
- if (!window)
- goto out;
-
- gtk_window_fullscreen (GTK_WINDOW (window));
- }
- else if (strcmp (argv[0], "unfullscreen") == 0)
- {
- if (argc != 2)
- {
- g_print ("usage: unfullscreen <id>\n");
- goto out;
- }
-
- GtkWidget *window = lookup_window (argv[1]);
- if (!window)
- goto out;
-
- gtk_window_unfullscreen (GTK_WINDOW (window));
- }
- else if (strcmp (argv[0], "freeze") == 0)
- {
- if (argc != 2)
- {
- g_print ("usage: freeze <id>\n");
- goto out;
- }
-
- GtkWidget *window = lookup_window (argv[1]);
- if (!window)
- goto out;
-
- gdk_window_freeze_updates (gtk_widget_get_window (window));
- }
- else if (strcmp (argv[0], "thaw") == 0)
- {
- if (argc != 2)
- {
- g_print ("usage: thaw <id>\n");
- goto out;
- }
-
- GtkWidget *window = lookup_window (argv[1]);
- if (!window)
- goto out;
-
- gdk_window_thaw_updates (gtk_widget_get_window (window));
- }
- else if (strcmp (argv[0], "assert_size") == 0)
- {
- int expected_width;
- int expected_height;
- int width;
- int height;
-
- if (argc != 4)
- {
- g_print ("usage: assert_size <id> <width> <height>\n");
- goto out;
- }
-
- GtkWidget *window = lookup_window (argv[1]);
- if (!window)
- goto out;
-
- gtk_window_get_size (GTK_WINDOW (window), &width, &height);
- height += calculate_titlebar_height (GTK_WINDOW (window));
-
- expected_width = atoi (argv[2]);
- expected_height = atoi (argv[3]);
- if (expected_width != width || expected_height != height)
- {
- g_print ("Expected size %dx%d didn't match actual size %dx%d\n",
- expected_width, expected_height,
- width, height);
- goto out;
- }
- }
- else
- {
- g_print ("Unknown command %s\n", 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);
- GdkScreen *screen;
- GtkCssProvider *provider;
- 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);
-
- screen = gdk_screen_get_default ();
- provider = gtk_css_provider_new ();
- static const char *no_decoration_css =
- "decoration {"
- " border-radius: 0 0 0 0;"
- " border-width: 0;"
- " padding: 0 0 0 0;"
- " box-shadow: 0 0 0 0 rgba(0, 0, 0, 0), 0 0 0 0 rgba(0, 0, 0, 0);"
- " margin: 0px;"
- "}";
- if (!gtk_css_provider_load_from_data (provider,
- no_decoration_css,
- strlen (no_decoration_css),
- &error))
- {
- g_printerr ("%s", error->message);
- return 1;
- }
- gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider),
- GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
-
- 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
deleted file mode 100644
index bdf2ef109..000000000
--- a/src/tests/test-runner.c
+++ /dev/null
@@ -1,1202 +0,0 @@
-/* -*- 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 "core/window-private.h"
-#include "meta-test/meta-context-test.h"
-#include "meta/util.h"
-#include "meta/window.h"
-#include "tests/meta-test-utils.h"
-#include "ui/ui.h"
-#include "wayland/meta-wayland.h"
-#include "x11/meta-x11-display-private.h"
-
-typedef struct {
- MetaContext *context;
- GHashTable *clients;
- MetaAsyncWaiter *waiter;
- GString *warning_messages;
- GMainLoop *loop;
- gulong x11_display_opened_handler_id;
-} TestCase;
-
-static gboolean
-test_case_alarm_filter (MetaX11Display *x11_display,
- XSyncAlarmNotifyEvent *event,
- gpointer data)
-{
- TestCase *test = data;
- GHashTableIter iter;
- gpointer key, value;
-
- if (meta_async_waiter_process_x11_event (test->waiter, x11_display, event))
- return TRUE;
-
- g_hash_table_iter_init (&iter, test->clients);
- while (g_hash_table_iter_next (&iter, &key, &value))
- {
- MetaTestClient *client = value;
-
- if (meta_test_client_process_x11_event (client, x11_display, event))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-on_x11_display_opened (MetaDisplay *display,
- TestCase *test)
-{
- meta_x11_display_set_alarm_filter (display->x11_display,
- test_case_alarm_filter, test);
- test->waiter = meta_async_waiter_new ();
-}
-
-static TestCase *
-test_case_new (MetaContext *context)
-{
- TestCase *test = g_new0 (TestCase, 1);
- MetaDisplay *display = meta_context_get_display (context);
-
- if (!meta_is_wayland_compositor ())
- {
- meta_context_test_wait_for_x11_display (META_CONTEXT_TEST (context));
- on_x11_display_opened (display, test);
- }
- else
- {
- if (display->x11_display)
- on_x11_display_opened (display, test);
- else
- test->x11_display_opened_handler_id =
- g_signal_connect (meta_get_display (), "x11-display-opened",
- G_CALLBACK (on_x11_display_opened),
- test);
- }
-
- test->context = context;
- test->clients = g_hash_table_new (g_str_hash, g_str_equal);
- 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 (!meta_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.
- */
- if (test->waiter)
- meta_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, \
- META_TEST_CLIENT_ERROR, \
- META_TEST_CLIENT_ERROR_BAD_COMMAND, \
- __VA_ARGS__); \
- return FALSE; \
- } G_STMT_END
-
-static MetaTestClient *
-test_case_lookup_client (TestCase *test,
- char *client_id,
- GError **error)
-{
- MetaTestClient *client = g_hash_table_lookup (test->clients, client_id);
- if (!client)
- {
- g_set_error (error,
- META_TEST_CLIENT_ERROR,
- META_TEST_CLIENT_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,
- MetaTestClient **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 doesn't 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,
- META_TEST_CLIENT_ERROR,
- META_TEST_CLIENT_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,
- META_TEST_CLIENT_ERROR,
- META_TEST_CLIENT_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,
- META_TEST_CLIENT_ERROR,
- META_TEST_CLIENT_ERROR_ASSERTION_FAILED,
- "focus: expected='%s', actual='%s'",
- expected_window, focused);
- }
-
- return *error == NULL;
-}
-
-static gboolean
-test_case_assert_size (TestCase *test,
- MetaWindow *window,
- int expected_width,
- int expected_height,
- GError **error)
-{
- MetaRectangle frame_rect;
-
- meta_window_get_frame_rect (window, &frame_rect);
-
- if (frame_rect.width != expected_width ||
- frame_rect.height != expected_height)
- {
- g_set_error (error,
- META_TEST_CLIENT_ERROR,
- META_TEST_CLIENT_ERROR_ASSERTION_FAILED,
- "Expected size %dx%d didn't match actual size %dx%d",
- expected_width, expected_height,
- frame_rect.width, frame_rect.height);
- return FALSE;
- }
-
- return TRUE;
-}
-
-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;
-
- if (!display->x11_display)
- return TRUE;
-
- 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,
- META_TEST_CLIENT_ERROR,
- META_TEST_CLIENT_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 int
-maybe_divide (const char *str,
- int value)
-{
- if (strstr (str, "/") == str)
- {
- int divisor;
-
- str += 1;
- divisor = atoi (str);
-
- value /= divisor;
- }
-
- return value;
-}
-
-static int
-parse_window_size (MetaWindow *window,
- const char *size_str)
-{
- MetaLogicalMonitor *logical_monitor;
- MetaRectangle logical_monitor_layout;
- int value;
-
- logical_monitor = meta_window_calculate_main_logical_monitor (window);
- g_assert_nonnull (logical_monitor);
-
- logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor);
-
- if (strstr (size_str, "MONITOR_WIDTH") == size_str)
- {
- value = logical_monitor_layout.width;
- size_str += strlen ("MONITOR_WIDTH");
- value = maybe_divide (size_str, value);
- }
- else if (strstr (size_str, "MONITOR_HEIGHT") == size_str)
- {
- value = logical_monitor_layout.height;
- size_str += strlen ("MONITOR_HEIGHT");
- value = maybe_divide (size_str, value);
- }
- else
- {
- value = atoi (size_str);
- }
-
- return value;
-}
-
-static gboolean
-test_case_do (TestCase *test,
- int argc,
- char **argv,
- GError **error)
-{
- if (strcmp (argv[0], "new_client") == 0)
- {
- MetaWindowClientType type;
- MetaTestClient *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 = meta_test_client_new (test->context, argv[1], type, error);
- if (!client)
- return FALSE;
-
- g_hash_table_insert (test->clients, meta_test_client_get_id (client), client);
- }
- else if (strcmp (argv[0], "quit_client") == 0)
- {
- if (argc != 2)
- BAD_COMMAND("usage: quit_client <client-id>");
-
- MetaTestClient *client = test_case_lookup_client (test, argv[1], error);
- if (!client)
- return FALSE;
-
- if (!meta_test_client_quit (client, error))
- return FALSE;
-
- g_hash_table_remove (test->clients, meta_test_client_get_id (client));
- meta_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]);
-
- MetaTestClient *client;
- const char *window_id;
- if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
- return FALSE;
-
- if (!meta_test_client_do (client, error,
- "create", window_id,
- argc == 3 ? argv[2] : NULL,
- NULL))
- return FALSE;
-
- if (!meta_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]);
-
- MetaTestClient *client;
- const char *window_id;
- if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
- return FALSE;
-
- if (!meta_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]);
-
- MetaTestClient *client;
- const char *window_id;
- if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
- return FALSE;
-
- if (!meta_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]);
-
- MetaTestClient *client;
- const char *window_id;
- if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
- return FALSE;
-
- if (!meta_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]);
-
- MetaTestClient *client;
- const char *window_id;
- if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
- return FALSE;
-
- if (!meta_test_client_do (client, error,
- argv[0], window_id,
- argv[2],
- NULL))
- return FALSE;
- }
- else if (strcmp (argv[0], "show") == 0)
- {
- MetaWindow *window;
- gboolean show_async = FALSE;
-
- if (argc != 2 && argc != 3)
- BAD_COMMAND("usage: %s <client-id>/<window-id> [async]", argv[0]);
-
- if (argc == 3 && strcmp (argv[2], "async") == 0)
- show_async = TRUE;
-
- MetaTestClient *client;
- const char *window_id;
- if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
- return FALSE;
-
- if (!meta_test_client_do (client, error, argv[0], window_id, NULL))
- return FALSE;
-
- if (!test_case_wait (test, error))
- return FALSE;
-
- window = meta_test_client_find_window (client, window_id, error);
- if (!window)
- return FALSE;
-
- if (!show_async)
- meta_test_client_wait_for_window_shown (client, window);
- }
- else if (strcmp (argv[0], "resize") == 0)
- {
- if (argc != 4)
- BAD_COMMAND("usage: %s <client-id>/<window-id> width height", argv[0]);
-
- MetaTestClient *client;
- const char *window_id;
- if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
- return FALSE;
-
- if (!meta_test_client_do (client, error, argv[0], window_id,
- argv[2], argv[3], NULL))
- return FALSE;
- }
- else if (strcmp (argv[0], "move") == 0)
- {
- MetaWindow *window;
-
- if (argc != 4)
- BAD_COMMAND("usage: %s <client-id>/<window-id> x y", argv[0]);
-
- MetaTestClient *client;
- const char *window_id;
- if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
- return FALSE;
-
- window = meta_test_client_find_window (client, window_id, error);
- if (!window)
- return FALSE;
-
- meta_window_move_frame (window, TRUE, atoi (argv[2]), atoi (argv[3]));
- }
- else if (strcmp (argv[0], "tile") == 0)
- {
- MetaWindow *window;
-
- if (argc != 3)
- BAD_COMMAND("usage: %s <client-id>/<window-id> [right|left]", argv[0]);
-
- MetaTestClient *client;
- const char *window_id;
- if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
- return FALSE;
-
- window = meta_test_client_find_window (client, window_id, error);
- if (!window)
- return FALSE;
-
- MetaTileMode tile_mode;
- if (strcmp (argv[2], "right") == 0)
- {
- tile_mode = META_TILE_RIGHT;
- }
- else if (strcmp (argv[2], "left") == 0)
- {
- tile_mode = META_TILE_LEFT;
- }
- else
- {
- g_set_error (error,
- META_TEST_CLIENT_ERROR,
- META_TEST_CLIENT_ERROR_ASSERTION_FAILED,
- "Invalid tile mode '%s'", argv[2]);
- return FALSE;
- }
-
- meta_window_tile (window, tile_mode);
- }
- else if (strcmp (argv[0], "untile") == 0)
- {
- MetaWindow *window;
-
- if (argc != 2)
- BAD_COMMAND("usage: %s <client-id>/<window-id>", argv[0]);
-
- MetaTestClient *client;
- const char *window_id;
- if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
- return FALSE;
-
- window = meta_test_client_find_window (client, window_id, error);
- if (!window)
- return FALSE;
-
- meta_window_untile (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], "maximize") == 0 ||
- strcmp (argv[0], "unmaximize") == 0 ||
- strcmp (argv[0], "fullscreen") == 0 ||
- strcmp (argv[0], "unfullscreen") == 0 ||
- strcmp (argv[0], "freeze") == 0 ||
- strcmp (argv[0], "thaw") == 0 ||
- strcmp (argv[0], "destroy") == 0)
- {
- if (argc != 2)
- BAD_COMMAND("usage: %s <client-id>/<window-id>", argv[0]);
-
- MetaTestClient *client;
- const char *window_id;
- if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
- return FALSE;
-
- if (!meta_test_client_do (client, error, argv[0], window_id, NULL))
- return FALSE;
- }
- else if (strcmp (argv[0], "local_activate") == 0)
- {
- MetaWindow *window;
-
- if (argc != 2)
- BAD_COMMAND("usage: %s <client-id>/<window-id>", argv[0]);
-
- MetaTestClient *client;
- const char *window_id;
- if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
- return FALSE;
-
- window = meta_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], "wait_reconfigure") == 0)
- {
- if (argc != 1)
- BAD_COMMAND("usage: %s", argv[0]);
-
- /*
- * Wait twice, so that we
- * 1) First wait for any requests to configure being made
- * 2) Then wait until the new configuration has been applied
- */
-
- if (!test_case_wait (test, error))
- return FALSE;
- if (!test_case_dispatch (test, error))
- return FALSE;
- 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 if (strcmp (argv[0], "assert_size") == 0)
- {
- MetaWindow *window;
-
- if (argc != 4)
- {
- BAD_COMMAND("usage: %s <client-id>/<window-id> <width> <height>",
- argv[0]);
- }
-
- MetaTestClient *client;
- const char *window_id;
- if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
- return FALSE;
-
- window = meta_test_client_find_window (client, window_id, error);
- if (!window)
- return FALSE;
-
- if (meta_window_get_frame (window))
- {
- g_set_error (error,
- META_TEST_CLIENT_ERROR,
- META_TEST_CLIENT_ERROR_ASSERTION_FAILED,
- "Can only assert size of CSD window");
- return FALSE;
- }
-
- int width = parse_window_size (window, argv[2]);
- int height = parse_window_size (window, argv[3]);
- g_autofree char *width_str = g_strdup_printf ("%d", width);
- g_autofree char *height_str = g_strdup_printf ("%d", height);
-
- if (!meta_test_client_do (client, error, argv[0],
- window_id,
- width_str,
- height_str,
- NULL))
- return FALSE;
-
- if (!test_case_assert_size (test, window,
- width, height,
- error))
- return FALSE;
- }
- else if (strcmp (argv[0], "assert_position") == 0)
- {
- MetaWindow *window;
-
- if (argc != 4)
- {
- BAD_COMMAND("usage: %s <client-id>/<window-id> <x> <y>",
- argv[0]);
- }
-
- MetaTestClient *client;
- const char *window_id;
- if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
- return FALSE;
-
- window = meta_test_client_find_window (client, window_id, error);
- if (!window)
- return FALSE;
-
- MetaRectangle frame_rect;
- meta_window_get_frame_rect (window, &frame_rect);
- int x = atoi (argv[2]);
- int y = atoi (argv[3]);
- if (frame_rect.x != x || frame_rect.y != y)
- {
- g_set_error (error,
- META_TEST_CLIENT_ERROR,
- META_TEST_CLIENT_ERROR_ASSERTION_FAILED,
- "Expected window position (%d, %d) doesn't match (%d, %d)",
- x, y, frame_rect.x, frame_rect.y);
- 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;
- MetaDisplay *display;
-
- g_hash_table_iter_init (&iter, test->clients);
- while (g_hash_table_iter_next (&iter, &key, &value))
- {
- if (!meta_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))
- meta_test_client_destroy (value);
-
- g_clear_pointer (&test->waiter, meta_async_waiter_destroy);
-
- display = meta_get_display ();
- g_clear_signal_handler (&test->x11_display_opened_handler_id, display);
- if (display->x11_display)
- meta_x11_display_set_alarm_filter (display->x11_display, NULL, NULL);
-
- g_hash_table_destroy (test->clients);
- g_free (test);
-
- return TRUE;
-}
-
-/**********************************************************************/
-
-static gboolean
-run_test (MetaContext *context,
- const char *filename,
- int index)
-{
- TestCase *test = test_case_new (context);
- 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 int
-run_tests (MetaContext *context,
- RunTestsInfo *info)
-{
- int i;
- gboolean success = TRUE;
-
- g_print ("1..%d\n", info->n_tests);
-
- for (i = 0; i < info->n_tests; i++)
- {
- if (!run_test (context, info->tests[i], i + 1))
- success = FALSE;
- }
-
- return success ? 0 : 1;
-}
-
-/**********************************************************************/
-
-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)
-{
- g_autoptr (MetaContext) context = NULL;
- GPtrArray *tests;
- RunTestsInfo info;
-
- context = meta_create_test_context (META_CONTEXT_TEST_TYPE_NESTED,
- META_CONTEXT_TEST_FLAG_TEST_CLIENT);
-
- meta_context_add_option_entries (context, options, NULL);
-
- g_assert (meta_context_configure (context, &argc, &argv, NULL));
-
- tests = g_ptr_array_new ();
- if (all_tests)
- {
- GFile *test_dir = g_file_new_for_path (MUTTER_PKGDATADIR "/tests");
- g_autoptr (GError) error = NULL;
-
- if (!find_metatests_in_directory (test_dir, tests, &error))
- {
- g_printerr ("Error enumerating tests: %s\n", error->message);
- return EXIT_FAILURE;
- }
- }
- 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);
- }
-
- info.tests = (char **) tests->pdata;
- info.n_tests = tests->len;
- g_signal_connect (context, "run-tests", G_CALLBACK (run_tests), &info);
-
- return meta_context_test_run_tests (META_CONTEXT_TEST (context));
-}
diff --git a/src/tests/unit-tests.c b/src/tests/unit-tests.c
deleted file mode 100644
index a31f50536..000000000
--- a/src/tests/unit-tests.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/* -*- 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 "tests/unit-tests.h"
-
-#include <glib.h>
-#include <stdlib.h>
-
-#include <meta/main.h>
-#include <meta/util.h>
-
-#include "core/boxes-private.h"
-#include "meta-test/meta-context-test.h"
-#include "meta/meta-context.h"
-#include "tests/boxes-tests.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/wayland-unit-tests.h"
-
-MetaContext *test_context;
-
-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, &not_adjacent[i]));
-}
-
-static void
-init_tests (void)
-{
- 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[])
-{
- g_autoptr (MetaContext) context = NULL;
-
- context = meta_create_test_context (META_CONTEXT_TEST_TYPE_NESTED,
- META_CONTEXT_TEST_FLAG_TEST_CLIENT);
- g_assert (meta_context_configure (context, &argc, &argv, NULL));
-
- test_context = context;
-
- init_tests ();
-
- g_signal_connect (context, "before-tests",
- G_CALLBACK (pre_run_monitor_tests), NULL);
- g_signal_connect (context, "before-tests",
- G_CALLBACK (pre_run_wayland_tests), NULL);
- g_signal_connect (context, "after-tests",
- G_CALLBACK (finish_monitor_tests), NULL);
-
- return meta_context_test_run_tests (META_CONTEXT_TEST (context));
-}
diff --git a/src/tests/unit-tests.h b/src/tests/unit-tests.h
deleted file mode 100644
index 30f24979e..000000000
--- a/src/tests/unit-tests.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2021 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 UNIT_TESTS_H
-#define UNIT_TESTS_H
-
-#include "meta/meta-context.h"
-
-extern MetaContext *test_context;
-
-#endif /* UNIT_TESTS_H */
diff --git a/src/tests/wayland-test-clients/invalid-subsurfaces.c b/src/tests/wayland-test-clients/invalid-subsurfaces.c
deleted file mode 100644
index f186dfbc9..000000000
--- a/src/tests/wayland-test-clients/invalid-subsurfaces.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * 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 <glib.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <wayland-client.h>
-
-#include "wayland-test-client-utils.h"
-
-#include "xdg-shell-client-protocol.h"
-
-static struct wl_display *display;
-static struct wl_registry *registry;
-static struct wl_compositor *compositor;
-static struct wl_subcompositor *subcompositor;
-
-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);
- }
-}
-
-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
-};
-
-static void
-connect_to_display (void)
-{
- g_assert_null (display);
- g_assert_null (registry);
- g_assert_null (subcompositor);
-
- display = wl_display_connect (NULL);
- g_assert_nonnull (display);
- registry = wl_display_get_registry (display);
- g_assert_nonnull (registry);
- wl_registry_add_listener (registry, &registry_listener, NULL);
-
- g_assert_cmpint (wl_display_roundtrip (display), !=, -1);
-
- g_assert_nonnull (subcompositor);
-}
-
-static void
-clean_up_display (void)
-{
- wl_display_disconnect (display);
- display = NULL;
- registry = NULL;
- subcompositor = NULL;
-}
-
-static void
-test_circular_subsurfaces1 (void)
-{
- struct wl_surface *surface1;
- struct wl_subsurface *subsurface1;
- struct wl_surface *surface2;
- struct wl_subsurface *subsurface2;
-
- connect_to_display ();
-
- surface1 = wl_compositor_create_surface (compositor);
- surface2 = wl_compositor_create_surface (compositor);
- g_assert_nonnull (surface1);
- g_assert_nonnull (surface2);
-
- subsurface1 = wl_subcompositor_get_subsurface (subcompositor,
- surface1,
- surface2);
- subsurface2 = wl_subcompositor_get_subsurface (subcompositor,
- surface2,
- surface1);
- g_assert_nonnull (subsurface1);
- g_assert_nonnull (subsurface2);
-
- g_assert_cmpint (wl_display_roundtrip (display), ==, -1);
-
- clean_up_display ();
-}
-
-static void
-test_circular_subsurfaces2 (void)
-{
- struct wl_surface *surface1;
- struct wl_subsurface *subsurface1;
- struct wl_surface *surface2;
- struct wl_subsurface *subsurface2;
- struct wl_surface *surface3;
- struct wl_subsurface *subsurface3;
-
- connect_to_display ();
-
- surface1 = wl_compositor_create_surface (compositor);
- surface2 = wl_compositor_create_surface (compositor);
- surface3 = wl_compositor_create_surface (compositor);
- g_assert_nonnull (surface1);
- g_assert_nonnull (surface2);
- g_assert_nonnull (surface3);
-
- subsurface1 = wl_subcompositor_get_subsurface (subcompositor,
- surface1,
- surface2);
- subsurface2 = wl_subcompositor_get_subsurface (subcompositor,
- surface2,
- surface3);
- subsurface3 = wl_subcompositor_get_subsurface (subcompositor,
- surface3,
- surface1);
- g_assert_nonnull (subsurface1);
- g_assert_nonnull (subsurface2);
- g_assert_nonnull (subsurface3);
-
- g_assert_cmpint (wl_display_roundtrip (display), ==, -1);
-
- clean_up_display ();
-}
-
-int
-main (int argc,
- char **argv)
-{
- test_circular_subsurfaces1 ();
- test_circular_subsurfaces2 ();
-
- return EXIT_SUCCESS;
-}
diff --git a/src/tests/wayland-test-clients/invalid-xdg-shell-actions.c b/src/tests/wayland-test-clients/invalid-xdg-shell-actions.c
deleted file mode 100644
index 67ff3671e..000000000
--- a/src/tests/wayland-test-clients/invalid-xdg-shell-actions.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * 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 <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"
-
-static struct wl_display *display;
-static struct wl_registry *registry;
-static struct wl_compositor *compositor;
-static struct xdg_wm_base *xdg_wm_base;
-static struct wl_shm *shm;
-
-static struct wl_surface *surface;
-static struct xdg_surface *xdg_surface;
-static struct xdg_toplevel *xdg_toplevel;
-
-static gboolean running;
-
-static void
-init_surface (void)
-{
- xdg_toplevel_set_title (xdg_toplevel, "bogus window geometry");
- wl_surface_commit (surface);
-}
-
-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
-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_xdg_surface_configure (void *data,
- struct xdg_surface *xdg_surface,
- uint32_t serial)
-{
- xdg_surface_set_window_geometry (xdg_surface, 0, 0, 0, 0);
- draw_main ();
- wl_surface_commit (surface);
-
- g_assert_cmpint (wl_display_roundtrip (display), !=, -1);
- running = FALSE;
-}
-
-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, "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);
- }
-}
-
-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
-};
-
-static void
-test_empty_window_geometry (void)
-{
- display = wl_display_connect (NULL);
- registry = wl_display_get_registry (display);
- wl_registry_add_listener (registry, &registry_listener, NULL);
- wl_display_roundtrip (display);
-
- g_assert_nonnull (shm);
- g_assert_nonnull (xdg_wm_base);
-
- wl_display_roundtrip (display);
-
- 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);
-
- init_surface ();
-
- running = TRUE;
- while (running)
- {
- if (wl_display_dispatch (display) == -1)
- return;
- }
-
- g_clear_pointer (&xdg_toplevel, xdg_toplevel_destroy);
- g_clear_pointer (&xdg_surface, xdg_surface_destroy);
- g_clear_pointer (&xdg_wm_base, xdg_wm_base_destroy);
- g_clear_pointer (&compositor, wl_compositor_destroy);
- g_clear_pointer (&shm, wl_shm_destroy);
- g_clear_pointer (&registry, wl_registry_destroy);
- g_clear_pointer (&display, wl_display_disconnect);
-}
-
-int
-main (int argc,
- char **argv)
-{
- test_empty_window_geometry ();
-
- return EXIT_SUCCESS;
-}
diff --git a/src/tests/wayland-test-clients/meson.build b/src/tests/wayland-test-clients/meson.build
deleted file mode 100644
index e26325d70..000000000
--- a/src/tests/wayland-test-clients/meson.build
+++ /dev/null
@@ -1,70 +0,0 @@
-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,
-]
-
-wayland_test_clients = [
- 'subsurface-remap-toplevel',
- 'invalid-subsurfaces',
- 'invalid-xdg-shell-actions',
- 'xdg-apply-limits',
-]
-
-foreach test : wayland_test_clients
- executable(test,
- sources: [
- '@0@.c'.format(test),
- common_sources,
- ],
- include_directories: tests_includes,
- c_args: tests_c_args,
- dependencies: [
- glib_dep,
- wayland_client_dep,
- ],
- install: have_installed_tests,
- install_dir: wayland_test_client_installed_tests_libexecdir,
- )
-endforeach
diff --git a/src/tests/wayland-test-clients/subsurface-remap-toplevel.c b/src/tests/wayland-test-clients/subsurface-remap-toplevel.c
deleted file mode 100644
index 25ff3a2d1..000000000
--- a/src/tests/wayland-test-clients/subsurface-remap-toplevel.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * 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, &registry_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
deleted file mode 100644
index 2433cf111..000000000
--- a/src/tests/wayland-test-clients/test-driver.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?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>
-
- <request name="sync_point">
- <arg name="sequence" type="uint"/>
- </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
deleted file mode 100644
index 9deb122cb..000000000
--- a/src/tests/wayland-test-clients/wayland-test-client-utils.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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
deleted file mode 100644
index a8dcb5321..000000000
--- a/src/tests/wayland-test-clients/wayland-test-client-utils.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#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-test-clients/xdg-apply-limits.c b/src/tests/wayland-test-clients/xdg-apply-limits.c
deleted file mode 100644
index aa5ab6e70..000000000
--- a/src/tests/wayland-test-clients/xdg-apply-limits.c
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (C) 2021 Christian Rauch
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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, "toplevel-limits-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;
-
- if (test_driver)
- {
- 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 ();
- test_driver_sync_point (test_driver, 1);
- 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, &registry_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;
-
- /* set minimum and maximum size and commit */
- xdg_toplevel_set_min_size(xdg_toplevel, 700, 500);
- xdg_toplevel_set_max_size(xdg_toplevel, 700, 500);
- wl_surface_commit (surface);
-
- test_driver_sync_point (test_driver, 0);
-
- running = TRUE;
- while (running)
- {
- if (wl_display_dispatch (display) == -1)
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
diff --git a/src/tests/wayland-unit-tests.c b/src/tests/wayland-unit-tests.c
deleted file mode 100644
index 98c2d905a..000000000
--- a/src/tests/wayland-unit-tests.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * 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 "core/display-private.h"
-#include "core/window-private.h"
-#include "tests/meta-wayland-test-driver.h"
-#include "wayland/meta-wayland.h"
-#include "wayland/meta-wayland-surface.h"
-
-typedef struct _WaylandTestClient
-{
- GSubprocess *subprocess;
- char *path;
- GMainLoop *main_loop;
-} WaylandTestClient;
-
-static MetaWaylandTestDriver *test_driver;
-
-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 MetaWindow *
-find_client_window (const char *title)
-{
- MetaDisplay *display = meta_get_display ();
- g_autoptr (GSList) windows = NULL;
- GSList *l;
-
- windows = meta_display_list_windows (display, META_LIST_DEFAULT);
- for (l = windows; l; l = l->next)
- {
- MetaWindow *window = l->data;
-
- if (g_strcmp0 (meta_window_get_title (window), title) == 0)
- return window;
- }
-
- return NULL;
-}
-
-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
-subsurface_invalid_subsurfaces (void)
-{
- WaylandTestClient *wayland_test_client;
-
- wayland_test_client = wayland_test_client_new ("invalid-subsurfaces");
- g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
- "WL: error in client communication*");
- g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
- "WL: error in client communication*");
- wayland_test_client_finish (wayland_test_client);
- g_test_assert_expected_messages ();
-}
-
-static void
-subsurface_invalid_xdg_shell_actions (void)
-{
- WaylandTestClient *wayland_test_client;
-
- wayland_test_client = wayland_test_client_new ("invalid-xdg-shell-actions");
- g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
- "Invalid geometry * set on xdg_surface*");
- wayland_test_client_finish (wayland_test_client);
- g_test_assert_expected_messages ();
-}
-
-typedef enum _ApplyLimitState
-{
- APPLY_LIMIT_STATE_INIT,
- APPLY_LIMIT_STATE_RESET,
- APPLY_LIMIT_STATE_FINISH,
-} ApplyLimitState;
-
-typedef struct _ApplyLimitData
-{
- GMainLoop *loop;
- WaylandTestClient *wayland_test_client;
- ApplyLimitState state;
-} ApplyLimitData;
-
-static void
-on_sync_point (MetaWaylandTestDriver *test_driver,
- unsigned int sequence,
- struct wl_client *wl_client,
- ApplyLimitData *data)
-{
- MetaWindow *window;
-
- if (sequence == 0)
- g_assert (data->state == APPLY_LIMIT_STATE_INIT);
- else if (sequence == 0)
- g_assert (data->state == APPLY_LIMIT_STATE_RESET);
-
- window = find_client_window ("toplevel-limits-test");
-
- if (sequence == 0)
- {
- g_assert_nonnull (window);
- g_assert_cmpint (window->size_hints.max_width, ==, 700);
- g_assert_cmpint (window->size_hints.max_height, ==, 500);
- g_assert_cmpint (window->size_hints.min_width, ==, 700);
- g_assert_cmpint (window->size_hints.min_height, ==, 500);
-
- data->state = APPLY_LIMIT_STATE_RESET;
- }
- else if (sequence == 1)
- {
- g_assert_null (window);
- data->state = APPLY_LIMIT_STATE_FINISH;
- g_main_loop_quit (data->loop);
- }
- else
- {
- g_assert_not_reached ();
- }
-}
-
-static void
-toplevel_apply_limits (void)
-{
- ApplyLimitData data = {};
-
- data.loop = g_main_loop_new (NULL, FALSE);
- data.wayland_test_client = wayland_test_client_new ("xdg-apply-limits");
- g_signal_connect (test_driver, "sync-point", G_CALLBACK (on_sync_point), &data);
- g_main_loop_run (data.loop);
- g_assert_cmpint (data.state, ==, APPLY_LIMIT_STATE_FINISH);
- wayland_test_client_finish (data.wayland_test_client);
- g_test_assert_expected_messages ();
-}
-
-void
-pre_run_wayland_tests (void)
-{
- MetaWaylandCompositor *compositor;
-
- compositor = meta_wayland_compositor_get_default ();
- g_assert_nonnull (compositor);
-
- test_driver = meta_wayland_test_driver_new (compositor);
-}
-
-void
-init_wayland_tests (void)
-{
- g_test_add_func ("/wayland/subsurface/remap-toplevel",
- subsurface_remap_toplevel);
- g_test_add_func ("/wayland/subsurface/invalid-subsurfaces",
- subsurface_invalid_subsurfaces);
- g_test_add_func ("/wayland/subsurface/invalid-xdg-shell-actions",
- subsurface_invalid_xdg_shell_actions);
- g_test_add_func ("/wayland/toplevel/apply-limits",
- toplevel_apply_limits);
-}
diff --git a/src/tests/wayland-unit-tests.h b/src/tests/wayland-unit-tests.h
deleted file mode 100644
index b7d8d4204..000000000
--- a/src/tests/wayland-unit-tests.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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/ui/frames.c b/src/ui/frames.c
deleted file mode 100644
index 48b2a361c..000000000
--- a/src/ui/frames.c
+++ /dev/null
@@ -1,1869 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Metacity window frame manager widget */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2003 Red Hat, 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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 <cairo-xlib.h>
-#include <math.h>
-#include <string.h>
-
-#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
-
-static void meta_frames_destroy (GtkWidget *object);
-static void meta_frames_finalize (GObject *object);
-static void meta_frames_style_updated (GtkWidget *widget);
-
-static gboolean meta_frames_draw (GtkWidget *widget,
- cairo_t *cr);
-
-static void meta_ui_frame_attach_style (MetaUIFrame *frame);
-
-static void meta_ui_frame_paint (MetaUIFrame *frame,
- cairo_t *cr);
-
-static void meta_ui_frame_calc_geometry (MetaUIFrame *frame,
- MetaFrameGeometry *fgeom);
-
-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);
-
-
-static GdkRectangle* control_rect (MetaFrameControl control,
- MetaFrameGeometry *fgeom);
-static MetaFrameControl get_control (MetaUIFrame *frame,
- int x,
- int y);
-
-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,
- GObjectConstructParam *properties)
-{
- GObject *object;
- GObjectClass *gobject_class;
-
- gobject_class = G_OBJECT_CLASS (meta_frames_parent_class);
- object = gobject_class->constructor (gtype, n_properties, properties);
-
- g_object_set (object,
- "type", GTK_WINDOW_POPUP,
- NULL);
-
- return object;
-}
-
-static void
-meta_frames_class_init (MetaFramesClass *class)
-{
- GObjectClass *gobject_class;
- GtkWidgetClass *widget_class;
-
- gobject_class = G_OBJECT_CLASS (class);
- widget_class = (GtkWidgetClass*) class;
-
- gobject_class->constructor = meta_frames_constructor;
- gobject_class->finalize = meta_frames_finalize;
-
- widget_class->destroy = meta_frames_destroy;
-
- widget_class->style_updated = meta_frames_style_updated;
-
- widget_class->draw = meta_frames_draw;
-}
-
-static gint
-unsigned_long_equal (gconstpointer v1,
- gconstpointer v2)
-{
- return *((const gulong*) v1) == *((const gulong*) v2);
-}
-
-static guint
-unsigned_long_hash (gconstpointer v)
-{
- gulong val = * (const gulong *) v;
-
- /* I'm not sure this works so well. */
-#if GLIB_SIZEOF_LONG > 4
- return (guint) (val ^ (val >> 32));
-#else
- return val;
-#endif
-}
-
-static void
-prefs_changed_callback (MetaPreference pref,
- void *data)
-{
- switch (pref)
- {
- case META_PREF_TITLEBAR_FONT:
- meta_frames_font_changed (META_FRAMES (data));
- break;
- case META_PREF_BUTTON_LAYOUT:
- meta_frames_button_layout_changed (META_FRAMES (data));
- break;
- default:
- break;
- }
-}
-
-static void
-invalidate_whole_window (MetaUIFrame *frame)
-{
- if (!frame->is_frozen)
- {
- meta_window_x11_freeze_commits (frame->meta_window);
- frame->is_frozen = TRUE;
- }
- gdk_window_invalidate_rect (frame->window, NULL, FALSE);
-}
-
-static MetaStyleInfo *
-meta_frames_get_theme_variant (MetaFrames *frames,
- const gchar *variant)
-{
- MetaStyleInfo *style_info;
-
- style_info = g_hash_table_lookup (frames->style_variants, variant);
- if (style_info == NULL)
- {
- 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_info;
-}
-
-static void
-update_style_contexts (MetaFrames *frames)
-{
- MetaStyleInfo *style_info;
- GList *variants, *variant;
- GdkScreen *screen;
-
- screen = gtk_widget_get_screen (GTK_WIDGET (frames));
-
- if (frames->normal_style)
- meta_style_info_unref (frames->normal_style);
- frames->normal_style = meta_theme_create_style_info (screen, NULL);
-
- variants = g_hash_table_get_keys (frames->style_variants);
- for (variant = variants; variant; variant = variant->next)
- {
- style_info = meta_theme_create_style_info (screen, (char *)variant->data);
- g_hash_table_insert (frames->style_variants,
- g_strdup (variant->data), style_info);
- }
- g_list_free (variants);
-}
-
-static void
-meta_frames_init (MetaFrames *frames)
-{
- frames->text_heights = g_hash_table_new (NULL, NULL);
-
- frames->frames = g_hash_table_new (unsigned_long_hash, unsigned_long_equal);
-
- frames->style_variants = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, (GDestroyNotify)meta_style_info_unref);
-
- update_style_contexts (frames);
-
- meta_prefs_add_listener (prefs_changed_callback, frames);
-}
-
-static void
-listify_func (gpointer key, gpointer value, gpointer data)
-{
- GSList **listp;
-
- listp = data;
- *listp = g_slist_prepend (*listp, value);
-}
-
-static void
-meta_frames_destroy (GtkWidget *object)
-{
- GSList *winlist;
- GSList *tmp;
- MetaFrames *frames;
-
- frames = META_FRAMES (object);
-
- winlist = NULL;
- g_hash_table_foreach (frames->frames, listify_func, &winlist);
-
- /* Unmanage all frames */
- for (tmp = winlist; tmp != NULL; tmp = tmp->next)
- {
- MetaUIFrame *frame = tmp->data;
- meta_ui_frame_unmanage (frame);
- }
- g_slist_free (winlist);
-
- if (frames->normal_style)
- {
- meta_style_info_unref (frames->normal_style);
- frames->normal_style = NULL;
- }
-
- if (frames->style_variants)
- {
- g_hash_table_destroy (frames->style_variants);
- frames->style_variants = NULL;
- }
-
- GTK_WIDGET_CLASS (meta_frames_parent_class)->destroy (object);
-}
-
-static void
-meta_frames_finalize (GObject *object)
-{
- MetaFrames *frames;
-
- frames = META_FRAMES (object);
-
- meta_prefs_remove_listener (prefs_changed_callback, frames);
-
- g_hash_table_destroy (frames->text_heights);
-
- g_assert (g_hash_table_size (frames->frames) == 0);
- g_hash_table_destroy (frames->frames);
-
- G_OBJECT_CLASS (meta_frames_parent_class)->finalize (object);
-}
-
-static void
-queue_recalc_func (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- MetaUIFrame *frame = value;
- MetaFrames *frames = user_data;
-
- invalidate_whole_window (frame);
- meta_x11_wm_queue_frame_resize (frames->x11_display,
- frame->xwindow);
-
- g_clear_object (&frame->text_layout);
-}
-
-static void
-meta_frames_font_changed (MetaFrames *frames)
-{
- if (g_hash_table_size (frames->text_heights) > 0)
- {
- g_hash_table_destroy (frames->text_heights);
- frames->text_heights = g_hash_table_new (NULL, NULL);
- }
-
- /* Queue a draw/resize on all frames */
- g_hash_table_foreach (frames->frames,
- queue_recalc_func, frames);
-
-}
-
-static void
-queue_draw_func (gpointer key, gpointer value, gpointer data)
-{
- MetaUIFrame *frame = value;
- invalidate_whole_window (frame);
-}
-
-static void
-meta_frames_button_layout_changed (MetaFrames *frames)
-{
- g_hash_table_foreach (frames->frames,
- queue_draw_func, frames);
-}
-
-static void
-reattach_style_func (gpointer key, gpointer value, gpointer data)
-{
- MetaUIFrame *frame = value;
- meta_ui_frame_attach_style (frame);
-}
-
-static void
-meta_frames_style_updated (GtkWidget *widget)
-{
- MetaFrames *frames;
-
- frames = META_FRAMES (widget);
-
- meta_frames_font_changed (frames);
-
- update_style_contexts (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_ui_frame_ensure_layout (MetaUIFrame *frame,
- MetaFrameType type)
-{
- MetaFrames *frames = frame->frames;
- GtkWidget *widget;
- MetaFrameLayout *layout;
-
- widget = GTK_WIDGET (frames);
-
- g_return_if_fail (gtk_widget_get_realized (widget));
-
- layout = meta_theme_get_frame_layout (meta_theme_get_default (), type);
-
- if (layout != frame->cache_layout)
- g_clear_object (&frame->text_layout);
-
- frame->cache_layout = layout;
-
- if (frame->text_layout == NULL)
- {
- gpointer key, value;
- PangoFontDescription *font_desc;
- int size;
-
- frame->text_layout = gtk_widget_create_pango_layout (widget, frame->title);
-
- 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_style_info_create_font_desc (frame->style_info);
- meta_frame_layout_apply_scale (layout, font_desc);
-
- size = pango_font_description_get_size (font_desc);
-
- if (g_hash_table_lookup_extended (frames->text_heights,
- GINT_TO_POINTER (size),
- &key, &value))
- {
- frame->text_height = GPOINTER_TO_INT (value);
- }
- else
- {
- frame->text_height =
- meta_pango_font_desc_get_text_height (font_desc,
- gtk_widget_get_pango_context (widget));
-
- g_hash_table_replace (frames->text_heights,
- GINT_TO_POINTER (size),
- GINT_TO_POINTER (frame->text_height));
- }
-
- pango_layout_set_font_description (frame->text_layout,
- font_desc);
-
- pango_font_description_free (font_desc);
- }
-}
-
-static void
-meta_ui_frame_calc_geometry (MetaUIFrame *frame,
- MetaFrameGeometry *fgeom)
-{
- MetaFrameFlags flags;
- MetaFrameType type;
- MetaButtonLayout button_layout;
- MetaWindowX11 *window_x11 = META_WINDOW_X11 (frame->meta_window);
- MetaRectangle client_rect;
-
- 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);
-
- client_rect = meta_window_x11_get_client_rect (window_x11);
-
- meta_theme_calc_geometry (meta_theme_get_default (),
- frame->style_info,
- type,
- frame->text_height,
- flags,
- client_rect.width,
- client_rect.height,
- &button_layout,
- fgeom);
-}
-
-MetaFrames*
-meta_frames_new (MetaX11Display *x11_display)
-{
- MetaFrames *frames;
-
- frames = g_object_new (META_TYPE_FRAMES,
- "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
- * mistake it for a window created via meta_create_offscreen_window()
- * and ignore it, and we need this window to get frame-synchronization
- * messages so that GTK+'s style change handling works.
- */
- gtk_window_move (GTK_WINDOW (frames), -200, -200);
- gtk_window_resize (GTK_WINDOW (frames), 1, 1);
-
- 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
- * to multiple windows with the same colormap, we can just go ahead
- * and attach separately for each window.
- */
-static void
-meta_ui_frame_attach_style (MetaUIFrame *frame)
-{
- MetaFrames *frames = frame->frames;
- const char *variant;
-
- if (frame->style_info != NULL)
- meta_style_info_unref (frame->style_info);
-
- variant = frame->meta_window->gtk_theme_variant;
- if (variant == NULL)
- variant = get_global_theme_variant (frame->frames);
-
- if (variant == NULL || *variant == '\0')
- frame->style_info = meta_style_info_ref (frames->normal_style);
- else
- frame->style_info = meta_style_info_ref (meta_frames_get_theme_variant (frames,
- variant));
-}
-
-MetaUIFrame *
-meta_frames_manage_window (MetaFrames *frames,
- MetaWindow *meta_window,
- Window xwindow,
- GdkWindow *window)
-{
- MetaUIFrame *frame;
-
- g_assert (window);
-
- frame = g_new (MetaUIFrame, 1);
-
- frame->frames = frames;
- frame->window = window;
-
- gdk_window_set_user_data (frame->window, frames);
-
- frame->style_info = NULL;
-
- /* Don't set event mask here, it's in frame.c */
-
- frame->xwindow = xwindow;
- frame->meta_window = meta_window;
- frame->cache_layout = NULL;
- frame->text_layout = NULL;
- frame->text_height = -1;
- frame->title = NULL;
- 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);
-
- g_hash_table_replace (frames->frames, &frame->xwindow, frame);
-
- return frame;
-}
-
-void
-meta_ui_frame_unmanage (MetaUIFrame *frame)
-{
- MetaFrames *frames = frame->frames;
-
- /* restore the cursor */
- meta_x11_wm_set_screen_cursor (frames->x11_display,
- frame->xwindow,
- META_CURSOR_DEFAULT);
-
- gdk_window_set_user_data (frame->window, NULL);
-
- g_hash_table_remove (frames->frames, &frame->xwindow);
-
- meta_style_info_unref (frame->style_info);
-
- gdk_window_destroy (frame->window);
-
- if (frame->text_layout)
- g_object_unref (G_OBJECT (frame->text_layout));
-
- if (frame->is_frozen)
- meta_window_x11_thaw_commits (frame->meta_window);
-
- g_free (frame->title);
-
- g_free (frame);
-}
-
-void
-meta_ui_frame_get_borders (MetaUIFrame *frame,
- MetaFrameBorders *borders)
-{
- MetaFrameFlags flags;
- MetaFrameType type;
-
- 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_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_default (),
- frame->style_info,
- type,
- frame->text_height,
- flags,
- borders);
-}
-
-/* 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,
- cairo_rectangle_int_t *rect)
-{
- rect->x = fgeom->borders.invisible.left;
- rect->y = fgeom->borders.invisible.top;
- 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 (MetaUIFrame *frame,
- MetaFrameGeometry *fgeom)
-{
- cairo_region_t *corners_region;
- cairo_region_t *visible_region;
- cairo_rectangle_int_t rect;
- cairo_rectangle_int_t frame_rect;
-
- corners_region = cairo_region_create ();
- 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 = 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))));
- rect.x = frame_rect.x;
- rect.y = frame_rect.y + i;
- rect.width = width;
- rect.height = 1;
-
- cairo_region_union_rectangle (corners_region, &rect);
- }
- }
-
- if (fgeom->top_right_corner_rounded_radius != 0)
- {
- const int corner = fgeom->top_right_corner_rounded_radius;
- const float radius = 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))));
- rect.x = frame_rect.x + frame_rect.width - width;
- rect.y = frame_rect.y + i;
- rect.width = width;
- rect.height = 1;
-
- cairo_region_union_rectangle (corners_region, &rect);
- }
- }
-
- if (fgeom->bottom_left_corner_rounded_radius != 0)
- {
- const int corner = fgeom->bottom_left_corner_rounded_radius;
- const float radius = 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))));
- rect.x = frame_rect.x;
- rect.y = frame_rect.y + frame_rect.height - i - 1;
- rect.width = width;
- rect.height = 1;
-
- cairo_region_union_rectangle (corners_region, &rect);
- }
- }
-
- if (fgeom->bottom_right_corner_rounded_radius != 0)
- {
- const int corner = fgeom->bottom_right_corner_rounded_radius;
- const float radius = 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))));
- rect.x = frame_rect.x + frame_rect.width - width;
- rect.y = frame_rect.y + frame_rect.height - i - 1;
- rect.width = width;
- rect.height = 1;
-
- cairo_region_union_rectangle (corners_region, &rect);
- }
- }
-
- visible_region = cairo_region_create_rectangle (&frame_rect);
- cairo_region_subtract (visible_region, corners_region);
- cairo_region_destroy (corners_region);
-
- return visible_region;
-}
-
-cairo_region_t *
-meta_ui_frame_get_bounds (MetaUIFrame *frame)
-{
- MetaFrameGeometry fgeom;
- meta_ui_frame_calc_geometry (frame, &fgeom);
- return get_visible_region (frame, &fgeom);
-}
-
-void
-meta_ui_frame_move_resize (MetaUIFrame *frame,
- int x, int y, int width, int height)
-{
- int old_width, old_height;
-
- old_width = gdk_window_get_width (frame->window);
- old_height = gdk_window_get_height (frame->window);
-
- gdk_window_move_resize (frame->window, x, y, width, height);
-
- if (old_width != width || old_height != height)
- invalidate_whole_window (frame);
-}
-
-void
-meta_ui_frame_queue_draw (MetaUIFrame *frame)
-{
- invalidate_whole_window (frame);
-}
-
-void
-meta_ui_frame_set_title (MetaUIFrame *frame,
- const char *title)
-{
- g_free (frame->title);
- frame->title = g_strdup (title);
-
- g_clear_object (&frame->text_layout);
-
- invalidate_whole_window (frame);
-}
-
-void
-meta_ui_frame_update_style (MetaUIFrame *frame)
-{
- meta_ui_frame_attach_style (frame);
- invalidate_whole_window (frame);
-}
-
-static void
-redraw_control (MetaUIFrame *frame,
- MetaFrameControl control)
-{
- MetaFrameGeometry fgeom;
- GdkRectangle *rect;
-
- meta_ui_frame_calc_geometry (frame, &fgeom);
-
- rect = control_rect (control, &fgeom);
-
- gdk_window_invalidate_rect (frame->window, rect, FALSE);
-}
-
-static gboolean
-meta_frame_titlebar_event (MetaUIFrame *frame,
- const ClutterEvent *event,
- int action)
-{
- MetaFrameFlags flags;
- 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);
-
- switch (action)
- {
- case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_SHADE:
- {
- if (flags & META_FRAME_ALLOWS_SHADE)
- {
- if (flags & META_FRAME_SHADED)
- meta_window_unshade (frame->meta_window, evtime);
- else
- meta_window_shade (frame->meta_window, evtime);
- }
- }
- break;
-
- case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE:
- {
- if (flags & META_FRAME_ALLOWS_MAXIMIZE)
- {
- meta_x11_wm_toggle_maximize (x11_display, frame->xwindow);
- }
- }
- break;
-
- case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_HORIZONTALLY:
- {
- if (flags & META_FRAME_ALLOWS_MAXIMIZE)
- {
- meta_x11_wm_toggle_maximize_horizontally (x11_display,
- frame->xwindow);
- }
- }
- break;
-
- case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_VERTICALLY:
- {
- if (flags & META_FRAME_ALLOWS_MAXIMIZE)
- {
- meta_x11_wm_toggle_maximize_vertically (x11_display, frame->xwindow);
- }
- }
- break;
-
- case G_DESKTOP_TITLEBAR_ACTION_MINIMIZE:
- {
- if (flags & META_FRAME_ALLOWS_MINIMIZE)
- meta_window_minimize (frame->meta_window);
- }
- break;
-
- case G_DESKTOP_TITLEBAR_ACTION_NONE:
- /* Yaay, a sane user that doesn't use that other weird crap! */
- break;
-
- case G_DESKTOP_TITLEBAR_ACTION_LOWER:
- meta_x11_wm_user_lower_and_unfocus (x11_display,
- frame->xwindow,
- evtime);
- break;
-
- case G_DESKTOP_TITLEBAR_ACTION_MENU:
- meta_x11_wm_show_window_menu (x11_display,
- frame->xwindow,
- META_WINDOW_MENU_WM,
- x, y, evtime);
- break;
- }
-
- return TRUE;
-}
-
-static gboolean
-meta_frame_double_click_event (MetaUIFrame *frame,
- const ClutterEvent *event)
-{
- int action = meta_prefs_get_action_double_click_titlebar ();
-
- return meta_frame_titlebar_event (frame, event, action);
-}
-
-static gboolean
-meta_frame_middle_click_event (MetaUIFrame *frame,
- ClutterButtonEvent *event)
-{
- int action = meta_prefs_get_action_middle_click_titlebar();
-
- return meta_frame_titlebar_event (frame, (const ClutterEvent *) event,
- action);
-}
-
-static gboolean
-meta_frame_right_click_event (MetaUIFrame *frame,
- ClutterButtonEvent *event)
-{
- int action = meta_prefs_get_action_right_click_titlebar();
-
- return meta_frame_titlebar_event (frame, (const ClutterEvent *) event,
- action);
-}
-
-static gboolean
-meta_frames_try_grab_op (MetaUIFrame *frame,
- MetaGrabOp op,
- gdouble grab_x,
- gdouble grab_y,
- guint32 time)
-{
- MetaFrames *frames = frame->frames;
- gboolean ret;
-
- 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;
-
- return ret;
-}
-
-static gboolean
-meta_frames_retry_grab_op (MetaFrames *frames,
- guint time)
-{
- MetaGrabOp op;
- gboolean ret;
-
- if (frames->current_grab_op == META_GRAB_OP_NONE)
- return TRUE;
-
- op = frames->current_grab_op;
- frames->current_grab_op = META_GRAB_OP_NONE;
-
- 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;
-
- return ret;
-}
-
-static MetaGrabOp
-grab_op_from_resize_control (MetaFrameControl control)
-{
- switch (control)
- {
- 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;
- }
-}
-
-static guint
-get_action (const ClutterEvent *event)
-{
- if (event->type == CLUTTER_BUTTON_PRESS ||
- event->type == CLUTTER_BUTTON_RELEASE)
- {
- 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",
- 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)
- {
- return META_ACTION_CLICK;
- }
-
- return META_ACTION_IGNORE;
-}
-
-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);
-
- 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 (frame, control);
-
- if (control == META_FRAME_CONTROL_MENU)
- {
- MetaFrameGeometry fgeom;
- GdkRectangle *rect;
- 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
- {
- meta_frames_try_grab_op (frame, META_GRAB_OP_FRAME_BUTTON,
- x, y, evtime);
- }
-
- 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);
-
- if (flags & META_FRAME_ALLOWS_MOVE)
- {
- meta_frames_try_grab_op (frame,
- META_GRAB_OP_MOVING,
- x, y, evtime);
- }
- }
-
- 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;
- case META_FRAME_CONTROL_CLIENT_AREA:
- /* This can happen with broken gtk themes that have a larger shadow size
- * in the unfocused state than in the focused one. Then when clicking
- * below the titlebar area in the unfocused state would still be
- * considered a click on the titlebar due to it being shifted down because
- * of the shadow. This then causes the window to be focused before this
- * function is called, which removes the shadow such that the same
- * position is now considered to be on the client area */
- return FALSE;
- default:
- g_assert_not_reached ();
- return FALSE;
- }
-}
-
-static gboolean
-handle_press_event (MetaUIFrame *frame,
- const ClutterEvent *event)
-{
- 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))
- {
- meta_topic (META_DEBUG_FOCUS,
- "Focusing window with frame 0x%lx due to button 1 press",
- frame->xwindow);
- meta_window_focus (frame->meta_window, evtime);
- }
-
- /* 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 (meta_x11_wm_get_grab_op (frame->frames->x11_display) != META_GRAB_OP_NONE)
- return FALSE; /* already up to something */
-
- frame->grab_button = get_button_number (event);
-
- 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
-handle_release_event (MetaUIFrame *frame,
- const ClutterEvent *event)
-{
- guint32 evtime, button;
- gfloat x, y;
-
- g_assert (event->type == CLUTTER_BUTTON_RELEASE ||
- event->type == CLUTTER_TOUCH_END);
-
- evtime = clutter_event_get_time (event);
- clutter_event_get_coords (event, &x, &y);
- button = get_button_number (event);
-
- 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 (((int) button) == frame->grab_button &&
- frame->button_state == META_BUTTON_STATE_PRESSED)
- {
- switch (frame->prelit_control)
- {
- case META_FRAME_CONTROL_MINIMIZE:
- meta_window_minimize (frame->meta_window);
- break;
- 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_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_FRAME_CONTROL_DELETE:
- meta_window_delete (frame->meta_window, evtime);
- break;
- default:
- break;
- }
-
- /* Update the prelit control regardless of what button the mouse
- * was released over; needed so that the new button can become
- * prelit so to let the user know that it can now be pressed.
- * :)
- */
- MetaFrameControl control = get_control (frame, x, y);
- meta_ui_frame_update_prelit_control (frame, control);
- }
-
- return TRUE;
-}
-
-static void
-meta_ui_frame_update_prelit_control (MetaUIFrame *frame,
- MetaFrameControl control)
-{
- MetaFrameControl old_control;
- MetaCursor cursor;
-
- meta_verbose ("Updating prelit control from %u to %u",
- frame->prelit_control, control);
-
- cursor = META_CURSOR_DEFAULT;
-
- switch (control)
- {
- case META_FRAME_CONTROL_CLIENT_AREA:
- break;
- case META_FRAME_CONTROL_NONE:
- break;
- case META_FRAME_CONTROL_TITLE:
- break;
- case META_FRAME_CONTROL_DELETE:
- break;
- case META_FRAME_CONTROL_MENU:
- break;
- case META_FRAME_CONTROL_MINIMIZE:
- break;
- case META_FRAME_CONTROL_MAXIMIZE:
- break;
- case META_FRAME_CONTROL_UNMAXIMIZE:
- break;
- case META_FRAME_CONTROL_RESIZE_SE:
- cursor = META_CURSOR_SE_RESIZE;
- break;
- case META_FRAME_CONTROL_RESIZE_S:
- cursor = META_CURSOR_SOUTH_RESIZE;
- break;
- case META_FRAME_CONTROL_RESIZE_SW:
- cursor = META_CURSOR_SW_RESIZE;
- break;
- case META_FRAME_CONTROL_RESIZE_N:
- cursor = META_CURSOR_NORTH_RESIZE;
- break;
- case META_FRAME_CONTROL_RESIZE_NE:
- cursor = META_CURSOR_NE_RESIZE;
- break;
- case META_FRAME_CONTROL_RESIZE_NW:
- cursor = META_CURSOR_NW_RESIZE;
- break;
- case META_FRAME_CONTROL_RESIZE_W:
- cursor = META_CURSOR_WEST_RESIZE;
- break;
- case META_FRAME_CONTROL_RESIZE_E:
- cursor = META_CURSOR_EAST_RESIZE;
- break;
- }
-
- /* set/unset the prelight cursor */
- meta_x11_wm_set_screen_cursor (frame->frames->x11_display,
- frame->xwindow,
- cursor);
-
- switch (control)
- {
- case META_FRAME_CONTROL_MENU:
- case META_FRAME_CONTROL_MINIMIZE:
- case META_FRAME_CONTROL_MAXIMIZE:
- case META_FRAME_CONTROL_DELETE:
- case META_FRAME_CONTROL_UNMAXIMIZE:
- /* leave control set */
- break;
- default:
- /* Only prelight buttons */
- control = META_FRAME_CONTROL_NONE;
- break;
- }
-
- 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 (frame, old_control);
- redraw_control (frame, control);
-}
-
-static gboolean
-handle_motion_event (MetaUIFrame *frame,
- const ClutterEvent *event)
-{
- MetaFrames *frames = frame->frames;
- MetaFrameControl control;
- ClutterModifierType modifiers;
- guint32 evtime;
- gfloat x, y;
-
- g_assert (event->type == CLUTTER_MOTION ||
- event->type == CLUTTER_TOUCH_UPDATE);
-
- 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);
-
- if (frame->button_state == META_BUTTON_STATE_PRESSED)
- {
- /* 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
- {
- /* Update prelit control and cursor */
- meta_ui_frame_update_prelit_control (frame, control);
- }
-
- 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);
-
- return TRUE;
-}
-
-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;
- MetaRectangle buffer_rect = frame->meta_window->buffer_rect;
-
- 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_default (), frame->style_info,
- type, frame->text_height, flags,
- &borders);
-
- /* Frame rect */
- area.x = 0;
- area.y = 0;
- area.width = buffer_rect.width;
- area.height = buffer_rect.height;
-
- frame_border = cairo_region_create_rectangle (&area);
-
- /* 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;
-
- /* Visible frame border */
- cairo_region_subtract_rectangle (frame_border, &area);
- return frame_border;
-}
-
-/*
- * 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)
-{
- MetaFrameBorders borders;
- MetaFrameFlags flags;
- cairo_surface_t *surface;
- double xscale, yscale;
- int scale;
-
- flags = meta_frame_get_flags (frame->meta_window->frame);
-
- 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);
-
- 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);
-
- cairo_surface_set_device_scale (surface, xscale, yscale);
-}
-
-/* XXX -- this is disgusting. Find a better approach here.
- * Use multiple widgets? */
-static MetaUIFrame *
-find_frame_to_draw (MetaFrames *frames,
- cairo_t *cr)
-{
- GHashTableIter iter;
- MetaUIFrame *frame;
-
- 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;
-
- return NULL;
-}
-
-static gboolean
-meta_frames_draw (GtkWidget *widget,
- cairo_t *cr)
-{
- MetaUIFrame *frame;
- MetaFrames *frames;
- cairo_region_t *region;
-
- frames = META_FRAMES (widget);
-
- frame = find_frame_to_draw (frames, cr);
- if (frame == NULL)
- return FALSE;
-
- region = get_visible_frame_border_region (frame);
- gdk_cairo_region (cr, region);
- cairo_clip (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_ui_frame_paint (MetaUIFrame *frame,
- cairo_t *cr)
-{
- MetaFrameFlags flags;
- MetaFrameType type;
- cairo_surface_t *mini_icon;
- MetaButtonState button_states[META_BUTTON_TYPE_LAST];
- int i;
- int button_type = -1;
- MetaButtonLayout button_layout;
- MetaWindowX11 *window_x11 = META_WINDOW_X11 (frame->meta_window);
- MetaRectangle client_rect;
-
- for (i = 0; i < META_BUTTON_TYPE_LAST; i++)
- button_states[i] = META_BUTTON_STATE_NORMAL;
-
- /* Set prelight state */
- switch (frame->prelit_control)
- {
- case META_FRAME_CONTROL_MENU:
- button_type = META_BUTTON_TYPE_MENU;
- break;
- case META_FRAME_CONTROL_MINIMIZE:
- button_type = META_BUTTON_TYPE_MINIMIZE;
- break;
- case META_FRAME_CONTROL_MAXIMIZE:
- button_type = META_BUTTON_TYPE_MAXIMIZE;
- break;
- case META_FRAME_CONTROL_UNMAXIMIZE:
- button_type = META_BUTTON_TYPE_MAXIMIZE;
- break;
- case META_FRAME_CONTROL_DELETE:
- button_type = META_BUTTON_TYPE_CLOSE;
- break;
- default:
- break;
- }
-
- 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);
-
- client_rect = meta_window_x11_get_client_rect (window_x11);
-
- meta_theme_draw_frame (meta_theme_get_default (),
- frame->style_info,
- cr,
- type,
- flags,
- client_rect.width,
- 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
-handle_enter_notify_event (MetaUIFrame *frame,
- ClutterCrossingEvent *event)
-{
- MetaFrameControl control;
-
- frame->maybe_ignore_leave_notify = FALSE;
-
- control = get_control (frame, event->x, event->y);
- meta_ui_frame_update_prelit_control (frame, control);
-
- return TRUE;
-}
-
-static gboolean
-handle_leave_notify_event (MetaUIFrame *frame,
- ClutterCrossingEvent *event)
-{
- MetaGrabOp grab_op;
-
- grab_op = meta_x11_wm_get_grab_op (frame->frames->x11_display);
-
- /* 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_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)
-{
- GdkRectangle *rect;
-
- rect = NULL;
- switch (control)
- {
- case META_FRAME_CONTROL_TITLE:
- rect = &fgeom->title_rect;
- break;
- case META_FRAME_CONTROL_DELETE:
- rect = &fgeom->close_rect.visible;
- break;
- case META_FRAME_CONTROL_MENU:
- rect = &fgeom->menu_rect.visible;
- break;
- case META_FRAME_CONTROL_MINIMIZE:
- rect = &fgeom->min_rect.visible;
- break;
- case META_FRAME_CONTROL_MAXIMIZE:
- case META_FRAME_CONTROL_UNMAXIMIZE:
- rect = &fgeom->max_rect.visible;
- break;
- case META_FRAME_CONTROL_RESIZE_SE:
- break;
- case META_FRAME_CONTROL_RESIZE_S:
- break;
- case META_FRAME_CONTROL_RESIZE_SW:
- break;
- case META_FRAME_CONTROL_RESIZE_N:
- break;
- case META_FRAME_CONTROL_RESIZE_NE:
- break;
- case META_FRAME_CONTROL_RESIZE_NW:
- break;
- case META_FRAME_CONTROL_RESIZE_W:
- break;
- case META_FRAME_CONTROL_RESIZE_E:
- break;
- case META_FRAME_CONTROL_NONE:
- break;
- case META_FRAME_CONTROL_CLIENT_AREA:
- break;
- }
-
- return rect;
-}
-
-#define TOP_RESIZE_HEIGHT 4
-#define CORNER_SIZE_MULT 2
-static MetaFrameControl
-get_control (MetaUIFrame *frame, int root_x, int root_y)
-{
- MetaFrameGeometry fgeom;
- MetaFrameFlags flags;
- MetaFrameType type;
- gboolean has_vert, has_horiz;
- gboolean has_north_resize;
- cairo_rectangle_int_t client;
- int x, y;
- int win_x, win_y;
-
- if (meta_window_is_fullscreen (frame->meta_window))
- return META_FRAME_CONTROL_CLIENT_AREA;
-
- 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;
-
- if (META_POINT_IN_RECT (x, y, fgeom.min_rect.clickable))
- return META_FRAME_CONTROL_MINIMIZE;
-
- if (META_POINT_IN_RECT (x, y, fgeom.menu_rect.clickable))
- return META_FRAME_CONTROL_MENU;
-
- 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;
-
- 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))
- {
- if (has_vert && y <= TOP_RESIZE_HEIGHT && has_north_resize)
- return META_FRAME_CONTROL_RESIZE_N;
- else
- return META_FRAME_CONTROL_TITLE;
- }
-
- if (META_POINT_IN_RECT (x, y, fgeom.max_rect.clickable))
- {
- if (flags & META_FRAME_MAXIMIZED)
- return META_FRAME_CONTROL_UNMAXIMIZE;
- else
- return META_FRAME_CONTROL_MAXIMIZE;
- }
-
- /* South resize always has priority over north resize,
- * in case of overlap.
- */
-
- 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)
- return META_FRAME_CONTROL_RESIZE_SE;
- else if (has_vert)
- return META_FRAME_CONTROL_RESIZE_S;
- 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)
- return META_FRAME_CONTROL_RESIZE_SW;
- else if (has_vert)
- return META_FRAME_CONTROL_RESIZE_S;
- 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)
- {
- if (has_vert && has_horiz)
- return META_FRAME_CONTROL_RESIZE_NW;
- else if (has_vert)
- return META_FRAME_CONTROL_RESIZE_N;
- 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)
- {
- if (has_vert && has_horiz)
- return META_FRAME_CONTROL_RESIZE_NE;
- else if (has_vert)
- return META_FRAME_CONTROL_RESIZE_N;
- else if (has_horiz)
- return META_FRAME_CONTROL_RESIZE_E;
- }
- else if (y < (fgeom.borders.invisible.top + TOP_RESIZE_HEIGHT))
- {
- if (has_vert && has_north_resize)
- return META_FRAME_CONTROL_RESIZE_N;
- }
- else if (y >= (fgeom.height - fgeom.borders.total.bottom))
- {
- if (has_vert)
- return META_FRAME_CONTROL_RESIZE_S;
- }
- else if (x <= fgeom.borders.total.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_horiz || flags & META_FRAME_TILED_LEFT)
- return META_FRAME_CONTROL_RESIZE_E;
- }
-
- if (y >= fgeom.borders.total.top)
- return META_FRAME_CONTROL_NONE;
- else
- return META_FRAME_CONTROL_TITLE;
-}
diff --git a/src/ui/frames.h b/src/ui/frames.h
deleted file mode 100644
index d81be1c72..000000000
--- a/src/ui/frames.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_FRAMES_H
-#define META_FRAMES_H
-
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-
-#include "meta/common.h"
-#include "meta/types.h"
-#include "ui/theme-private.h"
-#include "ui/ui.h"
-
-typedef enum
-{
- META_FRAME_CONTROL_NONE,
- META_FRAME_CONTROL_TITLE,
- META_FRAME_CONTROL_DELETE,
- META_FRAME_CONTROL_MENU,
- META_FRAME_CONTROL_MINIMIZE,
- META_FRAME_CONTROL_MAXIMIZE,
- META_FRAME_CONTROL_UNMAXIMIZE,
- META_FRAME_CONTROL_RESIZE_SE,
- META_FRAME_CONTROL_RESIZE_S,
- META_FRAME_CONTROL_RESIZE_SW,
- META_FRAME_CONTROL_RESIZE_N,
- META_FRAME_CONTROL_RESIZE_NE,
- META_FRAME_CONTROL_RESIZE_NW,
- META_FRAME_CONTROL_RESIZE_W,
- META_FRAME_CONTROL_RESIZE_E,
- META_FRAME_CONTROL_CLIENT_AREA
-} MetaFrameControl;
-
-/* This is one widget that manages all the window frames
- * as subwindows.
- */
-
-#define META_TYPE_FRAMES (meta_frames_get_type ())
-#define META_FRAMES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_FRAMES, MetaFrames))
-#define META_FRAMES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_FRAMES, MetaFramesClass))
-#define META_IS_FRAMES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_FRAMES))
-#define META_IS_FRAMES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_FRAMES))
-#define META_FRAMES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_FRAMES, MetaFramesClass))
-
-typedef struct _MetaFrames MetaFrames;
-typedef struct _MetaFramesClass MetaFramesClass;
-
-struct _MetaUIFrame
-{
- MetaFrames *frames;
- MetaWindow *meta_window;
- Window xwindow;
- GdkWindow *window;
- MetaStyleInfo *style_info;
- MetaFrameLayout *cache_layout;
- PangoLayout *text_layout;
- int text_height;
- char *title; /* NULL once we have a layout */
- 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;
-
- MetaStyleInfo *normal_style;
- GHashTable *style_variants;
-
- MetaGrabOp current_grab_op;
- MetaUIFrame *grab_frame;
- guint grab_button;
- gdouble grab_x;
- gdouble grab_y;
-
- ClutterEventSequence *grab_touch;
-};
-
-struct _MetaFramesClass
-{
- GtkWindowClass parent_class;
-
-};
-
-GType meta_frames_get_type (void) G_GNUC_CONST;
-
-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/theme-private.h b/src/ui/theme-private.h
deleted file mode 100644
index 269dbe867..000000000
--- a/src/ui/theme-private.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_THEME_PRIVATE_H
-#define META_THEME_PRIVATE_H
-
-#include <gtk/gtk.h>
-
-#include "meta/boxes.h"
-#include "meta/common.h"
-#include "meta/theme.h"
-
-/**
- * MetaStyleInfo: (skip)
- *
- */
-typedef struct _MetaStyleInfo MetaStyleInfo;
-/**
- * MetaFrameLayout: (skip)
- *
- */
-typedef struct _MetaFrameLayout MetaFrameLayout;
-/**
- * MetaButtonSpace: (skip)
- *
- */
-typedef struct _MetaButtonSpace MetaButtonSpace;
-/**
- * MetaFrameGeometry: (skip)
- *
- */
-typedef struct _MetaFrameGeometry MetaFrameGeometry;
-
-/**
- * Various parameters used to calculate the geometry of a frame.
- **/
-struct _MetaFrameLayout
-{
- /** 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;
-
- /** Margin of title */
- GtkBorder title_margin;
- /** Margin of titlebar buttons */
- GtkBorder button_margin;
-
- /** Min size of titlebar region */
- GtkRequisition titlebar_min_size;
- /** Min size of titlebar buttons */
- GtkRequisition button_min_size;
-
- /** Size of images in buttons */
- guint icon_size;
-
- /** 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;
-
- /** Whether we should hide the buttons */
- guint hide_buttons : 1;
-
- /** Radius of the top left-hand corner; 0 if not rounded */
- guint top_left_corner_rounded_radius;
- /** Radius of the top right-hand corner; 0 if not rounded */
- guint top_right_corner_rounded_radius;
- /** Radius of the bottom left-hand corner; 0 if not rounded */
- guint bottom_left_corner_rounded_radius;
- /** Radius of the bottom right-hand corner; 0 if not rounded */
- guint bottom_right_corner_rounded_radius;
-};
-
-/**
- * The computed size of a button (really just a way of tying its
- * visible and clickable areas together).
- * The reason for two different rectangles here is Fitts' law & maximized
- * windows; see bug #97703 for more details.
- */
-struct _MetaButtonSpace
-{
- /** The screen area where the button's image is drawn */
- GdkRectangle visible;
- /** The screen area where the button can be activated by clicking */
- GdkRectangle clickable;
-};
-
-/**
- * Calculated actual geometry of the frame
- */
-struct _MetaFrameGeometry
-{
- MetaFrameBorders borders;
-
- int width;
- int height;
-
- GdkRectangle title_rect;
-
- 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, 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;
- /* 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;
- guint bottom_left_corner_rounded_radius;
- guint bottom_right_corner_rounded_radius;
-};
-
-typedef enum
-{
- META_BUTTON_STATE_NORMAL,
- META_BUTTON_STATE_PRESSED,
- META_BUTTON_STATE_PRELIGHT,
- META_BUTTON_STATE_LAST
-} MetaButtonState;
-
-typedef enum
-{
- META_BUTTON_TYPE_CLOSE,
- META_BUTTON_TYPE_MAXIMIZE,
- META_BUTTON_TYPE_MINIMIZE,
- META_BUTTON_TYPE_MENU,
- META_BUTTON_TYPE_LAST
-} MetaButtonType;
-
-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
-{
- int refcount;
-
- GtkStyleContext *styles[META_STYLE_ELEMENT_LAST];
-};
-
-/* Kinds of frame...
- *
- * normal -> focused / unfocused
- * max -> focused / unfocused
- * shaded -> focused / unfocused
- * max/shaded -> focused / unfocused
- *
- * so 4 states with 2 sub-states each, meaning 8 total
- *
- * 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
-{
- META_FRAME_STATE_NORMAL,
- META_FRAME_STATE_MAXIMIZED,
- META_FRAME_STATE_TILED_LEFT,
- META_FRAME_STATE_TILED_RIGHT,
- META_FRAME_STATE_SHADED,
- META_FRAME_STATE_MAXIMIZED_AND_SHADED,
- META_FRAME_STATE_TILED_LEFT_AND_SHADED,
- META_FRAME_STATE_TILED_RIGHT_AND_SHADED,
- META_FRAME_STATE_LAST
-} MetaFrameState;
-
-typedef enum
-{
- META_FRAME_FOCUS_NO,
- META_FRAME_FOCUS_YES,
- META_FRAME_FOCUS_LAST
-} MetaFrameFocus;
-
-/**
- * A theme. This is a singleton class which groups all settings from a theme
- * together.
- */
-struct _MetaTheme
-{
- MetaFrameLayout *layouts[META_FRAME_TYPE_LAST];
-};
-
-void meta_frame_layout_apply_scale (const MetaFrameLayout *layout,
- PangoFontDescription *font_desc);
-
-MetaFrameLayout* meta_theme_get_frame_layout (MetaTheme *theme,
- MetaFrameType type);
-
-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);
-
-void meta_style_info_set_flags (MetaStyleInfo *style_info,
- MetaFrameFlags flags);
-
-PangoFontDescription * meta_style_info_create_font_desc (MetaStyleInfo *style_info);
-
-void meta_theme_draw_frame (MetaTheme *theme,
- MetaStyleInfo *style_info,
- 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],
- 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,
- int client_width,
- int client_height,
- const MetaButtonLayout *button_layout,
- MetaFrameGeometry *fgeom);
-
-/* random stuff */
-
-int meta_pango_font_desc_get_text_height (const PangoFontDescription *font_desc,
- PangoContext *context);
-int meta_theme_get_window_scaling_factor (void);
-
-#endif /* META_THEME_PRIVATE_H */
diff --git a/src/ui/theme.c b/src/ui/theme.c
deleted file mode 100644
index a4c8a0de2..000000000
--- a/src/ui/theme.c
+++ /dev/null
@@ -1,1397 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * 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/>.
- */
-
-#include "config.h"
-
-#include "ui/theme-private.h"
-
-#include <gtk/gtk.h>
-#include <math.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "core/util-private.h"
-#include "meta/prefs.h"
-#include "ui/frames.h"
-
-static void scale_border (GtkBorder *border, double factor);
-
-static MetaFrameLayout *
-meta_frame_layout_new (void)
-{
- MetaFrameLayout *layout;
-
- layout = g_new0 (MetaFrameLayout, 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 = PANGO_SCALE_MEDIUM;
- layout->icon_size = META_MINI_ICON_WIDTH;
-
- return layout;
-}
-
-static void
-meta_frame_layout_free (MetaFrameLayout *layout)
-{
- g_return_if_fail (layout != NULL);
-
- g_free (layout);
-}
-
-static void
-meta_frame_layout_get_borders (const MetaFrameLayout *layout,
- int text_height,
- MetaFrameFlags flags,
- MetaFrameType type,
- MetaFrameBorders *borders)
-{
- int buttons_height, content_height, draggable_borders;
- int scale = meta_theme_get_window_scaling_factor ();
-
- meta_frame_borders_clear (borders);
-
- /* For a full-screen window, we don't have any borders, visible or not. */
- if (flags & META_FRAME_FULLSCREEN)
- return;
-
- g_return_if_fail (layout != NULL);
-
- if (!layout->has_title)
- text_height = 0;
- else
- text_height = layout->title_margin.top + text_height + layout->title_margin.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 = 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;
-
- borders->invisible = layout->invisible_border;
-
- draggable_borders = meta_prefs_get_draggable_border_width ();
-
- if (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE)
- {
- 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_VERTICAL_RESIZE)
- {
- borders->invisible.bottom = MAX (borders->invisible.bottom,
- draggable_borders - borders->visible.bottom);
-
- /* 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);
-}
-
-int
-meta_theme_get_window_scaling_factor (void)
-{
- 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;
-}
-
-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*
-rect_for_function (MetaFrameGeometry *fgeom,
- MetaFrameFlags flags,
- MetaButtonFunction function,
- MetaTheme *theme)
-{
- switch (function)
- {
- case META_BUTTON_FUNCTION_MENU:
- if (flags & META_FRAME_ALLOWS_MENU)
- return &fgeom->menu_rect;
- else
- return NULL;
- case META_BUTTON_FUNCTION_MINIMIZE:
- if (flags & META_FRAME_ALLOWS_MINIMIZE)
- return &fgeom->min_rect;
- else
- return NULL;
- case META_BUTTON_FUNCTION_MAXIMIZE:
- if (flags & META_FRAME_ALLOWS_MAXIMIZE)
- return &fgeom->max_rect;
- else
- return NULL;
- case META_BUTTON_FUNCTION_CLOSE:
- if (flags & META_FRAME_ALLOWS_DELETE)
- return &fgeom->close_rect;
- else
- return NULL;
-
- case META_BUTTON_FUNCTION_LAST:
- return NULL;
- }
-
- return NULL;
-}
-
-static gboolean
-strip_button (MetaButtonSpace *func_rects[MAX_BUTTONS_PER_CORNER],
- int *n_rects,
- MetaButtonSpace *to_strip)
-{
- int i;
-
- i = 0;
- while (i < *n_rects)
- {
- if (func_rects[i] == to_strip)
- {
- *n_rects -= 1;
-
- /* shift the other rects back in the array */
- while (i < *n_rects)
- {
- func_rects[i] = func_rects[i+1];
-
- ++i;
- }
-
- func_rects[i] = NULL;
-
- return TRUE;
- }
-
- ++i;
- }
-
- return FALSE; /* did not strip anything */
-}
-
-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,
- int client_height,
- const MetaButtonLayout *button_layout,
- MetaFrameType type,
- MetaFrameGeometry *fgeom,
- MetaTheme *theme)
-{
- int i, n_left, n_right, n_left_spacers, n_right_spacers;
- int x;
- 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];
- gboolean left_buttons_has_spacer[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 = borders.total.top + borders.total.bottom;
- if (!(flags & META_FRAME_SHADED))
- height += client_height;
-
- fgeom->width = width;
- fgeom->height = height;
-
- 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;
-
- 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
- * code in frames.c, so isn't really allowed right now.
- * Would need left_close_rect, right_close_rect, etc.
- */
-
- /* Init all button rects to 0, lame hack */
- memset (ADDRESS_OF_BUTTON_RECTS (fgeom), '\0',
- LENGTH_OF_BUTTON_RECTS);
-
- n_left = 0;
- n_right = 0;
- n_left_spacers = 0;
- n_right_spacers = 0;
-
- if (!layout->hide_buttons)
- {
- /* Try to fill in rects */
- for (i = 0; i < MAX_BUTTONS_PER_CORNER && button_layout->left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++)
- {
- left_func_rects[n_left] = rect_for_function (fgeom, flags,
- button_layout->left_buttons[i],
- theme);
- if (left_func_rects[n_left] != NULL)
- {
- left_buttons_has_spacer[n_left] = button_layout->left_buttons_has_spacer[i];
- if (button_layout->left_buttons_has_spacer[i])
- ++n_left_spacers;
-
- ++n_left;
- }
- }
-
- for (i = 0; i < MAX_BUTTONS_PER_CORNER && button_layout->right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++)
- {
- right_func_rects[n_right] = rect_for_function (fgeom, flags,
- button_layout->right_buttons[i],
- theme);
- if (right_func_rects[n_right] != NULL)
- {
- right_buttons_has_spacer[n_right] = button_layout->right_buttons_has_spacer[i];
- if (button_layout->right_buttons_has_spacer[i])
- ++n_right_spacers;
-
- ++n_right;
- }
- }
- }
-
- /* Be sure buttons fit */
- while (n_left > 0 || n_right > 0)
- {
- int space_used_by_buttons;
-
- 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->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->titlebar_spacing * scale * MAX (n_right - 1, 0);
-
- if (space_used_by_buttons <= content_width)
- break; /* Everything fits, bail out */
-
- /* First try to remove separators */
- if (n_left_spacers > 0)
- {
- left_buttons_has_spacer[--n_left_spacers] = FALSE;
- continue;
- }
- else if (n_right_spacers > 0)
- {
- right_buttons_has_spacer[--n_right_spacers] = FALSE;
- continue;
- }
-
- /* Otherwise we need to shave out a button. Shave
- * min, max, close, then menu (menu is most useful);
- * prefer the default button locations.
- */
- if (strip_button (left_func_rects, &n_left, &fgeom->min_rect))
- continue;
- else if (strip_button (right_func_rects, &n_right, &fgeom->min_rect))
- continue;
- else if (strip_button (left_func_rects, &n_left, &fgeom->max_rect))
- continue;
- else if (strip_button (right_func_rects, &n_right, &fgeom->max_rect))
- continue;
- else if (strip_button (left_func_rects, &n_left, &fgeom->close_rect))
- continue;
- else if (strip_button (right_func_rects, &n_right, &fgeom->close_rect))
- continue;
- else if (strip_button (right_func_rects, &n_right, &fgeom->menu_rect))
- continue;
- else if (strip_button (left_func_rects, &n_left, &fgeom->menu_rect))
- continue;
- else
- {
- meta_bug ("Could not find a button to strip. n_left = %d n_right = %d",
- n_left, n_right);
- }
- }
-
- /* Save the button layout */
- fgeom->button_layout = *button_layout;
- fgeom->n_left_buttons = n_left;
- fgeom->n_right_buttons = n_right;
-
- /* center buttons vertically */
- button_y = fgeom->content_border.top + borders.invisible.top +
- (content_height - button_height) / 2;
-
- /* right edge of farthest-right button */
- x = width - fgeom->content_border.right - borders.invisible.right;
-
- i = n_right - 1;
- while (i >= 0)
- {
- MetaButtonSpace *rect;
-
- 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 - button_width;
- if (right_buttons_has_spacer[i])
- rect->visible.x -= (button_width * 0.75);
-
- rect->visible.y = button_y;
- rect->visible.width = button_width;
- rect->visible.height = button_height;
-
- if (flags & META_FRAME_MAXIMIZED ||
- flags & META_FRAME_TILED_LEFT ||
- flags & META_FRAME_TILED_RIGHT)
- {
- rect->clickable.x = rect->visible.x;
- rect->clickable.y = 0;
- rect->clickable.width = rect->visible.width;
- rect->clickable.height = button_height + button_y;
-
- if (i == n_right - 1)
- rect->clickable.width += fgeom->content_border.right;
-
- }
- else
- memmove (&(rect->clickable), &(rect->visible), sizeof (rect->clickable));
-
- x = rect->visible.x - layout->button_margin.left * scale;
-
- if (i > 0)
- x -= layout->titlebar_spacing * scale;
-
- --i;
- }
-
- /* save right edge of titlebar for later use */
- title_right_edge = x;
-
- /* Now x changes to be position from the left and we go through
- * the left-side buttons
- */
- 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;
- rect->visible.y = button_y;
- rect->visible.width = button_width;
- rect->visible.height = button_height;
-
- if (flags & META_FRAME_MAXIMIZED)
- {
- if (i==0)
- {
- rect->clickable.x = 0;
- rect->clickable.width = button_width + x;
- }
- else
- {
- rect->clickable.x = rect->visible.x;
- rect->clickable.width = button_width;
- }
-
- 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_margin.right * scale;
- if (i < n_left - 1)
- x += layout->titlebar_spacing * scale;
- if (left_buttons_has_spacer[i])
- x += (button_width * 0.75);
- }
-
- /* 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 = text_height;
-
- /* Nuke title if it won't fit */
- if (fgeom->title_rect.width < 0 ||
- fgeom->title_rect.height < 0)
- {
- fgeom->title_rect.width = 0;
- fgeom->title_rect.height = 0;
- }
-
- if (flags & META_FRAME_SHADED)
- min_size_for_rounding = 0;
- else
- min_size_for_rounding = 5 * scale;
-
- fgeom->top_left_corner_rounded_radius = 0;
- fgeom->top_right_corner_rounded_radius = 0;
- fgeom->bottom_left_corner_rounded_radius = 0;
- 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 * scale;
- if (borders.visible.top + borders.visible.right >= min_size_for_rounding)
- 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 * scale;
- if (borders.visible.bottom + borders.visible.right >= min_size_for_rounding)
- fgeom->bottom_right_corner_rounded_radius = layout->bottom_right_corner_rounded_radius * scale;
-}
-
-static void
-get_button_rect (MetaButtonType type,
- const MetaFrameGeometry *fgeom,
- GdkRectangle *rect)
-{
- switch (type)
- {
- case META_BUTTON_TYPE_CLOSE:
- *rect = fgeom->close_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;
-
- default:
- case META_BUTTON_TYPE_LAST:
- g_assert_not_reached ();
- break;
- }
-}
-
-static const char *
-get_class_from_button_type (MetaButtonType type)
-{
- switch (type)
- {
- case META_BUTTON_TYPE_CLOSE:
- return "close";
- case META_BUTTON_TYPE_MAXIMIZE:
- return "maximize";
- case META_BUTTON_TYPE_MINIMIZE:
- return "minimize";
- default:
- return NULL;
- }
-}
-
-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)
-{
- 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);
-
- borders = &fgeom->borders;
-
- 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;
-
- meta_style_info_set_flags (style_info, flags);
-
- 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);
-
- 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;
-
- 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);
-
- if (layout->has_title && title_layout)
- {
- PangoRectangle logical;
- int text_width, x, y;
-
- pango_layout_set_width (title_layout, -1);
- pango_layout_get_pixel_extents (title_layout, NULL, &logical);
-
- text_width = MIN(fgeom->title_rect.width / scale, logical.width);
-
- if (text_width < logical.width)
- pango_layout_set_width (title_layout, PANGO_SCALE * text_width);
-
- /* 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;
-
- 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;
-
- style = style_info->styles[META_STYLE_ELEMENT_TITLE];
- gtk_render_layout (style, cr, x, y, title_layout);
- }
-
- 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);
-
- get_button_rect (button_type, fgeom, &button_rect);
-
- button_rect.x /= scale;
- button_rect.y /= scale;
- button_rect.width /= scale;
- button_rect.height /= scale;
-
- 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);
-
- cairo_save (cr);
-
- if (button_rect.width > 0 && button_rect.height > 0)
- {
- cairo_surface_t *surface = NULL;
- const char *icon_name = NULL;
-
- 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);
-
- switch (button_type)
- {
- 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;
- }
-
- if (icon_name)
- {
- GtkIconTheme *theme = gtk_icon_theme_get_default ();
- g_autoptr (GtkIconInfo) info = NULL;
- g_autoptr (GdkPixbuf) pixbuf = NULL;
-
- info = gtk_icon_theme_lookup_icon_for_scale (theme, icon_name,
- layout->icon_size, scale, 0);
- pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL);
- surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL);
- }
-
- if (surface)
- {
- float width, height;
- int x, y;
-
- width = cairo_image_surface_get_width (surface) / scale;
- height = cairo_image_surface_get_height (surface) / scale;
- x = button_rect.x + (button_rect.width - layout->icon_size) / 2;
- y = button_rect.y + (button_rect.height - layout->icon_size) / 2;
-
- cairo_translate (cr, x, y);
- cairo_scale (cr,
- layout->icon_size / width,
- layout->icon_size / height);
- cairo_set_source_surface (cr, surface, 0, 0);
- cairo_paint (cr);
-
- 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);
- }
-
- cairo_surface_set_device_scale (frame_surface, xscale, yscale);
-}
-
-/**
- * meta_theme_get_default: (skip)
- *
- */
-MetaTheme*
-meta_theme_get_default (void)
-{
- static MetaTheme *theme = NULL;
- int frame_type;
-
- if (theme)
- return theme;
-
- theme = meta_theme_new ();
-
- for (frame_type = 0; frame_type < META_FRAME_TYPE_LAST; frame_type++)
- {
- MetaFrameLayout *layout = meta_frame_layout_new ();
-
- switch (frame_type)
- {
- 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 ();
- }
-
- theme->layouts[frame_type] = layout;
- }
- return theme;
-}
-
-/**
- * meta_theme_new: (skip)
- *
- */
-MetaTheme*
-meta_theme_new (void)
-{
- return g_new0 (MetaTheme, 1);
-}
-
-
-void
-meta_theme_free (MetaTheme *theme)
-{
- int i;
-
- g_return_if_fail (theme != NULL);
-
- for (i = 0; i < META_FRAME_TYPE_LAST; i++)
- if (theme->layouts[i])
- meta_frame_layout_free (theme->layouts[i]);
-
- g_free (theme);
-}
-
-MetaFrameLayout*
-meta_theme_get_frame_layout (MetaTheme *theme,
- MetaFrameType type)
-{
- g_return_val_if_fail (type < META_FRAME_TYPE_LAST, NULL);
-
- return theme->layouts[type];
-}
-
-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;
-
- 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);
-
- if (parent_style)
- path = gtk_widget_path_copy (gtk_style_context_get_path (parent_style));
- else
- path = gtk_widget_path_new ();
-
- gtk_widget_path_append_type (path, widget_type);
-
- if (object_name)
- gtk_widget_path_iter_set_object_name (path, -1, object_name);
-
- 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
- {
- state |= GTK_STATE_FLAG_DIR_LTR;
- state &= ~GTK_STATE_FLAG_DIR_RTL;
- }
- gtk_style_context_set_state (style, state);
-
- 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);
-
- gtk_style_context_set_path (style, path);
- gtk_widget_path_unref (path);
-
- gtk_style_context_add_provider (style, GTK_STYLE_PROVIDER (provider),
- GTK_STYLE_PROVIDER_PRIORITY_SETTINGS);
-
- return style;
-}
-
-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;
-}
-
-void
-meta_style_info_unref (MetaStyleInfo *style_info)
-{
- g_return_if_fail (style_info != NULL);
- g_return_if_fail (style_info->refcount > 0);
-
- if (g_atomic_int_dec_and_test ((volatile int *)&style_info->refcount))
- {
- int i;
- for (i = 0; i < META_STYLE_ELEMENT_LAST; i++)
- g_object_unref (style_info->styles[i]);
- g_free (style_info);
- }
-}
-
-static void
-add_toplevel_class (GtkStyleContext *style,
- const char *class_name)
-{
- if (gtk_style_context_get_parent (style))
- {
- GtkWidgetPath *path;
-
- 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
-remove_toplevel_class (GtkStyleContext *style,
- const char *class_name)
-{
- if (gtk_style_context_get_parent (style))
- {
- GtkWidgetPath *path;
-
- 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);
-}
-
-void
-meta_style_info_set_flags (MetaStyleInfo *style_info,
- MetaFrameFlags flags)
-{
- GtkStyleContext *style;
- const char *class_name = NULL;
- gboolean backdrop;
- GtkStateFlags state;
- int i;
-
- backdrop = !(flags & META_FRAME_HAS_FOCUS);
-
- if (flags & META_FRAME_MAXIMIZED)
- class_name = "maximized";
- else if (flags & META_FRAME_TILED_LEFT ||
- flags & META_FRAME_TILED_RIGHT)
- class_name = "tiled";
-
- for (i = 0; i < META_STYLE_ELEMENT_LAST; i++)
- {
- style = style_info->styles[i];
-
- 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);
-
- remove_toplevel_class (style, "maximized");
- remove_toplevel_class (style, "tiled");
-
- if (class_name)
- add_toplevel_class (style, class_name);
- }
-}
-
-PangoFontDescription*
-meta_style_info_create_font_desc (MetaStyleInfo *style_info)
-{
- PangoFontDescription *font_desc;
- const PangoFontDescription *override = meta_prefs_get_titlebar_font ();
- GtkStyleContext *context = style_info->styles[META_STYLE_ELEMENT_TITLE];
-
- gtk_style_context_get (context,
- gtk_style_context_get_state (context),
- "font", &font_desc, NULL);
-
- if (override)
- pango_font_description_merge (font_desc, override, TRUE);
-
- return font_desc;
-}
-
-void
-meta_theme_draw_frame (MetaTheme *theme,
- MetaStyleInfo *style_info,
- 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],
- cairo_surface_t *mini_icon)
-{
- MetaFrameGeometry fgeom;
- MetaFrameLayout *layout;
-
- g_return_if_fail (type < META_FRAME_TYPE_LAST);
-
- layout = theme->layouts[type];
-
- /* Parser is not supposed to allow this currently */
- if (layout == NULL)
- return;
-
- meta_frame_layout_calc_geometry (layout,
- style_info,
- text_height,
- flags,
- client_width, client_height,
- button_layout,
- type,
- &fgeom,
- theme);
-
- meta_frame_layout_draw_with_style (layout,
- style_info,
- cr,
- &fgeom,
- title_layout,
- flags,
- button_states,
- mini_icon);
-}
-
-void
-meta_theme_get_frame_borders (MetaTheme *theme,
- MetaStyleInfo *style_info,
- MetaFrameType type,
- int text_height,
- MetaFrameFlags flags,
- MetaFrameBorders *borders)
-{
- MetaFrameLayout *layout;
-
- g_return_if_fail (type < META_FRAME_TYPE_LAST);
-
- layout = theme->layouts[type];
-
- meta_frame_borders_clear (borders);
-
- /* Parser is not supposed to allow this currently */
- if (layout == NULL)
- return;
-
- meta_frame_layout_sync_with_style (layout, style_info, flags);
-
- meta_frame_layout_get_borders (layout,
- text_height,
- flags, type,
- borders);
-}
-
-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)
-{
- MetaFrameLayout *layout;
-
- g_return_if_fail (type < META_FRAME_TYPE_LAST);
-
- layout = theme->layouts[type];
-
- /* Parser is not supposed to allow this currently */
- if (layout == NULL)
- return;
-
- meta_frame_layout_calc_geometry (layout,
- style_info,
- text_height,
- flags,
- client_width, client_height,
- button_layout,
- type,
- fgeom,
- theme);
-}
-
-/**
- * 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)
-{
- 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;
-}
-
-/**
- * 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.
- *
- * Return value: the string value
- */
-const char*
-meta_frame_type_to_string (MetaFrameType type)
-{
- switch (type)
- {
- case META_FRAME_TYPE_NORMAL:
- return "normal";
- case META_FRAME_TYPE_DIALOG:
- return "dialog";
- case META_FRAME_TYPE_MODAL_DIALOG:
- return "modal_dialog";
- case META_FRAME_TYPE_UTILITY:
- return "utility";
- case META_FRAME_TYPE_MENU:
- return "menu";
- case META_FRAME_TYPE_BORDER:
- return "border";
- case META_FRAME_TYPE_ATTACHED:
- return "attached";
-#if 0
- case META_FRAME_TYPE_TOOLBAR:
- return "toolbar";
-#endif
- case META_FRAME_TYPE_LAST:
- break;
- }
-
- return "<unknown>";
-}
diff --git a/src/ui/ui.c b/src/ui/ui.c
deleted file mode 100644
index 2fbaad993..000000000
--- a/src/ui/ui.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Mutter interface for talking to GTK+ UI module */
-
-/*
- * 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 <cairo-xlib.h>
-#include <stdlib.h>
-#include <string.h>
-
-#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;
- MetaFrames *frames;
-
- /* For double-click tracking */
- gint button_click_number;
- Window button_click_window;
- int button_click_x;
- int button_click_y;
- guint32 button_click_time;
-};
-
-MetaUI *
-meta_ui_new (MetaX11Display *x11_display)
-{
- MetaUI *ui;
-
- if (!gtk_init_check (NULL, NULL))
- meta_fatal ("Unable to initialize GTK");
-
- g_assert (x11_display->gdk_display == gdk_display_get_default ());
-
- ui = g_new0 (MetaUI, 1);
- ui->xdisplay = x11_display->xdisplay;
-
- 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
- * and fully tracked as a MetaWindow. Horrible, but mostly harmless -
- * the window is a 1x1 override redirect window positioned offscreen.
- */
- gtk_widget_show (GTK_WIDGET (ui->frames));
-
- g_object_set_data (G_OBJECT (x11_display->gdk_display), "meta-ui", ui);
-
- return ui;
-}
-
-void
-meta_ui_free (MetaUI *ui)
-{
- GdkDisplay *gdk_display;
-
- gtk_widget_destroy (GTK_WIDGET (ui->frames));
-
- gdk_display = gdk_x11_lookup_xdisplay (ui->xdisplay);
- g_object_set_data (G_OBJECT (gdk_display), "meta-ui", NULL);
-
- g_free (ui);
-}
-
-static void
-set_background_none (Display *xdisplay,
- Window xwindow)
-{
- XSetWindowAttributes attrs;
-
- attrs.background_pixmap = None;
- XChangeWindowAttributes (xdisplay, xwindow,
- CWBackPixmap, &attrs);
-}
-
-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;
- 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
- * visual as the client.
- */
- if (!xvisual)
- visual = gdk_screen_get_system_visual (screen);
- else
- {
- visual = gdk_x11_screen_lookup_visual (screen,
- XVisualIDFromVisual (xvisual));
- }
-
- attrs.title = NULL;
-
- attrs.event_mask = GDK_EXPOSURE_MASK;
- attrs.x = x;
- attrs.y = y;
- attrs.wclass = GDK_INPUT_OUTPUT;
- attrs.visual = visual;
- attrs.window_type = GDK_WINDOW_CHILD;
- attrs.cursor = NULL;
- attrs.wmclass_name = NULL;
- attrs.wmclass_class = NULL;
- attrs.override_redirect = FALSE;
-
- attrs.width = width;
- attrs.height = height;
-
- attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
-
- /* We make an assumption that gdk_window_new() is going to call
- * XCreateWindow as it's first operation; this seems to be true currently
- * as long as you pass in a colormap.
- */
- if (create_serial)
- *create_serial = XNextRequest (xdisplay);
- window =
- gdk_window_new (gdk_screen_get_root_window(screen),
- &attrs, attributes_mask);
-
- gdk_window_resize (window, width, height);
- set_background_none (xdisplay, GDK_WINDOW_XID (window));
-
- return meta_frames_manage_window (ui->frames, meta_window, GDK_WINDOW_XID (window), window);
-}
-
-void
-meta_ui_map_frame (MetaUI *ui,
- Window xwindow)
-{
- GdkWindow *window;
- GdkDisplay *display;
-
- display = gdk_x11_lookup_xdisplay (ui->xdisplay);
- window = gdk_x11_window_lookup_for_display (display, xwindow);
-
- if (window)
- gdk_window_show_unraised (window);
-}
-
-void
-meta_ui_unmap_frame (MetaUI *ui,
- Window xwindow)
-{
- GdkWindow *window;
- GdkDisplay *display;
-
- display = gdk_x11_lookup_xdisplay (ui->xdisplay);
- window = gdk_x11_window_lookup_for_display (display, xwindow);
-
- if (window)
- gdk_window_hide (window);
-}
-
-gboolean
-meta_ui_window_should_not_cause_focus (Display *xdisplay,
- Window xwindow)
-{
- GdkWindow *window;
- GdkDisplay *display;
-
- display = gdk_x11_lookup_xdisplay (xdisplay);
- window = gdk_x11_window_lookup_for_display (display, xwindow);
-
- /* we shouldn't cause focus if we're an override redirect
- * toplevel which is not foreign
- */
- if (window && gdk_window_get_window_type (window) == GDK_WINDOW_TEMP)
- return TRUE;
- else
- return FALSE;
-}
-
-void
-meta_ui_theme_get_frame_borders (MetaUI *ui,
- MetaFrameType type,
- MetaFrameFlags flags,
- MetaFrameBorders *borders)
-{
- GdkDisplay *display;
- GdkScreen *screen;
- int text_height;
- MetaStyleInfo *style_info = NULL;
- PangoContext *context;
- const PangoFontDescription *font_desc;
- PangoFontDescription *free_font_desc = NULL;
-
- display = gdk_x11_lookup_xdisplay (ui->xdisplay);
- screen = gdk_display_get_default_screen (display);
-
- style_info = meta_theme_create_style_info (screen, NULL);
-
- context = gtk_widget_get_pango_context (GTK_WIDGET (ui->frames));
- font_desc = meta_prefs_get_titlebar_font ();
-
- if (!font_desc)
- {
- free_font_desc = meta_style_info_create_font_desc (style_info);
- 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_default (),
- style_info, type, text_height, flags,
- borders);
-
- if (free_font_desc)
- pango_font_description_free (free_font_desc);
-
- if (style_info != NULL)
- meta_style_info_unref (style_info);
-}
-
-gboolean
-meta_ui_window_is_widget (MetaUI *ui,
- Window xwindow)
-{
- GdkDisplay *display;
- GdkWindow *window;
-
- display = gdk_x11_lookup_xdisplay (ui->xdisplay);
- window = gdk_x11_window_lookup_for_display (display, xwindow);
-
- if (window)
- {
- void *user_data = NULL;
- gdk_window_get_user_data (window, &user_data);
- return user_data != NULL && user_data != ui->frames;
- }
- else
- return FALSE;
-}
-
-gboolean
-meta_ui_window_is_dummy (MetaUI *ui,
- Window xwindow)
-{
- GdkWindow *frames_window = gtk_widget_get_window (GTK_WIDGET (ui->frames));
- return xwindow == gdk_x11_window_get_xid (frames_window);
-}
diff --git a/src/ui/ui.h b/src/ui/ui.h
deleted file mode 100644
index e7a00e4e6..000000000
--- a/src/ui/ui.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_UI_H
-#define META_UI_H
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <cairo.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);
-
-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);
-
-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);
-void meta_ui_move_resize_frame (MetaUI *ui,
- Window frame,
- int x,
- int y,
- int width,
- int height);
-
-/* GDK insists on tracking map/unmap */
-void meta_ui_map_frame (MetaUI *ui,
- Window xwindow);
-void meta_ui_unmap_frame (MetaUI *ui,
- Window xwindow);
-
-gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay,
- Window xwindow);
-
-gboolean meta_ui_window_is_widget (MetaUI *ui,
- Window xwindow);
-
-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
deleted file mode 100644
index 7c14960ff..000000000
--- a/src/wayland/meta-cursor-sprite-wayland.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 107698f3f..000000000
--- a/src/wayland/meta-cursor-sprite-wayland.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 3df6ed0ab..000000000
--- a/src/wayland/meta-pointer-confinement-wayland.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/* -*- 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 "wayland/meta-wayland-pointer-constraints.h"
-#include "wayland/meta-wayland-pointer.h"
-#include "wayland/meta-wayland-seat.h"
-#include "wayland/meta-wayland-surface.h"
-
-typedef struct _MetaPointerConfinementWaylandPrivate MetaPointerConfinementWaylandPrivate;
-
-struct _MetaPointerConfinementWaylandPrivate
-{
- MetaWaylandPointerConstraint *constraint;
- gboolean enabled;
-};
-
-enum
-{
- PROP_0,
- PROP_WAYLAND_POINTER_CONSTRAINT,
- N_PROPS,
-};
-
-static GParamSpec *props[N_PROPS] = { 0 };
-
-G_DEFINE_TYPE_WITH_PRIVATE (MetaPointerConfinementWayland,
- meta_pointer_confinement_wayland,
- G_TYPE_OBJECT)
-
-static void
-meta_pointer_confinement_wayland_update (MetaPointerConfinementWayland *self)
-{
- MetaPointerConstraint *constraint;
-
- constraint =
- META_POINTER_CONFINEMENT_WAYLAND_GET_CLASS (self)->create_constraint (self);
- meta_backend_set_client_pointer_constraint (meta_get_backend (), constraint);
- g_object_unref (constraint);
-}
-
-static void
-surface_geometry_changed (MetaWaylandSurface *surface,
- MetaPointerConfinementWayland *self)
-{
- meta_pointer_confinement_wayland_update (self);
-}
-
-static void
-window_position_changed (MetaWindow *window,
- MetaPointerConfinementWayland *self)
-{
- meta_pointer_confinement_wayland_update (self);
-}
-
-void
-meta_pointer_confinement_wayland_enable (MetaPointerConfinementWayland *confinement)
-{
- MetaPointerConfinementWaylandPrivate *priv;
- MetaWaylandPointerConstraint *constraint;
- MetaWaylandSurface *surface;
- MetaWindow *window;
-
- priv = meta_pointer_confinement_wayland_get_instance_private (confinement);
- g_assert (!priv->enabled);
-
- priv->enabled = TRUE;
- constraint = priv->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);
- }
-
- meta_pointer_confinement_wayland_update (confinement);
-}
-
-void
-meta_pointer_confinement_wayland_disable (MetaPointerConfinementWayland *confinement)
-{
- MetaPointerConfinementWaylandPrivate *priv;
- MetaWaylandPointerConstraint *constraint;
- MetaWaylandSurface *surface;
- MetaWindow *window;
-
- priv = meta_pointer_confinement_wayland_get_instance_private (confinement);
- constraint = priv->constraint;
- g_assert (priv->enabled);
-
- priv->enabled = FALSE;
- surface = meta_wayland_pointer_constraint_get_surface (constraint);
- g_signal_handlers_disconnect_by_func (surface, surface_geometry_changed,
- confinement);
-
- window = meta_wayland_surface_get_window (surface);
- if (window)
- {
- g_signal_handlers_disconnect_by_func (window, window_position_changed,
- confinement);
- }
-
- meta_backend_set_client_pointer_constraint (meta_get_backend (), NULL);
-}
-
-static void
-meta_pointer_confinement_wayland_init (MetaPointerConfinementWayland *confinement_wayland)
-{
-}
-
-static void
-meta_pointer_confinement_wayland_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MetaPointerConfinementWayland *confinement;
- MetaPointerConfinementWaylandPrivate *priv;
-
- confinement = META_POINTER_CONFINEMENT_WAYLAND (object);
- priv = meta_pointer_confinement_wayland_get_instance_private (confinement);
-
- switch (prop_id)
- {
- case PROP_WAYLAND_POINTER_CONSTRAINT:
- g_value_set_object (value, priv->constraint);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-meta_pointer_confinement_wayland_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MetaPointerConfinementWayland *confinement;
- MetaPointerConfinementWaylandPrivate *priv;
-
- confinement = META_POINTER_CONFINEMENT_WAYLAND (object);
- priv = meta_pointer_confinement_wayland_get_instance_private (confinement);
-
- switch (prop_id)
- {
- case PROP_WAYLAND_POINTER_CONSTRAINT:
- priv->constraint = g_value_get_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static MetaPointerConstraint *
-meta_pointer_confinement_wayland_create_constraint (MetaPointerConfinementWayland *confinement)
-{
- MetaPointerConfinementWaylandPrivate *priv;
- MetaPointerConstraint *constraint;
- MetaWaylandSurface *surface;
- cairo_region_t *region;
- float dx, dy;
-
- priv = meta_pointer_confinement_wayland_get_instance_private (confinement);
-
- surface = meta_wayland_pointer_constraint_get_surface (priv->constraint);
- region =
- meta_wayland_pointer_constraint_calculate_effective_region (priv->constraint);
-
- meta_wayland_surface_get_absolute_coordinates (surface, 0, 0, &dx, &dy);
- cairo_region_translate (region, dx, dy);
-
- constraint = meta_pointer_constraint_new (region);
- cairo_region_destroy (region);
-
- return constraint;
-}
-
-static void
-meta_pointer_confinement_wayland_class_init (MetaPointerConfinementWaylandClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->set_property = meta_pointer_confinement_wayland_set_property;
- object_class->get_property = meta_pointer_confinement_wayland_get_property;
-
- klass->create_constraint = meta_pointer_confinement_wayland_create_constraint;
-
- props[PROP_WAYLAND_POINTER_CONSTRAINT] =
- g_param_spec_object ("wayland-pointer-constraint",
- "Wayland pointer constraint",
- "Wayland pointer constraint",
- META_TYPE_WAYLAND_POINTER_CONSTRAINT,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, N_PROPS, props);
-}
-
-MetaPointerConfinementWayland *
-meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint)
-{
- return g_object_new (META_TYPE_POINTER_CONFINEMENT_WAYLAND,
- "wayland-pointer-constraint", constraint,
- NULL);
-}
-
-MetaWaylandPointerConstraint *
-meta_pointer_confinement_wayland_get_wayland_pointer_constraint (MetaPointerConfinementWayland *confinement)
-{
- MetaPointerConfinementWaylandPrivate *priv;
-
- priv = meta_pointer_confinement_wayland_get_instance_private (confinement);
- return priv->constraint;
-}
diff --git a/src/wayland/meta-pointer-confinement-wayland.h b/src/wayland/meta-pointer-confinement-wayland.h
deleted file mode 100644
index 4f265779c..000000000
--- a/src/wayland/meta-pointer-confinement-wayland.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- 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_DERIVABLE_TYPE (MetaPointerConfinementWayland,
- meta_pointer_confinement_wayland,
- META, POINTER_CONFINEMENT_WAYLAND,
- GObject)
-
-struct _MetaPointerConfinementWaylandClass
-{
- GObjectClass parent_class;
-
- MetaPointerConstraint * (*create_constraint) (MetaPointerConfinementWayland *confinement);
-};
-
-MetaPointerConfinementWayland *meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint);
-MetaWaylandPointerConstraint *
- meta_pointer_confinement_wayland_get_wayland_pointer_constraint (MetaPointerConfinementWayland *confinement);
-void meta_pointer_confinement_wayland_enable (MetaPointerConfinementWayland *confinement);
-void meta_pointer_confinement_wayland_disable (MetaPointerConfinementWayland *confinement);
-
-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
deleted file mode 100644
index 9e0e8bcb8..000000000
--- a/src/wayland/meta-pointer-lock-wayland.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* -*- 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-backend-private.h"
-#include "compositor/meta-surface-actor-wayland.h"
-
-struct _MetaPointerLockWayland
-{
- GObject parent;
- MetaWaylandPointerConstraint *constraint;
-};
-
-G_DEFINE_TYPE (MetaPointerLockWayland, meta_pointer_lock_wayland,
- META_TYPE_POINTER_CONFINEMENT_WAYLAND)
-
-static MetaPointerConstraint *
-meta_pointer_lock_wayland_create_constraint (MetaPointerConfinementWayland *confinement)
-{
- MetaBackend *backend = meta_get_backend ();
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
- ClutterInputDevice *pointer = clutter_seat_get_pointer (seat);
- MetaWaylandPointerConstraint *wayland_constraint;
- MetaPointerConstraint *constraint;
- MetaWaylandSurface *surface;
- graphene_point_t point;
- cairo_region_t *region;
- float sx, sy, x, y;
-
- clutter_seat_query_state (seat, pointer, NULL, &point, NULL);
- wayland_constraint =
- meta_pointer_confinement_wayland_get_wayland_pointer_constraint (confinement);
- surface = meta_wayland_pointer_constraint_get_surface (wayland_constraint);
- meta_wayland_surface_get_relative_coordinates (surface,
- point.x, point.y,
- &sx, &sy);
-
- meta_wayland_surface_get_absolute_coordinates (surface, sx, sy, &x, &y);
- region = cairo_region_create_rectangle (&(cairo_rectangle_int_t) { (int) x, (int) y, 1 , 1 });
-
- constraint = meta_pointer_constraint_new (region);
- cairo_region_destroy (region);
-
- return constraint;
-}
-
-MetaPointerConfinementWayland *
-meta_pointer_lock_wayland_new (MetaWaylandPointerConstraint *constraint)
-{
- return g_object_new (META_TYPE_POINTER_LOCK_WAYLAND,
- "wayland-pointer-constraint", constraint,
- NULL);
-}
-
-static void
-meta_pointer_lock_wayland_init (MetaPointerLockWayland *lock_wayland)
-{
-}
-
-static void
-meta_pointer_lock_wayland_class_init (MetaPointerLockWaylandClass *klass)
-{
- MetaPointerConfinementWaylandClass *confinement_class =
- META_POINTER_CONFINEMENT_WAYLAND_CLASS (klass);
-
- confinement_class->create_constraint =
- meta_pointer_lock_wayland_create_constraint;
-}
diff --git a/src/wayland/meta-pointer-lock-wayland.h b/src/wayland/meta-pointer-lock-wayland.h
deleted file mode 100644
index d52aaa30d..000000000
--- a/src/wayland/meta-pointer-lock-wayland.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- 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 "wayland/meta-pointer-confinement-wayland.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, MetaPointerConfinementWayland)
-
-MetaPointerConfinementWayland *meta_pointer_lock_wayland_new (MetaWaylandPointerConstraint *constraint);
-
-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
deleted file mode 100644
index 38489530a..000000000
--- a/src/wayland/meta-selection-source-wayland-private.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 4f6f0c33c..000000000
--- a/src/wayland/meta-selection-source-wayland.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * 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-activation.c b/src/wayland/meta-wayland-activation.c
deleted file mode 100644
index 07bc1adaa..000000000
--- a/src/wayland/meta-wayland-activation.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * 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.
- *
- * Author: Carlos Garnacho <carlosg@gnome.org>
- */
-
-#include "config.h"
-
-#include "wayland/meta-wayland-activation.h"
-
-#include <glib.h>
-#include <wayland-server.h>
-
-#include "wayland/meta-wayland-private.h"
-#include "wayland/meta-wayland-versions.h"
-
-#include "xdg-activation-v1-server-protocol.h"
-
-typedef struct _MetaXdgActivationToken MetaXdgActivationToken;
-
-struct _MetaWaylandActivation
-{
- MetaWaylandCompositor *compositor;
- struct wl_list resource_list;
- struct wl_list token_list;
- GHashTable *tokens;
-};
-
-struct _MetaXdgActivationToken
-{
- MetaWaylandSurface *surface;
- MetaWaylandSeat *seat;
- MetaWaylandActivation *activation;
- MetaStartupSequence *sequence;
- char *app_id;
- char *token;
- uint32_t serial;
- gulong sequence_complete_id;
- gboolean committed;
-};
-
-static void
-unbind_resource (struct wl_resource *resource)
-{
- wl_list_remove (wl_resource_get_link (resource));
-}
-
-static void
-token_set_serial (struct wl_client *client,
- struct wl_resource *resource,
- uint32_t serial,
- struct wl_resource *seat_resource)
-{
- MetaXdgActivationToken *token = wl_resource_get_user_data (resource);
- MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
-
- token->serial = serial;
- token->seat = seat;
-}
-
-static void
-token_set_app_id (struct wl_client *client,
- struct wl_resource *resource,
- const char *app_id)
-{
- MetaXdgActivationToken *token = wl_resource_get_user_data (resource);
-
- g_clear_pointer (&token->app_id, g_free);
- token->app_id = g_strdup (app_id);
-}
-
-static void
-token_set_surface (struct wl_client *client,
- struct wl_resource *resource,
- struct wl_resource *surface_resource)
-{
- MetaXdgActivationToken *token = wl_resource_get_user_data (resource);
- MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
-
- token->surface = surface;
-}
-
-static void
-sequence_complete_cb (MetaStartupSequence *sequence,
- MetaXdgActivationToken *token)
-{
- MetaWaylandActivation *activation = token->activation;
- MetaDisplay *display = meta_get_display ();
-
- meta_startup_notification_remove_sequence (display->startup_notification,
- sequence);
- g_hash_table_remove (activation->tokens, token->token);
-}
-
-static char *
-create_startup_token (MetaWaylandActivation *activation,
- MetaDisplay *display)
-{
- g_autofree char *uuid = NULL, *token = NULL;
-
- do
- {
- g_clear_pointer (&uuid, g_free);
- g_clear_pointer (&token, g_free);
- uuid = g_uuid_string_random ();
- token = g_strdup_printf ("%s_TIME%d", uuid,
- meta_display_get_current_time (display));
- }
- while (g_hash_table_contains (activation->tokens, token));
-
- return g_steal_pointer (&token);
-}
-
-static void
-token_commit (struct wl_client *client,
- struct wl_resource *resource)
-{
- MetaXdgActivationToken *token = wl_resource_get_user_data (resource);
- MetaWaylandActivation *activation = token->activation;
- MetaDisplay *display = meta_get_display ();
- uint32_t timestamp;
-
- if (token->committed)
- {
- wl_resource_post_error (resource,
- XDG_ACTIVATION_TOKEN_V1_ERROR_ALREADY_USED,
- "Activation token was already used");
- return;
- }
-
- timestamp = meta_display_get_current_time_roundtrip (display);
-
- token->committed = TRUE;
- token->token = create_startup_token (activation, display);
- token->sequence = g_object_new (META_TYPE_STARTUP_SEQUENCE,
- "id", token->token,
- "application-id", token->app_id,
- "timestamp", timestamp,
- NULL);
-
- token->sequence_complete_id =
- g_signal_connect (token->sequence,
- "complete",
- G_CALLBACK (sequence_complete_cb),
- token);
-
- meta_startup_notification_add_sequence (display->startup_notification,
- token->sequence);
-
- xdg_activation_token_v1_send_done (resource, token->token);
- g_hash_table_insert (activation->tokens, token->token, token);
-}
-
-static void
-token_destroy (struct wl_client *client,
- struct wl_resource *resource)
-{
- wl_resource_destroy (resource);
-}
-
-static const struct xdg_activation_token_v1_interface token_interface = {
- token_set_serial,
- token_set_app_id,
- token_set_surface,
- token_commit,
- token_destroy,
-};
-
-static void
-meta_xdg_activation_token_free (MetaXdgActivationToken *token)
-{
- if (token->sequence)
- {
- g_clear_signal_handler (&token->sequence_complete_id,
- token->sequence);
- g_clear_object (&token->sequence);
- }
-
- g_free (token->app_id);
- g_free (token->token);
- g_free (token);
-}
-
-static void
-meta_wayland_activation_token_create_new_resource (MetaWaylandActivation *activation,
- struct wl_client *client,
- struct wl_resource *activation_resource,
- uint32_t id)
-{
- MetaXdgActivationToken *token;
- struct wl_resource *token_resource;
-
- token = g_new0 (MetaXdgActivationToken, 1);
- token->activation = activation;
-
- token_resource =
- wl_resource_create (client, &xdg_activation_token_v1_interface,
- wl_resource_get_version (activation_resource),
- id);
- wl_resource_set_implementation (token_resource, &token_interface,
- token, unbind_resource);
- wl_resource_set_user_data (token_resource, token);
- wl_list_insert (&activation->token_list,
- wl_resource_get_link (token_resource));
-}
-
-static void
-activation_destroy (struct wl_client *client,
- struct wl_resource *resource)
-{
- wl_resource_destroy (resource);
-}
-
-static void
-activation_get_activation_token (struct wl_client *client,
- struct wl_resource *resource,
- uint32_t id)
-{
- MetaWaylandActivation *activation = wl_resource_get_user_data (resource);
-
- meta_wayland_activation_token_create_new_resource (activation,
- client,
- resource,
- id);
-}
-
-static void
-activation_activate (struct wl_client *client,
- struct wl_resource *resource,
- const char *token_str,
- struct wl_resource *surface_resource)
-{
- MetaWaylandActivation *activation = wl_resource_get_user_data (resource);
- MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
- MetaXdgActivationToken *token;
- MetaWindow *window;
-
- window = meta_wayland_surface_get_window (surface);
- if (!window)
- return;
-
- token = g_hash_table_lookup (activation->tokens, token_str);
- if (!token)
- return;
-
- if (meta_wayland_seat_get_grab_info (token->seat,
- token->surface,
- token->serial,
- FALSE, NULL, NULL))
- {
- uint32_t timestamp;
- int32_t workspace_idx;
-
- workspace_idx = meta_startup_sequence_get_workspace (token->sequence);
- timestamp = meta_startup_sequence_get_timestamp (token->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);
- }
-
- meta_startup_sequence_complete (token->sequence);
-}
-
-static const struct xdg_activation_v1_interface activation_interface = {
- activation_destroy,
- activation_get_activation_token,
- activation_activate,
-};
-
-static void
-bind_activation (struct wl_client *client,
- void *data,
- uint32_t version,
- uint32_t id)
-{
- MetaWaylandCompositor *compositor = data;
- MetaWaylandActivation *activation = compositor->activation;
- struct wl_resource *resource;
-
- resource = wl_resource_create (client, &xdg_activation_v1_interface,
- MIN (version, META_XDG_ACTIVATION_V1_VERSION),
- id);
- wl_resource_set_implementation (resource, &activation_interface,
- activation, unbind_resource);
- wl_resource_set_user_data (resource, activation);
- wl_list_insert (&activation->resource_list,
- wl_resource_get_link (resource));
-}
-
-void
-meta_wayland_activation_init (MetaWaylandCompositor *compositor)
-{
- MetaWaylandActivation *activation;
-
- activation = g_new0 (MetaWaylandActivation, 1);
- activation->compositor = compositor;
- wl_list_init (&activation->resource_list);
- wl_list_init (&activation->token_list);
-
- activation->tokens =
- g_hash_table_new_full (g_str_hash, g_str_equal,
- NULL,
- (GDestroyNotify) meta_xdg_activation_token_free);
-
- wl_global_create (compositor->wayland_display,
- &xdg_activation_v1_interface,
- META_XDG_ACTIVATION_V1_VERSION,
- compositor, bind_activation);
-
- compositor->activation = activation;
-}
diff --git a/src/wayland/meta-wayland-activation.h b/src/wayland/meta-wayland-activation.h
deleted file mode 100644
index 8fcc0fa42..000000000
--- a/src/wayland/meta-wayland-activation.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Wayland Support
- *
- * Copyright (C) 2020 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_ACTIVATION_H
-#define META_WAYLAND_ACTIVATION_H
-
-#include <glib.h>
-#include <wayland-server.h>
-
-#include "wayland/meta-wayland-types.h"
-
-void meta_wayland_activation_init (MetaWaylandCompositor *compositor);
-
-#endif /* META_WAYLAND_ACTIVATION_H */
diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c
deleted file mode 100644
index bdebe6b2b..000000000
--- a/src/wayland/meta-wayland-actor-surface.c
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * 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_signal_handlers_disconnect_by_func (priv->actor,
- meta_wayland_surface_update_outputs,
- 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_shaped_texture_ensure_size_valid (stex);
-
- 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 &&
- clutter_actor_is_mapped (CLUTTER_ACTOR (priv->actor)) &&
- !meta_surface_actor_is_obscured (priv->actor))
- {
- ClutterActor *stage =
- clutter_actor_get_stage (CLUTTER_ACTOR (priv->actor));
-
- 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) &&
- !clutter_actor_has_mapped_clones (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::mapped",
- G_CALLBACK (meta_wayland_surface_update_outputs),
- surface);
- g_signal_connect_swapped (priv->actor, "stage-views-changed",
- G_CALLBACK (meta_wayland_surface_update_outputs),
- surface);
-}
diff --git a/src/wayland/meta-wayland-actor-surface.h b/src/wayland/meta-wayland-actor-surface.h
deleted file mode 100644
index bd0cca275..000000000
--- a/src/wayland/meta-wayland-actor-surface.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 2b6fe6b6e..000000000
--- a/src/wayland/meta-wayland-buffer.c
+++ /dev/null
@@ -1,852 +0,0 @@
-/* -*- 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"
-#include "wayland/meta-wayland-private.h"
-
-#ifdef HAVE_NATIVE_BACKEND
-#include "backends/native/meta-drm-buffer-gbm.h"
-#include "backends/native/meta-kms-utils.h"
-#include "backends/native/meta-onscreen-native.h"
-#include "backends/native/meta-renderer-native.h"
-#endif
-
-#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 gboolean
-shm_format_to_cogl_pixel_format (enum wl_shm_format shm_format,
- CoglPixelFormat *format_out,
- CoglTextureComponents *components_out)
-{
- CoglPixelFormat format;
- CoglTextureComponents components = COGL_TEXTURE_COMPONENTS_RGBA;
-
- switch (shm_format)
- {
-#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_RGB565:
- format = COGL_PIXEL_FORMAT_RGB_565;
- components = COGL_TEXTURE_COMPONENTS_RGB;
- break;
- 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;
- case WL_SHM_FORMAT_XRGB2101010:
- components = COGL_TEXTURE_COMPONENTS_RGB;
- G_GNUC_FALLTHROUGH;
- case WL_SHM_FORMAT_ARGB2101010:
- format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE;
- break;
- case WL_SHM_FORMAT_XBGR2101010:
- components = COGL_TEXTURE_COMPONENTS_RGB;
- G_GNUC_FALLTHROUGH;
- case WL_SHM_FORMAT_ABGR2101010:
- format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE;
- break;
- case WL_SHM_FORMAT_XRGB16161616F:
- components = COGL_TEXTURE_COMPONENTS_RGB;
- G_GNUC_FALLTHROUGH;
- case WL_SHM_FORMAT_ARGB16161616F:
- format = COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE;
- break;
- case WL_SHM_FORMAT_XBGR16161616F:
- components = COGL_TEXTURE_COMPONENTS_RGB;
- G_GNUC_FALLTHROUGH;
- case WL_SHM_FORMAT_ABGR16161616F:
- format = COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE;
- break;
-#endif
- default:
- return FALSE;
- }
-
- if (format_out)
- *format_out = format;
- if (components_out)
- *components_out = components;
-
- return TRUE;
-}
-
-static gboolean
-shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer,
- CoglPixelFormat *format_out,
- CoglTextureComponents *components_out)
-{
- MetaBackend *backend = meta_get_backend ();
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- CoglContext *cogl_context =
- clutter_backend_get_cogl_context (clutter_backend);
- CoglPixelFormat cogl_format;
- CoglTextureComponents cogl_components;
-
- if (!shm_format_to_cogl_pixel_format (wl_shm_buffer_get_format (shm_buffer),
- &cogl_format,
- &cogl_components))
- return FALSE;
-
- if (!cogl_context_format_supports_upload (cogl_context, cogl_format))
- return FALSE;
-
- if (format_out)
- *format_out = cogl_format;
- if (components_out)
- *components_out = cogl_components;
-
- return TRUE;
-}
-
-static const char *
-shm_format_to_string (MetaDrmFormatBuf *format_buf,
- uint32_t shm_format)
-{
- const char *result;
-
- switch (shm_format)
- {
- case WL_SHM_FORMAT_ARGB8888:
- result = "ARGB8888";
- break;
- case WL_SHM_FORMAT_XRGB8888:
- result = "XRGB8888";
- break;
- default:
- result = meta_drm_format_to_string (format_buf, shm_format);
- break;
- }
-
- return result;
-}
-
-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;
- MetaDrmFormatBuf format_buf;
-
- 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);
- if (!shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &components))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Invalid shm pixel format");
- return FALSE;
- }
-
- meta_topic (META_DEBUG_WAYLAND,
- "[wl-shm] wl_buffer@%u wl_shm_format %s -> CoglPixelFormat %s",
- wl_resource_get_id (meta_wayland_buffer_get_resource (buffer)),
- shm_format_to_string (&format_buf,
- wl_shm_buffer_get_format (shm_buffer)),
- cogl_pixel_format_to_string (format));
-
- 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);
-
- COGL_TRACE_BEGIN_SCOPED (MetaWaylandBufferAttach, "WaylandBuffer (attach)");
-
- 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 CoglScanout *
-try_acquire_egl_image_scanout (MetaWaylandBuffer *buffer,
- CoglOnscreen *onscreen)
-{
-#ifdef HAVE_NATIVE_BACKEND
- MetaBackend *backend = meta_get_backend ();
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
- MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
- MetaGpuKms *gpu_kms;
- MetaDeviceFile *device_file;
- struct gbm_device *gbm_device;
- struct gbm_bo *gbm_bo;
- uint32_t drm_format;
- uint64_t drm_modifier;
- uint32_t stride;
- MetaDrmBufferGbm *fb;
- g_autoptr (GError) error = NULL;
-
- gpu_kms = meta_renderer_native_get_primary_gpu (renderer_native);
- device_file = meta_renderer_native_get_primary_device_file (renderer_native);
- gbm_device = meta_gbm_device_from_gpu (gpu_kms);
-
- gbm_bo = gbm_bo_import (gbm_device,
- GBM_BO_IMPORT_WL_BUFFER, buffer->resource,
- GBM_BO_USE_SCANOUT);
- if (!gbm_bo)
- return NULL;
-
- drm_format = gbm_bo_get_format (gbm_bo);
- drm_modifier = gbm_bo_get_modifier (gbm_bo);
- stride = gbm_bo_get_stride (gbm_bo);
- if (!meta_onscreen_native_is_buffer_scanout_compatible (onscreen,
- drm_format,
- drm_modifier,
- stride))
- {
- gbm_bo_destroy (gbm_bo);
- return NULL;
- }
-
- fb = meta_drm_buffer_gbm_new_take (device_file,
- gbm_bo,
- drm_modifier != DRM_FORMAT_MOD_INVALID,
- &error);
- if (!fb)
- {
- g_debug ("Failed to create scanout buffer: %s", error->message);
- gbm_bo_destroy (gbm_bo);
- return NULL;
- }
-
- return COGL_SCANOUT (fb);
-#else
- return NULL;
-#endif
-}
-
-CoglScanout *
-meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer,
- CoglOnscreen *onscreen)
-{
- switch (buffer->type)
- {
- case META_WAYLAND_BUFFER_TYPE_SHM:
- return NULL;
- case META_WAYLAND_BUFFER_TYPE_EGL_IMAGE:
- return try_acquire_egl_image_scanout (buffer, onscreen);
-#ifdef HAVE_WAYLAND_EGLSTREAM
- case META_WAYLAND_BUFFER_TYPE_EGL_STREAM:
- return NULL;
-#endif
- case META_WAYLAND_BUFFER_TYPE_DMA_BUF:
- {
- MetaWaylandDmaBufBuffer *dma_buf;
-
- dma_buf = meta_wayland_dma_buf_from_buffer (buffer);
- if (!dma_buf)
- return NULL;
-
- return meta_wayland_dma_buf_try_acquire_scanout (dma_buf, onscreen);
- }
- case META_WAYLAND_BUFFER_TYPE_UNKNOWN:
- g_warn_if_reached ();
- return NULL;
- }
-
- g_assert_not_reached ();
- return NULL;
-}
-
-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);
-}
-
-void
-meta_wayland_init_shm (MetaWaylandCompositor *compositor)
-{
- MetaBackend *backend = meta_get_backend ();
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- CoglContext *cogl_context =
- clutter_backend_get_cogl_context (clutter_backend);
-
- static const enum wl_shm_format shm_formats[] = {
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- WL_SHM_FORMAT_RGB565,
- WL_SHM_FORMAT_ARGB2101010,
- WL_SHM_FORMAT_XRGB2101010,
- WL_SHM_FORMAT_ABGR2101010,
- WL_SHM_FORMAT_XBGR2101010,
- WL_SHM_FORMAT_ARGB16161616F,
- WL_SHM_FORMAT_XRGB16161616F,
- WL_SHM_FORMAT_ABGR16161616F,
- WL_SHM_FORMAT_XBGR16161616F,
-#endif
- };
- int i;
-
- wl_display_init_shm (compositor->wayland_display);
-
- for (i = 0; i < G_N_ELEMENTS (shm_formats); i++)
- {
- CoglPixelFormat cogl_format;
-
- if (!shm_format_to_cogl_pixel_format (shm_formats[i],
- &cogl_format,
- NULL))
- continue;
-
- if (!cogl_context_format_supports_upload (cogl_context, cogl_format))
- continue;
-
- wl_display_add_shm_format (compositor->wayland_display, shm_formats[i]);
- }
-}
diff --git a/src/wayland/meta-wayland-buffer.h b/src/wayland/meta-wayland-buffer.h
deleted file mode 100644
index e00406ba2..000000000
--- a/src/wayland/meta-wayland-buffer.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- 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);
-CoglScanout * meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer,
- CoglOnscreen *onscreen);
-
-void meta_wayland_init_shm (MetaWaylandCompositor *compositor);
-
-#endif /* META_WAYLAND_BUFFER_H */
diff --git a/src/wayland/meta-wayland-client.c b/src/wayland/meta-wayland-client.c
deleted file mode 100644
index dfae1eda6..000000000
--- a/src/wayland/meta-wayland-client.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright 2019 Sergio Costas (rastersoft@gmail.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public 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-wayland-client
- * @title MetaWaylandClient
- * @include: gio/gsubprocess.h
- * A class that allows to launch a trusted client and detect if an specific
- * Wayland window belongs to it.
- */
-
-#include "config.h"
-
-#include "meta/meta-wayland-client.h"
-
-#include <gio/gio.h>
-#include <glib-object.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <wayland-server.h>
-
-#include "core/window-private.h"
-#include "meta/util.h"
-#include "wayland/meta-wayland-private.h"
-#include "wayland/meta-wayland-types.h"
-
-struct _MetaWaylandClient
-{
- GObject parent_instance;
-
- GSubprocessLauncher *launcher;
- GSubprocess *subprocess;
- GCancellable *died_cancellable;
- gboolean process_running;
- gboolean process_launched;
- struct wl_client *wayland_client;
-};
-
-G_DEFINE_TYPE (MetaWaylandClient, meta_wayland_client, G_TYPE_OBJECT)
-
-static void
-meta_wayland_client_dispose (GObject *object)
-{
- MetaWaylandClient *client = META_WAYLAND_CLIENT (object);
-
- g_cancellable_cancel (client->died_cancellable);
- g_clear_object (&client->died_cancellable);
- g_clear_object (&client->launcher);
- g_clear_object (&client->subprocess);
-
- G_OBJECT_CLASS (meta_wayland_client_parent_class)->dispose (object);
-}
-
-static void
-meta_wayland_client_class_init (MetaWaylandClientClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->dispose = meta_wayland_client_dispose;
-}
-
-static void
-meta_wayland_client_init (MetaWaylandClient *client)
-{
-}
-
-static void
-process_died (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- MetaWaylandClient *client = META_WAYLAND_CLIENT (user_data);
-
- client->process_running = FALSE;
-}
-
-/**
- * meta_wayland_client_new:
- * @launcher: (not nullable): a GSubprocessLauncher to use to launch the subprocess
- * @error: (nullable): Error
- *
- * Creates a new #MetaWaylandClient. The GSubprocesslauncher passed is
- * stored internally and will be used to launch the subprocess.
- *
- * Returns: A #MetaWaylandClient or %NULL if %error is set. Free with
- * g_object_unref().
- */
-MetaWaylandClient *
-meta_wayland_client_new (GSubprocessLauncher *launcher,
- GError **error)
-{
- MetaWaylandClient *client;
-
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
- if (!meta_is_wayland_compositor ())
- {
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_NOT_SUPPORTED,
- "MetaWaylandClient can be used only with Wayland.");
- return NULL;
- }
-
- if (launcher == NULL)
- {
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_INVALID_ARGUMENT,
- "Invalid launcher.");
- return NULL;
- }
-
- client = g_object_new (META_TYPE_WAYLAND_CLIENT, NULL);
- client->launcher = g_object_ref (launcher);
- return client;
-}
-
-/**
- * meta_wayland_client_spawnv:
- * @client: a #MetaWaylandClient
- * @display: (not nullable): the current MetaDisplay
- * @argv: (array zero-terminated=1) (element-type filename): Command line arguments
- * @error: (nullable): Error
- *
- * Creates a #GSubprocess given a provided array of arguments, launching a new
- * process with the binary specified in the first element of argv, and with the
- * rest of elements as parameters. It also sets up a new Wayland socket and sets
- * the environment variable WAYLAND_SOCKET to make the new process to use it.
- *
- * Returns: (transfer full): A new #GSubprocess, or %NULL on error (and @error
- * will be set)
- **/
-GSubprocess *
-meta_wayland_client_spawnv (MetaWaylandClient *client,
- MetaDisplay *display,
- const char * const *argv,
- GError **error)
-{
- int client_fd[2];
- GSubprocess *subprocess;
- struct wl_client *wayland_client;
- MetaWaylandCompositor *compositor;
-
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- g_return_val_if_fail (argv != NULL &&
- argv[0] != NULL &&
- argv[0][0] != '\0',
- NULL);
-
- if (client->process_launched)
- {
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "This object already has spawned a subprocess.");
- return NULL;
- }
-
- if (client->launcher == NULL)
- {
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_NOT_INITIALIZED,
- "MetaWaylandClient must be created using meta_wayland_client_new().");
- return NULL;
- }
-
- if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, client_fd) < 0)
- {
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Failed to create a socket pair for the wayland client.");
- return NULL;
- }
-
- compositor = meta_wayland_compositor_get_default ();
- g_subprocess_launcher_take_fd (client->launcher, client_fd[1], 3);
- g_subprocess_launcher_setenv (client->launcher, "WAYLAND_SOCKET", "3", TRUE);
- wayland_client = wl_client_create (compositor->wayland_display, client_fd[0]);
- subprocess = g_subprocess_launcher_spawnv (client->launcher, argv, error);
- g_clear_object (&client->launcher);
- client->process_launched = TRUE;
-
- if (subprocess == NULL)
- return NULL;
-
- client->subprocess = subprocess;
- client->wayland_client = wayland_client;
- client->process_running = TRUE;
- client->died_cancellable = g_cancellable_new ();
- g_subprocess_wait_async (client->subprocess,
- client->died_cancellable,
- process_died,
- client);
-
- return g_object_ref (client->subprocess);
-}
-
-/**
- * meta_wayland_client_spawn:
- * @client: a #MetaWaylandClient
- * @display: (not nullable): the current MetaDisplay
- * @error: (nullable): Error
- * @argv0: Command line arguments
- * @...: Continued arguments, %NULL terminated
- *
- * Creates a #GSubprocess given a provided varargs list of arguments. It also
- * sets up a new Wayland socket and sets the environment variable WAYLAND_SOCKET
- * to make the new process to use it.
- *
- * Returns: (transfer full): A new #GSubprocess, or %NULL on error (and @error
- * will be set)
- **/
-GSubprocess *
-meta_wayland_client_spawn (MetaWaylandClient *client,
- MetaDisplay *display,
- GError **error,
- const char *argv0,
- ...)
-{
- g_autoptr (GPtrArray) args = NULL;
- GSubprocess *result;
- const char *arg;
- va_list ap;
-
- g_return_val_if_fail (argv0 != NULL && argv0[0] != '\0', NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
- args = g_ptr_array_new_with_free_func (g_free);
-
- va_start (ap, argv0);
- g_ptr_array_add (args, (char *) argv0);
- while ((arg = va_arg (ap, const char *)))
- g_ptr_array_add (args, (char *) arg);
-
- g_ptr_array_add (args, NULL);
- va_end (ap);
-
- result = meta_wayland_client_spawnv (client,
- display,
- (const char * const *) args->pdata,
- error);
-
- return result;
-}
-
-/**
- * meta_wayland_client_owns_wayland_window
- * @client: a #MetaWaylandClient
- * @window: (not nullable): a MetaWindow
- *
- * Checks whether @window belongs to the process launched from @client or not.
- * This only works under Wayland. If the window is an X11 window, an exception
- * will be triggered.
- *
- * Returns: TRUE if the window was created by this process; FALSE if not.
- */
-gboolean
-meta_wayland_client_owns_window (MetaWaylandClient *client,
- MetaWindow *window)
-{
- MetaWaylandSurface *surface;
-
- g_return_val_if_fail (meta_is_wayland_compositor (), FALSE);
- g_return_val_if_fail (client->subprocess != NULL, FALSE);
- g_return_val_if_fail (client->process_running, FALSE);
-
- surface = window->surface;
- if (surface == NULL)
- return FALSE;
-
- return wl_resource_get_client (surface->resource) == client->wayland_client;
-}
-
-/**
- * meta_wayland_client_skip_from_window_list
- * @client: a #MetaWaylandClient
- * @window: (not nullable): a MetaWindow
- *
- * Hides this window from any window list, like taskbars, pagers...
- */
-void
-meta_wayland_client_hide_from_window_list (MetaWaylandClient *client,
- MetaWindow *window)
-{
- if (!meta_wayland_client_owns_window (client, window))
- return;
-
- if (!window->skip_from_window_list)
- {
- window->skip_from_window_list = TRUE;
- meta_window_recalc_features (window);
- }
-}
-
-/**
- * meta_wayland_client_show_in_window_list
- * @client: a #MetaWaylandClient
- * @window: (not nullable): a MetaWindow
- *
- * Shows again this window in window lists, like taskbars, pagers...
- */
-void
-meta_wayland_client_show_in_window_list (MetaWaylandClient *client,
- MetaWindow *window)
-{
- if (!meta_wayland_client_owns_window (client, window))
- return;
-
- if (window->skip_from_window_list)
- {
- window->skip_from_window_list = FALSE;
- meta_window_recalc_features (window);
- }
-}
diff --git a/src/wayland/meta-wayland-cursor-surface.c b/src/wayland/meta-wayland-cursor-surface.c
deleted file mode 100644
index d1f521818..000000000
--- a/src/wayland/meta-wayland-cursor-surface.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * 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-presentation-time-private.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,
- float best_scale,
- 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);
- ClutterInputDevice *device;
- 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);
-
- device = meta_cursor_renderer_get_input_device (priv->cursor_renderer);
- clutter_seat_query_state (clutter_input_device_get_seat (device),
- device, NULL, &point, NULL);
-
- 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,
- ClutterStageView *stage_view,
- MetaWaylandCursorSurface *cursor_surface)
-{
- MetaWaylandCursorSurfacePrivate *priv =
- meta_wayland_cursor_surface_get_instance_private (cursor_surface);
- guint32 time = (guint32) (g_get_monotonic_time () / 1000);
- MetaBackend *backend = meta_get_backend ();
- MetaContext *context = meta_backend_get_context (backend);
- MetaWaylandCompositor *compositor =
- meta_context_get_wayland_compositor (context);
-
- 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);
- }
-
- meta_wayland_presentation_time_cursor_painted (&compositor->presentation_time,
- stage_view,
- cursor_surface);
-}
-
-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
deleted file mode 100644
index 05b344f04..000000000
--- a/src/wayland/meta-wayland-cursor-surface.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 684247e04..000000000
--- a/src/wayland/meta-wayland-data-device-primary-legacy.c
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * 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))
- {
- if (source)
- meta_wayland_data_source_cancel (source);
- 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, &gtk_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, &gtk_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, &gtk_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,
- &gtk_primary_selection_device_manager_interface,
- META_GTK_PRIMARY_SELECTION_VERSION,
- 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
deleted file mode 100644
index c1b4d6e99..000000000
--- a/src/wayland/meta-wayland-data-device-primary-legacy.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 9592e8f77..000000000
--- a/src/wayland/meta-wayland-data-device-primary.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * 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))
- {
- if (source)
- meta_wayland_data_source_cancel (source);
- 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,
- META_ZWP_PRIMARY_SELECTION_V1_VERSION,
- 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
deleted file mode 100644
index 77fcbf97e..000000000
--- a/src/wayland/meta-wayland-data-device-primary.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 2f3c154a1..000000000
--- a/src/wayland/meta-wayland-data-device.c
+++ /dev/null
@@ -1,1147 +0,0 @@
-/*
- * 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_free (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]);
- close (p[1]);
- channel = g_io_channel_unix_new (p[0]);
- g_io_channel_set_close_on_unref (channel, TRUE);
- 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_new0 (MetaWaylandDragGrab, 1);
-
- 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;
-
- clutter_seat_query_state (clutter_input_device_get_seat (seat->pointer->device),
- seat->pointer->device, NULL, NULL, &modifiers);
- 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_seat_query_state (clutter_input_device_get_seat (seat->pointer->device),
- seat->pointer->device, NULL, &pos, NULL);
- 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))
- {
- if (source)
- meta_wayland_data_source_cancel (source);
- 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;
- struct wl_resource *data_device_resource;
-
- 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);
-
- data_device_resource =
- wl_resource_find_for_client (&seat->data_device.resource_list, client);
- if (data_device_resource)
- {
- wl_list_remove (wl_resource_get_link (data_device_resource));
- wl_list_init (wl_resource_get_link (data_device_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
deleted file mode 100644
index 840893389..000000000
--- a/src/wayland/meta-wayland-data-device.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 0d5a98743..000000000
--- a/src/wayland/meta-wayland-data-offer-primary-legacy.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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_free (offer);
-}
-
-MetaWaylandDataOffer *
-meta_wayland_data_offer_primary_legacy_new (struct wl_resource *target)
-{
- MetaWaylandDataOffer *offer;
-
- offer = g_new0 (MetaWaylandDataOffer, 1);
- offer->selection_type = META_SELECTION_PRIMARY;
- offer->resource = wl_resource_create (wl_resource_get_client (target),
- &gtk_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
deleted file mode 100644
index 96a32c34e..000000000
--- a/src/wayland/meta-wayland-data-offer-primary-legacy.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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
deleted file mode 100644
index a5c8a6d5a..000000000
--- a/src/wayland/meta-wayland-data-offer-primary.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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_free (offer);
-}
-
-MetaWaylandDataOffer *
-meta_wayland_data_offer_primary_new (struct wl_resource *target)
-{
- MetaWaylandDataOffer *offer;
-
- offer = g_new0 (MetaWaylandDataOffer, 1);
- 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
deleted file mode 100644
index cf59fb5c7..000000000
--- a/src/wayland/meta-wayland-data-offer-primary.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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
deleted file mode 100644
index c686aee6f..000000000
--- a/src/wayland/meta-wayland-data-offer.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * 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_free (offer);
-}
-
-MetaWaylandDataOffer *
-meta_wayland_data_offer_new (MetaSelectionType selection_type,
- MetaWaylandDataSource *source,
- struct wl_resource *target)
-{
- MetaWaylandDataOffer *offer;
-
- offer = g_new0 (MetaWaylandDataOffer, 1);
- 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
deleted file mode 100644
index 811aa0935..000000000
--- a/src/wayland/meta-wayland-data-offer.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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
deleted file mode 100644
index a7a1788ae..000000000
--- a/src/wayland/meta-wayland-data-source-primary-legacy.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 2904807c8..000000000
--- a/src/wayland/meta-wayland-data-source-primary-legacy.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 0229c840a..000000000
--- a/src/wayland/meta-wayland-data-source-primary.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 78ab55c19..000000000
--- a/src/wayland/meta-wayland-data-source-primary.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 93aa3fdc8..000000000
--- a/src/wayland/meta-wayland-data-source.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 900329b10..000000000
--- a/src/wayland/meta-wayland-data-source.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 3fc431201..000000000
--- a/src/wayland/meta-wayland-dma-buf.c
+++ /dev/null
@@ -1,784 +0,0 @@
-/* -*- 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"
-
-#ifdef HAVE_NATIVE_BACKEND
-#include "backends/native/meta-drm-buffer-gbm.h"
-#include "backends/native/meta-kms-utils.h"
-#include "backends/native/meta-onscreen-native.h"
-#include "backends/native/meta-renderer-native.h"
-#endif
-
-#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;
- MetaDrmFormatBuf format_buf;
-
- 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_XRGB2101010:
- cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010;
- break;
- case DRM_FORMAT_ARGB2101010:
- cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE;
- break;
- case DRM_FORMAT_ABGR2101010:
- cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE;
- break;
- case DRM_FORMAT_RGB565:
- cogl_format = COGL_PIXEL_FORMAT_RGB_565;
- break;
- case DRM_FORMAT_XBGR16161616F:
- case DRM_FORMAT_ABGR16161616F:
- cogl_format = COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE;
- break;
- case DRM_FORMAT_XRGB16161616F:
- case DRM_FORMAT_ARGB16161616F:
- cogl_format = COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE;
- break;
- default:
- g_set_error (error, G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Unsupported buffer format %d", dma_buf->drm_format);
- return FALSE;
- }
-
- meta_topic (META_DEBUG_WAYLAND,
- "[dma-buf] wl_buffer@%u DRM format %s -> CoglPixelFormat %s",
- wl_resource_get_id (meta_wayland_buffer_get_resource (buffer)),
- meta_drm_format_to_string (&format_buf, dma_buf->drm_format),
- cogl_pixel_format_to_string (cogl_format));
-
- 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;
-}
-
-#ifdef HAVE_NATIVE_BACKEND
-static struct gbm_bo *
-import_scanout_gbm_bo (MetaWaylandDmaBufBuffer *dma_buf,
- MetaGpuKms *gpu_kms,
- int n_planes,
- gboolean *use_modifier)
-{
- struct gbm_device *gbm_device;
-
- gbm_device = meta_gbm_device_from_gpu (gpu_kms);
-
- if (dma_buf->drm_modifier != DRM_FORMAT_MOD_INVALID ||
- n_planes > 1 ||
- dma_buf->offsets[0] > 0)
- {
- struct gbm_import_fd_modifier_data import_with_modifier;
-
- import_with_modifier = (struct gbm_import_fd_modifier_data) {
- .width = dma_buf->width,
- .height = dma_buf->height,
- .format = dma_buf->drm_format,
- .num_fds = n_planes,
- .modifier = dma_buf->drm_modifier,
- };
- memcpy (import_with_modifier.fds,
- dma_buf->fds,
- sizeof (dma_buf->fds));
- memcpy (import_with_modifier.strides,
- dma_buf->strides,
- sizeof (import_with_modifier.strides));
- memcpy (import_with_modifier.offsets,
- dma_buf->offsets,
- sizeof (import_with_modifier.offsets));
-
- *use_modifier = TRUE;
- return gbm_bo_import (gbm_device, GBM_BO_IMPORT_FD_MODIFIER,
- &import_with_modifier,
- GBM_BO_USE_SCANOUT);
- }
- else
- {
- struct gbm_import_fd_data import_legacy;
-
- import_legacy = (struct gbm_import_fd_data) {
- .width = dma_buf->width,
- .height = dma_buf->height,
- .format = dma_buf->drm_format,
- .stride = dma_buf->strides[0],
- .fd = dma_buf->fds[0],
- };
-
- *use_modifier = FALSE;
- return gbm_bo_import (gbm_device, GBM_BO_IMPORT_FD,
- &import_legacy,
- GBM_BO_USE_SCANOUT);
- }
-}
-#endif
-
-CoglScanout *
-meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandDmaBufBuffer *dma_buf,
- CoglOnscreen *onscreen)
-{
-#ifdef HAVE_NATIVE_BACKEND
- MetaBackend *backend = meta_get_backend ();
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
- MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
- MetaDeviceFile *device_file;
- MetaGpuKms *gpu_kms;
- int n_planes;
- uint32_t drm_format;
- uint64_t drm_modifier;
- uint32_t stride;
- struct gbm_bo *gbm_bo;
- gboolean use_modifier;
- g_autoptr (GError) error = NULL;
- MetaDrmBufferGbm *fb;
-
- for (n_planes = 0; n_planes < META_WAYLAND_DMA_BUF_MAX_FDS; n_planes++)
- {
- if (dma_buf->fds[n_planes] < 0)
- break;
- }
-
- drm_format = dma_buf->drm_format;
- drm_modifier = dma_buf->drm_modifier;
- stride = dma_buf->strides[0];
- if (!meta_onscreen_native_is_buffer_scanout_compatible (onscreen,
- drm_format,
- drm_modifier,
- stride))
- return NULL;
-
- device_file = meta_renderer_native_get_primary_device_file (renderer_native);
- gpu_kms = meta_renderer_native_get_primary_gpu (renderer_native);
- gbm_bo = import_scanout_gbm_bo (dma_buf, gpu_kms, n_planes, &use_modifier);
- if (!gbm_bo)
- {
- g_debug ("Failed to import scanout gbm_bo: %s", g_strerror (errno));
- return NULL;
- }
-
- fb = meta_drm_buffer_gbm_new_take (device_file,
- gbm_bo,
- use_modifier,
- &error);
- if (!fb)
- {
- g_debug ("Failed to create scanout buffer: %s", error->message);
- gbm_bo_destroy (gbm_bo);
- return NULL;
- }
-
- return COGL_SCANOUT (fb);
-#else
- return NULL;
-#endif
-}
-
-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 (!buffer->resource)
- return NULL;
-
- 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 gboolean
-should_send_modifiers (MetaBackend *backend)
-{
- MetaSettings *settings = meta_backend_get_settings (backend);
-
-#ifdef HAVE_NATIVE_BACKEND
- if (META_IS_BACKEND_NATIVE (backend))
- {
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
- MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
- return meta_renderer_native_use_modifiers (renderer_native);
- }
-#endif
-
- return meta_settings_is_experimental_feature_enabled (
- settings, META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS);
-}
-
-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;
-
- if (!should_send_modifiers (backend))
- {
- zwp_linux_dmabuf_v1_send_modifier (resource, format,
- DRM_FORMAT_MOD_INVALID >> 32,
- DRM_FORMAT_MOD_INVALID & 0xffffffff);
- 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_ABGR2101010);
- send_modifiers (resource, DRM_FORMAT_XRGB2101010);
- send_modifiers (resource, DRM_FORMAT_RGB565);
- send_modifiers (resource, DRM_FORMAT_ABGR16161616F);
- send_modifiers (resource, DRM_FORMAT_XBGR16161616F);
- send_modifiers (resource, DRM_FORMAT_XRGB16161616F);
- send_modifiers (resource, DRM_FORMAT_ARGB16161616F);
-}
-
-/**
- * meta_wayland_dma_buf_init:
- * @compositor: The #MetaWaylandCompositor
- *
- * Creates the global Wayland object that exposes the linux-dmabuf protocol.
- *
- * Returns: Whether the initialization was successful. 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
deleted file mode 100644
index cdc65aeb5..000000000
--- a/src/wayland/meta-wayland-dma-buf.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- 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);
-
-CoglScanout *
-meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandDmaBufBuffer *dma_buf,
- CoglOnscreen *onscreen);
-
-#endif /* META_WAYLAND_DMA_BUF_H */
diff --git a/src/wayland/meta-wayland-dnd-surface.c b/src/wayland/meta-wayland-dnd-surface.c
deleted file mode 100644
index 047de6e2b..000000000
--- a/src/wayland/meta-wayland-dnd-surface.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * 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 ();
- MetaCursorTracker *cursor_tracker =
- meta_backend_get_cursor_tracker (backend);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- graphene_point_t point;
-
- meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
- return meta_monitor_manager_get_logical_monitor_at (monitor_manager,
- point.x, point.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
deleted file mode 100644
index 45cf689ee..000000000
--- a/src/wayland/meta-wayland-dnd-surface.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 3a2e1e56a..000000000
--- a/src/wayland/meta-wayland-egl-stream.c
+++ /dev/null
@@ -1,367 +0,0 @@
-/* -*- 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
deleted file mode 100644
index b8a6b1968..000000000
--- a/src/wayland/meta-wayland-egl-stream.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 12e1b0e4a..000000000
--- a/src/wayland/meta-wayland-gtk-shell.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * 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 (&gtk_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;
-
- if (!surface)
- return;
-
- 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;
-
- if (!surface)
- return;
-
- 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;
-
- if (!surface)
- return;
-
- 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;
-
- if (!surface)
- return;
-
- 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;
-
- if (!surface)
- return;
-
- 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 void
-gtk_surface_release (struct wl_client *client,
- struct wl_resource *resource)
-{
- wl_resource_destroy (resource);
-}
-
-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,
- gtk_surface_release
-};
-
-static void
-gtk_surface_surface_destroyed (MetaWaylandGtkSurface *gtk_surface)
-{
- 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,
- &gtk_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, &gtk_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,
- &gtk_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
deleted file mode 100644
index 347c1f398..000000000
--- a/src/wayland/meta-wayland-gtk-shell.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 818098460..000000000
--- a/src/wayland/meta-wayland-inhibit-shortcuts-dialog.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 7f3501565..000000000
--- a/src/wayland/meta-wayland-inhibit-shortcuts-dialog.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 68e90eec2..000000000
--- a/src/wayland/meta-wayland-inhibit-shortcuts.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 52b2240c4..000000000
--- a/src/wayland/meta-wayland-inhibit-shortcuts.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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
deleted file mode 100644
index b82f204cf..000000000
--- a/src/wayland/meta-wayland-input-device.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/* -*- 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
deleted file mode 100644
index c6a6c3d38..000000000
--- a/src/wayland/meta-wayland-input-device.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 836939c9d..000000000
--- a/src/wayland/meta-wayland-keyboard.c
+++ /dev/null
@@ -1,873 +0,0 @@
-/*
- * 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 <glib.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "backends/meta-backend-private.h"
-#include "core/display-private.h"
-#include "core/meta-anonymous-file.h"
-#include "wayland/meta-wayland-private.h"
-
-#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 void
-unbind_resource (struct wl_resource *resource)
-{
- wl_list_remove (wl_resource_get_link (resource));
-}
-
-static void
-send_keymap (MetaWaylandKeyboard *keyboard,
- struct wl_resource *resource)
-{
- MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
- int fd;
- size_t size;
- MetaAnonymousFileMapmode mapmode;
-
- if (wl_resource_get_version (resource) < 7)
- mapmode = META_ANONYMOUS_FILE_MAPMODE_SHARED;
- else
- mapmode = META_ANONYMOUS_FILE_MAPMODE_PRIVATE;
-
- fd = meta_anonymous_file_open_fd (xkb_info->keymap_rofile, mapmode);
- size = meta_anonymous_file_size (xkb_info->keymap_rofile);
-
- if (fd == -1)
- {
- g_warning ("Creating a keymap file failed: %s", strerror (errno));
- return;
- }
-
- wl_keyboard_send_keymap (resource,
- WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
- fd, size);
-
- meta_anonymous_file_close_fd (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;
- char *keymap_string;
- size_t keymap_size;
-
- if (keymap == NULL)
- {
- g_warning ("Attempting to set null keymap (compilation probably failed)");
- return;
- }
-
- xkb_keymap_unref (xkb_info->keymap);
- xkb_info->keymap = xkb_keymap_ref (keymap);
-
- meta_wayland_keyboard_update_xkb_state (keyboard);
-
- keymap_string =
- xkb_keymap_get_as_string (xkb_info->keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
- if (!keymap_string)
- {
- g_warning ("Failed to get string version of keymap");
- return;
- }
- keymap_size = strlen (keymap_string) + 1;
-
- g_clear_pointer (&xkb_info->keymap_rofile, meta_anonymous_file_free);
- xkb_info->keymap_rofile =
- meta_anonymous_file_new (keymap_size, (const uint8_t *) keymap_string);
-
- free (keymap_string);
-
- if (!xkb_info->keymap_rofile)
- {
- g_warning ("Failed to create anonymous file for keymap");
- return;
- }
-
- 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;
-
- /* Ignore autorepeat events, as autorepeat in Wayland is done on the client
- * side. */
- if (event->key.flags & CLUTTER_EVENT_FLAG_REPEATED)
- return FALSE;
-
- code = clutter_event_get_event_code (event);
-
- 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_rofile, meta_anonymous_file_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);
-}
-
-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",
- is_press ? "press" : "release",
- event->hardware_keycode);
-
- handled = notify_key (keyboard, (const ClutterEvent *) event);
-
- if (handled)
- meta_verbose ("Sent event to wayland client");
- else
- meta_verbose ("No wayland surface is focused, continuing normal operation");
-
- 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);
-
- G_OBJECT_CLASS (meta_wayland_keyboard_parent_class)->finalize (object);
-}
-
-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
deleted file mode 100644
index ac57d7677..000000000
--- a/src/wayland/meta-wayland-keyboard.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * 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 "core/meta-anonymous-file.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;
- MetaAnonymousFile *keymap_rofile;
-} 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
deleted file mode 100644
index 3c1ed8e93..000000000
--- a/src/wayland/meta-wayland-legacy-xdg-shell.c
+++ /dev/null
@@ -1,2105 +0,0 @@
-/* -*- 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;
-
- 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 (!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;
-
- if (width == 0 || height == 0)
- {
- g_warning ("Invalid geometry %dx%d+%d+%d set on xdg_surface@%d. Ignoring for "
- "now, but this will result in client termination in the future.",
- width, height, x, y,
- wl_resource_get_id (resource));
- return;
- }
-
- 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 && 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
deleted file mode 100644
index 8a07dfb29..000000000
--- a/src/wayland/meta-wayland-legacy-xdg-shell.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 6c766ea51..000000000
--- a/src/wayland/meta-wayland-outputs.c
+++ /dev/null
@@ -1,750 +0,0 @@
-/* -*- 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,
- OUTPUT_BOUND,
-
- 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",
- 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);
-
- g_signal_emit (wayland_output, signals[OUTPUT_BOUND], 0, resource);
-}
-
-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)
-{
- 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 (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;
-
- g_signal_emit (wayland_output, signals[OUTPUT_DESTROYED], 0);
-
- 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,
- g_object_unref);
-
- 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);
-
- signals[OUTPUT_BOUND] = g_signal_new ("output-bound",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
-}
-
-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,
- g_object_unref);
- 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
deleted file mode 100644
index 381febcdb..000000000
--- a/src/wayland/meta-wayland-outputs.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 965b95dda..000000000
--- a/src/wayland/meta-wayland-pointer-constraints.c
+++ /dev/null
@@ -1,1201 +0,0 @@
-/* -*- 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"
-
-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;
-
- MetaPointerConfinementWayland *confinement;
-};
-
-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 MetaPointerConfinementWayland *
-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 (constraint);
- }
- 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)
-{
- 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->confinement =
- meta_wayland_pointer_constraint_create_pointer_constraint (constraint);
- meta_pointer_confinement_wayland_enable (constraint->confinement);
- g_object_add_weak_pointer (G_OBJECT (constraint->confinement),
- (gpointer *) &constraint->confinement);
-}
-
-static void
-meta_wayland_pointer_constraint_disable (MetaWaylandPointerConstraint *constraint)
-{
- constraint->is_enabled = FALSE;
-
- if (constraint->confinement)
- {
- meta_pointer_confinement_wayland_disable (constraint->confinement);
- g_object_unref (constraint->confinement);
- }
-
- meta_wayland_pointer_constraint_notify_deactivated (constraint);
- 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
deleted file mode 100644
index dee7568de..000000000
--- a/src/wayland/meta-wayland-pointer-constraints.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- 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
deleted file mode 100644
index f7b37ff27..000000000
--- a/src/wayland/meta-wayland-pointer-gesture-pinch.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 9ea3733f7..000000000
--- a/src/wayland/meta-wayland-pointer-gesture-pinch.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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
deleted file mode 100644
index d95e84941..000000000
--- a/src/wayland/meta-wayland-pointer-gesture-swipe.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * 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:
- case CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL:
- 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
deleted file mode 100644
index ed53fc4b2..000000000
--- a/src/wayland/meta-wayland-pointer-gesture-swipe.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 7222a8a8c..000000000
--- a/src/wayland/meta-wayland-pointer-gestures.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 48792da12..000000000
--- a/src/wayland/meta-wayland-pointer-gestures.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 3132abfd2..000000000
--- a/src/wayland/meta-wayland-pointer.c
+++ /dev/null
@@ -1,1370 +0,0 @@
-/*
- * 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"
-#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_new0 (MetaWaylandPointerClient, 1);
- 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_set_user_data (resource, NULL);
- }
- 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_set_user_data (resource, NULL);
- }
- 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_set_user_data (resource, NULL);
- }
- 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));
- wl_resource_set_user_data (resource, NULL);
- }
-
- g_free (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);
-
- pointer = wl_resource_get_user_data (resource);
- if (!pointer)
- return;
-
- 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)
-{
- 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;
-
- if (!pointer->focus_client)
- return;
-
- if (!clutter_event_get_relative_motion (event,
- &dx, &dy,
- &dx_unaccel, &dy_unaccel))
- return;
-
- time_us = clutter_event_get_time_us (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);
- }
-}
-
-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;
-
- button = clutter_event_get_event_code (event);
- 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 (clutter_event_type (for_event) == CLUTTER_LEAVE)
- actor = clutter_event_get_related (for_event);
- else
- actor = clutter_event_get_source (for_event);
-
- 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)
-{
- if ((event->type == CLUTTER_MOTION ||
- event->type == CLUTTER_ENTER ||
- event->type == CLUTTER_LEAVE) &&
- !clutter_event_get_event_sequence (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)
- {
- ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
- 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_stage_get_device_coords (stage, 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_get_relative_coordinates (MetaWaylandPointer *pointer,
- MetaWaylandSurface *surface,
- wl_fixed_t *sx,
- wl_fixed_t *sy)
-{
- MetaBackend *backend = meta_get_backend ();
- ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
- float xf = 0.0f, yf = 0.0f;
- graphene_point_t pos;
-
- clutter_stage_get_device_coords (stage, 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;
- MetaWaylandSurface *surface;
-
- pointer = wl_resource_get_user_data (resource);
- if (!pointer)
- return;
-
- 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)
- {
- ClutterBackend *clutter_backend = clutter_get_default_backend ();
- ClutterSeat *clutter_seat =
- clutter_backend_get_default_seat (clutter_backend);
- ClutterInputDevice *device = clutter_seat_get_pointer (clutter_seat);
- MetaCursorRenderer *cursor_renderer =
- meta_backend_get_cursor_renderer_for_device (meta_get_backend (),
- device);
- 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
deleted file mode 100644
index 5eda5276f..000000000
--- a/src/wayland/meta-wayland-pointer.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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_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
deleted file mode 100644
index 995d5f967..000000000
--- a/src/wayland/meta-wayland-popup.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * 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);
- MetaWaylandPointer *pointer = 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 if (pointer->button_count == 0)
- 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_new0 (MetaWaylandPopupGrab, 1);
- 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_free (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_free (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_new0 (MetaWaylandPopup, 1);
- 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
deleted file mode 100644
index 3cc90e22a..000000000
--- a/src/wayland/meta-wayland-popup.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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-presentation-time-private.h b/src/wayland/meta-wayland-presentation-time-private.h
deleted file mode 100644
index bc3dc6a40..000000000
--- a/src/wayland/meta-wayland-presentation-time-private.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * presentation-time protocol
- *
- * Copyright (C) 2020 Ivan Molodetskikh <yalterz@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public 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_PRESENTATION_TIME_PRIVATE_H
-#define META_WAYLAND_PRESENTATION_TIME_PRIVATE_H
-
-#include <wayland-server.h>
-
-#include "clutter/clutter.h"
-#include "wayland/meta-wayland-cursor-surface.h"
-#include "wayland/meta-wayland-types.h"
-
-typedef struct _MetaWaylandPresentationFeedback
-{
- struct wl_list link;
- struct wl_resource *resource;
-
- MetaWaylandSurface *surface;
-} MetaWaylandPresentationFeedback;
-
-typedef struct _MetaWaylandPresentationTime
-{
- GList *feedback_surfaces;
-
- /*
- * A mapping from (ClutterStageView *) to a
- * (MetaWaylandPresentationFeedback *) wl_list of presentation-time feedbacks
- * that are scheduled to be presented.
- */
- GHashTable *feedbacks;
-} MetaWaylandPresentationTime;
-
-void meta_wayland_init_presentation_time (MetaWaylandCompositor *compositor);
-
-void meta_wayland_presentation_feedback_discard (MetaWaylandPresentationFeedback *feedback);
-
-void meta_wayland_presentation_feedback_present (MetaWaylandPresentationFeedback *feedback,
- ClutterFrameInfo *frame_info,
- MetaWaylandOutput *output);
-
-struct wl_list * meta_wayland_presentation_time_ensure_feedbacks (MetaWaylandPresentationTime *presentation_time,
- ClutterStageView *stage_view);
-
-void meta_wayland_presentation_time_cursor_painted (MetaWaylandPresentationTime *presentation_time,
- ClutterStageView *stage_view,
- MetaWaylandCursorSurface *cursor_surface);
-
-#endif /* META_WAYLAND_PRESENTATION_TIME_PRIVATE_H */
diff --git a/src/wayland/meta-wayland-presentation-time.c b/src/wayland/meta-wayland-presentation-time.c
deleted file mode 100644
index b0d8cf81c..000000000
--- a/src/wayland/meta-wayland-presentation-time.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * presentation-time protocol
- *
- * Copyright (C) 2020 Ivan Molodetskikh <yalterz@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public 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-presentation-time-private.h"
-
-#include <glib.h>
-
-#include "compositor/meta-surface-actor-wayland.h"
-#include "wayland/meta-wayland-cursor-surface.h"
-#include "wayland/meta-wayland-private.h"
-#include "wayland/meta-wayland-surface.h"
-#include "wayland/meta-wayland-outputs.h"
-#include "wayland/meta-wayland-versions.h"
-
-#include "presentation-time-server-protocol.h"
-
-static void
-wp_presentation_feedback_destructor (struct wl_resource *resource)
-{
- MetaWaylandPresentationFeedback *feedback =
- wl_resource_get_user_data (resource);
-
- wl_list_remove (&feedback->link);
- g_free (feedback);
-}
-
-static void
-wp_presentation_destroy (struct wl_client *client,
- struct wl_resource *resource)
-{
- wl_resource_destroy (resource);
-}
-
-static void
-wp_presentation_feedback (struct wl_client *client,
- struct wl_resource *resource,
- struct wl_resource *surface_resource,
- uint32_t callback_id)
-{
- MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
- MetaWaylandSurfaceState *pending;
- MetaWaylandPresentationFeedback *feedback;
-
- feedback = g_new0 (MetaWaylandPresentationFeedback, 1);
- wl_list_init (&feedback->link);
- feedback->resource = wl_resource_create (client,
- &wp_presentation_feedback_interface,
- wl_resource_get_version (resource),
- callback_id);
- wl_resource_set_implementation (feedback->resource,
- NULL,
- feedback,
- wp_presentation_feedback_destructor);
-
- if (surface == NULL)
- {
- g_warn_if_reached ();
- meta_wayland_presentation_feedback_discard (feedback);
- return;
- }
-
- pending = meta_wayland_surface_get_pending_state (surface);
- wl_list_insert (&pending->presentation_feedback_list, &feedback->link);
-
- feedback->surface = surface;
-}
-
-static const struct wp_presentation_interface
-meta_wayland_presentation_interface = {
- wp_presentation_destroy,
- wp_presentation_feedback,
-};
-
-static void
-wp_presentation_bind (struct wl_client *client,
- void *data,
- uint32_t version,
- uint32_t id)
-{
- struct wl_resource *resource;
-
- resource = wl_resource_create (client,
- &wp_presentation_interface,
- version,
- id);
- wl_resource_set_implementation (resource,
- &meta_wayland_presentation_interface,
- NULL,
- NULL);
-
- /* Presentation timestamps in Mutter are guaranteed to be CLOCK_MONOTONIC. */
- wp_presentation_send_clock_id (resource, CLOCK_MONOTONIC);
-}
-
-static void
-discard_non_cursor_feedbacks (struct wl_list *feedbacks)
-{
- MetaWaylandPresentationFeedback *feedback, *next;
-
- wl_list_for_each_safe (feedback, next, feedbacks, link)
- {
- if (META_IS_WAYLAND_CURSOR_SURFACE (feedback->surface->role))
- continue;
-
- meta_wayland_presentation_feedback_discard (feedback);
- }
-}
-
-static void
-on_after_paint (ClutterStage *stage,
- ClutterStageView *stage_view,
- MetaWaylandCompositor *compositor)
-{
- struct wl_list *feedbacks;
- GList *l;
-
- /*
- * We just painted this stage view, which means that all non-cursor feedbacks
- * that didn't fire (e.g. due to page flip failing) are now obsolete and
- * should be discarded.
- *
- * Cursor feedbacks have a similar mechanism done separately, mainly because
- * they are painted earlier, in prepare_frame(). This means that the feedbacks
- * list currently contains stale non-cursor feedbacks and up-to-date cursor
- * feedbacks.
- */
- feedbacks =
- meta_wayland_presentation_time_ensure_feedbacks (&compositor->presentation_time,
- stage_view);
- discard_non_cursor_feedbacks (feedbacks);
-
- l = compositor->presentation_time.feedback_surfaces;
- while (l)
- {
- GList *l_cur = l;
- MetaWaylandSurface *surface = l->data;
- MetaSurfaceActor *actor;
- ClutterStageView *surface_primary_view;
-
- l = l->next;
-
- actor = meta_wayland_surface_get_actor (surface);
- if (!actor)
- continue;
-
- surface_primary_view =
- meta_surface_actor_wayland_get_current_primary_view (actor, stage);
- if (stage_view != surface_primary_view)
- continue;
-
- if (!wl_list_empty (&surface->presentation_time.feedback_list))
- {
- /* Add feedbacks to the list to be fired on presentation. */
- wl_list_insert_list (feedbacks,
- &surface->presentation_time.feedback_list);
- wl_list_init (&surface->presentation_time.feedback_list);
-
- surface->presentation_time.needs_sequence_update = TRUE;
- }
-
- compositor->presentation_time.feedback_surfaces =
- g_list_delete_link (compositor->presentation_time.feedback_surfaces,
- l_cur);
- }
-}
-
-static void
-destroy_feedback_list (gpointer data)
-{
- struct wl_list *feedbacks = data;
-
- while (!wl_list_empty (feedbacks))
- {
- MetaWaylandPresentationFeedback *feedback =
- wl_container_of (feedbacks->next, feedback, link);
-
- meta_wayland_presentation_feedback_discard (feedback);
- }
-
- g_free (feedbacks);
-}
-
-static void
-on_monitors_changed (MetaMonitorManager *manager,
- MetaWaylandCompositor *compositor)
-{
- /* All ClutterStageViews were re-created, so clear our map. */
- g_hash_table_remove_all (compositor->presentation_time.feedbacks);
-}
-
-void
-meta_wayland_init_presentation_time (MetaWaylandCompositor *compositor)
-{
- MetaContext *context = compositor->context;
- MetaBackend *backend = meta_context_get_backend (context);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- ClutterActor *stage = meta_backend_get_stage (backend);
-
- compositor->presentation_time.feedbacks =
- g_hash_table_new_full (NULL, NULL, NULL, destroy_feedback_list);
-
- g_signal_connect (monitor_manager, "monitors-changed-internal",
- G_CALLBACK (on_monitors_changed), compositor);
-
- g_signal_connect (stage, "after-paint",
- G_CALLBACK (on_after_paint), compositor);
-
- if (wl_global_create (compositor->wayland_display,
- &wp_presentation_interface,
- META_WP_PRESENTATION_VERSION,
- NULL,
- wp_presentation_bind) == NULL)
- g_error ("Failed to register a global wp_presentation object");
-}
-
-void
-meta_wayland_presentation_feedback_discard (MetaWaylandPresentationFeedback *feedback)
-{
- wp_presentation_feedback_send_discarded (feedback->resource);
- wl_resource_destroy (feedback->resource);
-}
-
-static void
-maybe_update_presentation_sequence (MetaWaylandSurface *surface,
- ClutterFrameInfo *frame_info,
- MetaWaylandOutput *output)
-{
- unsigned int sequence_delta;
-
- if (!surface->presentation_time.needs_sequence_update)
- return;
-
- surface->presentation_time.needs_sequence_update = FALSE;
-
- if (!(frame_info->flags & CLUTTER_FRAME_INFO_FLAG_VSYNC))
- goto invalid_sequence;
-
- /* Getting sequence = 0 after sequence = UINT_MAX is likely valid (32-bit
- * overflow, on a 144 Hz display that's ~173 days of operation). Getting it
- * otherwise is usually a driver bug.
- */
- if (frame_info->sequence == 0 &&
- !(surface->presentation_time.is_last_output_sequence_valid &&
- surface->presentation_time.last_output_sequence == UINT_MAX))
- {
- g_warning_once ("Invalid sequence for VSYNC frame info");
- goto invalid_sequence;
- }
-
- if (surface->presentation_time.is_last_output_sequence_valid &&
- surface->presentation_time.last_output == output)
- {
- sequence_delta =
- frame_info->sequence - surface->presentation_time.last_output_sequence;
- }
- else
- {
- /* Sequence generally has different base between different outputs, but we
- * want to keep it monotonic and without sudden jumps when the surface is
- * moved between outputs. This matches the Xorg behavior with regards to
- * the GLX_OML_sync_control implementation.
- */
- sequence_delta = 1;
- }
-
- surface->presentation_time.sequence += sequence_delta;
- surface->presentation_time.last_output = output;
- surface->presentation_time.last_output_sequence = frame_info->sequence;
- surface->presentation_time.is_last_output_sequence_valid = TRUE;
-
- return;
-
-invalid_sequence:
- surface->presentation_time.sequence += 1;
- surface->presentation_time.last_output = output;
- surface->presentation_time.is_last_output_sequence_valid = FALSE;
-}
-
-void
-meta_wayland_presentation_feedback_present (MetaWaylandPresentationFeedback *feedback,
- ClutterFrameInfo *frame_info,
- MetaWaylandOutput *output)
-{
- MetaWaylandSurface *surface = feedback->surface;
- int64_t time_us = frame_info->presentation_time;
- uint64_t time_s;
- uint32_t tv_sec_hi, tv_sec_lo, tv_nsec;
- uint32_t refresh_interval_ns;
- uint32_t seq_hi, seq_lo;
- uint32_t flags;
- GList *l;
-
- if (output == NULL)
- {
- g_warning ("Output is NULL while sending presentation feedback");
- meta_wayland_presentation_feedback_discard (feedback);
- return;
- }
-
- time_s = us2s (time_us);
-
- tv_sec_hi = time_s >> 32;
- tv_sec_lo = time_s;
- tv_nsec = (uint32_t) us2ns (time_us - s2us (time_s));
-
- refresh_interval_ns = (uint32_t) (0.5 + s2ns (1) / frame_info->refresh_rate);
-
- maybe_update_presentation_sequence (surface, frame_info, output);
-
- seq_hi = surface->presentation_time.sequence >> 32;
- seq_lo = surface->presentation_time.sequence;
-
- flags = WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION;
-
- if (frame_info->flags & CLUTTER_FRAME_INFO_FLAG_HW_CLOCK)
- flags |= WP_PRESENTATION_FEEDBACK_KIND_HW_CLOCK;
-
- if (frame_info->flags & CLUTTER_FRAME_INFO_FLAG_ZERO_COPY)
- flags |= WP_PRESENTATION_FEEDBACK_KIND_ZERO_COPY;
-
- if (frame_info->flags & CLUTTER_FRAME_INFO_FLAG_VSYNC)
- flags |= WP_PRESENTATION_FEEDBACK_KIND_VSYNC;
-
- for (l = output->resources; l; l = l->next)
- {
- struct wl_resource *output_resource = l->data;
-
- if (feedback->resource->client == output_resource->client)
- {
- wp_presentation_feedback_send_sync_output (feedback->resource,
- output_resource);
- }
- }
-
- wp_presentation_feedback_send_presented (feedback->resource,
- tv_sec_hi,
- tv_sec_lo,
- tv_nsec,
- refresh_interval_ns,
- seq_hi,
- seq_lo,
- flags);
-
- wl_resource_destroy (feedback->resource);
-}
-
-struct wl_list *
-meta_wayland_presentation_time_ensure_feedbacks (MetaWaylandPresentationTime *presentation_time,
- ClutterStageView *stage_view)
-{
- if (!g_hash_table_contains (presentation_time->feedbacks, stage_view))
- {
- struct wl_list *list;
-
- list = g_new0 (struct wl_list, 1);
- wl_list_init (list);
- g_hash_table_insert (presentation_time->feedbacks, stage_view, list);
-
- return list;
- }
-
- return g_hash_table_lookup (presentation_time->feedbacks, stage_view);
-}
-
-void
-meta_wayland_presentation_time_cursor_painted (MetaWaylandPresentationTime *presentation_time,
- ClutterStageView *stage_view,
- MetaWaylandCursorSurface *cursor_surface)
-{
- struct wl_list *feedbacks;
- MetaWaylandPresentationFeedback *feedback, *next;
- MetaWaylandSurfaceRole *role = META_WAYLAND_SURFACE_ROLE (cursor_surface);
- MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (role);
-
- feedbacks =
- meta_wayland_presentation_time_ensure_feedbacks (presentation_time,
- stage_view);
-
- /* Discard previous feedbacks for this cursor as now it has gone stale. */
- wl_list_for_each_safe (feedback, next, feedbacks, link)
- {
- if (feedback->surface->role == role)
- meta_wayland_presentation_feedback_discard (feedback);
- }
-
- /* Add new feedbacks. */
- if (!wl_list_empty (&surface->presentation_time.feedback_list))
- {
- wl_list_insert_list (feedbacks,
- &surface->presentation_time.feedback_list);
- wl_list_init (&surface->presentation_time.feedback_list);
-
- surface->presentation_time.needs_sequence_update = TRUE;
- }
-}
diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h
deleted file mode 100644
index 5272b530f..000000000
--- a/src/wayland/meta-wayland-private.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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-presentation-time-private.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 abstract_fd_watch_id;
- guint unix_fd_watch_id;
-
- 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;
-
- gboolean has_xrandr;
- int rr_event_base;
- int rr_error_base;
-} MetaXWaylandManager;
-
-struct _MetaWaylandCompositor
-{
- GObject parent;
-
- MetaContext *context;
-
- struct wl_display *wayland_display;
- char *display_name;
- GHashTable *outputs;
- GList *frame_callback_surfaces;
-
- MetaXWaylandManager xwayland_manager;
-
- MetaWaylandSeat *seat;
- MetaWaylandTabletManager *tablet_manager;
- MetaWaylandActivation *activation;
-
- GHashTable *scheduled_surface_associations;
-
- MetaWaylandPresentationTime presentation_time;
-};
-
-#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
deleted file mode 100644
index ee4b6950f..000000000
--- a/src/wayland/meta-wayland-region.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/* -*- 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_free (region);
-}
-
-MetaWaylandRegion *
-meta_wayland_region_create (MetaWaylandCompositor *compositor,
- struct wl_client *client,
- struct wl_resource *compositor_resource,
- guint32 id)
-{
- MetaWaylandRegion *region = g_new0 (MetaWaylandRegion, 1);
-
- 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
deleted file mode 100644
index 201580a67..000000000
--- a/src/wayland/meta-wayland-region.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- 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
deleted file mode 100644
index abc0b4dda..000000000
--- a/src/wayland/meta-wayland-seat.c
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * 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, logical devices have rather generic
- * keyboard/pointer device types, which is not truly representative of
- * the physical devices connected to them.
- */
- if (clutter_input_device_get_device_mode (l->data) == CLUTTER_INPUT_MODE_LOGICAL)
- 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);
-
- meta_wayland_pointer_disable (seat->pointer);
- g_object_unref (seat->pointer);
- meta_wayland_keyboard_disable (seat->keyboard);
- g_object_unref (seat->keyboard);
- meta_wayland_touch_disable (seat->touch);
- 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_LOGICAL;
-}
-
-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_PHYSICAL)
- 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_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
deleted file mode 100644
index ae4e1076b..000000000
--- a/src/wayland/meta-wayland-seat.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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);
-
-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
deleted file mode 100644
index 5e052e000..000000000
--- a/src/wayland/meta-wayland-shell-surface.c
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * 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;
-} 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);
- 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);
-}
-
-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);
-
- 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
deleted file mode 100644
index d1bbeef65..000000000
--- a/src/wayland/meta-wayland-shell-surface.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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
deleted file mode 100644
index d7f56b66e..000000000
--- a/src/wayland/meta-wayland-subsurface.c
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * 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 gboolean
-should_show (MetaWaylandSurface *surface)
-{
- if (!surface->buffer_ref->buffer)
- return FALSE;
- else if (surface->sub.parent)
- return should_show (surface->sub.parent);
- else
- return TRUE;
-}
-
-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 (should_show (surface))
- 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),
- };
-
- if (surface->buffer_ref->buffer)
- 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_subsurface_destroyed (struct wl_listener *listener,
- void *data)
-{
- MetaWaylandSubsurfacePlacementOp *op =
- wl_container_of (listener, op, subsurface_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->subsurface_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->subsurface_destroy_listener.notify =
- subsurface_handle_pending_subsurface_destroyed;
- op->sibling_destroy_listener.notify =
- subsurface_handle_pending_sibling_destroyed;
- wl_resource_add_destroy_listener (surface->wl_subsurface,
- &op->subsurface_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
deleted file mode 100644
index 45dbf8626..000000000
--- a/src/wayland/meta-wayland-subsurface.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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 subsurface_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
deleted file mode 100644
index 64e7de8db..000000000
--- a/src/wayland/meta-wayland-surface.c
+++ /dev/null
@@ -1,2133 +0,0 @@
-/*
- * 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 "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-presentation-time-private.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
-set_surface_is_on_output (MetaWaylandSurface *surface,
- MetaWaylandOutput *wayland_output,
- gboolean is_on_output);
-
-static MetaWaylandBufferRef *
-meta_wayland_buffer_ref_new (void)
-{
- MetaWaylandBufferRef *buffer_ref;
-
- buffer_ref = g_new0 (MetaWaylandBufferRef, 1);
- g_ref_count_init (&buffer_ref->ref_count);
-
- return buffer_ref;
-}
-
-static MetaWaylandBufferRef *
-meta_wayland_buffer_ref_ref (MetaWaylandBufferRef *buffer_ref)
-{
- g_ref_count_inc (&buffer_ref->ref_count);
- return buffer_ref;
-}
-
-static void
-meta_wayland_buffer_ref_unref (MetaWaylandBufferRef *buffer_ref)
-{
- if (g_ref_count_dec (&buffer_ref->ref_count))
- {
- g_warn_if_fail (buffer_ref->use_count == 0);
- g_clear_object (&buffer_ref->buffer);
- g_free (buffer_ref);
- }
-}
-
-static void
-meta_wayland_buffer_ref_inc_use_count (MetaWaylandBufferRef *buffer_ref)
-{
- g_return_if_fail (buffer_ref->buffer);
- g_warn_if_fail (buffer_ref->buffer->resource);
-
- buffer_ref->use_count++;
-}
-
-static void
-meta_wayland_buffer_ref_dec_use_count (MetaWaylandBufferRef *buffer_ref)
-{
- MetaWaylandBuffer *buffer = buffer_ref->buffer;
-
- g_return_if_fail (buffer_ref->use_count > 0);
- g_return_if_fail (buffer);
-
- buffer_ref->use_count--;
-
- if (buffer_ref->use_count == 0 && buffer->resource)
- wl_buffer_send_release (buffer->resource);
-}
-
-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)
-{
- meta_wayland_buffer_ref_inc_use_count (surface->buffer_ref);
-}
-
-void
-meta_wayland_surface_unref_buffer_use_count (MetaWaylandSurface *surface)
-{
- meta_wayland_buffer_ref_dec_use_count (surface->buffer_ref);
-}
-
-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;
-
- wl_list_init (&state->presentation_feedback_list);
-}
-
-static void
-meta_wayland_surface_state_discard_presentation_feedback (MetaWaylandSurfaceState *state)
-{
- while (!wl_list_empty (&state->presentation_feedback_list))
- {
- MetaWaylandPresentationFeedback *feedback =
- wl_container_of (state->presentation_feedback_list.next, feedback, link);
-
- meta_wayland_presentation_feedback_discard (feedback);
- }
-}
-
-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);
- }
-
- meta_wayland_surface_state_discard_presentation_feedback (state);
-}
-
-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);
-
- 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);
- wl_list_init (&from->frame_callback_list);
-
- cairo_region_union (to->surface_damage, from->surface_damage);
- cairo_region_union (to->buffer_damage, 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;
- }
-
- 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;
- }
-
- 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;
- }
-
- wl_list_insert_list (&to->presentation_feedback_list,
- &from->presentation_feedback_list);
- wl_list_init (&from->presentation_feedback_list);
-
- meta_wayland_surface_state_reset (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_discard_presentation_feedback (MetaWaylandSurface *surface)
-{
- while (!wl_list_empty (&surface->presentation_time.feedback_list))
- {
- MetaWaylandPresentationFeedback *feedback =
- wl_container_of (surface->presentation_time.feedback_list.next,
- feedback, link);
-
- meta_wayland_presentation_feedback_discard (feedback);
- }
-}
-
-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);
-
- if (surface->buffer_ref->use_count > 0)
- {
- meta_wayland_buffer_ref_unref (surface->buffer_ref);
- surface->buffer_ref = meta_wayland_buffer_ref_new ();
- }
-
- 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;
- }
-
- /*
- * A new commit indicates a new content update, so any previous
- * content update did not go on screen and needs to be discarded.
- */
- meta_wayland_surface_discard_presentation_feedback (surface);
-
- wl_list_insert_list (&surface->presentation_time.feedback_list,
- &state->presentation_feedback_list);
- wl_list_init (&state->presentation_feedback_list);
-
- if (!wl_list_empty (&surface->presentation_time.feedback_list))
- meta_wayland_compositor_add_presentation_feedback_surface (surface->compositor,
- surface);
-
- 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);
-
- /*
- * A new commit indicates a new content update, so any previous
- * cached content update did not go on screen and needs to be discarded.
- */
- meta_wayland_surface_state_discard_presentation_feedback (cached_state);
-
- 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_free (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_new0 (MetaWaylandFrameCallback, 1);
- 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",
- 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",
- 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
-handle_output_destroyed (MetaWaylandOutput *wayland_output,
- MetaWaylandSurface *surface)
-{
- set_surface_is_on_output (surface, wayland_output, FALSE);
-}
-
-static void
-handle_output_bound (MetaWaylandOutput *wayland_output,
- struct wl_resource *output_resource,
- MetaWaylandSurface *surface)
-{
- if (wl_resource_get_client (output_resource) ==
- wl_resource_get_client (surface->resource))
- wl_surface_send_enter (surface->resource, output_resource);
-}
-
-static void
-surface_entered_output (MetaWaylandSurface *surface,
- MetaWaylandOutput *wayland_output)
-{
- GList *iter;
- struct wl_resource *resource;
-
- g_signal_connect (wayland_output, "output-destroyed",
- G_CALLBACK (handle_output_destroyed),
- surface);
-
- 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);
- }
-
- g_signal_connect (wayland_output, "output-bound",
- G_CALLBACK (handle_output_bound),
- surface);
-}
-
-static void
-surface_left_output (MetaWaylandSurface *surface,
- MetaWaylandOutput *wayland_output)
-{
- GList *iter;
- struct wl_resource *resource;
-
- g_signal_handlers_disconnect_by_func (wayland_output,
- G_CALLBACK (handle_output_destroyed),
- surface);
-
- g_signal_handlers_disconnect_by_func (wayland_output,
- G_CALLBACK (handle_output_bound),
- surface);
-
- 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)
-{
- gboolean was_on_output;
-
- was_on_output = g_hash_table_contains (surface->outputs, wayland_output);
-
- if (!was_on_output && is_on_output)
- {
- g_hash_table_add (surface->outputs, wayland_output);
- surface_entered_output (surface, wayland_output);
- }
- else if (was_on_output && !is_on_output)
- {
- g_hash_table_remove (surface->outputs, wayland_output);
- 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_signals (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- MetaWaylandOutput *wayland_output = key;
- MetaWaylandSurface *surface = user_data;
-
- g_signal_handlers_disconnect_by_func (wayland_output,
- G_CALLBACK (handle_output_destroyed),
- surface);
-
- g_signal_handlers_disconnect_by_func (wayland_output,
- G_CALLBACK (handle_output_bound),
- surface);
-}
-
-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_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_pointer (&surface->buffer_ref, meta_wayland_buffer_ref_unref);
-
- 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);
- meta_wayland_compositor_remove_presentation_feedback_surface (compositor,
- surface);
-
- g_hash_table_foreach (surface->outputs,
- surface_output_disconnect_signals,
- surface);
- g_hash_table_destroy (surface->outputs);
-
- wl_list_for_each_safe (cb, next,
- &surface->unassigned.pending_frame_callback_list,
- link)
- wl_resource_destroy (cb->resource);
-
- meta_wayland_surface_discard_presentation_feedback (surface);
-
- 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);
-}
-
-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 = g_hash_table_new (NULL, NULL);
- surface->shortcut_inhibited_seats = g_hash_table_new (NULL, NULL);
-
- wl_list_init (&surface->presentation_time.feedback_list);
-
- 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->buffer_ref = meta_wayland_buffer_ref_new ();
-
- surface->subsurface_branch_node = g_node_new (surface);
- surface->subsurface_leaf_node =
- g_node_prepend_data (surface->subsurface_branch_node, surface);
-}
-
-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;
- }
-}
-
-static void
-scanout_destroyed (gpointer data,
- GObject *where_the_object_was)
-{
- MetaWaylandBufferRef *buffer_ref = data;
-
- meta_wayland_buffer_ref_dec_use_count (buffer_ref);
- meta_wayland_buffer_ref_unref (buffer_ref);
-}
-
-CoglScanout *
-meta_wayland_surface_try_acquire_scanout (MetaWaylandSurface *surface,
- CoglOnscreen *onscreen)
-{
- CoglScanout *scanout;
- MetaWaylandBufferRef *buffer_ref;
-
- if (!surface->buffer_ref->buffer)
- return NULL;
-
- if (surface->buffer_ref->use_count == 0)
- return NULL;
-
- scanout = meta_wayland_buffer_try_acquire_scanout (surface->buffer_ref->buffer,
- onscreen);
- if (!scanout)
- return NULL;
-
- buffer_ref = meta_wayland_buffer_ref_ref (surface->buffer_ref);
- meta_wayland_buffer_ref_inc_use_count (buffer_ref);
- g_object_weak_ref (G_OBJECT (scanout), scanout_destroyed, buffer_ref);
-
- return scanout;
-}
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
deleted file mode 100644
index f0153b23b..000000000
--- a/src/wayland/meta-wayland-surface.h
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * 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;
-
- /* presentation-time */
- struct wl_list presentation_feedback_list;
-};
-
-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);
-};
-
-typedef struct _MetaWaylandBufferRef
-{
- grefcount ref_count;
- MetaWaylandBuffer *buffer;
- unsigned int use_count;
-} MetaWaylandBufferRef;
-
-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;
- MetaMonitorTransform buffer_transform;
-
- CoglTexture *texture;
-
- /* Buffer reference state. */
- MetaWaylandBufferRef *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;
-
- /* presentation-time */
- struct {
- struct wl_list feedback_list;
- MetaWaylandOutput *last_output;
- unsigned int last_output_sequence;
- gboolean is_last_output_sequence_valid;
- gboolean needs_sequence_update;
-
- /*
- * Sequence has an undefined base, but is guaranteed to monotonically
- * increase. DRM only gives us a 32-bit sequence, so we compute our own
- * delta to update our own 64-bit sequence.
- */
- uint64_t sequence;
- } presentation_time;
-};
-
-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);
-
-int meta_wayland_surface_get_width (MetaWaylandSurface *surface);
-int meta_wayland_surface_get_height (MetaWaylandSurface *surface);
-
-CoglScanout * meta_wayland_surface_try_acquire_scanout (MetaWaylandSurface *surface,
- CoglOnscreen *onscreen);
-
-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
deleted file mode 100644
index 421b7c20a..000000000
--- a/src/wayland/meta-wayland-tablet-cursor-surface.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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
deleted file mode 100644
index df41e832e..000000000
--- a/src/wayland/meta-wayland-tablet-cursor-surface.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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
deleted file mode 100644
index a729c7b89..000000000
--- a/src/wayland/meta-wayland-tablet-manager.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * 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_LOGICAL)
- 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_new0 (MetaWaylandTabletManager, 1);
- 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_free (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;
-}
diff --git a/src/wayland/meta-wayland-tablet-manager.h b/src/wayland/meta-wayland-tablet-manager.h
deleted file mode 100644
index 83f9d3d0f..000000000
--- a/src/wayland/meta-wayland-tablet-manager.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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);
-
-#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
deleted file mode 100644
index 281651588..000000000
--- a/src/wayland/meta-wayland-tablet-pad-group.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * 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"
-
-#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_new0 (MetaWaylandTabletPadGroup, 1);
- 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_free (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)
-{
- int n_group = g_list_index (group->pad->groups, group);
-
- if (clutter_input_device_get_pad_feature_group (group->pad->device,
- CLUTTER_PAD_FEATURE_BUTTON,
- button) == n_group)
- return TRUE;
-
- return FALSE;
-}
-
-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
deleted file mode 100644
index 0df3cc1f8..000000000
--- a/src/wayland/meta-wayland-tablet-pad-group.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 55e45eaa2..000000000
--- a/src/wayland/meta-wayland-tablet-pad-ring.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * 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_new0 (MetaWaylandTabletPadRing, 1);
- 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_free (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
deleted file mode 100644
index 744ba2e84..000000000
--- a/src/wayland/meta-wayland-tablet-pad-ring.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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
deleted file mode 100644
index b320dbf80..000000000
--- a/src/wayland/meta-wayland-tablet-pad-strip.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * 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_new0 (MetaWaylandTabletPadStrip, 1);
- 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_free (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
deleted file mode 100644
index 9d69de4eb..000000000
--- a/src/wayland/meta-wayland-tablet-pad-strip.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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
deleted file mode 100644
index c0b408c10..000000000
--- a/src/wayland/meta-wayland-tablet-pad.c
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * 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 "core/display-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"
-
-#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;
-
- for (n_group = 0, g = pad->groups; g; g = g->next)
- {
- MetaWaylandTabletPadGroup *group = g->data;
-
- for (n_elem = 0, l = pad->rings; l; l = l->next)
- {
- MetaWaylandTabletPadRing *ring = l->data;
-
- if (clutter_input_device_get_pad_feature_group (pad->device,
- CLUTTER_PAD_FEATURE_RING,
- n_elem) == n_group)
- 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;
-
- if (clutter_input_device_get_pad_feature_group (pad->device,
- CLUTTER_PAD_FEATURE_STRIP,
- n_elem) == n_group)
- meta_wayland_tablet_pad_strip_set_group (strip, group);
-
- n_elem++;
- }
-
- n_group++;
- }
-}
-
-MetaWaylandTabletPad *
-meta_wayland_tablet_pad_new (ClutterInputDevice *device,
- MetaWaylandTabletSeat *tablet_seat)
-{
- MetaWaylandTabletPad *pad;
- guint n_elems, i;
-
- pad = g_new0 (MetaWaylandTabletPad, 1);
- 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);
-
- pad->n_buttons = clutter_input_device_get_n_buttons (device);
-
- 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_free (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);
- MetaPadActionMapper *mapper;
-
- if (!group || group->mode_switch_serial != serial)
- return;
-
- mapper = meta_get_display ()->pad_action_mapper;
-
- if (meta_pad_action_mapper_is_button_grabbed (mapper, 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)
-{
- MetaPadActionMapper *mapper;
- ClutterInputDevice *device;
-
- device = clutter_event_get_source_device (event);
- mapper = meta_get_display ()->pad_action_mapper;
-
- if (meta_pad_action_mapper_is_button_grabbed (mapper, 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
deleted file mode 100644
index 63eaa03ed..000000000
--- a/src/wayland/meta-wayland-tablet-pad.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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
deleted file mode 100644
index f9b95a656..000000000
--- a/src/wayland/meta-wayland-tablet-seat.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * 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"
-
-#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_LOGICAL)
- 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_LOGICAL)
- 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_new0 (MetaWaylandTabletSeat, 1);
- 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_free (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
deleted file mode 100644
index e8b5a2439..000000000
--- a/src/wayland/meta-wayland-tablet-seat.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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
deleted file mode 100644
index a8de868bc..000000000
--- a/src/wayland/meta-wayland-tablet-tool.c
+++ /dev/null
@@ -1,912 +0,0 @@
-/*
- * 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"
-
-#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 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)
-{
- ClutterInputAxisFlags axes;
-
- axes = clutter_input_device_tool_get_axes (tool->device_tool);
-
- if (axes & CLUTTER_INPUT_AXIS_FLAG_PRESSURE)
- zwp_tablet_tool_v2_send_capability (resource,
- ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE);
- if (axes & CLUTTER_INPUT_AXIS_FLAG_DISTANCE)
- zwp_tablet_tool_v2_send_capability (resource,
- ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE);
- if (axes & (CLUTTER_INPUT_AXIS_FLAG_XTILT | CLUTTER_INPUT_AXIS_FLAG_YTILT))
- zwp_tablet_tool_v2_send_capability (resource,
- ZWP_TABLET_TOOL_V2_CAPABILITY_TILT);
- if (axes & CLUTTER_INPUT_AXIS_FLAG_ROTATION)
- zwp_tablet_tool_v2_send_capability (resource,
- ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION);
- if (axes & CLUTTER_INPUT_AXIS_FLAG_SLIDER)
- zwp_tablet_tool_v2_send_capability (resource,
- ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER);
- if (axes & CLUTTER_INPUT_AXIS_FLAG_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,
- float best_scale,
- 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_new0 (MetaWaylandTabletTool, 1);
- 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_free (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
-};
-
-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));
- }
- 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;
- uint32_t button;
-
- button = clutter_event_get_event_code (event);
- 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;
- uint32_t value;
- double val;
-
- val = event->motion.axes[axis];
- 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;
- gdouble xtilt, ytilt;
-
- xtilt = event->motion.axes[CLUTTER_INPUT_AXIS_FLAG_XTILT];
- ytilt = event->motion.axes[CLUTTER_INPUT_AXIS_FLAG_YTILT];
-
- 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;
- gdouble rotation;
-
- rotation = event->motion.axes[CLUTTER_INPUT_AXIS_FLAG_ROTATION];
-
- 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;
- gdouble angle;
- gint32 clicks = 0;
-
- angle = event->motion.axes[CLUTTER_INPUT_AXIS_FLAG_WHEEL];
-
- /* 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)
-{
- ClutterInputAxisFlags axes;
-
- axes = clutter_input_device_tool_get_axes (tool->device_tool);
-
- if (axes & CLUTTER_INPUT_AXIS_FLAG_PRESSURE)
- broadcast_axis (tool, event, CLUTTER_INPUT_AXIS_PRESSURE);
- if (axes & CLUTTER_INPUT_AXIS_FLAG_DISTANCE)
- broadcast_axis (tool, event, CLUTTER_INPUT_AXIS_DISTANCE);
- if (axes & (CLUTTER_INPUT_AXIS_FLAG_XTILT | CLUTTER_INPUT_AXIS_FLAG_YTILT))
- broadcast_tilt (tool, event);
- if (axes & CLUTTER_INPUT_AXIS_FLAG_ROTATION)
- broadcast_rotation (tool, event);
- if (axes & CLUTTER_INPUT_AXIS_FLAG_SLIDER)
- broadcast_axis (tool, event, CLUTTER_INPUT_AXIS_SLIDER);
- if (axes & CLUTTER_INPUT_AXIS_FLAG_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)
- {
- MetaCursorRenderer *renderer;
-
- renderer =
- meta_backend_get_cursor_renderer_for_device (meta_get_backend (),
- clutter_event_get_source_device (event));
- g_set_object (&tool->cursor_renderer, renderer);
- }
- 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;
-}
-
-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
deleted file mode 100644
index e9ad7db40..000000000
--- a/src/wayland/meta-wayland-tablet-tool.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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);
-
-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
deleted file mode 100644
index bb83bb255..000000000
--- a/src/wayland/meta-wayland-tablet.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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_new0 (MetaWaylandTablet, 1);
- 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_free (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
deleted file mode 100644
index 0bc3b87b9..000000000
--- a/src/wayland/meta-wayland-tablet.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 442708e0f..000000000
--- a/src/wayland/meta-wayland-text-input-legacy.c
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
- * 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,
- &gtk_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,
- &gtk_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,
- &gtk_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
deleted file mode 100644
index 55bfed809..000000000
--- a/src/wayland/meta-wayland-text-input-legacy.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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
deleted file mode 100644
index b471e8e1a..000000000
--- a/src/wayland/meta-wayland-text-input.c
+++ /dev/null
@@ -1,766 +0,0 @@
-/*
- * 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
- * CLUTTER_PRIORITY_EVENTS + 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
deleted file mode 100644
index 7e3544d95..000000000
--- a/src/wayland/meta-wayland-text-input.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 002ff16f7..000000000
--- a/src/wayland/meta-wayland-touch.c
+++ /dev/null
@@ -1,616 +0,0 @@
-/*
- * 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"
-
-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;
-};
-
-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 = clutter_event_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);
-}
-
-void
-meta_wayland_touch_update (MetaWaylandTouch *touch,
- const ClutterEvent *event)
-{
- 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;
-}
-
-static void
-handle_touch_begin (MetaWaylandTouch *touch,
- const ClutterEvent *event)
-{
- 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;
-}
-
-static void
-handle_touch_update (MetaWaylandTouch *touch,
- const ClutterEvent *event)
-{
- 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));
- }
-}
-
-static void
-handle_touch_end (MetaWaylandTouch *touch,
- const ClutterEvent *event)
-{
- 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);
-}
-
-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 gboolean
-queue_frame_event_cb (MetaWaylandTouch *touch)
-{
- touch_send_frame_event (touch);
- touch->queued_frame_id = 0;
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-send_or_queue_frame_event (MetaWaylandTouch *touch)
-{
- if (clutter_events_pending ())
- {
- if (touch->queued_frame_id == 0)
- {
- touch->queued_frame_id =
- g_idle_add_full (CLUTTER_PRIORITY_EVENTS + 1,
- (GSourceFunc) queue_frame_event_cb,
- touch, NULL);
- }
- }
- else
- {
- /* There's no more events */
- g_clear_handle_id (&touch->queued_frame_id, g_source_remove);
- 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;
-
- case CLUTTER_TOUCH_CANCEL:
- meta_wayland_touch_cancel (touch);
- break;
-
- default:
- return FALSE;
- }
-
- send_or_queue_frame_event (touch);
- 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,
-};
-
-static void
-touch_info_free (MetaWaylandTouchInfo *touch_info)
-{
- touch_surface_decrement_touch (touch_info->touch_surface);
- g_free (touch_info);
-}
-
-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);
-}
-
-void
-meta_wayland_touch_enable (MetaWaylandTouch *touch)
-{
- 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);
-
- wl_list_init (&touch->resource_list);
-}
-
-void
-meta_wayland_touch_disable (MetaWaylandTouch *touch)
-{
- 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
deleted file mode 100644
index 304d8227e..000000000
--- a/src/wayland/meta-wayland-touch.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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;
-
- guint queued_frame_id;
- GHashTable *touch_surfaces; /* HT of MetaWaylandSurface->MetaWaylandTouchSurface */
- GHashTable *touches; /* HT of sequence->MetaWaylandTouchInfo */
-};
-
-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
deleted file mode 100644
index aeb6f6178..000000000
--- a/src/wayland/meta-wayland-types.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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;
-
-typedef struct _MetaWaylandActivation MetaWaylandActivation;
-
-#endif
diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h
deleted file mode 100644
index 05dd937b2..000000000
--- a/src/wayland/meta-wayland-versions.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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 4
-#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
-#define META_GTK_PRIMARY_SELECTION_VERSION 1
-#define META_ZWP_PRIMARY_SELECTION_V1_VERSION 1
-#define META_WP_PRESENTATION_VERSION 1
-#define META_XDG_ACTIVATION_V1_VERSION 1
-
-#endif
diff --git a/src/wayland/meta-wayland-viewporter.c b/src/wayland/meta-wayland-viewporter.c
deleted file mode 100644
index 619f3177c..000000000
--- a/src/wayland/meta-wayland-viewporter.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 8cc099b11..000000000
--- a/src/wayland/meta-wayland-viewporter.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 6a91a7141..000000000
--- a/src/wayland/meta-wayland-window-configuration.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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;
-
-static gboolean
-is_window_size_fixed (MetaWindow *window)
-{
- if (meta_window_is_fullscreen (window))
- return TRUE;
-
- if (meta_window_get_maximized (window) |
- (META_MAXIMIZE_VERTICAL | META_MAXIMIZE_VERTICAL))
- return TRUE;
-
- if (meta_window_get_tile_mode (window) != META_TILE_NONE)
- return TRUE;
-
- return FALSE;
-}
-
-MetaWaylandWindowConfiguration *
-meta_wayland_window_configuration_new (MetaWindow *window,
- 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,
-
- .scale = scale,
- .gravity = gravity,
- .flags = flags,
- };
-
- if (flags & META_MOVE_RESIZE_MOVE_ACTION ||
- window->rect.x != x ||
- window->rect.y != y)
- {
- configuration->has_position = TRUE;
- configuration->x = x;
- configuration->y = y;
- }
-
- if (flags & META_MOVE_RESIZE_RESIZE_ACTION ||
- is_window_size_fixed (window) ||
- window->rect.width != width ||
- window->rect.height != height)
- {
- configuration->has_size = TRUE;
- configuration->width = width;
- configuration->height = height;
- }
-
- 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
deleted file mode 100644
index b3211d1ad..000000000
--- a/src/wayland/meta-wayland-window-configuration.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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 (MetaWindow *window,
- 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
deleted file mode 100644
index 964c185b2..000000000
--- a/src/wayland/meta-wayland-wl-shell.c
+++ /dev/null
@@ -1,777 +0,0 @@
-/* -*- 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;
-
- 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
deleted file mode 100644
index 4a62d8a72..000000000
--- a/src/wayland/meta-wayland-wl-shell.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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
deleted file mode 100644
index eb480b996..000000000
--- a/src/wayland/meta-wayland-xdg-foreign.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/* -*- 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/wayland/meta-wayland-xdg-foreign.h b/src/wayland/meta-wayland-xdg-foreign.h
deleted file mode 100644
index 5542a301e..000000000
--- a/src/wayland/meta-wayland-xdg-foreign.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- 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_FOREIGN_H
-#define META_WAYLAND_FOREIGN_H
-
-#include <glib.h>
-
-#include "wayland/meta-wayland-types.h"
-
-gboolean meta_wayland_xdg_foreign_init (MetaWaylandCompositor *compositor);
-
-#endif /* META_WAYLAND_FOREIGN_H */
diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c
deleted file mode 100644
index c5f0d0b91..000000000
--- a/src/wayland/meta-wayland-xdg-shell.c
+++ /dev/null
@@ -1,2437 +0,0 @@
-/* -*- 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 (!window->has_resize_func)
- 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);
-
- 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 (!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;
-
- if (width == 0 || height == 0)
- {
- g_warning ("Invalid geometry %dx%d+%d+%d set on xdg_surface@%d. Ignoring for "
- "now, but this will result in client termination in the future.",
- width, height, x, y,
- wl_resource_get_id (resource));
- return;
- }
-
- 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);
- if (priv->geometry.width == 0 || priv->geometry.height == 0)
- {
- g_warning ("Invalid window geometry for xdg_surface@%d. Ignoring "
- "for now, but this will result in client termination "
- "in the future.",
- wl_resource_get_id (priv->resource));
- return;
- }
-
- 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
deleted file mode 100644
index f90e29bea..000000000
--- a/src/wayland/meta-wayland-xdg-shell.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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
deleted file mode 100644
index e2832bbc4..000000000
--- a/src/wayland/meta-wayland.c
+++ /dev/null
@@ -1,741 +0,0 @@
-/*
- * 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 "cogl/cogl-egl.h"
-#include "compositor/meta-surface-actor-wayland.h"
-#include "core/meta-context-private.h"
-#include "wayland/meta-wayland-activation.h"
-#include "wayland/meta-wayland-buffer.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-presentation-time-private.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;
- MetaContext *context;
- MetaWaylandCompositor *wayland_compositor;
-
- backend = meta_get_backend ();
- context = meta_backend_get_context (backend);
- wayland_compositor = meta_context_get_wayland_compositor (context);
- 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);
-}
-
-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);
-}
-
-static void
-on_after_update (ClutterStage *stage,
- ClutterStageView *stage_view,
- 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;
- ClutterStageView *surface_primary_view;
-
- l = l->next;
-
- actor = meta_wayland_surface_get_actor (surface);
- if (!actor)
- continue;
-
- surface_primary_view =
- meta_surface_actor_wayland_get_current_primary_view (actor, stage);
- if (stage_view != surface_primary_view)
- 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);
- }
-}
-
-static MetaWaylandOutput *
-get_output_for_stage_view (MetaWaylandCompositor *compositor,
- ClutterStageView *stage_view)
-{
- MetaCrtc *crtc;
- MetaOutput *output;
- MetaMonitor *monitor;
- MetaLogicalMonitor *logical_monitor;
-
- crtc = meta_renderer_view_get_crtc (META_RENDERER_VIEW (stage_view));
-
- /*
- * All outputs occupy the same region of the screen, as their contents are
- * the same, so pick the first one.
- */
- output = meta_crtc_get_outputs (crtc)->data;
-
- monitor = meta_output_get_monitor (output);
- logical_monitor = meta_monitor_get_logical_monitor (monitor);
- return g_hash_table_lookup (compositor->outputs, &logical_monitor->winsys_id);
-}
-
-static void
-on_presented (ClutterStage *stage,
- ClutterStageView *stage_view,
- ClutterFrameInfo *frame_info,
- MetaWaylandCompositor *compositor)
-{
- MetaWaylandPresentationFeedback *feedback, *next;
- struct wl_list *feedbacks;
- MetaWaylandOutput *output;
-
- feedbacks =
- meta_wayland_presentation_time_ensure_feedbacks (&compositor->presentation_time,
- stage_view);
-
- output = get_output_for_stage_view (compositor, stage_view);
-
- wl_list_for_each_safe (feedback, next, feedbacks, link)
- {
- meta_wayland_presentation_feedback_present (feedback,
- frame_info,
- output);
- }
-}
-
-/**
- * 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);
-}
-
-void
-meta_wayland_compositor_add_presentation_feedback_surface (MetaWaylandCompositor *compositor,
- MetaWaylandSurface *surface)
-{
- if (g_list_find (compositor->presentation_time.feedback_surfaces, surface))
- return;
-
- compositor->presentation_time.feedback_surfaces =
- g_list_prepend (compositor->presentation_time.feedback_surfaces, surface);
-}
-
-void
-meta_wayland_compositor_remove_presentation_feedback_surface (MetaWaylandCompositor *compositor,
- MetaWaylandSurface *surface)
-{
- compositor->presentation_time.feedback_surfaces =
- g_list_remove (compositor->presentation_time.feedback_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",
- 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);
-}
-
-void
-meta_wayland_compositor_prepare_shutdown (MetaWaylandCompositor *compositor)
-{
- meta_xwayland_shutdown (&compositor->xwayland_manager);
-
- if (compositor->wayland_display)
- wl_display_destroy_clients (compositor->wayland_display);
-}
-
-static void
-meta_wayland_compositor_finalize (GObject *object)
-{
- MetaWaylandCompositor *compositor = META_WAYLAND_COMPOSITOR (object);
-
- g_clear_pointer (&compositor->seat, meta_wayland_seat_free);
-
- g_clear_pointer (&compositor->display_name, g_free);
- g_clear_pointer (&compositor->wayland_display, wl_display_destroy);
-
- G_OBJECT_CLASS (meta_wayland_compositor_parent_class)->finalize (object);
-}
-
-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");
-}
-
-static void
-meta_wayland_compositor_class_init (MetaWaylandCompositorClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = meta_wayland_compositor_finalize;
-}
-
-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;
-}
-
-static void
-meta_wayland_init_egl (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_autoptr (GError) error = NULL;
-
- if (!meta_egl_has_extensions (egl, egl_display, NULL,
- "EGL_WL_bind_wayland_display",
- NULL))
- {
- meta_topic (META_DEBUG_WAYLAND,
- "Not binding Wayland display, missing extension");
- return;
- }
-
- meta_topic (META_DEBUG_WAYLAND,
- "Binding Wayland EGL display");
-
- if (!meta_egl_bind_wayland_display (egl,
- egl_display,
- compositor->wayland_display,
- &error))
- g_warning ("Failed to bind Wayland display: %s", error->message);
-}
-
-MetaWaylandCompositor *
-meta_wayland_compositor_new (MetaContext *context)
-{
- MetaBackend *backend = meta_context_get_backend (context);
- ClutterActor *stage = meta_backend_get_stage (backend);
- MetaWaylandCompositor *compositor;
- GSource *wayland_event_source;
- MetaX11DisplayPolicy x11_display_policy;
-
- compositor = g_object_new (META_TYPE_WAYLAND_COMPOSITOR, NULL);
- compositor->context = context;
-
- 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);
-
- g_signal_connect (stage, "after-update",
- G_CALLBACK (on_after_update), compositor);
- g_signal_connect (stage, "presented",
- G_CALLBACK (on_presented), compositor);
-
- 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");
-
- meta_wayland_init_egl (compositor);
- meta_wayland_init_shm (compositor);
-
- 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);
- meta_wayland_init_presentation_time (compositor);
- meta_wayland_activation_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
-
- x11_display_policy =
- meta_context_get_x11_display_policy (compositor->context);
- if (x11_display_policy != META_X11_DISPLAY_POLICY_DISABLED)
- {
- g_autoptr (GError) error = NULL;
-
- if (!meta_xwayland_init (&compositor->xwayland_manager,
- compositor,
- compositor->wayland_display,
- &error))
- g_error ("Failed to start X Wayland: %s", error->message);
- }
-
- 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);
- }
-
- g_message ("Using Wayland display name '%s'", compositor->display_name);
-
- if (x11_display_policy != META_X11_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));
-
- return compositor;
-}
-
-const char *
-meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor)
-{
- return compositor->display_name;
-}
-
-const char *
-meta_wayland_get_public_xwayland_display_name (MetaWaylandCompositor *compositor)
-{
- return compositor->xwayland_manager.public_connection.name;
-}
-
-const char *
-meta_wayland_get_private_xwayland_display_name (MetaWaylandCompositor *compositor)
-{
- return compositor->xwayland_manager.private_connection.name;
-}
-
-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
deleted file mode 100644
index 387e98b52..000000000
--- a/src/wayland/meta-wayland.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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/meta-context-private.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);
-
-MetaWaylandCompositor * meta_wayland_compositor_new (MetaContext *context);
-
-void meta_wayland_compositor_prepare_shutdown (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_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);
-
-void meta_wayland_compositor_add_presentation_feedback_surface (MetaWaylandCompositor *compositor,
- MetaWaylandSurface *surface);
-
-void meta_wayland_compositor_remove_presentation_feedback_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_public_xwayland_display_name (MetaWaylandCompositor *compositor);
-
-const char *meta_wayland_get_private_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
deleted file mode 100644
index 12e9567d9..000000000
--- a/src/wayland/meta-window-wayland.c
+++ /dev/null
@@ -1,1195 +0,0 @@
-/* -*- 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;
-
- gboolean has_last_sent_configuration;
- 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;
-
- g_return_if_fail (wl_window->has_last_sent_configuration);
-
- configuration =
- meta_wayland_window_configuration_new (window,
- 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);
-
- 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 (!meta_wayland_surface_get_buffer (window->surface) &&
- !META_WINDOW_MAXIMIZED (window) &&
- window->tile_mode == META_TILE_NONE &&
- !meta_window_is_fullscreen (window))
- return;
-
- configuration =
- meta_wayland_window_configuration_new (window,
- 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->has_last_sent_configuration = 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 pid_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 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);
-
- rect = (MetaRectangle) {
- .x = window->rect.x,
- .y = window->rect.y,
- .width = new_geom.width,
- .height = new_geom.height
- };
-
- 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 if (acked_configuration->has_position)
- {
- calculate_offset (acked_configuration, &new_geom, &rect);
- }
- }
- }
- else
- {
- if (acked_configuration && acked_configuration->has_position)
- calculate_offset (acked_configuration, &new_geom, &rect);
- }
-
- rect.x += dx;
- rect.y += dy;
-
- 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;
- }
-
- 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",
- 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",
- 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
deleted file mode 100644
index db152daaa..000000000
--- a/src/wayland/meta-window-wayland.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 54ccc91fe..000000000
--- a/src/wayland/meta-window-xwayland.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * 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 <X11/Xatom.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;
- MetaFrame *frame;
- Window xwin;
- guint32 property[1];
-
- if (!x11_display)
- return;
-
- 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 (x11_display->xdisplay, xwin,
- x11_display->atom__XWAYLAND_ALLOW_COMMITS,
- XA_CARDINAL, 32, PropModeReplace,
- (guchar*) &property, 1);
- meta_x11_error_trap_pop (x11_display);
- XFlush (x11_display->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
deleted file mode 100644
index 5ea6041d4..000000000
--- a/src/wayland/meta-window-xwayland.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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
deleted file mode 100644
index b55b4f8d3..000000000
--- a/src/wayland/meta-xwayland-dnd-private.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- 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
deleted file mode 100644
index a3148ed95..000000000
--- a/src/wayland/meta-xwayland-dnd.c
+++ /dev/null
@@ -1,991 +0,0 @@
-/*
- * 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", 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_seat_query_state (clutter_input_device_get_seat (seat->pointer->device),
- seat->pointer->device, NULL, &pos, NULL);
- 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_seat_query_state (clutter_input_device_get_seat (seat->pointer->device),
- seat->pointer->device, NULL, &pos, NULL);
- 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_new0 (MetaXWaylandDnd, 1);
-
- 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 (MetaXWaylandManager *manager,
- Display *xdisplay)
-{
- MetaXWaylandDnd *dnd = manager->dnd;
-
- g_assert (dnd != NULL);
-
- XDestroyWindow (xdisplay, dnd->dnd_window);
- dnd->dnd_window = None;
-
- g_free (dnd);
- manager->dnd = NULL;
-}
diff --git a/src/wayland/meta-xwayland-grab-keyboard.c b/src/wayland/meta-xwayland-grab-keyboard.c
deleted file mode 100644
index 66c80d809..000000000
--- a/src/wayland/meta-xwayland-grab-keyboard.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * 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)
-{
- const char *class;
- const char *name;
- guint i;
-
- if (window->res_class)
- class = window->res_class;
- else
- class = "";
-
- if (window->res_name)
- name = window->res_name;
- else
- name = "";
-
- for (i = 0; pattern_array && i < pattern_array->len; i++)
- {
- GPatternSpec *pattern = (GPatternSpec *) g_ptr_array_index (pattern_array, i);
-
- if (g_pattern_match_string (pattern, class) ||
- g_pattern_match_string (pattern, name))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-meta_xwayland_grab_is_granted (MetaWindow *window)
-{
- MetaBackend *backend;
- MetaSettings *settings;
- GPtrArray *allow_list;
- GPtrArray *deny_list;
- gboolean may_grab;
-
- backend = meta_get_backend ();
- settings = meta_backend_get_settings (backend);
-
- /* Check whether the window is in the deny list */
- meta_settings_get_xwayland_grab_patterns (settings, &allow_list, &deny_list);
-
- if (deny_list && application_is_in_pattern_array (window, deny_list))
- return FALSE;
-
- /* Check if we are dealing with good citizen Xwayland client allowing itself. */
- g_object_get (G_OBJECT (window), "xwayland-may-grab-keyboard", &may_grab, NULL);
- if (may_grab)
- return TRUE;
-
- /* Last resort, is it in the grant list. */
- if (allow_list && application_is_in_pattern_array (window, allow_list))
- 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
deleted file mode 100644
index 597854af5..000000000
--- a/src/wayland/meta-xwayland-grab-keyboard.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 51fba035e..000000000
--- a/src/wayland/meta-xwayland-private.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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,
- MetaWaylandCompositor *compositor,
- struct wl_display *display,
- GError **error);
-
-void
-meta_xwayland_complete_init (MetaDisplay *display,
- Display *xdisplay);
-
-void
-meta_xwayland_shutdown (MetaXWaylandManager *manager);
-
-gboolean
-meta_xwayland_handle_xevent (XEvent *event);
-
-/* wl_data_device/X11 selection interoperation */
-void meta_xwayland_init_dnd (Display *xdisplay);
-void meta_xwayland_shutdown_dnd (MetaXWaylandManager *manager,
- 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
deleted file mode 100644
index 4697c9d21..000000000
--- a/src/wayland/meta-xwayland-surface.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * 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;
-};
-
-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);
- MetaSurfaceActor *surface_actor;
-
- if (!xwayland_surface->window)
- return;
-
- g_clear_signal_handler (&xwayland_surface->unmanaging_handler_id,
- xwayland_surface->window);
-
- 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);
-}
-
-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);
-
- 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
deleted file mode 100644
index 4bf305039..000000000
--- a/src/wayland/meta-xwayland-surface.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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
deleted file mode 100644
index dce4facd0..000000000
--- a/src/wayland/meta-xwayland.c
+++ /dev/null
@@ -1,1417 +0,0 @@
-/* -*- 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/stat.h>
-#include <sys/types.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/extensions/Xrandr.h>
-#include <X11/Xauth.h>
-#include <X11/Xlib-xcb.h>
-
-#include <xcb/res.h>
-
-#include "backends/meta-monitor-manager-private.h"
-#include "backends/meta-settings-private.h"
-#include "meta/main.h"
-#include "meta/meta-backend.h"
-#include "wayland/meta-xwayland-surface.h"
-#include "x11/meta-x11-display-private.h"
-
-#ifdef HAVE_XWAYLAND_LISTENFD
-#define XWAYLAND_LISTENFD "-listenfd"
-#else
-#define XWAYLAND_LISTENFD "-listen"
-#endif
-
-#define X11_TMP_UNIX_DIR "/tmp/.X11-unix"
-#define X11_TMP_UNIX_PATH "/tmp/.X11-unix/X"
-
-static int display_number_override = -1;
-
-static void meta_xwayland_stop_xserver (MetaXWaylandManager *manager);
-
-static void
-meta_xwayland_set_primary_output (Display *xdisplay);
-
-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 char *
-meta_xwayland_get_exe_from_proc_entry (const char *proc_entry)
-{
- g_autofree char *exepath;
- char *executable;
- char *p;
-
- exepath = g_file_read_link (proc_entry, NULL);
- if (!exepath)
- return NULL;
-
- p = strrchr (exepath, G_DIR_SEPARATOR);
- if (p)
- executable = g_strdup (++p);
- else
- executable = g_strdup (exepath);
-
- return executable;
-}
-
-static char *
-meta_xwayland_get_exe_from_pid (uint32_t pid)
-{
- g_autofree char *proc_entry;
- char *executable;
-
- proc_entry = g_strdup_printf ("/proc/%i/exe", pid);
- executable = meta_xwayland_get_exe_from_proc_entry (proc_entry);
-
- return executable;
-}
-
-static char *
-meta_xwayland_get_self_exe (void)
-{
- g_autofree char *proc_entry;
- char *executable;
-
- proc_entry = g_strdup_printf ("/proc/self/exe");
- executable = meta_xwayland_get_exe_from_proc_entry (proc_entry);
-
- return executable;
-}
-
-static gboolean
-can_xwayland_ignore_exe (const char *executable,
- const char *self)
-{
- char ** ignore_executables;
- gboolean ret;
-
- if (!g_strcmp0 (executable, self))
- return TRUE;
-
- ignore_executables = g_strsplit_set (XWAYLAND_IGNORE_EXECUTABLES, ",", -1);
- ret = g_strv_contains ((const char * const *) ignore_executables, executable);
- g_strfreev (ignore_executables);
-
- return ret;
-}
-
-static uint32_t
-meta_xwayland_get_client_pid (xcb_connection_t *xcb,
- uint32_t client)
-{
- 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;
- uint32_t pid = 0, *value;
-
- spec.client = client;
- 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;
-
- 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 gboolean
-can_terminate_xwayland (Display *xdisplay)
-{
- xcb_connection_t *xcb = XGetXCBConnection (xdisplay);
- xcb_res_query_clients_cookie_t cookie;
- xcb_res_query_clients_reply_t *reply = NULL;
- xcb_res_client_iterator_t it;
- gboolean can_terminate;
- char *self;
-
- cookie = xcb_res_query_clients (xcb);
- reply = xcb_res_query_clients_reply (xcb, cookie, NULL);
-
- /* Could not get the list of X11 clients, better not terminate Xwayland */
- if (reply == NULL)
- return FALSE;
-
- can_terminate = TRUE;
- self = meta_xwayland_get_self_exe ();
- for (it = xcb_res_query_clients_clients_iterator (reply);
- it.rem && can_terminate;
- xcb_res_client_next (&it))
- {
- uint32_t pid;
- char *executable;
-
- pid = meta_xwayland_get_client_pid (xcb, it.data->resource_base);
- if (pid == 0)
- {
- /* Unknown PID, don't risk terminating it */
- can_terminate = FALSE;
- break;
- }
-
- executable = meta_xwayland_get_exe_from_pid (pid);
- can_terminate = can_xwayland_ignore_exe (executable, self);
- g_free (executable);
- }
- free (reply);
-
- return can_terminate;
-}
-
-static gboolean
-try_display (int display,
- char **filename_out,
- int *fd_out,
- GError **error)
-{
- 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;
- int read_bytes;
-
- fd = open (filename, O_CLOEXEC, O_RDONLY);
- if (fd < 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to open lock file %s: %s",
- filename, g_strerror (errno));
- goto out;
- }
-
- read_bytes = read (fd, pid, 11);
- if (read_bytes != 11)
- {
- if (read_bytes < 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to read from lock file %s: %s",
- filename, g_strerror (errno));
- }
- else
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT,
- "Only read %d bytes (needed 11) from lock file: %s",
- read_bytes, filename);
- }
- goto out;
- }
- close (fd);
- fd = -1;
-
- pid[10] = '\0';
- other = strtol (pid, &end, 0);
- if (end != pid + 10)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
- "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_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to unlink stale lock file %s: %s",
- filename, g_strerror (errno));
- goto out;
- }
-
- goto again;
- }
-
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Lock file %s is already occupied", filename);
- goto out;
- }
- else if (fd < 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to create lock file %s: %s",
- filename, g_strerror (errno));
- 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,
- GError **error)
-{
- char *filename;
- int fd;
- char pid[12];
- int size;
- int number_of_tries = 0;
- g_autoptr (GError) local_error = NULL;
-
- while (!try_display (display, &filename, &fd, &local_error))
- {
- meta_topic (META_DEBUG_WAYLAND,
- "Failed to lock X11 display: %s", local_error->message);
- g_clear_error (&local_error);
- 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)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Gave up after trying to lock different "
- "X11 display lock file 50 times");
- 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 ());
- errno = 0;
- if (size != 11 || write (fd, pid, 11) != 11)
- {
- if (errno != 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to write pid to lock file %s: %s",
- filename, g_strerror (errno));
- }
- else
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Failed to write pid to lock file %s", filename);
- }
-
- unlink (filename);
- close (fd);
- g_free (filename);
- return NULL;
- }
-
- close (fd);
-
- *display_out = display;
- return filename;
-}
-
-static int
-bind_to_abstract_socket (int display,
- GError **error)
-{
- struct sockaddr_un addr;
- socklen_t size, name_size;
- int fd;
-
- fd = socket (PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
- if (fd < 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to create socket: %s", g_strerror (errno));
- return -1;
- }
-
- addr.sun_family = AF_LOCAL;
- name_size = snprintf (addr.sun_path, sizeof addr.sun_path,
- "%c%s%d", 0, X11_TMP_UNIX_PATH, display);
- size = offsetof (struct sockaddr_un, sun_path) + name_size;
- if (bind (fd, (struct sockaddr *) &addr, size) < 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to bind to %s: %s",
- addr.sun_path + 1, g_strerror (errno));
- close (fd);
- return -1;
- }
-
- if (listen (fd, 1) < 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to listen to %s: %s",
- addr.sun_path + 1, g_strerror (errno));
- close (fd);
- return -1;
- }
-
- return fd;
-}
-
-static int
-bind_to_unix_socket (int display,
- GError **error)
-{
- struct sockaddr_un addr;
- socklen_t size, name_size;
- int fd;
-
- fd = socket (PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
- if (fd < 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to create socket: %s", g_strerror (errno));
- return -1;
- }
-
- addr.sun_family = AF_LOCAL;
- name_size = snprintf (addr.sun_path, sizeof addr.sun_path,
- "%s%d", X11_TMP_UNIX_PATH, display) + 1;
- size = offsetof (struct sockaddr_un, sun_path) + name_size;
- unlink (addr.sun_path);
- if (bind (fd, (struct sockaddr *) &addr, size) < 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to bind to %s: %s",
- addr.sun_path, g_strerror (errno));
- close (fd);
- return -1;
- }
-
- if (listen (fd, 1) < 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to listen to %s: %s",
- addr.sun_path, g_strerror (errno));
- unlink (addr.sun_path);
- close (fd);
- return -1;
- }
-
- return fd;
-}
-
-static void
-xserver_died (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
- GSubprocess *proc = G_SUBPROCESS (source);
- MetaDisplay *display = meta_get_display ();
- g_autoptr (GError) error = NULL;
- MetaX11DisplayPolicy x11_display_policy;
-
- x11_display_policy =
- meta_context_get_x11_display_policy (compositor->context);
- 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 (x11_display_policy == META_X11_DISPLAY_POLICY_MANDATORY)
- g_warning ("X Wayland crashed; exiting");
- else
- g_warning ("X Wayland crashed; attempting to recover");
- }
-
- if (x11_display_policy == META_X11_DISPLAY_POLICY_MANDATORY)
- {
- meta_exit (META_EXIT_ERROR);
- }
- else if (x11_display_policy == META_X11_DISPLAY_POLICY_ON_DEMAND)
- {
- g_autoptr (GError) error = NULL;
-
- if (display->x11_display)
- meta_display_shutdown_x11 (display);
-
- if (!meta_xwayland_init (&compositor->xwayland_manager,
- compositor,
- compositor->wayland_display,
- &error))
- g_warning ("Failed to init X sockets: %s", error->message);
- }
-}
-
-static void
-meta_xwayland_terminate (MetaXWaylandManager *manager)
-{
- MetaDisplay *display = meta_get_display ();
-
- g_clear_handle_id (&manager->xserver_grace_period_id, g_source_remove);
- meta_display_shutdown_x11 (display);
- meta_xwayland_stop_xserver (manager);
-}
-
-static gboolean
-shutdown_xwayland_cb (gpointer data)
-{
- MetaXWaylandManager *manager = data;
- MetaDisplay *display = meta_get_display ();
- MetaBackend *backend = meta_get_backend ();
-
- if (!meta_settings_is_experimental_feature_enabled (meta_backend_get_settings (backend),
- META_EXPERIMENTAL_FEATURE_AUTOCLOSE_XWAYLAND))
- return G_SOURCE_REMOVE;
-
- if (display->x11_display &&
- !can_terminate_xwayland (display->x11_display->xdisplay))
- return G_SOURCE_CONTINUE;
-
- meta_verbose ("Shutting down Xwayland");
- manager->xserver_grace_period_id = 0;
- meta_xwayland_terminate (manager);
- return G_SOURCE_REMOVE;
-}
-
-static int
-x_io_error (Display *display)
-{
- MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
- MetaX11DisplayPolicy x11_display_policy;
-
- g_warning ("Connection to xwayland lost");
-
- x11_display_policy =
- meta_context_get_x11_display_policy (compositor->context);
- if (x11_display_policy == META_X11_DISPLAY_POLICY_MANDATORY)
- meta_exit (META_EXIT_ERROR);
-
- return 0;
-}
-
-static int
-x_io_error_noop (Display *display)
-{
- return 0;
-}
-
-#ifdef HAVE_XSETIOERROREXITHANDLER
-static void
-x_io_error_exit (Display *display,
- void *data)
-{
- MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
- MetaXWaylandManager *manager = &compositor->xwayland_manager;
-
- g_warning ("Xwayland just died, attempting to recover");
- manager->xserver_grace_period_id =
- g_idle_add (shutdown_xwayland_cb, manager);
-}
-
-static void
-x_io_error_exit_noop (Display *display,
- void *data)
-{
-}
-#endif
-
-void
-meta_xwayland_override_display_number (int number)
-{
- display_number_override = number;
-}
-
-static gboolean
-ensure_x11_unix_perms (GError **error)
-{
- struct stat buf;
-
- if (lstat (X11_TMP_UNIX_DIR, &buf) != 0)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to check permissions on directory \"%s\": %s",
- X11_TMP_UNIX_DIR, g_strerror (errno));
- return FALSE;
- }
-
- /* If the directory already exists, it should belong to root or ourselves ... */
- if (buf.st_uid != 0 && buf.st_uid != getuid ())
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
- "Wrong ownership for directory \"%s\"",
- X11_TMP_UNIX_DIR);
- return FALSE;
- }
-
- /* ... be writable ... */
- if ((buf.st_mode & 0022) != 0022)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
- "Directory \"%s\" is not writable",
- X11_TMP_UNIX_DIR);
- return FALSE;
- }
-
- /* ... and have the sticky bit set */
- if ((buf.st_mode & 01000) != 01000)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
- "Directory \"%s\" is missing the sticky bit",
- X11_TMP_UNIX_DIR);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-ensure_x11_unix_dir (GError **error)
-{
- if (mkdir (X11_TMP_UNIX_DIR, 01777) != 0)
- {
- if (errno == EEXIST)
- return ensure_x11_unix_perms (error);
-
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to create directory \"%s\": %s",
- X11_TMP_UNIX_DIR, g_strerror (errno));
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-open_display_sockets (MetaXWaylandManager *manager,
- int display_index,
- int *abstract_fd_out,
- int *unix_fd_out,
- GError **error)
-{
- int abstract_fd, unix_fd;
-
- abstract_fd = bind_to_abstract_socket (display_index, error);
- if (abstract_fd < 0)
- return FALSE;
-
- unix_fd = bind_to_unix_socket (display_index, error);
- if (unix_fd < 0)
- {
- 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,
- GError **error)
-{
- int number_of_tries = 0;
- char *lock_file = NULL;
-
- if (!ensure_x11_unix_dir (error))
- return FALSE;
-
- do
- {
- g_autoptr (GError) local_error = NULL;
-
- lock_file = create_lock_file (*display, display, &local_error);
- if (!lock_file)
- {
- g_prefix_error (&local_error, "Failed to create an X lock file: ");
- g_propagate_error (error, g_steal_pointer (&local_error));
- return FALSE;
- }
-
- if (!open_display_sockets (manager, *display,
- &connection->abstract_fd,
- &connection->unix_fd,
- &local_error))
- {
- unlink (lock_file);
-
- if (++number_of_tries >= 50)
- {
- g_prefix_error (&local_error, "Failed to bind X11 socket: ");
- g_propagate_error (error, g_steal_pointer (&local_error));
- return FALSE;
- }
-
- (*display)++;
- continue;
- }
-
- 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,
- GError **error)
-{
- 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_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "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_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to open Xauthority file: %s", g_strerror (errno));
- return FALSE;
- }
-
- fp = fdopen (fd, "w+");
- if (!fp)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Failed to open Xauthority stream: %s", g_strerror (errno));
- close (fd);
- return FALSE;
- }
-
- if (!XauWriteAuth (fp, &auth_entry))
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Error writing to Xauthority file: %s", g_strerror (errno));
- return FALSE;
- }
-
- auth_entry.family = FamilyWild;
- if (!XauWriteAuth (fp, &auth_entry))
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "Error writing to Xauthority file: %s", g_strerror (errno));
- return FALSE;
- }
-
- if (fflush (fp) == EOF)
- {
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
- "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", 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, !!(condition & G_IO_IN));
- g_object_unref (task);
-
- return G_SOURCE_REMOVE;
-}
-
-static int
-steal_fd (int *fd_ptr)
-{
- int fd = *fd_ptr;
- *fd_ptr = -1;
- return fd;
-}
-
-void
-meta_xwayland_start_xserver (MetaXWaylandManager *manager,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- struct {
- const char *extension_name;
- MetaXwaylandExtension disable_extension;
- } x11_extension_names[] = {
- { "SECURITY", META_XWAYLAND_EXTENSION_SECURITY },
- { "XTEST", META_XWAYLAND_EXTENSION_XTEST },
- };
-
- int xwayland_client_fd[2];
- int displayfd[2];
- g_autoptr(GSubprocessLauncher) launcher = NULL;
- GSubprocessFlags flags;
- GError *error = NULL;
- g_autoptr (GTask) task = NULL;
- MetaBackend *backend;
- MetaSettings *settings;
- const char *args[32];
- int xwayland_disable_extensions;
- int i, j;
-
- 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)
- {
- close (xwayland_client_fd[0]);
- close (xwayland_client_fd[1]);
-
- 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;
- }
-
- backend = meta_get_backend ();
- settings = meta_backend_get_settings (backend);
- xwayland_disable_extensions =
- meta_settings_get_xwayland_disable_extensions (settings);
-
- launcher = g_subprocess_launcher_new (flags);
-
- g_subprocess_launcher_take_fd (launcher,
- steal_fd (&xwayland_client_fd[1]), 3);
- g_subprocess_launcher_take_fd (launcher,
- steal_fd (&manager->public_connection.abstract_fd), 4);
- g_subprocess_launcher_take_fd (launcher,
- steal_fd (&manager->public_connection.unix_fd), 5);
- g_subprocess_launcher_take_fd (launcher,
- steal_fd (&displayfd[1]), 6);
- g_subprocess_launcher_take_fd (launcher,
- steal_fd (&manager->private_connection.abstract_fd), 7);
-
- g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE);
-
- i = 0;
- args[i++] = XWAYLAND_PATH;
- args[i++] = manager->public_connection.name;
- args[i++] = "-rootless";
- args[i++] = "-noreset";
- args[i++] = "-accessx";
- args[i++] = "-core";
- args[i++] = "-auth";
- args[i++] = manager->auth_file;
- args[i++] = XWAYLAND_LISTENFD;
- args[i++] = "4";
- args[i++] = XWAYLAND_LISTENFD;
- args[i++] = "5";
- args[i++] = "-displayfd";
- args[i++] = "6";
-#ifdef HAVE_XWAYLAND_INITFD
- args[i++] = "-initfd";
- args[i++] = "7";
-#else
- args[i++] = XWAYLAND_LISTENFD;
- args[i++] = "7";
-#endif
- for (j = 0; j < G_N_ELEMENTS (x11_extension_names); j++)
- {
- /* Make sure we don't go past the array size - We need room for
- * 2 arguments, plus the last NULL terminator.
- */
- if (i + 3 > G_N_ELEMENTS (args))
- break;
-
- if (xwayland_disable_extensions & x11_extension_names[j].disable_extension)
- {
- args[i++] = "-extension";
- args[i++] = x11_extension_names[j].extension_name;
- }
- }
- /* Terminator */
- args[i++] = NULL;
-
- manager->proc = g_subprocess_launcher_spawnv (launcher, args, &error);
-
- if (!manager->proc)
- {
- close (displayfd[0]);
- close (xwayland_client_fd[0]);
-
- 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)
-{
- MetaXWaylandManager *manager = user_data;
- MetaDisplay *display = meta_get_display ();
-
- meta_display_init_x11 (display, NULL,
- (GAsyncReadyCallback) on_init_x11_cb, NULL);
-
- /* Stop watching both file descriptors */
- g_clear_handle_id (&manager->abstract_fd_watch_id, g_source_remove);
- g_clear_handle_id (&manager->unix_fd_watch_id, g_source_remove);
-
- 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_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,
- MetaWaylandCompositor *compositor,
- struct wl_display *wl_display,
- GError **error)
-{
- MetaContext *context = compositor->context;
- MetaX11DisplayPolicy policy;
- int display = 0;
-
- if (display_number_override != -1)
- display = display_number_override;
- else if (g_getenv ("RUNNING_UNDER_GDM"))
- display = 1024;
-
-
- if (!manager->public_connection.name)
- {
- if (!choose_xdisplay (manager, &manager->public_connection, &display, error))
- return FALSE;
-
- display++;
- if (!choose_xdisplay (manager, &manager->private_connection, &display, error))
- return FALSE;
-
- if (!prepare_auth_file (manager, error))
- return FALSE;
- }
- else
- {
- if (!open_display_sockets (manager,
- manager->public_connection.display_index,
- &manager->public_connection.abstract_fd,
- &manager->public_connection.unix_fd,
- error))
- return FALSE;
-
- if (!open_display_sockets (manager,
- manager->private_connection.display_index,
- &manager->private_connection.abstract_fd,
- &manager->private_connection.unix_fd,
- error))
- return FALSE;
- }
-
- g_message ("Using public X11 display %s, (using %s for managed services)",
- manager->public_connection.name,
- manager->private_connection.name);
-
- manager->wayland_display = wl_display;
- policy = meta_context_get_x11_display_policy (context);
-
- if (policy == META_X11_DISPLAY_POLICY_ON_DEMAND)
- {
- manager->abstract_fd_watch_id =
- g_unix_fd_add (manager->public_connection.abstract_fd, G_IO_IN,
- xdisplay_connection_activity_cb, manager);
- manager->unix_fd_watch_id =
- g_unix_fd_add (manager->public_connection.unix_fd, G_IO_IN,
- xdisplay_connection_activity_cb, manager);
- }
-
- return TRUE;
-}
-
-static void
-monitors_changed_cb (MetaMonitorManager *monitor_manager)
-{
- MetaX11Display *x11_display = meta_get_display ()->x11_display;
-
- meta_xwayland_set_primary_output (x11_display->xdisplay);
-}
-
-static void
-on_x11_display_closing (MetaDisplay *display,
- MetaXWaylandManager *manager)
-{
- Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
-
- meta_xwayland_shutdown_dnd (manager, xdisplay);
- g_signal_handlers_disconnect_by_func (meta_monitor_manager_get (),
- monitors_changed_cb,
- NULL);
- g_signal_handlers_disconnect_by_func (display,
- on_x11_display_closing,
- manager);
-}
-
-static void
-meta_xwayland_init_xrandr (MetaXWaylandManager *manager,
- Display *xdisplay)
-{
- MetaMonitorManager *monitor_manager = meta_monitor_manager_get ();
-
- manager->has_xrandr = XRRQueryExtension (xdisplay,
- &manager->rr_event_base,
- &manager->rr_error_base);
-
- if (!manager->has_xrandr)
- return;
-
- XRRSelectInput (xdisplay, DefaultRootWindow (xdisplay),
- RRCrtcChangeNotifyMask | RROutputChangeNotifyMask);
-
- g_signal_connect (monitor_manager, "monitors-changed",
- G_CALLBACK (monitors_changed_cb), NULL);
-
- meta_xwayland_set_primary_output (xdisplay);
-}
-
-/* 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;
- MetaX11DisplayPolicy x11_display_policy;
-
- /* 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);
-#ifdef HAVE_XSETIOERROREXITHANDLER
- XSetIOErrorExitHandler (xdisplay, x_io_error_exit, display);
-#endif
-
- g_signal_connect (display, "x11-display-closing",
- G_CALLBACK (on_x11_display_closing), manager);
- meta_xwayland_init_dnd (xdisplay);
- add_local_user_to_xhost (xdisplay);
- meta_xwayland_init_xrandr (manager, xdisplay);
-
- x11_display_policy =
- meta_context_get_x11_display_policy (compositor->context);
- if (x11_display_policy == META_X11_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)
-{
-#ifdef HAVE_XSETIOERROREXITHANDLER
- MetaDisplay *display = meta_get_display ();
- MetaX11Display *x11_display;
-#endif
- char path[256];
-
- g_cancellable_cancel (manager->xserver_died_cancellable);
-
- XSetIOErrorHandler (x_io_error_noop);
-#ifdef HAVE_XSETIOERROREXITHANDLER
- x11_display = display->x11_display;
- if (x11_display)
- {
- XSetIOErrorExitHandler (meta_x11_display_get_xdisplay (x11_display),
- x_io_error_exit_noop, NULL);
- }
-#endif
-
- meta_xwayland_terminate (manager);
-
- snprintf (path, sizeof path, "%s%d", X11_TMP_UNIX_PATH,
- manager->public_connection.display_index);
- unlink (path);
-
- snprintf (path, sizeof path, "%s%d", X11_TMP_UNIX_PATH,
- 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);
- }
-}
-
-static void
-meta_xwayland_set_primary_output (Display *xdisplay)
-{
- XRRScreenResources *resources;
- MetaMonitorManager *monitor_manager;
- MetaLogicalMonitor *primary_monitor;
- int i;
-
- monitor_manager = meta_monitor_manager_get ();
- primary_monitor =
- meta_monitor_manager_get_primary_logical_monitor (monitor_manager);
-
- if (!primary_monitor)
- return;
-
- resources = XRRGetScreenResourcesCurrent (xdisplay,
- DefaultRootWindow (xdisplay));
- if (!resources)
- return;
-
- for (i = 0; i < resources->noutput; i++)
- {
- RROutput output_id = resources->outputs[i];
- XRROutputInfo *xrandr_output;
- XRRCrtcInfo *crtc_info = NULL;
- MetaRectangle crtc_geometry;
-
- xrandr_output = XRRGetOutputInfo (xdisplay, resources, output_id);
- if (!xrandr_output)
- continue;
-
- if (xrandr_output->crtc)
- crtc_info = XRRGetCrtcInfo (xdisplay, resources, xrandr_output->crtc);
-
- XRRFreeOutputInfo (xrandr_output);
-
- if (!crtc_info)
- continue;
-
- crtc_geometry.x = crtc_info->x;
- crtc_geometry.y = crtc_info->y;
- crtc_geometry.width = crtc_info->width;
- crtc_geometry.height = crtc_info->height;
-
- XRRFreeCrtcInfo (crtc_info);
-
- if (meta_rectangle_equal (&crtc_geometry, &primary_monitor->rect))
- {
- XRRSetOutputPrimary (xdisplay, DefaultRootWindow (xdisplay),
- output_id);
- break;
- }
- }
-
- XRRFreeScreenResources (resources);
-}
-
-gboolean
-meta_xwayland_handle_xevent (XEvent *event)
-{
- MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
- MetaXWaylandManager *manager = &compositor->xwayland_manager;
-
- if (meta_xwayland_dnd_handle_event (event))
- return TRUE;
-
- if (manager->has_xrandr && event->type == manager->rr_event_base + RRNotify)
- {
- MetaX11Display *x11_display = meta_get_display ()->x11_display;
- meta_xwayland_set_primary_output (x11_display->xdisplay);
- return TRUE;
- }
-
- return FALSE;
-}
diff --git a/src/wayland/meta-xwayland.h b/src/wayland/meta-xwayland.h
deleted file mode 100644
index dac9c689f..000000000
--- a/src/wayland/meta-xwayland.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 02cab94fc..000000000
--- a/src/wayland/protocol/gtk-primary-selection.xml
+++ /dev/null
@@ -1,225 +0,0 @@
-<?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
deleted file mode 100644
index 1aab593c4..000000000
--- a/src/wayland/protocol/gtk-shell.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-<protocol name="gtk">
-
- <interface name="gtk_shell1" version="4">
- <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="4">
- <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>
-
- <!-- Version 4 additions -->
- <request name="release" type="destructor" since="4"/>
- </interface>
-
-</protocol>
diff --git a/src/wayland/protocol/gtk-text-input.xml b/src/wayland/protocol/gtk-text-input.xml
deleted file mode 100644
index a134a19f6..000000000
--- a/src/wayland/protocol/gtk-text-input.xml
+++ /dev/null
@@ -1,302 +0,0 @@
-<?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/x11/atomnames.h b/src/x11/atomnames.h
deleted file mode 100644
index 4b25b099a..000000000
--- a/src/x11/atomnames.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/* -*- 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
- * 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/>.
- */
-
-/*
- * \file atomnames.h A list of atom names.
- *
- * 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
- * again.
- *
- * If you also define EWMH_ATOMS_ONLY then you will only get _NET_WM_*
- * atoms rather than all of them.
- */
-
-#ifndef item
-#error "item(x) must be defined when you include atomnames.h"
-#endif
-
-#ifndef EWMH_ATOMS_ONLY
-
-item(WM_PROTOCOLS) /* MUST BE FIRST */
-item(WM_TAKE_FOCUS)
-item(WM_DELETE_WINDOW)
-item(WM_STATE)
-item(_MOTIF_WM_HINTS)
-item(WM_CHANGE_STATE)
-item(SM_CLIENT_ID)
-item(WM_CLIENT_LEADER)
-item(WM_WINDOW_ROLE)
-item(UTF8_STRING)
-item(WM_ICON_SIZE)
-item(_KWM_WIN_ICON)
-item(_MUTTER_HINTS)
-item(_GTK_THEME_VARIANT)
-item(_GTK_APPLICATION_ID)
-item(_GTK_UNIQUE_BUS_NAME)
-item(_GTK_APPLICATION_OBJECT_PATH)
-item(_GTK_WINDOW_OBJECT_PATH)
-item(_GTK_APP_MENU_OBJECT_PATH)
-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(_MUTTER_TIMESTAMP_PING)
-item(_MUTTER_FOCUS_SET)
-item(_MUTTER_SENTINEL)
-item(_MUTTER_VERSION)
-item(WM_CLIENT_MACHINE)
-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
- * lists of which _NET_WM hints we support in order to advertise
- * it) we haven't historically listed them. I don't know what
- * the reason for this is. It may be a bug.
- */
-item(_NET_WM_SYNC_REQUEST)
-item(_NET_WM_SYNC_REQUEST_COUNTER)
-item(_NET_WM_VISIBLE_NAME)
-item(_NET_SUPPORTING_WM_CHECK)
-
-/* But I suppose it's quite reasonable not to advertise using
- * _NET_SUPPORTED that we support _NET_SUPPORTED :)
- */
-item(_NET_SUPPORTED)
-
-#endif /* !EWMH_ATOMS_ONLY */
-
-/**************************************************************************/
-
-item(_NET_WM_NAME)
-item(_NET_CLOSE_WINDOW)
-item(_NET_WM_STATE)
-item(_NET_WM_STATE_SHADED)
-item(_NET_WM_STATE_MAXIMIZED_HORZ)
-item(_NET_WM_STATE_MAXIMIZED_VERT)
-item(_NET_WM_DESKTOP)
-item(_NET_NUMBER_OF_DESKTOPS)
-item(_NET_CURRENT_DESKTOP)
-item(_NET_WM_WINDOW_TYPE)
-item(_NET_WM_WINDOW_TYPE_DESKTOP)
-item(_NET_WM_WINDOW_TYPE_DOCK)
-item(_NET_WM_WINDOW_TYPE_TOOLBAR)
-item(_NET_WM_WINDOW_TYPE_MENU)
-item(_NET_WM_WINDOW_TYPE_UTILITY)
-item(_NET_WM_WINDOW_TYPE_SPLASH)
-item(_NET_WM_WINDOW_TYPE_DIALOG)
-item(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
-item(_NET_WM_WINDOW_TYPE_POPUP_MENU)
-item(_NET_WM_WINDOW_TYPE_TOOLTIP)
-item(_NET_WM_WINDOW_TYPE_NOTIFICATION)
-item(_NET_WM_WINDOW_TYPE_COMBO)
-item(_NET_WM_WINDOW_TYPE_DND)
-item(_NET_WM_WINDOW_TYPE_NORMAL)
-item(_NET_WM_STATE_MODAL)
-item(_NET_CLIENT_LIST)
-item(_NET_CLIENT_LIST_STACKING)
-item(_NET_WM_STATE_SKIP_TASKBAR)
-item(_NET_WM_STATE_SKIP_PAGER)
-item(_NET_WM_ICON)
-item(_NET_WM_ICON_GEOMETRY)
-item(_NET_WM_MOVERESIZE)
-item(_NET_ACTIVE_WINDOW)
-item(_NET_WM_STRUT)
-item(_NET_WM_STATE_HIDDEN)
-item(_NET_WM_STATE_FULLSCREEN)
-item(_NET_WM_PING)
-item(_NET_WM_PID)
-item(_NET_WORKAREA)
-item(_NET_SHOWING_DESKTOP)
-item(_NET_DESKTOP_LAYOUT)
-item(_NET_DESKTOP_NAMES)
-item(_NET_WM_ALLOWED_ACTIONS)
-item(_NET_WM_ACTION_MOVE)
-item(_NET_WM_ACTION_RESIZE)
-item(_NET_WM_ACTION_SHADE)
-item(_NET_WM_ACTION_STICK)
-item(_NET_WM_ACTION_MAXIMIZE_HORZ)
-item(_NET_WM_ACTION_MAXIMIZE_VERT)
-item(_NET_WM_ACTION_CHANGE_DESKTOP)
-item(_NET_WM_ACTION_CLOSE)
-item(_NET_WM_STATE_ABOVE)
-item(_NET_WM_STATE_BELOW)
-item(_NET_STARTUP_ID)
-item(_NET_WM_STRUT_PARTIAL)
-item(_NET_WM_ACTION_FULLSCREEN)
-item(_NET_WM_ACTION_MINIMIZE)
-item(_NET_FRAME_EXTENTS)
-item(_NET_REQUEST_FRAME_EXTENTS)
-item(_NET_WM_USER_TIME)
-item(_NET_WM_STATE_DEMANDS_ATTENTION)
-item(_NET_MOVERESIZE_WINDOW)
-item(_NET_DESKTOP_GEOMETRY)
-item(_NET_DESKTOP_VIEWPORT)
-item(_NET_WM_USER_TIME_WINDOW)
-item(_NET_WM_ACTION_ABOVE)
-item(_NET_WM_ACTION_BELOW)
-item(_NET_WM_STATE_STICKY)
-item(_NET_WM_FULLSCREEN_MONITORS)
-item(_NET_WM_STATE_FOCUSED)
-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
deleted file mode 100644
index 9dec73a9b..000000000
--- a/src/x11/events.c
+++ /dev/null
@@ -1,1936 +0,0 @@
-/* -*- 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 "backends/x11/meta-cursor-tracker-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-context.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",
- 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");
- 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");
- 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.");
- 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.");
- 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", 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",
- 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", 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",
- 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");
-}
-
-static gboolean
-close_display_idle_cb (gpointer user_data)
-{
- MetaX11Display *x11_display = META_X11_DISPLAY (user_data);
- MetaDisplay *display = x11_display->display;
- MetaContext *context = meta_display_get_context (display);
-
- meta_display_close (display,
- x11_display->xselectionclear_timestamp);
- x11_display->display_close_idle = 0;
- meta_context_terminate (context);
-
- 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",
- str ? str : "(bad atom)", event->xselectionclear.window);
-
- meta_XFree (str);
-
- return FALSE;
- }
-
- meta_verbose ("Got selection clear for on display %s",
- 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)",
- 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",
- 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",
- 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",
- window->unmaps_pending);
- }
- }
- }
- break;
- case MapNotify:
- /* NB: override redirect windows won't 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");
- break;
- }
-
- /* Double check that creating the MetaWindow succeeded */
- if (window == NULL)
- break;
-
- meta_verbose ("MapRequest on %s mapped = %d minimized = %d",
- 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",
- 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)",
- 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",
- 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", 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",
- 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",
- 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");
-
- 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");
- 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_handle_xevent (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",
- 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_IS_CURSOR_TRACKER_X11 (cursor_tracker))
- {
- MetaCursorTrackerX11 *cursor_tracker_x11 =
- META_CURSOR_TRACKER_X11 (cursor_tracker);
-
- if (meta_cursor_tracker_x11_handle_xevent (cursor_tracker_x11, 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",
- 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
deleted file mode 100644
index 7e73edab6..000000000
--- a/src/x11/events.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- 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/x11/group-private.h b/src/x11/group-private.h
deleted file mode 100644
index f8149becc..000000000
--- a/src/x11/group-private.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_GROUP_PRIVATE_H
-#define META_GROUP_PRIVATE_H
-
-#include "meta/group.h"
-
-struct _MetaGroup
-{
- int refcount;
- MetaX11Display *x11_display;
- GSList *windows;
- Window group_leader;
- char *startup_id;
- char *wm_client_machine;
-};
-
-#endif
-
-
-
-
diff --git a/src/x11/group-props.c b/src/x11/group-props.c
deleted file mode 100644
index 24ee4992c..000000000
--- a/src/x11/group-props.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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/group-props.h"
-
-#include <X11/Xatom.h>
-
-#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
-{
- Atom property;
- InitValueFunc init_func;
- ReloadValueFunc reload_func;
-};
-
-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);
-
-void
-meta_group_reload_property (MetaGroup *group,
- Atom property)
-{
- meta_group_reload_properties (group, &property, 1);
-}
-
-void
-meta_group_reload_properties (MetaGroup *group,
- const Atom *properties,
- int n_properties)
-{
- int i;
- MetaPropValue *values;
-
- g_return_if_fail (properties != NULL);
- g_return_if_fail (n_properties > 0);
-
- values = g_new0 (MetaPropValue, n_properties);
-
- i = 0;
- while (i < n_properties)
- {
- init_prop_value (group->x11_display, properties[i], &values[i]);
- ++i;
- }
-
- meta_prop_get_values (group->x11_display,
- group->group_leader,
- values, n_properties);
-
- i = 0;
- while (i < n_properties)
- {
- reload_prop_value (group, &values[i]);
-
- ++i;
- }
-
- meta_prop_free_values (values, n_properties);
-
- g_free (values);
-}
-
-/* Fill in the MetaPropValue used to get the value of "property" */
-static void
-init_prop_value (MetaX11Display *x11_display,
- Atom property,
- MetaPropValue *value)
-{
- MetaGroupPropHooks *hooks;
-
- value->type = META_PROP_VALUE_INVALID;
- value->atom = None;
-
- hooks = find_hooks (x11_display, property);
- if (hooks && hooks->init_func != NULL)
- (* hooks->init_func) (x11_display, property, value);
-}
-
-static void
-reload_prop_value (MetaGroup *group,
- MetaPropValue *value)
-{
- MetaGroupPropHooks *hooks;
-
- 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 (MetaX11Display *x11_display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_STRING;
- value->atom = x11_display->atom_WM_CLIENT_MACHINE;
-}
-
-static void
-reload_wm_client_machine (MetaGroup *group,
- MetaPropValue *value)
-{
- g_free (group->wm_client_machine);
- group->wm_client_machine = NULL;
-
- if (value->type != META_PROP_VALUE_INVALID)
- group->wm_client_machine = g_strdup (value->v.str);
-
- meta_verbose ("Group has client machine \"%s\"",
- group->wm_client_machine ? group->wm_client_machine : "unset");
-}
-
-static void
-init_net_startup_id (MetaX11Display *x11_display,
- Atom property,
- MetaPropValue *value)
-{
- value->type = META_PROP_VALUE_UTF8;
- value->atom = x11_display->atom__NET_STARTUP_ID;
-}
-
-static void
-reload_net_startup_id (MetaGroup *group,
- MetaPropValue *value)
-{
- g_free (group->startup_id);
- group->startup_id = NULL;
-
- if (value->type != META_PROP_VALUE_INVALID)
- group->startup_id = g_strdup (value->v.str);
-
- meta_verbose ("Group has startup id \"%s\"",
- group->startup_id ? group->startup_id : "unset");
-}
-
-#define N_HOOKS 3
-
-void
-meta_x11_display_init_group_prop_hooks (MetaX11Display *x11_display)
-{
- int i;
- MetaGroupPropHooks *hooks;
-
- g_assert (x11_display->group_prop_hooks == NULL);
-
- x11_display->group_prop_hooks = g_new0 (MetaGroupPropHooks, N_HOOKS);
- hooks = x11_display->group_prop_hooks;
-
- i = 0;
-
- 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 = x11_display->atom__NET_WM_PID;
- hooks[i].init_func = NULL;
- hooks[i].reload_func = NULL;
- ++i;
-
- 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;
-
- if (i != N_HOOKS)
- {
- g_error ("Initialized %d group hooks should have been %d", i, N_HOOKS);
- }
-}
-
-void
-meta_x11_display_free_group_prop_hooks (MetaX11Display *x11_display)
-{
- g_assert (x11_display->group_prop_hooks != NULL);
-
- g_free (x11_display->group_prop_hooks);
- x11_display->group_prop_hooks = NULL;
-}
-
-static MetaGroupPropHooks*
-find_hooks (MetaX11Display *x11_display,
- Atom property)
-{
- int i;
-
- /* FIXME we could sort the array and do binary search or
- * something
- */
-
- i = 0;
- while (i < N_HOOKS)
- {
- if (x11_display->group_prop_hooks[i].property == property)
- return &x11_display->group_prop_hooks[i];
-
- ++i;
- }
-
- return NULL;
-}
diff --git a/src/x11/group-props.h b/src/x11/group-props.h
deleted file mode 100644
index 19b570008..000000000
--- a/src/x11/group-props.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_GROUP_PROPS_H
-#define META_GROUP_PROPS_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_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/x11/group.c b/src/x11/group.c
deleted file mode 100644
index 27f21d068..000000000
--- a/src/x11/group.c
+++ /dev/null
@@ -1,332 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2002 Red Hat Inc.
- * Copyright (C) 2003 Rob Adams
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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:group
- * @title: MetaGroup
- * @short_description: Mutter window groups
- *
- */
-
-#include "config.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 (MetaX11Display *x11_display,
- Window group_leader)
-{
- g_autofree MetaGroup *group = NULL;
-#define N_INITIAL_PROPS 3
- Atom initial_props[N_INITIAL_PROPS];
- int i;
-
- g_assert (N_INITIAL_PROPS == (int) G_N_ELEMENTS (initial_props));
-
- group = g_new0 (MetaGroup, 1);
-
- 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 */
-
- xcb_connection_t *xcb_conn = XGetXCBConnection (x11_display->xdisplay);
- g_autofree xcb_generic_error_t *e = NULL;
- 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 || !attrs)
- 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 (x11_display->groups_by_leader, &group_leader) == NULL);
-
- 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++] = 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);
-
- meta_topic (META_DEBUG_GROUPS,
- "Created new group with leader 0x%lx",
- group->group_leader);
-
- return g_steal_pointer (&group);
-}
-
-static void
-meta_group_unref (MetaGroup *group)
-{
- g_return_if_fail (group->refcount > 0);
-
- group->refcount -= 1;
- if (group->refcount == 0)
- {
- meta_topic (META_DEBUG_GROUPS,
- "Destroying group with leader 0x%lx",
- group->group_leader);
-
- g_assert (group->x11_display->groups_by_leader != NULL);
-
- 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->x11_display->groups_by_leader) == 0)
- {
- g_hash_table_destroy (group->x11_display->groups_by_leader);
- group->x11_display->groups_by_leader = NULL;
- }
-
- g_free (group->wm_client_machine);
- g_free (group->startup_id);
-
- g_free (group);
- }
-}
-
-/**
- * meta_window_get_group: (skip)
- * @window: a #MetaWindow
- *
- */
-MetaGroup*
-meta_window_get_group (MetaWindow *window)
-{
- if (window->unmanaging)
- return NULL;
-
- return window->group;
-}
-
-void
-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 */
-
- group = NULL;
-
- /* Determine the ancestor of the window; its group setting will override the
- * normal grouping rules; see bug 328211.
- */
- ancestor = meta_window_find_root_ancestor (window);
-
- if (x11_display->groups_by_leader)
- {
- if (ancestor != window)
- group = ancestor->group;
- else if (window->xgroup_leader != None)
- group = g_hash_table_lookup (x11_display->groups_by_leader,
- &window->xgroup_leader);
- else
- group = g_hash_table_lookup (x11_display->groups_by_leader,
- &window->xwindow);
- }
-
- if (group != NULL)
- {
- window->group = group;
- group->refcount += 1;
- }
- else
- {
- if (ancestor != window && ancestor->xgroup_leader != None)
- group = meta_group_new (x11_display,
- ancestor->xgroup_leader);
- else if (window->xgroup_leader != None)
- group = meta_group_new (x11_display,
- window->xgroup_leader);
- else
- 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",
- window->desc, group->group_leader);
-}
-
-static void
-remove_window_from_group (MetaWindow *window)
-{
- if (window->group != NULL)
- {
- meta_topic (META_DEBUG_GROUPS,
- "Removing %s from group with leader 0x%lx",
- window->desc, window->group->group_leader);
-
- window->group->windows =
- g_slist_remove (window->group->windows,
- window);
- meta_group_unref (window->group);
- window->group = NULL;
- }
-}
-
-void
-meta_window_group_leader_changed (MetaWindow *window)
-{
- remove_window_from_group (window);
- meta_window_compute_group (window);
-}
-
-void
-meta_window_shutdown_group (MetaWindow *window)
-{
- remove_window_from_group (window);
-}
-
-/**
- * meta_x11_display_lookup_group: (skip)
- * @x11_display: a #MetaX11Display
- * @group_leader: a X window
- *
- */
-MetaGroup *
-meta_x11_display_lookup_group (MetaX11Display *x11_display,
- Window group_leader)
-{
- MetaGroup *group;
-
- group = NULL;
-
- if (x11_display->groups_by_leader)
- group = g_hash_table_lookup (x11_display->groups_by_leader,
- &group_leader);
-
- return group;
-}
-
-/**
- * meta_group_list_windows:
- * @group: A #MetaGroup
- *
- * Returns: (transfer container) (element-type Meta.Window): List of windows
- */
-GSList*
-meta_group_list_windows (MetaGroup *group)
-{
- return g_slist_copy (group->windows);
-}
-
-void
-meta_group_update_layers (MetaGroup *group)
-{
- GSList *tmp;
- GSList *frozen_stacks;
-
- if (group->windows == NULL)
- return;
-
- frozen_stacks = NULL;
- tmp = group->windows;
- while (tmp != NULL)
- {
- MetaWindow *window = tmp->data;
-
- /* we end up freezing the same stack a lot of times,
- * but doesn't hurt anything. have to handle
- * groups that span 2 screens.
- */
- meta_stack_freeze (window->display->stack);
- frozen_stacks = g_slist_prepend (frozen_stacks, window->display->stack);
-
- meta_stack_update_layer (window->display->stack,
- window);
-
- tmp = tmp->next;
- }
-
- tmp = frozen_stacks;
- while (tmp != NULL)
- {
- meta_stack_thaw (tmp->data);
- tmp = tmp->next;
- }
-
- g_slist_free (frozen_stacks);
-}
-
-const char*
-meta_group_get_startup_id (MetaGroup *group)
-{
- return group->startup_id;
-}
-
-/**
- * meta_group_property_notify: (skip)
- * @group: a #MetaGroup
- * @event: a X event
- *
- */
-gboolean
-meta_group_property_notify (MetaGroup *group,
- XEvent *event)
-{
- meta_group_reload_property (group,
- event->xproperty.atom);
-
- return TRUE;
-
-}
-
-int
-meta_group_get_size (MetaGroup *group)
-{
- if (!group)
- return 0;
-
- return group->refcount;
-}
-
diff --git a/src/x11/iconcache.c b/src/x11/iconcache.c
deleted file mode 100644
index 941cf2075..000000000
--- a/src/x11/iconcache.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/* -*- 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/x11/iconcache.h b/src/x11/iconcache.h
deleted file mode 100644
index a4b63edf0..000000000
--- a/src/x11/iconcache.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- 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/>.
- */
-
-#ifndef META_ICON_CACHE_H
-#define META_ICON_CACHE_H
-
-#include "x11/meta-x11-display-private.h"
-
-typedef struct _MetaIconCache MetaIconCache;
-
-typedef enum
-{
- /* These MUST be in ascending order of preference;
- * i.e. if we get _NET_WM_ICON and already have
- * WM_HINTS, we prefer _NET_WM_ICON
- */
- USING_NO_ICON,
- USING_FALLBACK_ICON,
- USING_KWM_WIN_ICON,
- USING_WM_HINTS,
- USING_NET_WM_ICON
-} IconOrigin;
-
-struct _MetaIconCache
-{
- int origin;
- Pixmap prev_pixmap;
- Pixmap prev_mask;
- /* 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_property_changed (MetaIconCache *icon_cache,
- MetaX11Display *x11_display,
- Atom atom);
-gboolean meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache);
-
-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
deleted file mode 100644
index bcd21a356..000000000
--- a/src/x11/meta-selection-source-x11-private.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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
deleted file mode 100644
index c9fc8fbc6..000000000
--- a/src/x11/meta-selection-source-x11.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 42be6d580..000000000
--- a/src/x11/meta-startup-notification-x11.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/* -*- 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 <libsn/sn.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",
- 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",
- 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",
- sn_startup_sequence_get_id (sequence));
- break;
-
- case SN_MONITOR_EVENT_CANCELED:
- meta_topic (META_DEBUG_STARTUP,
- "Received startup canceled for %s",
- 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
deleted file mode 100644
index b46a45e5d..000000000
--- a/src/x11/meta-startup-notification-x11.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- 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
deleted file mode 100644
index d53073e11..000000000
--- a/src/x11/meta-x11-display-private.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 8b446e348..000000000
--- a/src/x11/meta-x11-display.c
+++ /dev/null
@@ -1,2320 +0,0 @@
-/* -*- 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 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\"",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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");
-}
-
-/*
- * Initialises the bell subsystem. This involves initialising
- * 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", 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");
-
- 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");
- 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)
-{
- MetaContext *context = meta_display_get_context (x11_display->display);
- const char *gnome_wm_keybindings;
- 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,
- meta_context_get_name (context));
-
- gnome_wm_keybindings = meta_context_get_gnome_wm_keybindings (context);
- 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", 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", 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);
-}
-
-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_private_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;
- const char *old_no_at_bridge;
- 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;
- }
-
- old_no_at_bridge = g_getenv ("NO_AT_BRIDGE");
- g_setenv ("NO_AT_BRIDGE", "1", TRUE);
- gdk_display = gdk_display_open (xdisplay_name);
-
- if (old_no_at_bridge)
- g_setenv ("NO_AT_BRIDGE", old_no_at_bridge, TRUE);
- else
- g_unsetenv ("NO_AT_BRIDGE");
-
- if (!gdk_display)
- {
- meta_warning (_("Failed to initialize GDK"));
-
- 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'", XDisplayName (NULL));
-
- xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display);
-
- if (xdisplay == NULL)
- {
- meta_warning (_("Failed to open X Window System display “%s”"),
- 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_context_is_replacing (meta_backend_get_context (backend));
-
- /* 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"),
- 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, "_MUTTER_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", (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, &timestamp);
- 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,
- &current_workspace_index))
- {
- meta_verbose ("Read existing _NET_CURRENT_DESKTOP = %d",
- (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");
- }
-
- 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, &timestamp))
- 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");
- return;
- }
-
- i = 0;
- while (i < n_names)
- {
- meta_topic (META_DEBUG_PREFS,
- "Setting workspace %d name to \"%s\" due to _NET_DESKTOP_NAMES change",
- 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");
- 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", 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");
- break;
- }
- }
- }
- else
- {
- meta_warning ("Someone set _NET_DESKTOP_LAYOUT to %d integers instead of 4 "
- "(3 is accepted for backwards compat)", 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/x11/meta-x11-errors.c b/src/x11/meta-x11-errors.c
deleted file mode 100644
index 506769464..000000000
--- a/src/x11/meta-x11-errors.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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:errors
- * @title: Errors
- * @short_description: Mutter X error handling
- */
-
-#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),
- * but it's basically incompatible with the hacks we played with GTK+-2.0 to
- * use a custom error handler along with gdk_error_trap_push().
- *
- * Since the main point of our custom error trap was to get the error logged
- * to the right place, with GTK+-3.0 we simply omit our own error handler and
- * use the GTK+ handling straight-up.
- * (See https://bugzilla.gnome.org/show_bug.cgi?id=630216 for restoring logging.)
- */
-
-void
-meta_x11_error_trap_push (MetaX11Display *x11_display)
-{
- gdk_x11_display_error_trap_push (x11_display->gdk_display);
-}
-
-void
-meta_x11_error_trap_pop (MetaX11Display *x11_display)
-{
- gdk_x11_display_error_trap_pop_ignored (x11_display->gdk_display);
-}
-
-int
-meta_x11_error_trap_pop_with_return (MetaX11Display *x11_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
deleted file mode 100644
index 3fcf9ffd1..000000000
--- a/src/x11/meta-x11-selection-input-stream-private.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* 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
deleted file mode 100644
index e8d782047..000000000
--- a/src/x11/meta-x11-selection-input-stream.c
+++ /dev/null
@@ -1,572 +0,0 @@
-/* -*- 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
deleted file mode 100644
index 83390da48..000000000
--- a/src/x11/meta-x11-selection-output-stream-private.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* 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
deleted file mode 100644
index 41a691c9a..000000000
--- a/src/x11/meta-x11-selection-output-stream.c
+++ /dev/null
@@ -1,686 +0,0 @@
-/* -*- 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
deleted file mode 100644
index b551ef602..000000000
--- a/src/x11/meta-x11-selection-private.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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
deleted file mode 100644
index e389f22c7..000000000
--- a/src/x11/meta-x11-selection.c
+++ /dev/null
@@ -1,551 +0,0 @@
-/*
- * 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", 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
deleted file mode 100644
index a00b8e743..000000000
--- a/src/x11/meta-x11-stack-private.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- 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
deleted file mode 100644
index d41fef78e..000000000
--- a/src/x11/meta-x11-stack.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/* -*- 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 <X11/Xatom.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_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");
-
- /* 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
deleted file mode 100644
index 3af43ce0c..000000000
--- a/src/x11/meta-x11-window-control.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/* -*- 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!", 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", 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
deleted file mode 100644
index dfb66f262..000000000
--- a/src/x11/meta-x11-window-control.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- 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/x11/mutter-Xatomtype.h b/src/x11/mutter-Xatomtype.h
deleted file mode 100644
index ed3e1f781..000000000
--- a/src/x11/mutter-Xatomtype.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \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
- * routines will handle conversion to and from actual 32 bit objects. If your
- * compiler doesn't treat &structoflongs the same as &arrayoflongs[0], you
- * will have some work to do.
- */
-
-/***********************************************************
-
-Copyright 1987, 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.
-
-
-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,
-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.
-
-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.
-
-******************************************************************/
-
-#ifndef _XATOMTYPE_H_
-#define _XATOMTYPE_H_
-
-#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 */
-typedef struct {
- UNSIGNEDINT flags;
- SIGNEDINT x, y, width, height; /* need to cvt; only for pre-ICCCM */
- SIGNEDINT minWidth, minHeight; /* need to cvt */
- SIGNEDINT maxWidth, maxHeight; /* need to cvt */
- SIGNEDINT widthInc, heightInc; /* need to cvt */
- SIGNEDINT minAspectX, minAspectY; /* need to cvt */
- SIGNEDINT maxAspectX, maxAspectY; /* need to cvt */
- SIGNEDINT baseWidth,baseHeight; /* need to cvt; ICCCM version 1 */
- SIGNEDINT winGravity; /* need to cvt; ICCCM version 1 */
-} xPropSizeHints;
-#define OldNumPropSizeElements 15 /* pre-ICCCM */
-#define NumPropSizeElements 18 /* ICCCM version 1 */
-
-/* this structure may be extended, but do not change the order */
-/* RGB properties */
-typedef struct {
- RESOURCEID colormap;
- UNSIGNEDINT red_max;
- UNSIGNEDINT red_mult;
- UNSIGNEDINT green_max;
- UNSIGNEDINT green_mult;
- UNSIGNEDINT blue_max;
- UNSIGNEDINT blue_mult;
- UNSIGNEDINT base_pixel;
- RESOURCEID visualid; /* ICCCM version 1 */
- RESOURCEID killid; /* ICCCM version 1 */
-} xPropStandardColormap;
-#define OldNumPropStandardColormapElements 8 /* pre-ICCCM */
-#define NumPropStandardColormapElements 10 /* ICCCM version 1 */
-
-
-/* this structure may be extended, but do not change the order */
-typedef struct {
- UNSIGNEDINT flags;
- BOOL input; /* need to convert */
- SIGNEDINT initialState; /* need to cvt */
- RESOURCEID iconPixmap;
- RESOURCEID iconWindow;
- SIGNEDINT iconX; /* need to cvt */
- SIGNEDINT iconY; /* need to cvt */
- RESOURCEID iconMask;
- UNSIGNEDINT windowGroup;
- } xPropWMHints;
-#define NumPropWMHintsElements 9 /* number of elements in this structure */
-
-/* this structure defines the icon size hints information */
-typedef struct {
- SIGNEDINT minWidth, minHeight; /* need to cvt */
- SIGNEDINT maxWidth, maxHeight; /* need to cvt */
- SIGNEDINT widthInc, heightInc; /* need to cvt */
- } xPropIconSize;
-#define NumPropIconSizeElements 6 /* number of elements in this structure */
-
-/* this structure defines the window manager state information */
-typedef struct {
- SIGNEDINT state; /* need to cvt */
- RESOURCEID iconWindow;
-} xPropWMState;
-#define NumPropWMStateElements 2 /* number of elements in struct */
-
-#undef BOOL
-#undef SIGNEDINT
-#undef UNSIGNEDINT
-#undef RESOURCEID
-
-#endif /* _XATOMTYPE_H_ */
diff --git a/src/x11/session.c b/src/x11/session.c
deleted file mode 100644
index 339a7ae33..000000000
--- a/src/x11/session.c
+++ /dev/null
@@ -1,1860 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Mutter Session Management */
-
-/*
- * Copyright (C) 2001 Havoc Pennington (some code in here from
- * libgnomeui, (C) Tom Tromey, Carsten Schaar)
- * 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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/session.h"
-
-#include <sys/wait.h>
-#include <time.h>
-#include <X11/Xatom.h>
-
-#include "core/util-private.h"
-#include "meta/meta-context.h"
-#include "x11/meta-x11-display-private.h"
-
-#ifndef HAVE_SM
-void
-meta_session_init (MetaContext *context,
- const char *client_id,
- const char *save_file)
-{
- meta_topic (META_DEBUG_SM, "Compiled without session management support");
-}
-
-const MetaWindowSessionInfo*
-meta_window_lookup_saved_state (MetaWindow *window)
-{
- return NULL;
-}
-
-void
-meta_window_release_saved_state (const MetaWindowSessionInfo *info)
-{
- ;
-}
-#else /* HAVE_SM */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <glib.h>
-#include <stdio.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"
-
-typedef struct _MetaIceConnection
-{
- IceConn ice_connection;
- MetaContext *context;
-} MetaIceConnection;
-
-static void ice_io_error_handler (IceConn connection);
-
-static void new_ice_connection (IceConn connection, IcePointer client_data,
- Bool opening, IcePointer *watch_data);
-
-static void save_state (void);
-static char* load_state (const char *previous_save_file);
-static void regenerate_save_file (void);
-static const char* full_save_file (void);
-static void warn_about_lame_clients_and_finish_interact (gboolean shutdown);
-static void disconnect (void);
-
-/* This is called when data is available on an ICE connection. */
-static gboolean
-process_ice_messages (GIOChannel *channel,
- GIOCondition condition,
- gpointer user_data)
-{
- MetaIceConnection *ice_connection = user_data;
- IceConn connection = ice_connection->ice_connection;
- IceProcessMessagesStatus status;
-
- /* This blocks infinitely sometimes. I don't know what
- * to do about it. Checking "condition" just breaks
- * session management.
- */
- status = IceProcessMessages (connection, NULL, NULL);
-
- if (status == IceProcessMessagesIOError)
- {
- /* We were disconnected; close our connection to the
- * session manager, this will result in the ICE connection
- * being cleaned up, since it is owned by libSM.
- */
- disconnect ();
- meta_context_terminate (ice_connection->context);
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* This is called when a new ICE connection is made. It arranges for
- the ICE connection to be handled via the event loop. */
-static void
-new_ice_connection (IceConn connection, IcePointer client_data, Bool opening,
- IcePointer *watch_data)
-{
- MetaContext *context = client_data;
- guint input_id;
-
- if (opening)
- {
- MetaIceConnection *ice_connection;
- GIOChannel *channel;
-
- fcntl (IceConnectionNumber (connection), F_SETFD,
- fcntl (IceConnectionNumber (connection), F_GETFD, 0) | FD_CLOEXEC);
-
- ice_connection = g_new0 (MetaIceConnection, 1);
- ice_connection->ice_connection = connection;
- ice_connection->context = context;
-
- channel = g_io_channel_unix_new (IceConnectionNumber (connection));
-
- input_id = g_io_add_watch_full (channel,
- G_PRIORITY_DEFAULT,
- G_IO_IN | G_IO_ERR,
- process_ice_messages,
- ice_connection,
- g_free);
-
- g_io_channel_unref (channel);
-
- *watch_data = (IcePointer) GUINT_TO_POINTER (input_id);
- }
- else
- {
- input_id = GPOINTER_TO_UINT ((gpointer) *watch_data);
-
- g_clear_handle_id (&input_id, g_source_remove);
- }
-}
-
-static IceIOErrorHandler ice_installed_handler;
-
-/* We call any handler installed before (or after) gnome_ice_init but
- avoid calling the default libICE handler which does an exit() */
-static void
-ice_io_error_handler (IceConn connection)
-{
- if (ice_installed_handler)
- (*ice_installed_handler) (connection);
-}
-
-static void
-ice_init (void)
-{
- static gboolean ice_initted = FALSE;
-
- if (! ice_initted)
- {
- IceIOErrorHandler default_handler;
-
- ice_installed_handler = IceSetIOErrorHandler (NULL);
- default_handler = IceSetIOErrorHandler (ice_io_error_handler);
-
- if (ice_installed_handler == default_handler)
- ice_installed_handler = NULL;
-
- IceAddConnectionWatch (new_ice_connection, NULL);
-
- ice_initted = TRUE;
- }
-}
-
-typedef enum
-{
- STATE_DISCONNECTED,
- STATE_IDLE,
- STATE_SAVING_PHASE_1,
- STATE_WAITING_FOR_PHASE_2,
- STATE_SAVING_PHASE_2,
- STATE_WAITING_FOR_INTERACT,
- STATE_DONE_WITH_INTERACT,
- STATE_SKIPPING_GLOBAL_SAVE,
- STATE_FROZEN,
- STATE_REGISTERING
-} ClientState;
-
-static void save_phase_2_callback (SmcConn smc_conn,
- SmPointer client_data);
-static void interact_callback (SmcConn smc_conn,
- SmPointer client_data);
-static void shutdown_cancelled_callback (SmcConn smc_conn,
- SmPointer client_data);
-static void save_complete_callback (SmcConn smc_conn,
- SmPointer client_data);
-static void die_callback (SmcConn smc_conn,
- SmPointer client_data);
-static void save_yourself_callback (SmcConn smc_conn,
- SmPointer client_data,
- int save_style,
- Bool shutdown,
- int interact_style,
- Bool fast);
-static void set_clone_restart_commands (void);
-
-static char *client_id = NULL;
-static gpointer session_connection = NULL;
-static ClientState current_state = STATE_DISCONNECTED;
-static gboolean interaction_allowed = FALSE;
-
-void
-meta_session_init (MetaContext *context,
- const char *previous_client_id,
- const char *previous_save_file)
-{
- /* Some code here from twm */
- char buf[256];
- unsigned long mask;
- SmcCallbacks callbacks;
- char *saved_client_id;
-
- if (!previous_client_id)
- {
- const char *desktop_autostart_id;
-
- desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
- if (desktop_autostart_id)
- previous_client_id = desktop_autostart_id;
- }
- g_unsetenv ("DESKTOP_AUTOSTART_ID");
-
- meta_topic (META_DEBUG_SM, "Initializing session with save file '%s'",
- previous_save_file ? previous_save_file : "(none)");
-
- if (previous_save_file)
- {
- saved_client_id = load_state (previous_save_file);
- previous_client_id = saved_client_id;
- }
- else if (previous_client_id)
- {
- char *save_file = g_strconcat (previous_client_id, ".ms", NULL);
- saved_client_id = load_state (save_file);
- g_free (save_file);
- }
- else
- {
- saved_client_id = NULL;
- }
-
- ice_init ();
-
- mask = SmcSaveYourselfProcMask | SmcDieProcMask |
- SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask;
-
- callbacks.save_yourself.callback = save_yourself_callback;
- callbacks.save_yourself.client_data = context;
-
- callbacks.die.callback = die_callback;
- callbacks.die.client_data = context;
-
- callbacks.save_complete.callback = save_complete_callback;
- callbacks.save_complete.client_data = context;
-
- callbacks.shutdown_cancelled.callback = shutdown_cancelled_callback;
- callbacks.shutdown_cancelled.client_data = context;
-
- session_connection =
- SmcOpenConnection (NULL, /* use SESSION_MANAGER env */
- NULL, /* means use existing ICE connection */
- SmProtoMajor,
- SmProtoMinor,
- mask,
- &callbacks,
- (char*) previous_client_id,
- &client_id,
- 255, buf);
-
- if (session_connection == NULL)
- {
- meta_topic (META_DEBUG_SM,
- "Failed to a open connection to a session manager, so window positions will not be saved: %s",
- buf);
-
- goto out;
- }
- else
- {
- if (client_id == NULL)
- meta_bug ("Session manager gave us a NULL client ID?");
- meta_topic (META_DEBUG_SM, "Obtained session ID '%s'", client_id);
- }
-
- if (previous_client_id && strcmp (previous_client_id, client_id) == 0)
- current_state = STATE_IDLE;
- else
- current_state = STATE_REGISTERING;
-
- {
- SmProp prop1, prop2, prop3, prop4, prop5, prop6, *props[6];
- SmPropValue prop1val, prop2val, prop3val, prop4val, prop5val, prop6val;
- char pid[32];
- /* Historically, this was SmRestartImmediately, which made sense
- * for a stateless window manager, but we don't really control
- * what embedders do, and it's all around better if gnome-session
- * handles this.
- */
- char hint = SmRestartIfRunning;
- char priority = 20; /* low to run before other apps */
- const char *prgname;
-
- prgname = g_get_prgname ();
-
- prop1.name = (char *)SmProgram;
- prop1.type = (char *)SmARRAY8;
- prop1.num_vals = 1;
- prop1.vals = &prop1val;
- prop1val.value = (char *)prgname;
- prop1val.length = strlen (prgname);
-
- /* twm sets getuid() for this, but the SM spec plainly
- * says pw_name, twm is on crack
- */
- 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 = (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 = (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 = (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 = (char *)"_GSM_Priority";
- prop6.type = (char *)SmCARD8;
- prop6.num_vals = 1;
- prop6.vals = &prop6val;
- prop6val.value = &priority;
- prop6val.length = 1;
-
- props[0] = &prop1;
- props[1] = &prop2;
- props[2] = &prop3;
- props[3] = &prop4;
- props[4] = &prop5;
- props[5] = &prop6;
-
- SmcSetProperties (session_connection, 6, props);
- }
-
- out:
- g_free (saved_client_id);
-}
-
-static void
-disconnect (void)
-{
- SmcCloseConnection (session_connection, 0, NULL);
- session_connection = NULL;
- current_state = STATE_DISCONNECTED;
-}
-
-static void
-save_yourself_possibly_done (gboolean shutdown,
- gboolean successful)
-{
- meta_topic (META_DEBUG_SM,
- "save possibly done shutdown = %d success = %d",
- shutdown, successful);
-
- if (current_state == STATE_SAVING_PHASE_1)
- {
- Status status;
-
- status = SmcRequestSaveYourselfPhase2 (session_connection,
- save_phase_2_callback,
- GINT_TO_POINTER (shutdown));
-
- if (status)
- current_state = STATE_WAITING_FOR_PHASE_2;
-
- meta_topic (META_DEBUG_SM,
- "Requested phase 2, status = %d", status);
- }
-
- if (current_state == STATE_SAVING_PHASE_2 &&
- interaction_allowed)
- {
- Status status;
-
- status = SmcInteractRequest (session_connection,
- /* ignore this feature of the protocol by always
- * claiming normal
- */
- SmDialogNormal,
- interact_callback,
- GINT_TO_POINTER (shutdown));
-
- if (status)
- current_state = STATE_WAITING_FOR_INTERACT;
-
- meta_topic (META_DEBUG_SM,
- "Requested interact, status = %d", status);
- }
-
- if (current_state == STATE_SAVING_PHASE_1 ||
- current_state == STATE_SAVING_PHASE_2 ||
- current_state == STATE_DONE_WITH_INTERACT ||
- current_state == STATE_SKIPPING_GLOBAL_SAVE)
- {
- meta_topic (META_DEBUG_SM, "Sending SaveYourselfDone");
-
- SmcSaveYourselfDone (session_connection,
- successful);
-
- if (shutdown)
- current_state = STATE_FROZEN;
- else
- current_state = STATE_IDLE;
- }
-}
-
-static void
-save_phase_2_callback (SmcConn smc_conn, SmPointer client_data)
-{
- gboolean shutdown;
-
- meta_topic (META_DEBUG_SM, "Phase 2 save");
-
- shutdown = GPOINTER_TO_INT (client_data);
-
- current_state = STATE_SAVING_PHASE_2;
-
- save_state ();
-
- save_yourself_possibly_done (shutdown, TRUE);
-}
-
-static void
-save_yourself_callback (SmcConn smc_conn,
- SmPointer client_data,
- int save_style,
- Bool shutdown,
- int interact_style,
- Bool fast)
-{
- gboolean successful;
-
- meta_topic (META_DEBUG_SM, "SaveYourself received");
-
- successful = TRUE;
-
- /* The first SaveYourself after registering for the first time
- * is a special case (SM specs 7.2).
- */
-
-#if 0 /* I think the GnomeClient rationale for this doesn't apply */
- if (current_state == STATE_REGISTERING)
- {
- current_state = STATE_IDLE;
- /* Double check that this is a section 7.2 SaveYourself: */
-
- if (save_style == SmSaveLocal &&
- interact_style == SmInteractStyleNone &&
- !shutdown && !fast)
- {
- /* The protocol requires this even if xsm ignores it. */
- SmcSaveYourselfDone (session_connection, successful);
- return;
- }
- }
-#endif
-
- /* ignore Global style saves
- *
- * This interpretaion of the Local/Global/Both styles
- * was discussed extensively on the xdg-list. See:
- *
- * https://listman.redhat.com/pipermail/xdg-list/2002-July/000615.html
- */
- if (save_style == SmSaveGlobal)
- {
- current_state = STATE_SKIPPING_GLOBAL_SAVE;
- save_yourself_possibly_done (shutdown, successful);
- return;
- }
-
- interaction_allowed = interact_style != SmInteractStyleNone;
-
- current_state = STATE_SAVING_PHASE_1;
-
- regenerate_save_file ();
-
- set_clone_restart_commands ();
-
- save_yourself_possibly_done (shutdown, successful);
-}
-
-
-static void
-die_callback (SmcConn smc_conn, SmPointer client_data)
-{
- MetaContext *context = client_data;
-
- meta_topic (META_DEBUG_SM, "Disconnecting from session manager");
-
- disconnect ();
- /* We don't actually exit here - we will simply go away with the X
- * server on logout, when we lose the X connection and libx11 kills
- * us. It looks like *crap* on logout if the user sees their
- * windows lose the decorations, etc.
- *
- * 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_context_terminate (context);
-}
-
-static void
-save_complete_callback (SmcConn smc_conn, SmPointer client_data)
-{
- /* nothing */
- meta_topic (META_DEBUG_SM, "SaveComplete received");
-}
-
-static void
-shutdown_cancelled_callback (SmcConn smc_conn, SmPointer client_data)
-{
- meta_topic (META_DEBUG_SM, "Shutdown cancelled received");
-
- if (session_connection != NULL &&
- (current_state != STATE_IDLE && current_state != STATE_FROZEN))
- {
- SmcSaveYourselfDone (session_connection, True);
- current_state = STATE_IDLE;
- }
-}
-
-static void
-interact_callback (SmcConn smc_conn, SmPointer client_data)
-{
- /* nothing */
- gboolean shutdown;
-
- meta_topic (META_DEBUG_SM, "Interaction permission received");
-
- shutdown = GPOINTER_TO_INT (client_data);
-
- current_state = STATE_DONE_WITH_INTERACT;
-
- warn_about_lame_clients_and_finish_interact (shutdown);
-}
-
-static void
-set_clone_restart_commands (void)
-{
- char *restartv[10];
- char *clonev[10];
- char *discardv[10];
- int i;
- SmProp prop1, prop2, prop3, *props[3];
- const char *prgname;
-
- prgname = g_get_prgname ();
-
- /* Restart (use same client ID) */
-
- prop1.name = (char *)SmRestartCommand;
- prop1.type = (char *)SmLISTofARRAY8;
-
- g_return_if_fail (client_id);
-
- i = 0;
- restartv[i] = (char *)prgname;
- ++i;
- restartv[i] = (char *)"--sm-client-id";
- ++i;
- restartv[i] = client_id;
- ++i;
- restartv[i] = NULL;
-
- prop1.vals = g_new (SmPropValue, i);
- i = 0;
- while (restartv[i])
- {
- prop1.vals[i].value = restartv[i];
- prop1.vals[i].length = strlen (restartv[i]);
- ++i;
- }
- prop1.num_vals = i;
-
- /* Clone (no client ID) */
-
- i = 0;
- clonev[i] = (char *)prgname;
- ++i;
- clonev[i] = NULL;
-
- prop2.name = (char *)SmCloneCommand;
- prop2.type = (char *)SmLISTofARRAY8;
-
- prop2.vals = g_new (SmPropValue, i);
- i = 0;
- while (clonev[i])
- {
- prop2.vals[i].value = clonev[i];
- prop2.vals[i].length = strlen (clonev[i]);
- ++i;
- }
- prop2.num_vals = i;
-
- /* Discard */
-
- i = 0;
- discardv[i] = (char *)"rm";
- ++i;
- discardv[i] = (char *)"-f";
- ++i;
- discardv[i] = (char*) full_save_file ();
- ++i;
- discardv[i] = NULL;
-
- prop3.name = (char *)SmDiscardCommand;
- prop3.type = (char *)SmLISTofARRAY8;
-
- prop3.vals = g_new (SmPropValue, i);
- i = 0;
- while (discardv[i])
- {
- prop3.vals[i].value = discardv[i];
- prop3.vals[i].length = strlen (discardv[i]);
- ++i;
- }
- prop3.num_vals = i;
-
-
- props[0] = &prop1;
- props[1] = &prop2;
- props[2] = &prop3;
-
- SmcSetProperties (session_connection, 3, props);
-
- g_free (prop1.vals);
- g_free (prop2.vals);
- g_free (prop3.vals);
-}
-
-/* The remaining code in this file actually loads/saves the session,
- * while the code above this comment handles chatting with the
- * session manager.
- */
-
-static const char*
-window_type_to_string (MetaWindowType type)
-{
- switch (type)
- {
- case META_WINDOW_NORMAL:
- return "normal";
- case META_WINDOW_DESKTOP:
- return "desktop";
- case META_WINDOW_DOCK:
- return "dock";
- case META_WINDOW_DIALOG:
- return "dialog";
- case META_WINDOW_MODAL_DIALOG:
- return "modal_dialog";
- case META_WINDOW_TOOLBAR:
- return "toolbar";
- case META_WINDOW_MENU:
- return "menu";
- case META_WINDOW_SPLASHSCREEN:
- return "splashscreen";
- case META_WINDOW_UTILITY:
- return "utility";
- case META_WINDOW_DROPDOWN_MENU:
- return "dropdown_menu";
- case META_WINDOW_POPUP_MENU:
- return "popup_menu";
- case META_WINDOW_TOOLTIP:
- return "tooltip";
- case META_WINDOW_NOTIFICATION:
- return "notification";
- case META_WINDOW_COMBO:
- return "combo";
- case META_WINDOW_DND:
- return "dnd";
- case META_WINDOW_OVERRIDE_OTHER:
- return "override_redirect";
- }
-
- return "";
-}
-
-static MetaWindowType
-window_type_from_string (const char *str)
-{
- if (strcmp (str, "normal") == 0)
- return META_WINDOW_NORMAL;
- else if (strcmp (str, "desktop") == 0)
- return META_WINDOW_DESKTOP;
- else if (strcmp (str, "dock") == 0)
- return META_WINDOW_DOCK;
- else if (strcmp (str, "dialog") == 0)
- return META_WINDOW_DIALOG;
- else if (strcmp (str, "modal_dialog") == 0)
- return META_WINDOW_MODAL_DIALOG;
- else if (strcmp (str, "toolbar") == 0)
- return META_WINDOW_TOOLBAR;
- else if (strcmp (str, "menu") == 0)
- return META_WINDOW_MENU;
- else if (strcmp (str, "utility") == 0)
- return META_WINDOW_UTILITY;
- else if (strcmp (str, "splashscreen") == 0)
- return META_WINDOW_SPLASHSCREEN;
- else
- return META_WINDOW_NORMAL;
-}
-
-static int
-window_gravity_from_string (const char *str)
-{
- 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 META_GRAVITY_NORTH_WEST;
-}
-
-static char*
-encode_text_as_utf8_markup (const char *text)
-{
- /* text can be any encoding, and is nul-terminated.
- * we pretend it's Latin-1 and encode as UTF-8
- */
- GString *str;
- const char *p;
- char *escaped;
-
- str = g_string_new ("");
-
- p = text;
- while (*p)
- {
- g_string_append_unichar (str, *p);
- ++p;
- }
-
- escaped = g_markup_escape_text (str->str, str->len);
- g_string_free (str, TRUE);
-
- return escaped;
-}
-
-static char*
-decode_text_from_utf8 (const char *text)
-{
- /* Convert back from the encoded (but not escaped) UTF-8 */
- GString *str;
- const char *p;
-
- str = g_string_new ("");
-
- p = text;
- while (*p)
- {
- /* obviously this barfs if the UTF-8 contains chars > 255 */
- g_string_append_c (str, g_utf8_get_char (p));
-
- p = g_utf8_next_char (p);
- }
-
- return g_string_free (str, FALSE);
-}
-
-static void
-save_state (void)
-{
- char *mutter_dir;
- char *session_dir;
- FILE *outfile;
- GSList *windows;
- GSList *tmp;
- int stack_position;
-
- g_assert (client_id);
-
- outfile = NULL;
-
- /*
- * g_get_user_config_dir() is guaranteed to return an existing directory.
- * Eventually, if SM stays with the WM, I'd like to make this
- * something like <config>/window_placement in a standard format.
- * Future optimisers should note also that by the time we get here
- * we probably already have full_save_path figured out and therefore
- * can just use the directory name from that.
- */
- mutter_dir = g_strconcat (g_get_user_config_dir (),
- G_DIR_SEPARATOR_S "mutter",
- NULL);
-
- session_dir = g_strconcat (mutter_dir,
- G_DIR_SEPARATOR_S "sessions",
- NULL);
-
- if (mkdir (mutter_dir, 0700) < 0 &&
- errno != EEXIST)
- {
- meta_warning ("Could not create directory '%s': %s",
- mutter_dir, g_strerror (errno));
- }
-
- if (mkdir (session_dir, 0700) < 0 &&
- errno != EEXIST)
- {
- meta_warning ("Could not create directory '%s': %s",
- session_dir, g_strerror (errno));
- }
-
- meta_topic (META_DEBUG_SM, "Saving session to '%s'", full_save_file ());
-
- outfile = fopen (full_save_file (), "w");
-
- if (outfile == NULL)
- {
- meta_warning ("Could not open session file '%s' for writing: %s",
- full_save_file (), g_strerror (errno));
- goto out;
- }
-
- /* The file format is:
- * <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>
- * </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
- * child elements are the saved state to be applied.
- *
- */
-
- 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;
- stack_position = 0;
-
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- if (window->sm_client_id)
- {
- char *sm_client_id;
- char *res_class;
- char *res_name;
- char *role;
- char *title;
-
- /* client id, class, name, role are not expected to be
- * in UTF-8 (I think they are in XPCS which is Latin-1?
- * in practice they are always ascii though.)
- */
-
- sm_client_id = encode_text_as_utf8_markup (window->sm_client_id);
- res_class = window->res_class ?
- encode_text_as_utf8_markup (window->res_class) : NULL;
- res_name = window->res_name ?
- encode_text_as_utf8_markup (window->res_name) : NULL;
- role = window->role ?
- encode_text_as_utf8_markup (window->role) : NULL;
- if (window->title)
- title = g_markup_escape_text (window->title, -1);
- else
- title = NULL;
-
- meta_topic (META_DEBUG_SM, "Saving session managed window %s, client ID '%s'",
- window->desc, window->sm_client_id);
-
- fprintf (outfile,
- " <window id=\"%s\" class=\"%s\" name=\"%s\" title=\"%s\" role=\"%s\" type=\"%s\" stacking=\"%d\">\n",
- sm_client_id,
- res_class ? res_class : "",
- res_name ? res_name : "",
- title ? title : "",
- role ? role : "",
- window_type_to_string (window->type),
- stack_position);
-
- 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);
- } 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)
- fputs (" <minimized/>\n", outfile);
-
- /* Maximized */
- if (META_WINDOW_MAXIMIZED (window))
- {
- fprintf (outfile,
- " <maximized saved_x=\"%d\" saved_y=\"%d\" saved_width=\"%d\" saved_height=\"%d\"/>\n",
- window->saved_rect.x,
- window->saved_rect.y,
- window->saved_rect.width,
- window->saved_rect.height);
- }
-
- /* Gravity */
- {
- int 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",
- x, y, w, h,
- meta_gravity_to_string (window->size_hints.win_gravity));
- }
-
- fputs (" </window>\n", outfile);
- }
- else
- {
- meta_topic (META_DEBUG_SM, "Not saving window '%s', not session managed",
- window->desc);
- }
-
- tmp = tmp->next;
- ++stack_position;
- }
-
- g_slist_free (windows);
-
- fputs ("</mutter_session>\n", outfile);
-
- out:
- if (outfile)
- {
- /* FIXME need a dialog for this */
- if (ferror (outfile))
- {
- meta_warning ("Error writing session file '%s': %s",
- full_save_file (), g_strerror (errno));
- }
- if (fclose (outfile))
- {
- meta_warning ("Error closing session file '%s': %s",
- full_save_file (), g_strerror (errno));
- }
- }
-
- g_free (mutter_dir);
- g_free (session_dir);
-}
-
-typedef enum
-{
- WINDOW_TAG_NONE,
- WINDOW_TAG_DESKTOP,
- WINDOW_TAG_STICKY,
- WINDOW_TAG_MINIMIZED,
- WINDOW_TAG_MAXIMIZED,
- WINDOW_TAG_GEOMETRY
-} WindowTag;
-
-typedef struct
-{
- MetaWindowSessionInfo *info;
- char *previous_id;
-} ParseData;
-
-static void session_info_free (MetaWindowSessionInfo *info);
-static MetaWindowSessionInfo* session_info_new (void);
-
-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);
-
-static GMarkupParser mutter_session_parser = {
- start_element_handler,
- end_element_handler,
- text_handler,
- NULL,
- NULL
-};
-
-static GSList *window_info_list = NULL;
-
-static char*
-load_state (const char *previous_save_file)
-{
- GMarkupParseContext *context;
- GError *error;
- ParseData parse_data;
- char *text;
- gsize length;
- char *session_file;
-
- session_file = g_strconcat (g_get_user_config_dir (),
- G_DIR_SEPARATOR_S "mutter"
- G_DIR_SEPARATOR_S "sessions" G_DIR_SEPARATOR_S,
- previous_save_file,
- NULL);
-
- error = NULL;
- if (!g_file_get_contents (session_file,
- &text,
- &length,
- &error))
- {
- char *canonical_session_file = session_file;
-
- /* Maybe they were doing it the old way, with ~/.mutter */
- session_file = g_strconcat (g_get_home_dir (),
- G_DIR_SEPARATOR_S ".mutter"
- G_DIR_SEPARATOR_S "sessions"
- G_DIR_SEPARATOR_S,
- previous_save_file,
- NULL);
-
- if (!g_file_get_contents (session_file,
- &text,
- &length,
- NULL))
- {
- /* oh, just give up */
-
- g_error_free (error);
- g_free (session_file);
- g_free (canonical_session_file);
- return NULL;
- }
-
- g_free (canonical_session_file);
- }
-
- meta_topic (META_DEBUG_SM, "Parsing saved session file %s", session_file);
- g_free (session_file);
- session_file = NULL;
-
- parse_data.info = NULL;
- parse_data.previous_id = NULL;
-
- context = g_markup_parse_context_new (&mutter_session_parser,
- 0, &parse_data, NULL);
-
- error = NULL;
- if (!g_markup_parse_context_parse (context,
- text,
- length,
- &error))
- goto error;
-
-
- error = NULL;
- if (!g_markup_parse_context_end_parse (context, &error))
- goto error;
-
- g_markup_parse_context_free (context);
-
- goto out;
-
- error:
-
- meta_warning ("Failed to parse saved session file: %s",
- error->message);
- g_error_free (error);
-
- if (parse_data.info)
- session_info_free (parse_data.info);
-
- g_free (parse_data.previous_id);
- parse_data.previous_id = NULL;
-
- out:
-
- g_free (text);
-
- return parse_data.previous_id;
-}
-
-/* FIXME this isn't very robust against bogus session files */
-static void
-start_element_handler (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- gpointer user_data,
- GError **error)
-{
- ParseData *pd;
-
- pd = user_data;
-
- if (strcmp (element_name, "mutter_session") == 0)
- {
- /* Get previous ID */
- int i;
-
- i = 0;
- while (attribute_names[i])
- {
- const char *name;
- const char *val;
-
- name = attribute_names[i];
- val = attribute_values[i];
-
- if (pd->previous_id)
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- "<mutter_session> attribute seen but we already have the session ID");
- return;
- }
-
- if (strcmp (name, "id") == 0)
- {
- pd->previous_id = decode_text_from_utf8 (val);
- }
- else
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
- "Unknown attribute %s on <%s> element",
- name, "mutter_session");
- return;
- }
-
- ++i;
- }
- }
- else if (strcmp (element_name, "window") == 0)
- {
- int i;
-
- if (pd->info)
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_PARSE,
- "nested <window> tag");
- return;
- }
-
- pd->info = session_info_new ();
-
- i = 0;
- while (attribute_names[i])
- {
- const char *name;
- const char *val;
-
- name = attribute_names[i];
- val = attribute_values[i];
-
- if (strcmp (name, "id") == 0)
- {
- if (*val)
- pd->info->id = decode_text_from_utf8 (val);
- }
- else if (strcmp (name, "class") == 0)
- {
- if (*val)
- pd->info->res_class = decode_text_from_utf8 (val);
- }
- else if (strcmp (name, "name") == 0)
- {
- if (*val)
- pd->info->res_name = decode_text_from_utf8 (val);
- }
- else if (strcmp (name, "title") == 0)
- {
- if (*val)
- pd->info->title = g_strdup (val);
- }
- else if (strcmp (name, "role") == 0)
- {
- if (*val)
- pd->info->role = decode_text_from_utf8 (val);
- }
- else if (strcmp (name, "type") == 0)
- {
- if (*val)
- pd->info->type = window_type_from_string (val);
- }
- else if (strcmp (name, "stacking") == 0)
- {
- if (*val)
- {
- pd->info->stack_position = atoi (val);
- pd->info->stack_position_set = TRUE;
- }
- }
- else
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
- "Unknown attribute %s on <%s> element",
- name, "window");
- session_info_free (pd->info);
- pd->info = NULL;
- return;
- }
-
- ++i;
- }
- }
- else if (strcmp (element_name, "workspace") == 0)
- {
- int i;
-
- i = 0;
- while (attribute_names[i])
- {
- const char *name;
-
- name = attribute_names[i];
-
- if (strcmp (name, "index") == 0)
- {
- pd->info->workspace_indices =
- g_slist_prepend (pd->info->workspace_indices,
- GINT_TO_POINTER (atoi (attribute_values[i])));
- }
- else
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
- "Unknown attribute %s on <%s> element",
- name, "window");
- session_info_free (pd->info);
- pd->info = NULL;
- return;
- }
-
- ++i;
- }
- }
- else if (strcmp (element_name, "sticky") == 0)
- {
- pd->info->on_all_workspaces = TRUE;
- pd->info->on_all_workspaces_set = TRUE;
- }
- else if (strcmp (element_name, "minimized") == 0)
- {
- pd->info->minimized = TRUE;
- pd->info->minimized_set = TRUE;
- }
- else if (strcmp (element_name, "maximized") == 0)
- {
- int i;
-
- i = 0;
- pd->info->maximized = TRUE;
- pd->info->maximized_set = TRUE;
- while (attribute_names[i])
- {
- const char *name;
- const char *val;
-
- name = attribute_names[i];
- val = attribute_values[i];
-
- if (strcmp (name, "saved_x") == 0)
- {
- if (*val)
- {
- pd->info->saved_rect.x = atoi (val);
- pd->info->saved_rect_set = TRUE;
- }
- }
- else if (strcmp (name, "saved_y") == 0)
- {
- if (*val)
- {
- pd->info->saved_rect.y = atoi (val);
- pd->info->saved_rect_set = TRUE;
- }
- }
- else if (strcmp (name, "saved_width") == 0)
- {
- if (*val)
- {
- pd->info->saved_rect.width = atoi (val);
- pd->info->saved_rect_set = TRUE;
- }
- }
- else if (strcmp (name, "saved_height") == 0)
- {
- if (*val)
- {
- pd->info->saved_rect.height = atoi (val);
- pd->info->saved_rect_set = TRUE;
- }
- }
- else
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
- "Unknown attribute %s on <%s> element",
- name, "maximized");
- return;
- }
-
- ++i;
- }
-
- if (pd->info->saved_rect_set)
- meta_topic (META_DEBUG_SM, "Saved unmaximized size %d,%d %dx%d ",
- pd->info->saved_rect.x,
- pd->info->saved_rect.y,
- pd->info->saved_rect.width,
- pd->info->saved_rect.height);
- }
- else if (strcmp (element_name, "geometry") == 0)
- {
- int i;
-
- pd->info->geometry_set = TRUE;
-
- i = 0;
- while (attribute_names[i])
- {
- const char *name;
- const char *val;
-
- name = attribute_names[i];
- val = attribute_values[i];
-
- if (strcmp (name, "x") == 0)
- {
- if (*val)
- pd->info->rect.x = atoi (val);
- }
- else if (strcmp (name, "y") == 0)
- {
- if (*val)
- pd->info->rect.y = atoi (val);
- }
- else if (strcmp (name, "width") == 0)
- {
- if (*val)
- pd->info->rect.width = atoi (val);
- }
- else if (strcmp (name, "height") == 0)
- {
- if (*val)
- pd->info->rect.height = atoi (val);
- }
- else if (strcmp (name, "gravity") == 0)
- {
- if (*val)
- pd->info->gravity = window_gravity_from_string (val);
- }
- else
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
- "Unknown attribute %s on <%s> element",
- name, "geometry");
- return;
- }
-
- ++i;
- }
-
- meta_topic (META_DEBUG_SM, "Loaded geometry %d,%d %dx%d gravity %s",
- pd->info->rect.x,
- pd->info->rect.y,
- pd->info->rect.width,
- pd->info->rect.height,
- meta_gravity_to_string (pd->info->gravity));
- }
- else
- {
- g_set_error (error,
- G_MARKUP_ERROR,
- G_MARKUP_ERROR_UNKNOWN_ELEMENT,
- "Unknown element %s",
- element_name);
- return;
- }
-}
-
-static void
-end_element_handler (GMarkupParseContext *context,
- const gchar *element_name,
- gpointer user_data,
- GError **error)
-{
- ParseData *pd;
-
- pd = user_data;
-
- if (strcmp (element_name, "window") == 0)
- {
- g_assert (pd->info);
-
- window_info_list = g_slist_prepend (window_info_list,
- pd->info);
-
- meta_topic (META_DEBUG_SM, "Loaded window info from session with class: %s name: %s role: %s",
- pd->info->res_class ? pd->info->res_class : "(none)",
- pd->info->res_name ? pd->info->res_name : "(none)",
- pd->info->role ? pd->info->role : "(none)");
-
- pd->info = NULL;
- }
-}
-
-static void
-text_handler (GMarkupParseContext *context,
- const gchar *text,
- gsize text_len,
- gpointer user_data,
- GError **error)
-{
- /* Right now we don't have any elements where we care about their
- * content
- */
-}
-
-static gboolean
-both_null_or_matching (const char *a,
- const char *b)
-{
- if (a == NULL && b == NULL)
- return TRUE;
- else if (a && b && strcmp (a, b) == 0)
- return TRUE;
- else
- return FALSE;
-}
-
-static GSList*
-get_possible_matches (MetaWindow *window)
-{
- /* Get all windows with this client ID */
- GSList *retval;
- GSList *tmp;
- gboolean ignore_client_id;
-
- retval = NULL;
-
- ignore_client_id = g_getenv ("MUTTER_DEBUG_SM") != NULL;
-
- tmp = window_info_list;
- while (tmp != NULL)
- {
- MetaWindowSessionInfo *info;
-
- info = tmp->data;
-
- if ((ignore_client_id ||
- both_null_or_matching (info->id, window->sm_client_id)) &&
- both_null_or_matching (info->res_class, window->res_class) &&
- both_null_or_matching (info->res_name, window->res_name) &&
- both_null_or_matching (info->role, window->role))
- {
- meta_topic (META_DEBUG_SM, "Window %s may match saved window with class: %s name: %s role: %s",
- window->desc,
- info->res_class ? info->res_class : "(none)",
- info->res_name ? info->res_name : "(none)",
- info->role ? info->role : "(none)");
-
- retval = g_slist_prepend (retval, info);
- }
- else
- {
- if (meta_is_verbose ())
- {
- if (!both_null_or_matching (info->id, window->sm_client_id))
- meta_topic (META_DEBUG_SM, "Window %s has SM client ID %s, saved state has %s, no match",
- window->desc,
- window->sm_client_id ? window->sm_client_id : "(none)",
- info->id ? info->id : "(none)");
- else if (!both_null_or_matching (info->res_class, window->res_class))
- meta_topic (META_DEBUG_SM, "Window %s has class %s doesn't match saved class %s, no match",
- window->desc,
- window->res_class ? window->res_class : "(none)",
- info->res_class ? info->res_class : "(none)");
-
- else if (!both_null_or_matching (info->res_name, window->res_name))
- meta_topic (META_DEBUG_SM, "Window %s has name %s doesn't match saved name %s, no match",
- window->desc,
- window->res_name ? window->res_name : "(none)",
- info->res_name ? info->res_name : "(none)");
- else if (!both_null_or_matching (info->role, window->role))
- meta_topic (META_DEBUG_SM, "Window %s has role %s doesn't match saved role %s, no match",
- window->desc,
- window->role ? window->role : "(none)",
- info->role ? info->role : "(none)");
- else
- meta_topic (META_DEBUG_SM, "???? should not happen - window %s doesn't match saved state %s for no good reason",
- window->desc, info->id);
- }
- }
-
- tmp = tmp->next;
- }
-
- return retval;
-}
-
-static const MetaWindowSessionInfo*
-find_best_match (GSList *infos,
- MetaWindow *window)
-{
- GSList *tmp;
- const MetaWindowSessionInfo *matching_title;
- const MetaWindowSessionInfo *matching_type;
-
- matching_title = NULL;
- matching_type = NULL;
-
- tmp = infos;
- while (tmp != NULL)
- {
- MetaWindowSessionInfo *info;
-
- info = tmp->data;
-
- if (matching_title == NULL &&
- both_null_or_matching (info->title, window->title))
- matching_title = info;
-
- if (matching_type == NULL &&
- info->type == window->type)
- matching_type = info;
-
- tmp = tmp->next;
- }
-
- /* Prefer same title, then same type of window, then
- * just pick something. Eventually we could enhance this
- * to e.g. break ties by geometry hint similarity,
- * or other window features.
- */
-
- if (matching_title)
- return matching_title;
- else if (matching_type)
- return matching_type;
- else
- return infos->data;
-}
-
-const MetaWindowSessionInfo*
-meta_window_lookup_saved_state (MetaWindow *window)
-{
- GSList *possibles;
- const MetaWindowSessionInfo *info;
-
- /* Window is not session managed.
- * I haven't yet figured out how to deal with these
- * in a way that doesn't cause broken side effects in
- * situations other than on session restore.
- */
- if (window->sm_client_id == NULL)
- {
- meta_topic (META_DEBUG_SM,
- "Window %s is not session managed, not checking for saved state",
- window->desc);
- return NULL;
- }
-
- possibles = get_possible_matches (window);
-
- if (possibles == NULL)
- {
- meta_topic (META_DEBUG_SM,
- "Window %s has no possible matches in the list of saved window states",
- window->desc);
- return NULL;
- }
-
- info = find_best_match (possibles, window);
-
- g_slist_free (possibles);
-
- return info;
-}
-
-void
-meta_window_release_saved_state (const MetaWindowSessionInfo *info)
-{
- /* We don't want to use the same saved state again for another
- * window.
- */
- window_info_list = g_slist_remove (window_info_list, info);
-
- session_info_free ((MetaWindowSessionInfo*) info);
-}
-
-static void
-session_info_free (MetaWindowSessionInfo *info)
-{
- 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);
-
- g_free (info);
-}
-
-static MetaWindowSessionInfo*
-session_info_new (void)
-{
- MetaWindowSessionInfo *info;
-
- info = g_new0 (MetaWindowSessionInfo, 1);
-
- info->type = META_WINDOW_NORMAL;
- info->gravity = META_GRAVITY_NORTH_WEST;
-
- return info;
-}
-
-static char* full_save_path = NULL;
-
-static void
-regenerate_save_file (void)
-{
- g_free (full_save_path);
-
- if (client_id)
- full_save_path = g_strconcat (g_get_user_config_dir (),
- G_DIR_SEPARATOR_S "mutter"
- G_DIR_SEPARATOR_S "sessions" G_DIR_SEPARATOR_S,
- client_id,
- ".ms",
- NULL);
- else
- full_save_path = NULL;
-}
-
-static const char*
-full_save_file (void)
-{
- return full_save_path;
-}
-
-static int
-windows_cmp_by_title (MetaWindow *a,
- MetaWindow *b)
-{
- return g_utf8_collate (a->title, b->title);
-}
-
-static void
-finish_interact (gboolean shutdown)
-{
- if (current_state == STATE_DONE_WITH_INTERACT) /* paranoia */
- {
- SmcInteractDone (session_connection, False /* don't cancel logout */);
-
- save_yourself_possibly_done (shutdown, TRUE);
- }
-}
-
-static void
-dialog_closed (GPid pid, int status, gpointer user_data)
-{
- gboolean shutdown = GPOINTER_TO_INT (user_data);
-
- if (WIFEXITED (status) && WEXITSTATUS (status) == 0) /* pressed "OK" */
- {
- finish_interact (shutdown);
- }
-}
-
-static void
-warn_about_lame_clients_and_finish_interact (gboolean shutdown)
-{
- GSList *lame = NULL;
- GSList *windows;
- GSList *lame_details = NULL;
- GSList *tmp;
- GSList *columns = NULL;
- GPid pid;
-
- windows = meta_display_list_windows (meta_get_display (), META_LIST_DEFAULT);
- tmp = windows;
- while (tmp != NULL)
- {
- MetaWindow *window;
-
- window = tmp->data;
-
- /* only complain about normal windows, the others
- * are kind of dumb to worry about
- */
- if (window->sm_client_id == NULL &&
- window->type == META_WINDOW_NORMAL)
- lame = g_slist_prepend (lame, window);
-
- tmp = tmp->next;
- }
-
- g_slist_free (windows);
-
- if (lame == NULL)
- {
- /* No lame apps. */
- finish_interact (shutdown);
- return;
- }
-
- columns = g_slist_prepend (columns, (gpointer)"Window");
- columns = g_slist_prepend (columns, (gpointer)"Class");
-
- lame = g_slist_sort (lame, (GCompareFunc) windows_cmp_by_title);
-
- tmp = lame;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- lame_details = g_slist_prepend (lame_details,
- w->res_class ? w->res_class : (gpointer)"");
- lame_details = g_slist_prepend (lame_details,
- w->title);
-
- tmp = tmp->next;
- }
- g_slist_free (lame);
-
- pid = meta_show_dialog("--list",
- _("These windows do not support “save current setup” "
- "and will have to be restarted manually next time "
- "you log in."),
- "240",
- meta_get_display()->x11_display->screen_name,
- NULL, NULL, NULL,
- None,
- columns,
- lame_details);
-
- g_slist_free (lame_details);
-
- g_child_watch_add (pid, dialog_closed, GINT_TO_POINTER (shutdown));
-}
-
-#endif /* HAVE_SM */
diff --git a/src/x11/session.h b/src/x11/session.h
deleted file mode 100644
index 8df77efbc..000000000
--- a/src/x11/session.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/**
- * \file session.h Session management
- *
- * Maps windows to information about their placing and state on startup.
- * This is window matching, which we have a policy of leaving in general
- * to programs such as Devil's Pie, but the session manager specification
- * 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
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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_SESSION_H
-#define META_SESSION_H
-
-#include "core/window-private.h"
-
-typedef struct _MetaWindowSessionInfo MetaWindowSessionInfo;
-
-struct _MetaWindowSessionInfo
-{
- /* Fields we use to match against */
-
- char *id;
- char *res_class;
- char *res_name;
- char *title;
- char *role;
- MetaWindowType type;
-
- /* Information we restore */
-
- 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.
- */
- MetaGravity gravity;
- MetaRectangle rect;
- MetaRectangle saved_rect;
- guint on_all_workspaces : 1;
- guint minimized : 1;
- guint maximized : 1;
-
- guint stack_position_set : 1;
- guint geometry_set : 1;
- guint on_all_workspaces_set : 1;
- guint minimized_set : 1;
- guint maximized_set : 1;
- guint saved_rect_set : 1;
-};
-
-/* If lookup_saved_state returns something, it should be used,
- * and then released when you're done with it.
- */
-const MetaWindowSessionInfo* meta_window_lookup_saved_state (MetaWindow *window);
-void meta_window_release_saved_state (const MetaWindowSessionInfo *info);
-
-void meta_session_init (MetaContext *context,
- const char *client_id,
- const char *save_file);
-
-
-void meta_session_shutdown (void);
-
-#endif
-
-
-
-
diff --git a/src/x11/window-props.c b/src/x11/window-props.c
deleted file mode 100644
index 1d8cf63a6..000000000
--- a/src/x11/window-props.c
+++ /dev/null
@@ -1,2012 +0,0 @@
-/* -*- 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.
- *
- * The guts of this system are in meta_display_init_window_prop_hooks().
- * Reading this function will give you insight into how this all fits
- * together.
- */
-
-/*
- * Copyright (C) 2001, 2002, 2003 Red Hat, Inc.
- * Copyright (C) 2004, 2005 Elijah Newren
- * Copyright (C) 2009 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/>.
- */
-
-#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 "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
-#endif
-
-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;
- MetaPropHookFlags flags;
-};
-
-static void init_prop_value (MetaWindow *window,
- MetaWindowPropHooks *hooks,
- MetaPropValue *value);
-static void reload_prop_value (MetaWindow *window,
- MetaWindowPropHooks *hooks,
- MetaPropValue *value,
- gboolean initial);
-static MetaWindowPropHooks *find_hooks (MetaX11Display *x11_display,
- Atom property);
-
-
-void
-meta_window_reload_property_from_xwindow (MetaWindow *window,
- Window xwindow,
- Atom property,
- gboolean initial)
-{
- MetaPropValue value = { 0, };
- MetaWindowPropHooks *hooks;
-
- hooks = find_hooks (window->display->x11_display, property);
- if (!hooks)
- return;
-
- if ((hooks->flags & INIT_ONLY) && !initial)
- return;
-
- init_prop_value (window, hooks, &value);
-
- meta_prop_get_values (window->display->x11_display, xwindow,
- &value, 1);
-
- reload_prop_value (window, hooks, &value,
- initial);
-
- meta_prop_free_values (&value, 1);
-}
-
-static void
-meta_window_reload_property (MetaWindow *window,
- Atom property,
- gboolean initial)
-{
- meta_window_reload_property_from_xwindow (window,
- window->xwindow,
- property,
- initial);
-}
-
-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, x11_display->n_prop_hooks);
-
- j = 0;
- for (i = 0; i < x11_display->n_prop_hooks; i++)
- {
- MetaWindowPropHooks *hooks = &x11_display->prop_hooks_table[i];
- if (hooks->flags & LOAD_INIT)
- {
- init_prop_value (window, hooks, &values[j]);
- ++j;
- }
- }
- n_properties = j;
-
- meta_prop_get_values (window->display->x11_display, window->xwindow,
- values, n_properties);
-
- j = 0;
- for (i = 0; i < x11_display->n_prop_hooks; i++)
- {
- 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 ||
- hooks->flags & FORCE_INIT)
- reload_prop_value (window, hooks, &values[j], TRUE);
- ++j;
- }
- }
-
- meta_prop_free_values (values, n_properties);
-
- g_free (values);
-}
-
-/* Fill in the MetaPropValue used to get the value of "property" */
-static void
-init_prop_value (MetaWindow *window,
- MetaWindowPropHooks *hooks,
- MetaPropValue *value)
-{
- if (!hooks || hooks->type == META_PROP_VALUE_INVALID ||
- (window->override_redirect && !(hooks->flags & INCLUDE_OR)))
- {
- value->type = META_PROP_VALUE_INVALID;
- value->atom = None;
- }
- else
- {
- value->type = hooks->type;
- value->atom = hooks->property;
- }
-}
-
-static void
-reload_prop_value (MetaWindow *window,
- MetaWindowPropHooks *hooks,
- MetaPropValue *value,
- gboolean initial)
-{
- if (!(window->override_redirect && !(hooks->flags & INCLUDE_OR)))
- (* hooks->reload_func) (window, value, initial);
-}
-
-static void
-reload_wm_client_machine (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- g_free (window->wm_client_machine);
- window->wm_client_machine = NULL;
-
- if (value->type != META_PROP_VALUE_INVALID)
- window->wm_client_machine = g_strdup (value->v.str);
-
- meta_verbose ("Window has client machine \"%s\"",
- window->wm_client_machine ? window->wm_client_machine : "unset");
-
- if (window->wm_client_machine == NULL)
- {
- window->is_remote = FALSE;
- }
- else
- {
- char hostname[HOST_NAME_MAX + 1] = "";
-
- gethostname (hostname, HOST_NAME_MAX + 1);
-
- window->is_remote = g_strcmp0 (window->wm_client_machine, hostname) != 0;
- }
-}
-
-static void
-complain_about_broken_client (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- meta_warning ("Broken client! Window %s changed client leader window or SM client ID",
- window->desc);
-}
-
-static void
-reload_net_wm_window_type (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- MetaX11Display *x11_display = window->display->x11_display;
- MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
- MetaWindowX11Private *priv = meta_window_x11_get_private (window_x11);
-
- 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)
-{
- MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
- MetaWindowX11Private *priv = meta_window_x11_get_private (window_x11);
-
- meta_icon_cache_property_changed (&priv->icon_cache,
- window->display->x11_display,
- atom);
- meta_window_queue(window, META_QUEUE_UPDATE_ICON);
-}
-
-static void
-reload_net_wm_icon (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- reload_icon (window, window->display->x11_display->atom__NET_WM_ICON);
-}
-
-static void
-reload_kwm_win_icon (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- reload_icon (window, window->display->x11_display->atom__KWM_WIN_ICON);
-}
-
-static void
-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 ("_NET_WM_ICON_GEOMETRY on %s has %d values instead of 4",
- 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);
- }
- }
- 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;
-
- /* 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_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 ("_GTK_FRAME_EXTENTS on %s has %d values instead of 4",
- window->desc, value->v.cardinal_list.n_cardinals);
- }
- else
- {
- 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_custom_frame_extents (window, NULL, initial);
- }
-}
-
-static void
-reload_struts (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- meta_window_update_struts (window);
-}
-
-static void
-reload_wm_window_role (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- g_clear_pointer (&window->role, g_free);
- if (value->type != META_PROP_VALUE_INVALID)
- window->role = g_strdup (value->v.str);
-}
-
-static void
-reload_net_wm_user_time (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- if (value->type != META_PROP_VALUE_INVALID)
- {
- uint32_t cardinal = value->v.cardinal;
- meta_window_set_user_time (window, cardinal);
- }
-}
-
-static void
-reload_net_wm_user_time_window (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- 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_x11_display_unregister_x_window (window->display->x11_display,
- window->user_time_window);
- /* Don't get events on not-managed windows */
- XSelectInput (window->display->x11_display->xdisplay,
- window->user_time_window,
- NoEventMask);
- }
-
- /* 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_x11_display_lookup_x_window (window->display->x11_display,
- value->v.xwindow);
- if (prev_owner && prev_owner->user_time_window == value->v.xwindow)
- {
- meta_x11_display_unregister_x_window (window->display->x11_display,
- value->v.xwindow);
- prev_owner->user_time_window = None;
- }
-
- /* Obtain the new NET_WM_USER_TIME_WINDOW and register it */
- window->user_time_window = value->v.xwindow;
- if (window->user_time_window != None)
- {
- /* Kind of a hack; display.c:event_callback() ignores events
- * for unknown windows. We make window->user_time_window
- * known by registering it with window (despite the fact
- * that window->xwindow is already registered with window).
- * This basically means that property notifies to either the
- * window->user_time_window or window->xwindow will be
- * treated identically and will result in functions for
- * window being called to update it. Maybe we should ignore
- * any property notifies to window->user_time_window other
- * than atom__NET_WM_USER_TIME ones, but I just don't care
- * and it's not specified in the spec anyway.
- */
- meta_x11_display_register_x_window (window->display->x11_display,
- &window->user_time_window,
- window);
- /* Just listen for property notify events */
- XSelectInput (window->display->x11_display->xdisplay,
- window->user_time_window,
- PropertyChangeMask);
-
- /* Manually load the _NET_WM_USER_TIME field from the given window
- * at this time as well. If the user_time_window ever broadens in
- * scope, we'll probably want to load all relevant properties here.
- */
- meta_window_reload_property_from_xwindow (
- window,
- window->user_time_window,
- window->display->x11_display->atom__NET_WM_USER_TIME,
- initial);
- }
- }
-}
-
-#define MAX_TITLE_LENGTH 512
-
-/**
- * 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.
- */
-static gboolean
-set_title_text (MetaWindow *window,
- gboolean previous_was_modified,
- const char *title,
- Atom atom,
- char **target)
-{
- gboolean modified = FALSE;
-
- if (!target)
- return FALSE;
-
- g_free (*target);
-
- if (!title)
- *target = g_strdup ("");
- else if (g_utf8_strlen (title, MAX_TITLE_LENGTH + 1) > MAX_TITLE_LENGTH)
- {
- *target = meta_g_utf8_strndup (title, MAX_TITLE_LENGTH);
- modified = TRUE;
- }
- /* if WM_CLIENT_MACHINE indicates this machine is on a remote host
- * lets place that hostname in the title */
- else if (meta_window_is_remote (window))
- {
- *target = g_strdup_printf (_("%s (on %s)"),
- title, window->wm_client_machine);
- modified = TRUE;
- }
- else
- *target = g_strdup (title);
-
- if (modified && atom != None)
- 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_x11_error_trap_push (window->display->x11_display);
- XDeleteProperty (window->display->x11_display->xdisplay,
- window->xwindow,
- atom);
- meta_x11_error_trap_pop (window->display->x11_display);
- }
-
- return modified;
-}
-
-static void
-set_window_title (MetaWindow *window,
- const char *title)
-{
- MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
- MetaWindowX11Private *priv = meta_window_x11_get_private (window_x11);
-
- char *new_title = NULL;
-
- gboolean modified =
- set_title_text (window,
- priv->using_net_wm_visible_name,
- 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
-reload_net_wm_name (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
- MetaWindowX11Private *priv = meta_window_x11_get_private (window_x11);
-
- if (value->type != META_PROP_VALUE_INVALID)
- {
- set_window_title (window, value->v.str);
- priv->using_net_wm_name = TRUE;
-
- meta_verbose ("Using _NET_WM_NAME for new title of %s: \"%s\"",
- window->desc, window->title);
- }
- else
- {
- set_window_title (window, NULL);
- priv->using_net_wm_name = FALSE;
- if (!initial)
- meta_window_reload_property (window, XA_WM_NAME, FALSE);
- }
-}
-
-static void
-reload_wm_name (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
- MetaWindowX11Private *priv = meta_window_x11_get_private (window_x11);
-
- if (priv->using_net_wm_name)
- {
- meta_verbose ("Ignoring WM_NAME \"%s\" as _NET_WM_NAME is set",
- value->v.str);
- return;
- }
-
- if (value->type != META_PROP_VALUE_INVALID)
- {
- set_window_title (window, value->v.str);
-
- meta_verbose ("Using WM_NAME for new title of %s: \"%s\"",
- window->desc, window->title);
- }
- else
- {
- set_window_title (window, NULL);
- }
-}
-
-static void
-meta_window_set_opaque_region (MetaWindow *window,
- cairo_region_t *region)
-{
- if (cairo_region_equal (window->opaque_region, region))
- return;
-
- g_clear_pointer (&window->opaque_region, cairo_region_destroy);
-
- if (region != NULL)
- window->opaque_region = cairo_region_reference (region);
-
- meta_compositor_window_shape_changed (window->display->compositor, window);
-}
-
-static void
-reload_opaque_region (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- cairo_region_t *opaque_region = NULL;
-
- if (value->type != META_PROP_VALUE_INVALID)
- {
- uint32_t *region = value->v.cardinal_list.cardinals;
- int nitems = value->v.cardinal_list.n_cardinals;
-
- cairo_rectangle_int_t *rects;
- int i, rect_index, nrects;
-
- if (nitems % 4 != 0)
- {
- meta_verbose ("_NET_WM_OPAQUE_REGION does not have a list of 4-tuples.");
- goto out;
- }
-
- /* empty region */
- if (nitems == 0)
- goto out;
-
- nrects = nitems / 4;
-
- rects = g_new (cairo_rectangle_int_t, nrects);
-
- rect_index = 0;
- i = 0;
- while (i < nitems)
- {
- cairo_rectangle_int_t *rect = &rects[rect_index];
-
- rect->x = region[i++];
- rect->y = region[i++];
- rect->width = region[i++];
- rect->height = region[i++];
-
- rect_index++;
- }
-
- opaque_region = cairo_region_create_rectangles (rects, nrects);
-
- g_free (rects);
- }
-
- out:
- meta_window_set_opaque_region (window, opaque_region);
- cairo_region_destroy (opaque_region);
-}
-
-static void
-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->mutter_hints;
- gboolean changed = FALSE;
-
- if (new_hints)
- {
- if (!old_hints || strcmp (new_hints, old_hints))
- changed = TRUE;
- }
- else
- {
- if (old_hints)
- changed = TRUE;
- }
-
- if (changed)
- {
- g_free (old_hints);
-
- if (new_hints)
- window->mutter_hints = g_strdup (new_hints);
- else
- window->mutter_hints = NULL;
-
- g_object_notify (G_OBJECT (window), "mutter-hints");
- }
- }
- else if (window->mutter_hints)
- {
- g_free (window->mutter_hints);
- window->mutter_hints = NULL;
-
- g_object_notify (G_OBJECT (window), "mutter-hints");
- }
-}
-
-static void
-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 = meta_window_x11_get_private (window_x11);
-
- int i;
-
- /* We know this is only an initial window creation,
- * clients don't change the property.
- */
-
- if (!initial) {
- /* no, they DON'T change the property */
- meta_verbose ("Ignoring _NET_WM_STATE: we should be the one who set "
- "the property in the first place");
- return;
- }
-
- window->shaded = FALSE;
- window->maximized_horizontally = FALSE;
- window->maximized_vertically = FALSE;
- window->fullscreen = 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;
-
- if (value->type == META_PROP_VALUE_INVALID)
- return;
-
- i = 0;
- while (i < value->v.atom_list.n_atoms)
- {
- 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] == x11_display->atom__NET_WM_STATE_MAXIMIZED_HORZ)
- window->maximize_horizontally_after_placement = TRUE;
- 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] == x11_display->atom__NET_WM_STATE_HIDDEN)
- window->minimize_after_placement = TRUE;
- 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] == x11_display->atom__NET_WM_STATE_BELOW)
- window->wm_state_below = TRUE;
- 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] == x11_display->atom__NET_WM_STATE_STICKY)
- window->on_all_workspaces_requested = TRUE;
-
- ++i;
- }
-
- meta_verbose ("Reloaded _NET_WM_STATE for %s",
- window->desc);
-
- meta_window_x11_recalc_window_type (window);
- meta_window_recalc_features (window);
-}
-
-static void
-reload_mwm_hints (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- MotifWmHints *hints;
- gboolean old_decorated = window->decorated;
-
- window->mwm_decorated = TRUE;
- window->mwm_border_only = FALSE;
- window->mwm_has_close_func = TRUE;
- window->mwm_has_minimize_func = TRUE;
- window->mwm_has_maximize_func = TRUE;
- window->mwm_has_move_func = TRUE;
- window->mwm_has_resize_func = TRUE;
-
- if (value->type == META_PROP_VALUE_INVALID)
- {
- meta_verbose ("Window %s has no MWM hints", window->desc);
- meta_window_recalc_features (window);
- return;
- }
-
- hints = value->v.motif_hints;
-
- /* We support those MWM hints deemed non-stupid */
-
- meta_verbose ("Window %s has MWM hints",
- window->desc);
-
- if (hints->flags & MWM_HINTS_DECORATIONS)
- {
- meta_verbose ("Window %s sets MWM_HINTS_DECORATIONS 0x%x",
- window->desc, hints->decorations);
-
- if (hints->decorations == 0)
- window->mwm_decorated = FALSE;
- /* some input methods use this */
- else if (hints->decorations == MWM_DECOR_BORDER)
- window->mwm_border_only = TRUE;
- }
- else
- meta_verbose ("Decorations flag unset");
-
- if (hints->flags & MWM_HINTS_FUNCTIONS)
- {
- gboolean toggle_value;
-
- meta_verbose ("Window %s sets MWM_HINTS_FUNCTIONS 0x%x",
- window->desc, hints->functions);
-
- /* If _ALL is specified, then other flags indicate what to turn off;
- * if ALL is not specified, flags are what to turn on.
- * at least, I think so
- */
-
- if ((hints->functions & MWM_FUNC_ALL) == 0)
- {
- toggle_value = TRUE;
-
- meta_verbose ("Window %s disables all funcs then reenables some",
- window->desc);
- window->mwm_has_close_func = FALSE;
- window->mwm_has_minimize_func = FALSE;
- window->mwm_has_maximize_func = FALSE;
- window->mwm_has_move_func = FALSE;
- window->mwm_has_resize_func = FALSE;
- }
- else
- {
- meta_verbose ("Window %s enables all funcs then disables some",
- window->desc);
- toggle_value = FALSE;
- }
-
- if ((hints->functions & MWM_FUNC_CLOSE) != 0)
- {
- meta_verbose ("Window %s toggles close via MWM hints",
- window->desc);
- window->mwm_has_close_func = toggle_value;
- }
- if ((hints->functions & MWM_FUNC_MINIMIZE) != 0)
- {
- meta_verbose ("Window %s toggles minimize via MWM hints",
- window->desc);
- window->mwm_has_minimize_func = toggle_value;
- }
- if ((hints->functions & MWM_FUNC_MAXIMIZE) != 0)
- {
- meta_verbose ("Window %s toggles maximize via MWM hints",
- window->desc);
- window->mwm_has_maximize_func = toggle_value;
- }
- if ((hints->functions & MWM_FUNC_MOVE) != 0)
- {
- meta_verbose ("Window %s toggles move via MWM hints",
- window->desc);
- window->mwm_has_move_func = toggle_value;
- }
- if ((hints->functions & MWM_FUNC_RESIZE) != 0)
- {
- meta_verbose ("Window %s toggles resize via MWM hints",
- window->desc);
- window->mwm_has_resize_func = toggle_value;
- }
- }
- else
- {
- meta_verbose ("Functions flag unset");
- }
-
- meta_window_recalc_features (window);
-
- /* We do all this anyhow at the end of meta_window_x11_new() */
- if (!window->constructing)
- {
- if (window->decorated)
- meta_window_ensure_frame (window);
- else
- meta_window_destroy_frame (window);
-
- meta_window_queue (window,
- META_QUEUE_MOVE_RESIZE |
- /* because ensure/destroy frame may unmap: */
- META_QUEUE_CALC_SHOWING);
-
- if (old_decorated != window->decorated)
- g_object_notify (G_OBJECT (window), "decorated");
- }
-}
-
-static void
-reload_wm_class (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- if (value->type != META_PROP_VALUE_INVALID)
- {
- 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'",
- window->desc,
- window->res_class ? window->res_class : "none",
- window->res_name ? window->res_name : "none");
-}
-
-static void
-reload_net_wm_desktop (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- if (value->type != META_PROP_VALUE_INVALID)
- {
- window->initial_workspace_set = TRUE;
- window->initial_workspace = value->v.cardinal;
- meta_topic (META_DEBUG_PLACEMENT,
- "Read initial workspace prop %d for %s",
- window->initial_workspace, window->desc);
- }
-}
-
-static void
-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;
-
- g_free (window->startup_id);
-
- if (value->type != META_PROP_VALUE_INVALID)
- window->startup_id = g_strdup (value->v.str);
- else
- window->startup_id = NULL;
-
- /* Update timestamp and workspace on a running window */
- if (!window->constructing)
- {
- window->initial_timestamp_set = 0;
- window->initial_workspace_set = 0;
-
- 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_workspace_manager_get_workspace_by_index (workspace_manager,
- window->initial_workspace);
-
- meta_window_activate_with_workspace (window, timestamp, workspace);
- }
- }
-
- meta_verbose ("New _NET_STARTUP_ID \"%s\" for %s",
- window->startup_id ? window->startup_id : "unset",
- window->desc);
-}
-
-static void
-reload_update_counter (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- if (value->type != META_PROP_VALUE_INVALID)
- {
- 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");
- return;
- }
-
- if (value->v.xcounter_list.n_counters == 1)
- {
- window->sync_request_counter = value->v.xcounter_list.counters[0];
- window->extended_sync_request_counter = FALSE;
- }
- else
- {
- window->sync_request_counter = value->v.xcounter_list.counters[1];
- window->extended_sync_request_counter = TRUE;
- }
- meta_verbose ("Window has _NET_WM_SYNC_REQUEST_COUNTER 0x%lx (extended=%s)",
- window->sync_request_counter,
- window->extended_sync_request_counter ? "true" : "false");
-
- if (window->extended_sync_request_counter)
- 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) \
- (FLAG_IS_OFF(old,flag) && \
- FLAG_IS_ON(new,flag))
-
-#define FLAG_TOGGLED_OFF(old,new,flag) \
- (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))
-
-static void
-spew_size_hints_differences (const XSizeHints *old,
- const XSizeHints *new)
-{
- if (FLAG_CHANGED (old, new, USPosition))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: USPosition now %s",
- FLAG_TOGGLED_ON (old, new, USPosition) ? "set" : "unset");
- if (FLAG_CHANGED (old, new, USSize))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: USSize now %s",
- FLAG_TOGGLED_ON (old, new, USSize) ? "set" : "unset");
- if (FLAG_CHANGED (old, new, PPosition))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PPosition now %s",
- FLAG_TOGGLED_ON (old, new, PPosition) ? "set" : "unset");
- if (FLAG_CHANGED (old, new, PSize))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PSize now %s",
- FLAG_TOGGLED_ON (old, new, PSize) ? "set" : "unset");
- if (FLAG_CHANGED (old, new, PMinSize))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PMinSize now %s (%d x %d -> %d x %d)",
- FLAG_TOGGLED_ON (old, new, PMinSize) ? "set" : "unset",
- old->min_width, old->min_height,
- new->min_width, new->min_height);
- if (FLAG_CHANGED (old, new, PMaxSize))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PMaxSize now %s (%d x %d -> %d x %d)",
- FLAG_TOGGLED_ON (old, new, PMaxSize) ? "set" : "unset",
- old->max_width, old->max_height,
- new->max_width, new->max_height);
- if (FLAG_CHANGED (old, new, PResizeInc))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PResizeInc now %s (width_inc %d -> %d height_inc %d -> %d)",
- FLAG_TOGGLED_ON (old, new, PResizeInc) ? "set" : "unset",
- old->width_inc, new->width_inc,
- old->height_inc, new->height_inc);
- if (FLAG_CHANGED (old, new, PAspect))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PAspect now %s (min %d/%d -> %d/%d max %d/%d -> %d/%d)",
- FLAG_TOGGLED_ON (old, new, PAspect) ? "set" : "unset",
- old->min_aspect.x, old->min_aspect.y,
- new->min_aspect.x, new->min_aspect.y,
- old->max_aspect.x, old->max_aspect.y,
- new->max_aspect.x, new->max_aspect.y);
- if (FLAG_CHANGED (old, new, PBaseSize))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PBaseSize now %s (%d x %d -> %d x %d)",
- FLAG_TOGGLED_ON (old, new, PBaseSize) ? "set" : "unset",
- old->base_width, old->base_height,
- new->base_width, new->base_height);
- if (FLAG_CHANGED (old, new, PWinGravity))
- meta_topic (META_DEBUG_GEOMETRY, "XSizeHints: PWinGravity now %s (%d -> %d)",
- FLAG_TOGGLED_ON (old, new, PWinGravity) ? "set" : "unset",
- old->win_gravity, new->win_gravity);
-}
-
-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;
- /* Some convenience vars */
- int minw, minh, maxw, maxh; /* min/max width/height */
- int basew, baseh, winc, hinc; /* base width/height, width/height increment */
-
- /* Save the last ConfigureRequest, which we put here.
- * Values here set in the hints are supposed to
- * be ignored.
- */
- x = window->size_hints.x;
- y = window->size_hints.y;
- w = window->size_hints.width;
- h = window->size_hints.height;
-
- /* as far as I can tell, value->v.size_hints.flags is just to
- * check whether we had old-style normal hints without gravity,
- * base size as returned by XGetNormalHints(), so we don't
- * really use it as we fixup window->size_hints to have those
- * fields if they're missing.
- */
-
- /*
- * When the window is first created, NULL hints will
- * be passed in which will initialize all of the fields
- * as if flags were zero
- */
- if (hints)
- window->size_hints = *hints;
- else
- window->size_hints.flags = 0;
-
- /* Put back saved ConfigureRequest. */
- window->size_hints.x = x;
- window->size_hints.y = y;
- window->size_hints.width = w;
- window->size_hints.height = h;
-
- /* Get base size hints */
- if (window->size_hints.flags & PBaseSize)
- {
- meta_topic (META_DEBUG_GEOMETRY, "Window %s sets base size %d x %d",
- window->desc,
- window->size_hints.base_width,
- window->size_hints.base_height);
- }
- else if (window->size_hints.flags & PMinSize)
- {
- window->size_hints.base_width = window->size_hints.min_width;
- window->size_hints.base_height = window->size_hints.min_height;
- }
- else
- {
- window->size_hints.base_width = 0;
- window->size_hints.base_height = 0;
- }
- window->size_hints.flags |= PBaseSize;
-
- /* Get min size hints */
- if (window->size_hints.flags & PMinSize)
- {
- meta_topic (META_DEBUG_GEOMETRY, "Window %s sets min size %d x %d",
- window->desc,
- window->size_hints.min_width,
- window->size_hints.min_height);
- }
- else if (window->size_hints.flags & PBaseSize)
- {
- window->size_hints.min_width = window->size_hints.base_width;
- window->size_hints.min_height = window->size_hints.base_height;
- }
- else
- {
- window->size_hints.min_width = 0;
- window->size_hints.min_height = 0;
- }
- window->size_hints.flags |= PMinSize;
-
- /* Get max size hints */
- if (window->size_hints.flags & PMaxSize)
- {
- meta_topic (META_DEBUG_GEOMETRY, "Window %s sets max size %d x %d",
- window->desc,
- window->size_hints.max_width,
- window->size_hints.max_height);
- }
- else
- {
- window->size_hints.max_width = G_MAXINT;
- window->size_hints.max_height = G_MAXINT;
- window->size_hints.flags |= PMaxSize;
- }
-
- /* Get resize increment hints */
- if (window->size_hints.flags & PResizeInc)
- {
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets resize width inc: %d height inc: %d",
- window->desc,
- window->size_hints.width_inc,
- window->size_hints.height_inc);
- }
- else
- {
- window->size_hints.width_inc = 1;
- window->size_hints.height_inc = 1;
- window->size_hints.flags |= PResizeInc;
- }
-
- /* Get aspect ratio hints */
- if (window->size_hints.flags & PAspect)
- {
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets min_aspect: %d/%d max_aspect: %d/%d",
- window->desc,
- window->size_hints.min_aspect.x,
- window->size_hints.min_aspect.y,
- window->size_hints.max_aspect.x,
- window->size_hints.max_aspect.y);
- }
- else
- {
- window->size_hints.min_aspect.x = 1;
- window->size_hints.min_aspect.y = G_MAXINT;
- window->size_hints.max_aspect.x = G_MAXINT;
- window->size_hints.max_aspect.y = 1;
- window->size_hints.flags |= PAspect;
- }
-
- /* Get gravity hint */
- if (window->size_hints.flags & PWinGravity)
- {
- meta_topic (META_DEBUG_GEOMETRY, "Window %s sets gravity %d",
- window->desc,
- window->size_hints.win_gravity);
- }
- else
- {
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s doesn't set gravity, using NW",
- window->desc);
- 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 < 1)
- {
- /* someone is on crack */
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets min width to 0, which makes no sense",
- window->desc);
- window->size_hints.min_width = 1;
- }
- 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",
- window->desc);
- window->size_hints.max_width = 1;
- }
- 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",
- window->desc);
- window->size_hints.min_height = 1;
- }
- 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",
- window->desc);
- window->size_hints.max_height = 1;
- }
-
- /* Verify size increment hints are at least 1 pixel */
- if (window->size_hints.width_inc < 1)
- {
- /* app authors find so many ways to smoke crack */
- window->size_hints.width_inc = 1;
- meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 width_inc to 1");
- }
- if (window->size_hints.height_inc < 1)
- {
- /* another cracksmoker */
- window->size_hints.height_inc = 1;
- meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 height_inc to 1");
- }
- /* divide by 0 cracksmokers; note that x & y in (min|max)_aspect are
- * numerator & denominator
- */
- if (window->size_hints.min_aspect.y < 1)
- window->size_hints.min_aspect.y = 1;
- if (window->size_hints.max_aspect.y < 1)
- window->size_hints.max_aspect.y = 1;
-
- minw = window->size_hints.min_width; minh = window->size_hints.min_height;
- maxw = window->size_hints.max_width; maxh = window->size_hints.max_height;
- basew = window->size_hints.base_width; baseh = window->size_hints.base_height;
- winc = window->size_hints.width_inc; hinc = window->size_hints.height_inc;
-
- /* Make sure min and max size hints are consistent with the base + increment
- * size hints. If they're not, it's not a real big deal, but it means the
- * effective min and max size are more restrictive than the application
- * specified values.
- */
- if ((minw - basew) % winc != 0)
- {
- /* Take advantage of integer division throwing away the remainder... */
- window->size_hints.min_width = basew + ((minw - basew)/winc + 1)*winc;
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s has width_inc (%d) that does not evenly divide "
- "min_width - base_width (%d - %d); thus effective "
- "min_width is really %d",
- window->desc,
- winc, minw, basew, window->size_hints.min_width);
- minw = window->size_hints.min_width;
- }
- if (maxw != G_MAXINT && (maxw - basew) % winc != 0)
- {
- /* Take advantage of integer division throwing away the remainder... */
- window->size_hints.max_width = basew + ((maxw - basew)/winc)*winc;
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s has width_inc (%d) that does not evenly divide "
- "max_width - base_width (%d - %d); thus effective "
- "max_width is really %d",
- window->desc,
- winc, maxw, basew, window->size_hints.max_width);
- maxw = window->size_hints.max_width;
- }
- if ((minh - baseh) % hinc != 0)
- {
- /* Take advantage of integer division throwing away the remainder... */
- window->size_hints.min_height = baseh + ((minh - baseh)/hinc + 1)*hinc;
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s has height_inc (%d) that does not evenly divide "
- "min_height - base_height (%d - %d); thus effective "
- "min_height is really %d",
- window->desc,
- hinc, minh, baseh, window->size_hints.min_height);
- minh = window->size_hints.min_height;
- }
- if (maxh != G_MAXINT && (maxh - baseh) % hinc != 0)
- {
- /* Take advantage of integer division throwing away the remainder... */
- window->size_hints.max_height = baseh + ((maxh - baseh)/hinc)*hinc;
-
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s has height_inc (%d) that does not evenly divide "
- "max_height - base_height (%d - %d); thus effective "
- "max_height is really %d",
- window->desc,
- hinc, maxh, baseh, window->size_hints.max_height);
- maxh = window->size_hints.max_height;
- }
-
- /* make sure maximum size hints are compatible with minimum size hints; min
- * size hints take precedence.
- */
- if (window->size_hints.max_width < window->size_hints.min_width)
- {
- /* another cracksmoker */
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets max width %d less than min width %d, "
- "disabling resize",
- window->desc,
- window->size_hints.max_width,
- window->size_hints.min_width);
- maxw = window->size_hints.max_width = window->size_hints.min_width;
- }
- if (window->size_hints.max_height < window->size_hints.min_height)
- {
- /* another cracksmoker */
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets max height %d less than min height %d, "
- "disabling resize",
- window->desc,
- window->size_hints.max_height,
- window->size_hints.min_height);
- maxh = window->size_hints.max_height = window->size_hints.min_height;
- }
-
- /* Make sure the aspect ratio hints are sane. */
- minr = window->size_hints.min_aspect.x /
- (double)window->size_hints.min_aspect.y;
- maxr = window->size_hints.max_aspect.x /
- (double)window->size_hints.max_aspect.y;
- if (minr > maxr)
- {
- /* another cracksmoker; not even minimally (self) consistent */
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets min aspect ratio larger than max aspect "
- "ratio; disabling aspect ratio constraints.",
- window->desc);
- window->size_hints.min_aspect.x = 1;
- window->size_hints.min_aspect.y = G_MAXINT;
- window->size_hints.max_aspect.x = G_MAXINT;
- window->size_hints.max_aspect.y = 1;
- }
- else /* check consistency of aspect ratio hints with other hints */
- {
- if (minh > 0 && minr > (maxw / (double)minh))
- {
- /* another cracksmoker */
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets min aspect ratio larger than largest "
- "aspect ratio possible given min/max size constraints; "
- "disabling min aspect ratio constraint.",
- window->desc);
- window->size_hints.min_aspect.x = 1;
- window->size_hints.min_aspect.y = G_MAXINT;
- }
- if (maxr < (minw / (double)maxh))
- {
- /* another cracksmoker */
- meta_topic (META_DEBUG_GEOMETRY,
- "Window %s sets max aspect ratio smaller than smallest "
- "aspect ratio possible given min/max size constraints; "
- "disabling max aspect ratio constraint.",
- window->desc);
- window->size_hints.max_aspect.x = G_MAXINT;
- window->size_hints.max_aspect.y = 1;
- }
- /* FIXME: Would be nice to check that aspect ratios are
- * consistent with base and size increment constraints.
- */
- }
-}
-
-static void
-reload_normal_hints (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- 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", window->desc);
-
- old_hints = window->size_hints;
-
- meta_set_normal_hints (window, value->v.size_hints.hints);
-
- 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);
- }
- }
-}
-
-static void
-reload_wm_protocols (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- int i;
-
- 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;
-
- i = 0;
- while (i < value->v.atom_list.n_atoms)
- {
- if (value->v.atom_list.atoms[i] ==
- 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->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->x11_display->atom__NET_WM_PING)
- meta_window_x11_set_wm_ping (window, TRUE);
- ++i;
- }
-
- meta_verbose ("New _NET_STARTUP_ID \"%s\" for %s",
- window->startup_id ? window->startup_id : "unset",
- window->desc);
-}
-
-static void
-reload_wm_hints (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
- MetaWindowX11Private *priv = meta_window_x11_get_private (window_x11);
- Window old_group_leader;
- gboolean urgent;
-
- old_group_leader = window->xgroup_leader;
-
- /* Fill in defaults */
- window->input = TRUE;
- window->initially_iconic = FALSE;
- window->xgroup_leader = None;
- priv->wm_hints_pixmap = None;
- priv->wm_hints_mask = None;
- urgent = FALSE;
-
- if (value->type != META_PROP_VALUE_INVALID)
- {
- const XWMHints *hints = value->v.wm_hints;
-
- if (hints->flags & InputHint)
- window->input = hints->input;
-
- if (hints->flags & StateHint)
- window->initially_iconic = (hints->initial_state == IconicState);
-
- if (hints->flags & WindowGroupHint)
- window->xgroup_leader = hints->window_group;
-
- if (hints->flags & IconPixmapHint)
- priv->wm_hints_pixmap = hints->icon_pixmap;
-
- if (hints->flags & IconMaskHint)
- priv->wm_hints_mask = hints->icon_mask;
-
- if (hints->flags & XUrgencyHint)
- urgent = TRUE;
-
- meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%lx pixmap: 0x%lx mask: 0x%lx",
- window->input, window->initially_iconic,
- window->xgroup_leader,
- priv->wm_hints_pixmap,
- priv->wm_hints_mask);
- }
-
- if (window->xgroup_leader != old_group_leader)
- {
- meta_verbose ("Window %s changed its group leader to 0x%lx",
- window->desc, window->xgroup_leader);
-
- meta_window_group_leader_changed (window);
- }
-
- meta_window_set_urgent (window, urgent);
-
- meta_icon_cache_property_changed (&priv->icon_cache,
- window->display->x11_display,
- XA_WM_HINTS);
-
- meta_window_queue (window, META_QUEUE_UPDATE_ICON | META_QUEUE_MOVE_RESIZE);
-}
-
-static gboolean
-check_xtransient_for_loop (MetaWindow *window,
- MetaWindow *parent)
-{
- while (parent)
- {
- if (parent == window)
- return TRUE;
-
- parent = meta_x11_display_lookup_x_window (parent->display->x11_display,
- parent->xtransient_for);
- }
-
- return FALSE;
-}
-
-static void
-reload_transient_for (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- MetaWindow *parent = NULL;
- Window transient_for;
-
- if (value->type != META_PROP_VALUE_INVALID)
- {
- transient_for = value->v.xwindow;
-
- parent = meta_x11_display_lookup_x_window (window->display->x11_display,
- transient_for);
- if (!parent)
- {
- meta_warning ("Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.",
- 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->xtransient_for != None)
- {
- /* 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.",
- 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 ("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.", parent->desc, window_kind,
- window->desc);
- transient_for = parent->display->x11_display->xroot;
- parent = NULL;
- }
- }
-
- /* Make sure there is not a loop */
- if (check_xtransient_for_loop (window, parent))
- {
- meta_warning ("WM_TRANSIENT_FOR window 0x%lx for %s would create a "
- "loop.", transient_for, window->desc);
- transient_for = None;
- }
- }
- else
- transient_for = None;
-
- if (transient_for == window->xtransient_for)
- return;
-
- window->xtransient_for = transient_for;
-
- if (window->xtransient_for != None)
- meta_verbose ("Window %s transient for 0x%lx", window->desc, window->xtransient_for);
- else
- meta_verbose ("Window %s is not transient", window->desc);
-
- if (window->xtransient_for == None ||
- window->xtransient_for == window->display->x11_display->xroot)
- meta_window_set_transient_for (window, NULL);
- else
- {
- meta_window_set_transient_for (window, parent);
- }
-}
-
-static void
-reload_gtk_theme_variant (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- char *requested_variant = NULL;
- char *current_variant = window->gtk_theme_variant;
-
- if (value->type != META_PROP_VALUE_INVALID)
- {
- requested_variant = value->v.str;
- meta_verbose ("Requested \"%s\" theme variant for window %s.",
- requested_variant, window->desc);
- }
-
- if (g_strcmp0 (requested_variant, current_variant) != 0)
- {
- g_free (current_variant);
-
- window->gtk_theme_variant = g_strdup (requested_variant);
-
- if (window->frame)
- meta_frame_update_style (window->frame);
- }
-}
-
-static void
-reload_bypass_compositor (MetaWindow *window,
- MetaPropValue *value,
- gboolean initial)
-{
- MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
- MetaWindowX11Private *priv = meta_window_x11_get_private (window_x11);
- MetaBypassCompositorHint requested_value;
- MetaBypassCompositorHint current_value;
-
- if (value->type != META_PROP_VALUE_INVALID)
- requested_value = (MetaBypassCompositorHint) value->v.cardinal;
- else
- requested_value = META_BYPASS_COMPOSITOR_HINT_AUTO;
-
- current_value = priv->bypass_compositor;
- if (requested_value == current_value)
- return;
-
- if (requested_value == META_BYPASS_COMPOSITOR_HINT_ON)
- meta_verbose ("Request to bypass compositor for window %s.", window->desc);
- else if (requested_value == META_BYPASS_COMPOSITOR_HINT_OFF)
- meta_verbose ("Request to don't bypass compositor for window %s.", window->desc);
- else if (requested_value != META_BYPASS_COMPOSITOR_HINT_AUTO)
- return;
-
- priv->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) \
- { \
- g_free (window->var_name); \
- \
- if (value->type != META_PROP_VALUE_INVALID) \
- window->var_name = g_strdup (value->v.str); \
- else \
- window->var_name = NULL; \
- \
- g_object_notify (G_OBJECT (window), propname); \
- }
-
-RELOAD_STRING (gtk_unique_bus_name, "gtk-unique-bus-name")
-RELOAD_STRING (gtk_application_id, "gtk-application-id")
-RELOAD_STRING (gtk_application_object_path, "gtk-application-object-path")
-RELOAD_STRING (gtk_window_object_path, "gtk-window-object-path")
-RELOAD_STRING (gtk_app_menu_object_path, "gtk-app-menu-object-path")
-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.
- *
- * The first column shows which atom the row concerns.
- * The second gives the type of the property data. The property will be
- * queried for its new value, unless the type is given as
- * META_PROP_VALUE_INVALID, in which case nothing will be queried.
- * The third column gives the name of a callback which gets called with the
- * new value. (If the new value was not retrieved because the second column
- * was META_PROP_VALUE_INVALID, the callback still gets called anyway.)
- * This value may be NULL, in which case no callback will be called.
- */
-void
-meta_x11_display_init_window_prop_hooks (MetaX11Display *x11_display)
-{
- /* 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
- * depending on wm_client_machine, so push it slightly sooner.
- *
- * For override-redirect windows, we pay attention to:
- *
- * - properties that identify the window: useful for debugging
- * purposes.
- * - NET_WM_WINDOW_TYPE: can be used to do appropriate handling
- * for different types of override-redirect windows.
- */
- 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 },
- { 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;
- MetaWindowPropHooks *cursor;
-
- table = g_memdup2 (hooks, sizeof (hooks)),
- cursor = table;
-
- g_assert (x11_display->prop_hooks == 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 (!((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 (x11_display->prop_hooks,
- GINT_TO_POINTER (cursor->property),
- cursor);
- cursor++;
- }
- x11_display->n_prop_hooks = cursor - table;
-}
-
-void
-meta_x11_display_free_window_prop_hooks (MetaX11Display *x11_display)
-{
- g_hash_table_unref (x11_display->prop_hooks);
- x11_display->prop_hooks = NULL;
-
- g_free (x11_display->prop_hooks_table);
- x11_display->prop_hooks_table = NULL;
-}
-
-static MetaWindowPropHooks *
-find_hooks (MetaX11Display *x11_display,
- Atom property)
-{
- 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
deleted file mode 100644
index 4f37e0c0f..000000000
--- a/src/x11/window-props.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- 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
deleted file mode 100644
index e12f83be0..000000000
--- a/src/x11/window-x11-private.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- 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"
-#include "x11/window-x11.h"
-
-G_BEGIN_DECLS
-
-/*
- * Mirrors _NET_WM_BYPASS_COMPOSITOR preference values.
- */
-typedef enum _MetaBypassCompositorHint
-{
- META_BYPASS_COMPOSITOR_HINT_AUTO = 0,
- META_BYPASS_COMPOSITOR_HINT_ON = 1,
- META_BYPASS_COMPOSITOR_HINT_OFF = 2,
-} MetaBypassCompositorHint;
-
-typedef struct _MetaWindowX11Private MetaWindowX11Private;
-
-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;
-
- /* Bypass compositor hints */
- MetaBypassCompositorHint bypass_compositor;
-};
-
-MetaWindowX11Private * meta_window_x11_get_private (MetaWindowX11 *window_x11);
-
-void meta_window_x11_set_bypass_compositor_hint (MetaWindowX11 *window_x11,
- MetaBypassCompositorHint requested_value);
-
-G_END_DECLS
-
-#endif
diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
deleted file mode 100644
index 204b49e93..000000000
--- a/src/x11/window-x11.c
+++ /dev/null
@@ -1,4223 +0,0 @@
-/* -*- 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 "compositor/meta-window-actor-private.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)
-{
-}
-
-MetaWindowX11Private *
-meta_window_x11_get_private (MetaWindowX11 *window_x11)
-{
- return 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", 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.",
- window->desc);
- }
- }
-
- meta_verbose ("Window %s client leader: 0x%lx SM_CLIENT_ID: '%s'",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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",
- 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", 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",
- 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",
- 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()",
- 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)",
- 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 void
-focus_window_delayed_unmanaged (gpointer user_data)
-{
- MetaWindowX11DelayedFocusData *data = user_data;
- uint32_t timestamp = data->timestamp;
-
- focus_candidates_maybe_take_and_focus_next (&data->pending_focus_candidates,
- timestamp);
-
- meta_window_x11_delayed_focus_data_free (data);
-}
-
-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", window->desc);
-
- data->unmanaged_id =
- g_signal_connect_swapped (window, "unmanaged",
- G_CALLBACK (focus_window_delayed_unmanaged),
- 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", 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",
- 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",
- 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",
- 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", 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_edge_resistance_flags,
- 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",
- 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 gboolean
-meta_window_x11_can_freeze_commits (MetaWindow *window)
-{
- MetaWindowActor *window_actor;
-
- window_actor = meta_window_actor_from_window (window);
- if (window_actor == NULL)
- return FALSE;
-
- return meta_window_actor_can_freeze_commits (window_actor);
-}
-
-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_can_freeze_commits (window) &&
- !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 update,
- * 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", 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",
- 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",
- struts[0], struts[1], struts[2], struts[3],
- window->desc);
- }
- g_free (struts);
- }
- else
- {
- meta_verbose ("No _NET_WM_STRUT property for %s",
- 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",
- 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",
- 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",
- 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 pid_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_t) 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",
- window->desc, layer, group_max);
- layer = group_max;
- }
- }
-
- meta_topic (META_DEBUG_STACK,
- "Window %s on layer %u type = %u has_focus = %d",
- 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", 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");
- 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");
- 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 (&region, 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;
- MetaRectangle buffer_rect;
-
- /* 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",
- window->desc, window->size_hints.flags & PPosition,
- window->size_hints.flags & USPosition,
- window->type);
- }
-
- meta_window_get_buffer_rect (window, &buffer_rect);
- width = buffer_rect.width;
- height = buffer_rect.height;
- if (!in_grab_op || !meta_grab_op_is_resizing (window->display->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",
- 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.",
- 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).",
- 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",
- 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",
- 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, &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!",
- 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",
- 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", space);
-
- meta_verbose ("Window %s now on_all_workspaces = %d",
- 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",
- 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",
- 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",
- 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", 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",
- 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",
- 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'",
- 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", xwindow);
-
- if (meta_x11_display_xwindow_is_a_no_focus_window (x11_display, xwindow))
- {
- meta_verbose ("Not managing no_focus_window 0x%lx",
- 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",
- xwindow);
- goto error;
- }
-
- if (attrs.root != x11_display->xroot)
- {
- meta_verbose ("Not on our screen");
- goto error;
- }
-
- if (attrs.class == InputOnly)
- {
- meta_verbose ("Not managing InputOnly windows");
- goto error;
- }
-
- if (is_our_xwindow (x11_display, xwindow, &attrs))
- {
- meta_verbose ("Not managing our own windows");
- goto error;
- }
-
- if (maybe_filter_xwindow (display, xwindow, must_be_viewable, &attrs))
- {
- meta_verbose ("Not managing filtered window");
- 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",
- xwindow);
- goto error;
- }
-
- existing_wm_state = state;
- meta_verbose ("WM_STATE of %lx = %s", 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",
- 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 ",
- 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",
- 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");
-
- 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", 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",
- 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_edge_resistance_flags,
- 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;
-}
-
-MetaRectangle
-meta_window_x11_get_client_rect (MetaWindowX11 *window_x11)
-{
- MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
-
- return priv->client_rect;
-}
-
-static gboolean
-has_requested_bypass_compositor (MetaWindowX11 *window_x11)
-{
- MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
-
- return priv->bypass_compositor == META_BYPASS_COMPOSITOR_HINT_ON;
-}
-
-static gboolean
-has_requested_dont_bypass_compositor (MetaWindowX11 *window_x11)
-{
- MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
-
- return priv->bypass_compositor == META_BYPASS_COMPOSITOR_HINT_OFF;
-}
-
-gboolean
-meta_window_x11_can_unredirect (MetaWindowX11 *window_x11)
-{
- MetaWindow *window = META_WINDOW (window_x11);
-
- if (has_requested_dont_bypass_compositor (window_x11))
- return FALSE;
-
- if (window->opacity != 0xFF)
- return FALSE;
-
- if (window->shape_region != NULL)
- return FALSE;
-
- if (!window->monitor)
- return FALSE;
-
- if (window->fullscreen)
- return TRUE;
-
- if (meta_window_is_screen_sized (window))
- return TRUE;
-
- if (has_requested_bypass_compositor (window_x11))
- return TRUE;
-
- if (window->override_redirect)
- {
- MetaRectangle window_rect;
- MetaRectangle logical_monitor_layout;
- MetaLogicalMonitor *logical_monitor = window->monitor;
-
- meta_window_get_frame_rect (window, &window_rect);
- logical_monitor_layout =
- meta_logical_monitor_get_layout (logical_monitor);
-
- if (meta_rectangle_equal (&window_rect, &logical_monitor_layout))
- return TRUE;
- }
-
- return FALSE;
-}
diff --git a/src/x11/window-x11.h b/src/x11/window-x11.h
deleted file mode 100644
index 5e45adf57..000000000
--- a/src/x11/window-x11.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- 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 "core/window-private.h"
-#include "meta/compositor.h"
-#include "meta/window.h"
-
-G_BEGIN_DECLS
-
-#define META_TYPE_WINDOW_X11 (meta_window_x11_get_type())
-G_DECLARE_DERIVABLE_TYPE (MetaWindowX11, meta_window_x11,
- META, WINDOW_X11, MetaWindow)
-
-struct _MetaWindowX11Class
-{
- MetaWindowClass parent_class;
-
- void (*freeze_commits) (MetaWindow *window);
- void (*thaw_commits) (MetaWindow *window);
- gboolean (*always_update_shape) (MetaWindow *window);
-};
-
-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);
-
-MetaRectangle meta_window_x11_get_client_rect (MetaWindowX11 *window_x11);
-
-gboolean meta_window_x11_can_unredirect (MetaWindowX11 *window_x11);
-
-#endif
diff --git a/src/x11/xprops.c b/src/x11/xprops.c
deleted file mode 100644
index 729d5b684..000000000
--- a/src/x11/xprops.c
+++ /dev/null
@@ -1,1126 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Mutter X property convenience routines */
-
-/*
- * Copyright (C) 2001 Havoc Pennington
- * Copyright (C) 2002 Red Hat Inc.
- *
- * Some trivial property-unpacking code from Xlib:
- * Copyright 1987, 1988, 1998 The Open Group
- * Copyright 1988 by Wyse Technology, Inc., San Jose, Ca,
- * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * 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/>.
- */
-
-/***********************************************************
-Copyright 1988 by Wyse Technology, Inc., San Jose, Ca,
-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,
-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.
-
-DIGITAL AND WYSE 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.
-
-******************************************************************/
-
-/*
-
-Copyright 1987, 1988, 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.
-
-*/
-
-
-#include "config.h"
-
-#include "x11/xprops.h"
-
-#include <string.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
-{
- 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
-validate_or_free_results (GetPropertyResults *results,
- int expected_format,
- Atom expected_type,
- gboolean must_have_items)
-{
- MetaX11Display *x11_display = results->x11_display;
- char *type_name;
- char *expected_name;
- char *prop_name;
- const char *title;
- const char *res_class;
- const char *res_name;
- MetaWindow *w;
-
- if (expected_format == results->format &&
- expected_type == results->type &&
- (!must_have_items || results->n_items > 0))
- return TRUE;
-
- 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_x11_display_lookup_x_window (x11_display, results->xwindow);
-
- if (w != NULL)
- {
- title = w->title;
- res_class = w->res_class;
- res_name = w->res_name;
- }
- else
- {
- title = NULL;
- res_class = NULL;
- res_name = NULL;
- }
-
- if (title == NULL)
- title = "unknown";
-
- if (res_class == NULL)
- res_class = "unknown";
-
- if (res_name == NULL)
- res_name = "unknown";
-
- meta_warning ("Window 0x%lx has property %s that was expected to have type %s format %d and actually has type %s format %d n_items %d. This is most likely an application bug, not a window manager bug. The window has title=\"%s\" class=\"%s\" name=\"%s\"",
- results->xwindow,
- prop_name ? prop_name : "(bad atom)",
- expected_name ? expected_name : "(bad atom)",
- expected_format,
- type_name ? type_name : "(bad atom)",
- results->format, (int) results->n_items,
- title, res_class, res_name);
-
- meta_XFree (type_name);
- meta_XFree (expected_name);
- meta_XFree (prop_name);
-
- if (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
-async_get_property_finish (xcb_connection_t *xcb_conn,
- xcb_get_property_cookie_t cookie,
- GetPropertyResults *results)
-{
- g_autofree xcb_get_property_reply_t *reply = NULL;
- g_autofree xcb_generic_error_t *error = NULL;
- int length;
-
- reply = xcb_get_property_reply (xcb_conn, cookie, &error);
- if (error || !reply)
- 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';
- }
-
- return (results->prop != NULL);
-}
-
-static gboolean
-get_property (MetaX11Display *x11_display,
- Window xwindow,
- Atom xatom,
- Atom req_type,
- GetPropertyResults *results)
-{
- 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;
- results->n_items = 0;
- results->type = None;
- results->bytes_after = 0;
- results->format = 0;
-
- 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,
- uint32_t **atoms_p,
- int *n_atoms_p)
-{
- if (!validate_or_free_results (results, 32, XA_ATOM, FALSE))
- return FALSE;
-
- *atoms_p = (uint32_t*) results->prop;
- *n_atoms_p = results->n_items;
- results->prop = NULL;
-
- return TRUE;
-}
-
-static gboolean
-cardinal_list_from_results (GetPropertyResults *results,
- uint32_t **cardinals_p,
- int *n_cardinals_p)
-{
- if (!validate_or_free_results (results, 32, XA_CARDINAL, FALSE))
- return FALSE;
-
- *cardinals_p = (uint32_t *) results->prop;
- *n_cardinals_p = results->n_items;
- results->prop = NULL;
-
- return TRUE;
-}
-
-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 (x11_display, xwindow, xatom, XA_CARDINAL,
- &results))
- return FALSE;
-
- return cardinal_list_from_results (&results, cardinals_p, n_cardinals_p);
-}
-
-static gboolean
-motif_hints_from_results (GetPropertyResults *results,
- MotifWmHints **hints_p)
-{
- *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");
- return FALSE;
- }
-
- /* The issue here is that some old crufty code will set a smaller
- * MotifWmHints than the one we expect, apparently. I'm not sure of
- * the history behind it. See bug #89841 for example.
- */
- *hints_p = g_new0 (MotifWmHints, 1);
- memcpy(*hints_p, results->prop, MIN (sizeof (MotifWmHints),
- results->n_items * sizeof (uint32_t)));
-
- g_free (results->prop);
- results->prop = NULL;
-
- return TRUE;
-}
-
-gboolean
-meta_prop_get_motif_hints (MetaX11Display *x11_display,
- Window xwindow,
- Atom xatom,
- MotifWmHints **hints_p)
-{
- GetPropertyResults results;
-
- *hints_p = NULL;
-
- if (!get_property (x11_display, xwindow, xatom, AnyPropertyType,
- &results))
- return FALSE;
-
- return motif_hints_from_results (&results, hints_p);
-}
-
-static gboolean
-latin1_string_from_results (GetPropertyResults *results,
- char **str_p)
-{
- *str_p = NULL;
-
- if (!validate_or_free_results (results, 8, XA_STRING, FALSE))
- return FALSE;
-
- *str_p = g_strndup ((char *) results->prop, results->n_items);
-
- g_free (results->prop);
- results->prop = NULL;
-
- return TRUE;
-}
-
-gboolean
-meta_prop_get_latin1_string (MetaX11Display *x11_display,
- Window xwindow,
- Atom xatom,
- char **str_p)
-{
- GetPropertyResults results;
-
- *str_p = NULL;
-
- if (!get_property (x11_display, xwindow, xatom, XA_STRING,
- &results))
- return FALSE;
-
- return latin1_string_from_results (&results, str_p);
-}
-
-static gboolean
-utf8_string_from_results (GetPropertyResults *results,
- char **str_p)
-{
- *str_p = NULL;
-
- if (!validate_or_free_results (results, 8,
- results->x11_display->atom_UTF8_STRING, FALSE))
- return FALSE;
-
- if (results->n_items > 0 &&
- !g_utf8_validate ((gchar *)results->prop, results->n_items, NULL))
- {
- char *name;
-
- name = XGetAtomName (results->x11_display->xdisplay, results->xatom);
- meta_warning ("Property %s on window 0x%lx contained invalid UTF-8",
- name, results->xwindow);
- meta_XFree (name);
- g_free (results->prop);
- results->prop = NULL;
-
- return FALSE;
- }
-
- *str_p = g_strndup ((char *) results->prop, results->n_items);
-
- g_free (results->prop);
- results->prop = NULL;
-
- return TRUE;
-}
-
-/* this one freakishly returns g_malloc memory */
-static gboolean
-utf8_list_from_results (GetPropertyResults *results,
- char ***str_p,
- int *n_str_p)
-{
- int i;
- int n_strings;
- char **retval;
- const char *p;
-
- *str_p = NULL;
- *n_str_p = 0;
-
- if (!validate_or_free_results (results, 8,
- results->x11_display->atom_UTF8_STRING, FALSE))
- return FALSE;
-
- /* I'm not sure this is right, but I'm guessing the
- * property is nul-separated
- */
- i = 0;
- n_strings = 0;
- while (i < (int) results->n_items)
- {
- if (results->prop[i] == '\0')
- ++n_strings;
- ++i;
- }
-
- if (results->prop[results->n_items - 1] != '\0')
- ++n_strings;
-
- /* we're guaranteed that results->prop has a nul on the end
- * by XGetWindowProperty
- */
-
- retval = g_new0 (char*, n_strings + 1);
-
- p = (char *)results->prop;
- i = 0;
- while (i < n_strings)
- {
- if (!g_utf8_validate (p, -1, NULL))
- {
- char *name;
-
- 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",
- name, results->xwindow, i);
- meta_XFree (name);
- g_free (results->prop);
- results->prop = NULL;
-
- g_strfreev (retval);
- return FALSE;
- }
-
- retval[i] = g_strdup (p);
-
- p = p + strlen (p) + 1;
- ++i;
- }
-
- *str_p = retval;
- *n_str_p = i;
-
- g_free (results->prop);
- results->prop = NULL;
-
- return TRUE;
-}
-
-/* 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 (x11_display, xwindow, xatom,
- x11_display->atom_UTF8_STRING,
- &results))
- return FALSE;
-
- return utf8_list_from_results (&results, str_p, n_str_p);
-}
-
-void
-meta_prop_set_utf8_string_hint (MetaX11Display *x11_display,
- Window xwindow,
- Atom atom,
- const char *val)
-{
- meta_x11_error_trap_push (x11_display);
- XChangeProperty (x11_display->xdisplay,
- xwindow, atom,
- x11_display->atom_UTF8_STRING,
- 8, PropModeReplace, (guchar*) val, strlen (val));
- meta_x11_error_trap_pop (x11_display);
-}
-
-static gboolean
-window_from_results (GetPropertyResults *results,
- Window *window_p)
-{
- if (!validate_or_free_results (results, 32, XA_WINDOW, TRUE))
- return FALSE;
-
- *window_p = *(uint32_t *) results->prop;
- g_free (results->prop);
- results->prop = NULL;
-
- return TRUE;
-}
-
-static gboolean
-counter_from_results (GetPropertyResults *results,
- XSyncCounter *counter_p)
-{
- if (!validate_or_free_results (results, 32,
- XA_CARDINAL,
- TRUE))
- return FALSE;
-
- *counter_p = *(uint32_t *) results->prop;
- g_free (results->prop);
- results->prop = NULL;
-
- return TRUE;
-}
-
-static gboolean
-counter_list_from_results (GetPropertyResults *results,
- uint32_t **counters_p,
- int *n_counters_p)
-{
- if (!validate_or_free_results (results, 32,
- XA_CARDINAL,
- FALSE))
- return FALSE;
-
- *counters_p = (uint32_t *) results->prop;
- *n_counters_p = results->n_items;
- results->prop = NULL;
-
- return TRUE;
-}
-
-gboolean
-meta_prop_get_window (MetaX11Display *x11_display,
- Window xwindow,
- Atom xatom,
- Window *window_p)
-{
- GetPropertyResults results;
-
- *window_p = None;
-
- if (!get_property (x11_display, xwindow, xatom, XA_WINDOW,
- &results))
- return FALSE;
-
- return window_from_results (&results, window_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 (x11_display, xwindow, xatom,
- XA_CARDINAL, cardinal_p);
-}
-
-static gboolean
-cardinal_with_atom_type_from_results (GetPropertyResults *results,
- Atom prop_type,
- uint32_t *cardinal_p)
-{
- if (!validate_or_free_results (results, 32, prop_type, TRUE))
- return FALSE;
-
- *cardinal_p = *((uint32_t *) results->prop);
- g_free (results->prop);
- results->prop = NULL;
-
- return TRUE;
-}
-
-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 (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 (GetPropertyResults *results,
- const XTextProperty *prop)
-{
- char *ret = NULL;
- char **local_list = NULL;
- const char *charset = NULL;
- int count = 0;
- int res;
-
- res = XmbTextPropertyToTextList (results->x11_display->xdisplay, prop,
- &local_list, &count);
- if (res == XNoMemory || res == XLocaleNotSupported || res == XConverterNotFound)
- goto out;
-
- if (count == 0)
- goto out;
-
- if (g_get_charset (&charset))
- {
- if (!g_utf8_validate (local_list[0], -1, NULL))
- {
- char *name;
-
- 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",
- name, results->xwindow);
- meta_XFree (name);
-
- goto out;
- }
- 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)
-{
- XTextProperty tp;
-
- *utf8_str_p = NULL;
-
- tp.value = results->prop;
- tp.encoding = results->type;
- tp.format = results->format;
- tp.nitems = results->n_items;
-
- *utf8_str_p = text_property_to_utf8 (results, &tp);
-
- g_clear_pointer (&results->prop, g_free);
-
- return *utf8_str_p != NULL;
-}
-
-static gboolean
-wm_hints_from_results (GetPropertyResults *results,
- XWMHints **hints_p)
-{
- XWMHints *hints;
- xPropWMHints *raw;
-
- *hints_p = NULL;
-
- if (!validate_or_free_results (results, 32, XA_WM_HINTS, TRUE))
- return FALSE;
-
- /* pre-R3 bogusly truncated window_group, don't fail on them */
- if (results->n_items < (NumPropWMHintsElements - 1))
- {
- meta_verbose ("WM_HINTS property too short: %d should be %d",
- (int) results->n_items, NumPropWMHintsElements - 1);
- if (results->prop)
- {
- g_free (results->prop);
- results->prop = NULL;
- }
- return FALSE;
- }
-
- hints = g_new0 (XWMHints, 1);
-
- raw = (xPropWMHints*) results->prop;
-
- hints->flags = raw->flags;
- hints->input = (raw->input ? True : False);
- hints->initial_state = raw->initialState;
- hints->icon_pixmap = raw->iconPixmap;
- hints->icon_window = raw->iconWindow;
- 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;
- else
- hints->window_group = 0;
-
- if (results->prop)
- {
- g_free (results->prop);
- results->prop = NULL;
- }
-
- *hints_p = hints;
-
- return TRUE;
-}
-
-static gboolean
-class_hint_from_results (GetPropertyResults *results,
- XClassHint *class_hint)
-{
- int len_name;
-
- class_hint->res_class = NULL;
- class_hint->res_name = NULL;
-
- if (!validate_or_free_results (results, 8, XA_STRING, FALSE))
- return FALSE;
-
- class_hint->res_name = g_strdup ((char *) results->prop);
-
- len_name = strlen (class_hint->res_name);
- if (len_name == (int) results->n_items)
- class_hint->res_class = g_strdup ("");
- else
- class_hint->res_class = g_strdup ((char *) results->prop + len_name + 1);
-
- g_free (results->prop);
- results->prop = NULL;
-
- return TRUE;
-}
-
-static gboolean
-size_hints_from_results (GetPropertyResults *results,
- XSizeHints **hints_p,
- gulong *flags_p)
-{
- xPropSizeHints *raw;
- XSizeHints *hints;
-
- *hints_p = NULL;
- *flags_p = 0;
-
- if (!validate_or_free_results (results, 32, XA_WM_SIZE_HINTS, FALSE))
- return FALSE;
-
- if (results->n_items < OldNumPropSizeElements)
- {
- g_free (results->prop);
- results->prop = NULL;
- return FALSE;
- }
-
- raw = (xPropSizeHints*) results->prop;
-
- hints = g_new0 (XSizeHints, 1);
-
- hints->flags = raw->flags;
- 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 = 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 */
-
- g_free (results->prop);
- results->prop = NULL;
-
- *hints_p = hints;
-
- return TRUE;
-}
-
-static char*
-latin1_to_utf8 (const char *text)
-{
- GString *str;
- const char *p;
-
- str = g_string_new ("");
-
- p = text;
- while (*p)
- {
- g_string_append_unichar (str, *p);
- ++p;
- }
-
- return g_string_free (str, FALSE);
-}
-
-void
-meta_prop_get_values (MetaX11Display *x11_display,
- Window xwindow,
- MetaPropValue *values,
- int n_values)
-{
- int i;
- 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_values, xwindow);
-
- if (n_values == 0)
- return;
-
- 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.
- */
- i = 0;
- while (i < n_values)
- {
- if (values[i].required_type == None)
- {
- switch (values[i].type)
- {
- case META_PROP_VALUE_INVALID:
- /* This means we don't really want a value, e.g. got
- * property notify on an atom we don't care about.
- */
- if (values[i].atom != None)
- meta_bug ("META_PROP_VALUE_INVALID requested in %s", G_STRFUNC);
- break;
- case META_PROP_VALUE_UTF8_LIST:
- case META_PROP_VALUE_UTF8:
- values[i].required_type = x11_display->atom_UTF8_STRING;
- break;
- case META_PROP_VALUE_STRING:
- case META_PROP_VALUE_STRING_AS_UTF8:
- values[i].required_type = XA_STRING;
- break;
- case META_PROP_VALUE_MOTIF_HINTS:
- values[i].required_type = AnyPropertyType;
- break;
- case META_PROP_VALUE_CARDINAL_LIST:
- case META_PROP_VALUE_CARDINAL:
- values[i].required_type = XA_CARDINAL;
- break;
- case META_PROP_VALUE_WINDOW:
- values[i].required_type = XA_WINDOW;
- break;
- case META_PROP_VALUE_ATOM_LIST:
- values[i].required_type = XA_ATOM;
- break;
- case META_PROP_VALUE_TEXT_PROPERTY:
- values[i].required_type = AnyPropertyType;
- break;
- case META_PROP_VALUE_WM_HINTS:
- values[i].required_type = XA_WM_HINTS;
- break;
- case META_PROP_VALUE_CLASS_HINT:
- values[i].required_type = XA_STRING;
- break;
- case META_PROP_VALUE_SIZE_HINTS:
- values[i].required_type = XA_WM_SIZE_HINTS;
- break;
- case META_PROP_VALUE_SYNC_COUNTER:
- case META_PROP_VALUE_SYNC_COUNTER_LIST:
- values[i].required_type = XA_CARDINAL;
- break;
- }
- }
-
- if (values[i].atom != None)
- 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_values, G_STRFUNC);
- XSync (x11_display->xdisplay, False);
-
- /* Collect results, should arrive in order requested */
- i = 0;
- while (i < n_values)
- {
- GetPropertyResults results;
-
- /* 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.
- */
- values[i].type = META_PROP_VALUE_INVALID;
- goto next;
- }
-
- results.x11_display = x11_display;
- results.xwindow = xwindow;
- results.xatom = values[i].atom;
- results.prop = NULL;
- results.n_items = 0;
- results.type = None;
- results.bytes_after = 0;
- results.format = 0;
-
- if (!async_get_property_finish (xcb_conn, tasks[i], &results))
- {
- values[i].type = META_PROP_VALUE_INVALID;
- goto next;
- }
-
- switch (values[i].type)
- {
- case META_PROP_VALUE_INVALID:
- g_assert_not_reached ();
- break;
- case META_PROP_VALUE_UTF8_LIST:
- if (!utf8_list_from_results (&results,
- &values[i].v.string_list.strings,
- &values[i].v.string_list.n_strings))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_UTF8:
- if (!utf8_string_from_results (&results,
- &values[i].v.str))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_STRING:
- if (!latin1_string_from_results (&results,
- &values[i].v.str))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_STRING_AS_UTF8:
- if (!latin1_string_from_results (&results,
- &values[i].v.str))
- values[i].type = META_PROP_VALUE_INVALID;
- else
- {
- char *new_str;
- new_str = latin1_to_utf8 (values[i].v.str);
- g_free (values[i].v.str);
- values[i].v.str = new_str;
- }
- break;
- case META_PROP_VALUE_MOTIF_HINTS:
- if (!motif_hints_from_results (&results,
- &values[i].v.motif_hints))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_CARDINAL_LIST:
- if (!cardinal_list_from_results (&results,
- &values[i].v.cardinal_list.cardinals,
- &values[i].v.cardinal_list.n_cardinals))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_CARDINAL:
- if (!cardinal_with_atom_type_from_results (&results,
- values[i].required_type,
- &values[i].v.cardinal))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_WINDOW:
- if (!window_from_results (&results,
- &values[i].v.xwindow))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_ATOM_LIST:
- if (!atom_list_from_results (&results,
- &values[i].v.atom_list.atoms,
- &values[i].v.atom_list.n_atoms))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_TEXT_PROPERTY:
- if (!text_property_from_results (&results, &values[i].v.str))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_WM_HINTS:
- if (!wm_hints_from_results (&results, &values[i].v.wm_hints))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_CLASS_HINT:
- if (!class_hint_from_results (&results, &values[i].v.class_hint))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_SIZE_HINTS:
- if (!size_hints_from_results (&results,
- &values[i].v.size_hints.hints,
- &values[i].v.size_hints.flags))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_SYNC_COUNTER:
- if (!counter_from_results (&results,
- &values[i].v.xcounter))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- case META_PROP_VALUE_SYNC_COUNTER_LIST:
- if (!counter_list_from_results (&results,
- &values[i].v.xcounter_list.counters,
- &values[i].v.xcounter_list.n_counters))
- values[i].type = META_PROP_VALUE_INVALID;
- break;
- }
-
- next:
- ++i;
- }
-
- g_free (tasks);
-}
-
-static void
-free_value (MetaPropValue *value)
-{
- switch (value->type)
- {
- case META_PROP_VALUE_INVALID:
- break;
- case META_PROP_VALUE_UTF8:
- case META_PROP_VALUE_STRING:
- g_free (value->v.str);
- break;
- case META_PROP_VALUE_STRING_AS_UTF8:
- g_free (value->v.str);
- break;
- case META_PROP_VALUE_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:
- g_free (value->v.atom_list.atoms);
- break;
- case META_PROP_VALUE_TEXT_PROPERTY:
- g_free (value->v.str);
- break;
- case META_PROP_VALUE_WM_HINTS:
- g_free (value->v.wm_hints);
- break;
- case META_PROP_VALUE_CLASS_HINT:
- g_free (value->v.class_hint.res_class);
- g_free (value->v.class_hint.res_name);
- break;
- case META_PROP_VALUE_SIZE_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:
- g_free (value->v.cardinal_list.cardinals);
- break;
- case META_PROP_VALUE_SYNC_COUNTER:
- break;
- case META_PROP_VALUE_SYNC_COUNTER_LIST:
- g_free (value->v.xcounter_list.counters);
- break;
- }
-}
-
-void
-meta_prop_free_values (MetaPropValue *values,
- int n_values)
-{
- int i;
-
- i = 0;
- while (i < n_values)
- {
- free_value (&values[i]);
- ++i;
- }
-
- /* Zero the whole thing to quickly detect breakage */
- memset (values, '\0', sizeof (MetaPropValue) * n_values);
-}
diff --git a/src/x11/xprops.h b/src/x11/xprops.h
deleted file mode 100644
index b8d723f07..000000000
--- a/src/x11/xprops.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/* -*- 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
-
-
-
-