From 871ded20fce663380c67bea9d6e23e8c96dcf435 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Tue, 4 Nov 2025 13:28:23 +0100 Subject: [PATCH 1/8] Drop the X11 backend Part-of: --- .gitlab-ci.yml | 57 +- cogl/cogl/cogl-mutter.h | 7 - cogl/cogl/cogl-renderer-private.h | 16 - cogl/cogl/cogl-renderer.c | 164 +- cogl/cogl/cogl-renderer.h | 17 - cogl/cogl/cogl-types.h | 13 - cogl/cogl/cogl-x11-onscreen.c | 38 - cogl/cogl/cogl-x11-onscreen.h | 44 - cogl/cogl/cogl-xlib-renderer-private.h | 80 - cogl/cogl/cogl-xlib-renderer.c | 435 --- cogl/cogl/cogl-xlib-renderer.h | 54 - cogl/cogl/meson.build | 39 - cogl/cogl/winsys/cogl-glx-display-private.h | 60 - cogl/cogl/winsys/cogl-glx-renderer-private.h | 99 - cogl/cogl/winsys/cogl-onscreen-glx.c | 1088 ------- cogl/cogl/winsys/cogl-onscreen-glx.h | 56 - cogl/cogl/winsys/cogl-onscreen-xlib.c | 284 -- cogl/cogl/winsys/cogl-onscreen-xlib.h | 49 - .../winsys/cogl-texture-pixmap-x11-private.h | 94 - cogl/cogl/winsys/cogl-texture-pixmap-x11.c | 1178 ------- cogl/cogl/winsys/cogl-texture-pixmap-x11.h | 225 -- .../cogl-winsys-egl-feature-functions.h | 6 +- cogl/cogl/winsys/cogl-winsys-egl-private.h | 1 - .../cogl/winsys/cogl-winsys-egl-x11-private.h | 40 - cogl/cogl/winsys/cogl-winsys-egl-x11.c | 638 ---- .../cogl-winsys-glx-feature-functions.h | 210 -- cogl/cogl/winsys/cogl-winsys-glx-private.h | 46 - cogl/cogl/winsys/cogl-winsys-glx.c | 1397 --------- cogl/cogl/winsys/cogl-winsys-private.h | 25 - cogl/meson.build | 11 - config.h.meson | 8 - doc/mutter-relationships.md | 1 - doc/website/index.html | 10 +- meson.build | 39 +- meson.options | 11 - src/backends/meta-barrier.c | 9 - src/backends/meta-dnd-private.h | 15 - src/backends/meta-monitor-manager.c | 4 - src/backends/meta-renderdoc.c | 28 - src/backends/x11/cm/meta-backend-x11-cm.c | 584 ---- src/backends/x11/cm/meta-backend-x11-cm.h | 28 - .../x11/cm/meta-cursor-sprite-xfixes.c | 237 -- .../x11/cm/meta-cursor-sprite-xfixes.h | 34 - src/backends/x11/cm/meta-renderer-x11-cm.c | 112 - src/backends/x11/cm/meta-renderer-x11-cm.h | 37 - src/backends/x11/meta-backend-x11-types.h | 22 - src/backends/x11/meta-backend-x11.c | 1365 -------- src/backends/x11/meta-backend-x11.h | 100 - src/backends/x11/meta-backlight-x11.c | 199 -- src/backends/x11/meta-backlight-x11.h | 38 - src/backends/x11/meta-barrier-x11.c | 234 -- src/backends/x11/meta-barrier-x11.h | 45 - src/backends/x11/meta-clutter-backend-x11.c | 372 --- src/backends/x11/meta-clutter-backend-x11.h | 60 - src/backends/x11/meta-color-manager-x11.c | 201 -- src/backends/x11/meta-color-manager-x11.h | 27 - src/backends/x11/meta-crtc-xrandr.c | 377 --- src/backends/x11/meta-crtc-xrandr.h | 52 - src/backends/x11/meta-cursor-renderer-x11.c | 157 - src/backends/x11/meta-cursor-renderer-x11.h | 34 - src/backends/x11/meta-cursor-tracker-x11.c | 194 -- src/backends/x11/meta-cursor-tracker-x11.h | 29 - src/backends/x11/meta-event-x11.c | 99 - src/backends/x11/meta-event-x11.h | 31 - src/backends/x11/meta-gpu-xrandr.c | 297 -- src/backends/x11/meta-gpu-xrandr.h | 37 - src/backends/x11/meta-input-device-tool-x11.c | 61 - src/backends/x11/meta-input-device-tool-x11.h | 34 - src/backends/x11/meta-input-device-x11.c | 810 ----- src/backends/x11/meta-input-device-x11.h | 92 - src/backends/x11/meta-input-settings-x11.c | 955 ------ src/backends/x11/meta-input-settings-x11.h | 33 - src/backends/x11/meta-keymap-x11.c | 946 ------ src/backends/x11/meta-keymap-x11.h | 55 - .../x11/meta-monitor-manager-xrandr.c | 1023 ------ .../x11/meta-monitor-manager-xrandr.h | 38 - src/backends/x11/meta-output-xrandr.c | 1065 ------- src/backends/x11/meta-output-xrandr.h | 44 - src/backends/x11/meta-renderer-x11.c | 106 - src/backends/x11/meta-renderer-x11.h | 37 - src/backends/x11/meta-seat-x11.c | 2738 ----------------- src/backends/x11/meta-seat-x11.h | 47 - src/backends/x11/meta-sprite-x11.c | 34 - src/backends/x11/meta-sprite-x11.h | 33 - src/backends/x11/meta-stage-x11.c | 804 ----- src/backends/x11/meta-stage-x11.h | 88 - .../x11/meta-virtual-input-device-x11.c | 277 -- .../x11/meta-virtual-input-device-x11.h | 28 - src/backends/x11/meta-xkb-a11y-x11.c | 319 -- src/backends/x11/meta-xkb-a11y-x11.h | 36 - .../x11/nested/meta-backend-x11-nested.c | 301 -- .../x11/nested/meta-backend-x11-nested.h | 29 - .../nested/meta-cursor-renderer-x11-nested.c | 102 - .../nested/meta-cursor-renderer-x11-nested.h | 33 - .../x11/nested/meta-renderer-x11-nested.c | 131 - .../x11/nested/meta-renderer-x11-nested.h | 28 - .../x11/nested/meta-sprite-x11-nested.c | 58 - .../x11/nested/meta-sprite-x11-nested.h | 28 - .../x11/nested/meta-stage-x11-nested.c | 216 -- .../x11/nested/meta-stage-x11-nested.h | 30 - src/compositor/compositor.c | 15 +- src/compositor/meta-compositor-x11.c | 1068 ------- src/compositor/meta-compositor-x11.h | 34 - src/compositor/meta-dnd.c | 109 - src/compositor/meta-plugin-manager.c | 11 - src/compositor/meta-plugin-manager.h | 7 - src/compositor/meta-plugin.c | 24 +- src/compositor/meta-surface-actor-x11.c | 441 --- src/compositor/meta-surface-actor-x11.h | 57 - src/compositor/meta-sync-ring.c | 595 ---- src/compositor/meta-sync-ring.h | 13 - src/compositor/meta-window-actor-x11.c | 70 - src/compositor/meta-window-actor-x11.h | 7 - src/compositor/meta-window-actor.c | 17 - src/core/display.c | 54 +- src/core/meta-context-main.c | 312 +- src/core/meta-context-private.h | 10 - src/core/meta-context.c | 57 +- src/core/meta-service-channel.c | 28 - src/core/mutter.c | 3 +- src/helpers/meson.build | 20 - src/meson.build | 251 +- src/meta/meta-context.h | 3 - src/meta/meta-enums.h | 6 - src/meta/meta-x11-display.h | 5 - src/tests/clutter/interactive/test-main.c | 2 - src/tests/cogl/conform/meson.build | 1 - .../cogl/conform/test-texture-pixmap-x11.c | 248 -- src/tests/meson.build | 34 - src/tests/meta-context-test.c | 19 +- src/tests/x11-test.sh | 51 - src/third_party/xcursor/xcursor.h | 2 +- src/x11/events.c | 49 +- src/x11/meta-x11-display.c | 219 +- src/x11/meta-x11-frame.c | 1 - src/x11/window-x11.c | 48 +- 136 files changed, 148 insertions(+), 26000 deletions(-) delete mode 100644 cogl/cogl/cogl-x11-onscreen.c delete mode 100644 cogl/cogl/cogl-x11-onscreen.h delete mode 100644 cogl/cogl/cogl-xlib-renderer-private.h delete mode 100644 cogl/cogl/cogl-xlib-renderer.c delete mode 100644 cogl/cogl/cogl-xlib-renderer.h delete mode 100644 cogl/cogl/winsys/cogl-glx-display-private.h delete mode 100644 cogl/cogl/winsys/cogl-glx-renderer-private.h delete mode 100644 cogl/cogl/winsys/cogl-onscreen-glx.c delete mode 100644 cogl/cogl/winsys/cogl-onscreen-glx.h delete mode 100644 cogl/cogl/winsys/cogl-onscreen-xlib.c delete mode 100644 cogl/cogl/winsys/cogl-onscreen-xlib.h delete mode 100644 cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h delete mode 100644 cogl/cogl/winsys/cogl-texture-pixmap-x11.c delete mode 100644 cogl/cogl/winsys/cogl-texture-pixmap-x11.h delete mode 100644 cogl/cogl/winsys/cogl-winsys-egl-x11-private.h delete mode 100644 cogl/cogl/winsys/cogl-winsys-egl-x11.c delete mode 100644 cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h delete mode 100644 cogl/cogl/winsys/cogl-winsys-glx-private.h delete mode 100644 cogl/cogl/winsys/cogl-winsys-glx.c delete mode 100644 src/backends/x11/cm/meta-backend-x11-cm.c delete mode 100644 src/backends/x11/cm/meta-backend-x11-cm.h delete mode 100644 src/backends/x11/cm/meta-cursor-sprite-xfixes.c delete mode 100644 src/backends/x11/cm/meta-cursor-sprite-xfixes.h delete mode 100644 src/backends/x11/cm/meta-renderer-x11-cm.c delete mode 100644 src/backends/x11/cm/meta-renderer-x11-cm.h delete mode 100644 src/backends/x11/meta-backend-x11-types.h delete mode 100644 src/backends/x11/meta-backend-x11.c delete mode 100644 src/backends/x11/meta-backend-x11.h delete mode 100644 src/backends/x11/meta-backlight-x11.c delete mode 100644 src/backends/x11/meta-backlight-x11.h delete mode 100644 src/backends/x11/meta-barrier-x11.c delete mode 100644 src/backends/x11/meta-barrier-x11.h delete mode 100644 src/backends/x11/meta-clutter-backend-x11.c delete mode 100644 src/backends/x11/meta-clutter-backend-x11.h delete mode 100644 src/backends/x11/meta-color-manager-x11.c delete mode 100644 src/backends/x11/meta-color-manager-x11.h delete mode 100644 src/backends/x11/meta-crtc-xrandr.c delete mode 100644 src/backends/x11/meta-crtc-xrandr.h delete mode 100644 src/backends/x11/meta-cursor-renderer-x11.c delete mode 100644 src/backends/x11/meta-cursor-renderer-x11.h delete mode 100644 src/backends/x11/meta-cursor-tracker-x11.c delete mode 100644 src/backends/x11/meta-cursor-tracker-x11.h delete mode 100644 src/backends/x11/meta-event-x11.c delete mode 100644 src/backends/x11/meta-event-x11.h delete mode 100644 src/backends/x11/meta-gpu-xrandr.c delete mode 100644 src/backends/x11/meta-gpu-xrandr.h delete mode 100644 src/backends/x11/meta-input-device-tool-x11.c delete mode 100644 src/backends/x11/meta-input-device-tool-x11.h delete mode 100644 src/backends/x11/meta-input-device-x11.c delete mode 100644 src/backends/x11/meta-input-device-x11.h delete mode 100644 src/backends/x11/meta-input-settings-x11.c delete mode 100644 src/backends/x11/meta-input-settings-x11.h delete mode 100644 src/backends/x11/meta-keymap-x11.c delete mode 100644 src/backends/x11/meta-keymap-x11.h delete mode 100644 src/backends/x11/meta-monitor-manager-xrandr.c delete mode 100644 src/backends/x11/meta-monitor-manager-xrandr.h delete mode 100644 src/backends/x11/meta-output-xrandr.c delete mode 100644 src/backends/x11/meta-output-xrandr.h delete mode 100644 src/backends/x11/meta-renderer-x11.c delete mode 100644 src/backends/x11/meta-renderer-x11.h delete mode 100644 src/backends/x11/meta-seat-x11.c delete mode 100644 src/backends/x11/meta-seat-x11.h delete mode 100644 src/backends/x11/meta-sprite-x11.c delete mode 100644 src/backends/x11/meta-sprite-x11.h delete mode 100644 src/backends/x11/meta-stage-x11.c delete mode 100644 src/backends/x11/meta-stage-x11.h delete mode 100644 src/backends/x11/meta-virtual-input-device-x11.c delete mode 100644 src/backends/x11/meta-virtual-input-device-x11.h delete mode 100644 src/backends/x11/meta-xkb-a11y-x11.c delete mode 100644 src/backends/x11/meta-xkb-a11y-x11.h delete mode 100644 src/backends/x11/nested/meta-backend-x11-nested.c delete mode 100644 src/backends/x11/nested/meta-backend-x11-nested.h delete mode 100644 src/backends/x11/nested/meta-cursor-renderer-x11-nested.c delete mode 100644 src/backends/x11/nested/meta-cursor-renderer-x11-nested.h delete mode 100644 src/backends/x11/nested/meta-renderer-x11-nested.c delete mode 100644 src/backends/x11/nested/meta-renderer-x11-nested.h delete mode 100644 src/backends/x11/nested/meta-sprite-x11-nested.c delete mode 100644 src/backends/x11/nested/meta-sprite-x11-nested.h delete mode 100644 src/backends/x11/nested/meta-stage-x11-nested.c delete mode 100644 src/backends/x11/nested/meta-stage-x11-nested.h delete mode 100644 src/compositor/meta-compositor-x11.c delete mode 100644 src/compositor/meta-compositor-x11.h delete mode 100644 src/compositor/meta-surface-actor-x11.c delete mode 100644 src/compositor/meta-surface-actor-x11.h delete mode 100644 src/compositor/meta-sync-ring.c delete mode 100644 src/compositor/meta-sync-ring.h delete mode 100644 src/tests/cogl/conform/test-texture-pixmap-x11.c delete mode 100755 src/tests/x11-test.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0f91954de87..3f61c1039ea 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -408,7 +408,6 @@ check-python-code-style: -Degl_device=true -Dwayland_eglstream=true -Dcatch=true - -Dx11=true .build-mutter: extends: @@ -455,7 +454,7 @@ build-mutter@aarch64: artifacts: false when: manual -build-without-opengl-and-glx@x86_64: +build-without-opengl@x86_64: extends: - .mutter.distribution-image - .mutter.fedora@x86_64 @@ -470,7 +469,6 @@ build-without-opengl-and-glx@x86_64: --wrap-mode nofallback -Dbuildtype=debugoptimized -Dopengl=false - -Dglx=false -Degl_device=true -Dwayland_eglstream=true -Dintrospection=false @@ -480,58 +478,6 @@ build-without-opengl-and-glx@x86_64: paths: - build/meson-logs -build-without-native-backend-and-wayland@x86_64: - extends: - - .mutter.distribution-image - - .mutter.fedora@x86_64 - stage: build - needs: - - job: build-fedora-container@x86_64 - artifacts: false - script: - - meson setup . build - --prefix /usr - --werror - --wrap-mode nofallback - -Dbuildtype=debugoptimized - -Dx11=true - -Dnative_backend=false - -Dudev=false - -Dwayland=false - -Dxwayland=false - -Dtests=disabled - -Dintrospection=false - - meson compile -C build - - sudo meson install --no-rebuild -C build - artifacts: - paths: - - build/meson-logs - -build-wayland-xwayland@x86_64: - extends: - - .mutter.distribution-image - - .mutter.fedora@x86_64 - stage: build - needs: - - job: build-fedora-container@x86_64 - artifacts: false - script: - - meson setup . build - --prefix /usr - --werror - --wrap-mode nofallback - -Dbuildtype=debugoptimized - -Dwayland=true - -Dxwayland=true - -Dx11=false - -Dtests=disabled - -Dintrospection=false - - meson compile -C build - - sudo meson install --no-rebuild -C build - artifacts: - paths: - - build/meson-logs - build-wayland-only@x86_64: extends: - .mutter.distribution-image @@ -548,7 +494,6 @@ build-wayland-only@x86_64: -Dbuildtype=debugoptimized -Dwayland=true -Dxwayland=false - -Dx11=false -Dtests=disabled -Dintrospection=false - meson compile -C build diff --git a/cogl/cogl/cogl-mutter.h b/cogl/cogl/cogl-mutter.h index 104c3551d73..70a4c1f3cf6 100644 --- a/cogl/cogl/cogl-mutter.h +++ b/cogl/cogl/cogl-mutter.h @@ -38,13 +38,6 @@ #include "cogl/winsys/cogl-onscreen-egl.h" #include "cogl/winsys/cogl-winsys-egl-private.h" #endif -#ifdef HAVE_GLX -#include "cogl/winsys/cogl-onscreen-glx.h" -#endif -#ifdef HAVE_X11 -#include "cogl/winsys/cogl-onscreen-xlib.h" -#include "cogl/cogl-x11-onscreen.h" -#endif #include "cogl/winsys/cogl-winsys-private.h" COGL_EXPORT diff --git a/cogl/cogl/cogl-renderer-private.h b/cogl/cogl/cogl-renderer-private.h index f142ceeb200..f35d95f19ca 100644 --- a/cogl/cogl/cogl-renderer-private.h +++ b/cogl/cogl/cogl-renderer-private.h @@ -40,26 +40,10 @@ typedef const CoglWinsysVtable *(*CoglCustomWinsysVtableGetter) (CoglRenderer *renderer); -typedef CoglFilterReturn (* CoglNativeFilterFunc) (void *native_event, - void *data); - -void -_cogl_renderer_add_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data); - -void -_cogl_renderer_remove_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data); - CoglDriver * cogl_renderer_get_driver (CoglRenderer *renderer); const CoglWinsysVtable * cogl_renderer_get_winsys_vtable (CoglRenderer *renderer); -void cogl_renderer_set_custom_winsys_data (CoglRenderer *renderer, - void *winsys_data); - CoglClosure * cogl_renderer_add_idle_closure (CoglRenderer *renderer, void (*closure)(void *), gpointer data); diff --git a/cogl/cogl/cogl-renderer.c b/cogl/cogl/cogl-renderer.c index e2430f3e00d..a468fd2d42d 100644 --- a/cogl/cogl/cogl-renderer.c +++ b/cogl/cogl/cogl-renderer.c @@ -46,13 +46,6 @@ #include "cogl/winsys/cogl-winsys-private.h" -#ifdef HAVE_EGL_PLATFORM_XLIB -#include "cogl/winsys/cogl-winsys-egl-x11-private.h" -#endif -#ifdef HAVE_GLX -#include "cogl/winsys/cogl-winsys-glx-private.h" -#endif - #ifdef HAVE_GL #include "cogl/driver/gl/gl3/cogl-driver-gl3-private.h" #endif @@ -61,12 +54,6 @@ #endif #include "cogl/driver/nop/cogl-driver-nop-private.h" -#ifdef HAVE_X11 -#include "cogl/cogl-xlib-renderer.h" -#include "cogl/cogl-xlib-renderer-private.h" -#endif - - static CoglDriverId _cogl_drivers[] = { #ifdef HAVE_GL @@ -78,22 +65,6 @@ static CoglDriverId _cogl_drivers[] = COGL_DRIVER_ID_NOP, }; -static CoglWinsysVtableGetter _cogl_winsys_vtable_getters[] = -{ -#ifdef HAVE_GLX - _cogl_winsys_glx_get_vtable, -#endif -#ifdef HAVE_EGL_PLATFORM_XLIB - _cogl_winsys_egl_xlib_get_vtable, -#endif -}; - -typedef struct _CoglNativeFilterClosure -{ - CoglNativeFilterFunc func; - void *data; -} CoglNativeFilterClosure; - typedef struct _CoglRenderer { GObject parent_instance; @@ -105,7 +76,6 @@ typedef struct _CoglRenderer CoglDriver *driver; const CoglWinsysVtable *winsys_vtable; void *custom_winsys_user_data; - gboolean should_free_custom_winsys_user_data; CoglCustomWinsysVtableGetter custom_winsys_vtable_getter; CoglList idle_closures; @@ -113,17 +83,9 @@ typedef struct _CoglRenderer CoglDriverId driver_id; GModule *libgl_module; - /* List of callback functions that will be given every native event */ - GSList *event_filters; void *winsys; } CoglRenderer; -static void -native_filter_closure_free (CoglNativeFilterClosure *closure) -{ - g_free (closure); -} - G_DEFINE_FINAL_TYPE (CoglRenderer, cogl_renderer, G_TYPE_OBJECT); static void @@ -139,15 +101,10 @@ cogl_renderer_dispose (GObject *object) winsys->renderer_disconnect (renderer); g_clear_pointer (&renderer->winsys, g_free); - if (renderer->should_free_custom_winsys_user_data) - g_clear_pointer (&renderer->custom_winsys_user_data, g_free); if (renderer->libgl_module) g_module_close (renderer->libgl_module); - g_slist_free_full (renderer->event_filters, - (GDestroyNotify) native_filter_closure_free); - g_clear_object (&renderer->driver); G_OBJECT_CLASS (cogl_renderer_parent_class)->dispose (object); @@ -178,29 +135,12 @@ cogl_renderer_new (void) CoglRenderer *renderer = g_object_new (COGL_TYPE_RENDERER, NULL); renderer->connected = FALSE; - renderer->event_filters = NULL; _cogl_list_init (&renderer->idle_closures); return renderer; } -#ifdef HAVE_X11 -void -cogl_xlib_renderer_set_foreign_display (CoglRenderer *renderer, - Display *xdisplay) -{ - CoglXlibRenderer *xlib_renderer; - g_return_if_fail (COGL_IS_RENDERER (renderer)); - - /* NB: Renderers are considered immutable once connected */ - g_return_if_fail (!renderer->connected); - - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - xlib_renderer->xdpy = xdisplay; -} -#endif /* HAVE_X11 */ - typedef gboolean (*CoglDriverCallback) (CoglDriverId driver_id, void *user_data); @@ -401,7 +341,6 @@ cogl_renderer_set_custom_winsys (CoglRenderer *renderer, { renderer->custom_winsys_user_data = user_data; renderer->custom_winsys_vtable_getter = winsys_vtable_getter; - renderer->should_free_custom_winsys_user_data = FALSE; } static gboolean @@ -441,9 +380,6 @@ connect_custom_winsys (CoglRenderer *renderer, gboolean cogl_renderer_connect (CoglRenderer *renderer, GError **error) { - int i; - g_autoptr (GString) error_message = NULL; - if (renderer->connected) return TRUE; @@ -456,107 +392,17 @@ cogl_renderer_connect (CoglRenderer *renderer, GError **error) if (renderer->custom_winsys_vtable_getter) return connect_custom_winsys (renderer, error); - error_message = g_string_new (""); - for (i = 0; i < G_N_ELEMENTS (_cogl_winsys_vtable_getters); i++) - { - const CoglWinsysVtable *winsys = _cogl_winsys_vtable_getters[i](); - GError *tmp_error = NULL; - - /* At least temporarily we will associate this winsys with - * the renderer in-case ->renderer_connect calls API that - * wants to query the current winsys... */ - renderer->winsys_vtable = winsys; - - if (!winsys->renderer_connect (renderer, &tmp_error)) - { - g_string_append_c (error_message, '\n'); - g_string_append (error_message, tmp_error->message); - g_error_free (tmp_error); - /* Free any leftover state, for now */ - g_clear_pointer (&renderer->winsys, g_free); - } - else - { - renderer->connected = TRUE; - return TRUE; - } - } - if (!renderer->connected) { renderer->winsys_vtable = NULL; g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, - "Failed to connected to any renderer: %s", - error_message->str); + "Failed to connected to any renderer"); return FALSE; } return TRUE; } -CoglFilterReturn -cogl_renderer_handle_event (CoglRenderer *renderer, - void *event) -{ - GSList *l, *next; - - /* Pass the event on to all of the registered filters in turn */ - for (l = renderer->event_filters; l; l = next) - { - CoglNativeFilterClosure *closure = l->data; - - /* The next pointer is taken now so that we can handle the - closure being removed during emission */ - next = l->next; - - if (closure->func (event, closure->data) == COGL_FILTER_REMOVE) - return COGL_FILTER_REMOVE; - } - - /* If the backend for the renderer also wants to see the events, it - should just register its own filter */ - - return COGL_FILTER_CONTINUE; -} - -void -_cogl_renderer_add_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data) -{ - CoglNativeFilterClosure *closure; - - closure = g_new0 (CoglNativeFilterClosure, 1); - closure->func = func; - closure->data = data; - - renderer->event_filters = g_slist_prepend (renderer->event_filters, closure); -} - -void -_cogl_renderer_remove_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data) -{ - GSList *l, *prev = NULL; - - for (l = renderer->event_filters; l; prev = l, l = l->next) - { - CoglNativeFilterClosure *closure = l->data; - - if (closure->func == func && closure->data == data) - { - native_filter_closure_free (closure); - if (prev) - prev->next = g_slist_delete_link (prev->next, l); - else - renderer->event_filters = - g_slist_delete_link (renderer->event_filters, l); - break; - } - } -} - CoglWinsysID cogl_renderer_get_winsys_id (CoglRenderer *renderer) { @@ -742,11 +588,3 @@ cogl_renderer_get_custom_winsys_data (CoglRenderer *renderer) { return renderer->custom_winsys_user_data; } - -void -cogl_renderer_set_custom_winsys_data (CoglRenderer *renderer, - void *winsys_data) -{ - renderer->custom_winsys_user_data = winsys_data; - renderer->should_free_custom_winsys_user_data = TRUE; -} diff --git a/cogl/cogl/cogl-renderer.h b/cogl/cogl/cogl-renderer.h index 5eb04fe234f..b52562a7f67 100644 --- a/cogl/cogl/cogl-renderer.h +++ b/cogl/cogl/cogl-renderer.h @@ -310,23 +310,6 @@ COGL_EXPORT void * cogl_renderer_get_proc_address (CoglRenderer *renderer, const char *name); -/** - * cogl_renderer_handle_event: (skip) - * @renderer: a #CoglRenderer - * @event: pointer to an event structure - * - * Processes a single event. - * - * Return value: #CoglFilterReturn. %COGL_FILTER_REMOVE indicates that - * Cogl has internally handled the event and the caller should do no - * further processing. %COGL_FILTER_CONTINUE indicates that Cogl is - * either not interested in the event, or has used the event to update - * internal state without taking any exclusive action. - */ -COGL_EXPORT CoglFilterReturn -cogl_renderer_handle_event (CoglRenderer *renderer, - void *event); - COGL_EXPORT void cogl_renderer_set_winsys (CoglRenderer *renderer, void *winsys); diff --git a/cogl/cogl/cogl-types.h b/cogl/cogl/cogl-types.h index 2dc65158819..ddeedd54ca1 100644 --- a/cogl/cogl/cogl-types.h +++ b/cogl/cogl/cogl-types.h @@ -218,19 +218,6 @@ typedef enum /*< prefix=COGL_RENDERER_ERROR >*/ COGL_RENDERER_ERROR_BAD_CONSTRAINT } CoglRendererError; -/** - * CoglFilterReturn: - * @COGL_FILTER_CONTINUE: The event was not handled, continues the - * processing - * @COGL_FILTER_REMOVE: Remove the event, stops the processing - * - * Return values for the #CoglXlibFilterFunc and #CoglWin32FilterFunc functions. - */ -typedef enum _CoglFilterReturn { /*< prefix=COGL_FILTER >*/ - COGL_FILTER_CONTINUE, - COGL_FILTER_REMOVE -} CoglFilterReturn; - typedef enum _CoglWinsysFeature { /* Available if its possible to query a counter that diff --git a/cogl/cogl/cogl-x11-onscreen.c b/cogl/cogl/cogl-x11-onscreen.c deleted file mode 100644 index d3550614db6..00000000000 --- a/cogl/cogl/cogl-x11-onscreen.c +++ /dev/null @@ -1,38 +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 . - * - */ - -#include "config.h" - -#include "cogl/cogl-x11-onscreen.h" - -G_DEFINE_INTERFACE (CoglX11Onscreen, cogl_x11_onscreen, - G_TYPE_OBJECT) - -Window -cogl_x11_onscreen_get_x11_window (CoglX11Onscreen *x11_onscreen) -{ - CoglX11OnscreenInterface *iface = - COGL_X11_ONSCREEN_GET_IFACE (x11_onscreen); - - return iface->get_x11_window (x11_onscreen); -} - -static void -cogl_x11_onscreen_default_init (CoglX11OnscreenInterface *iface) -{ -} diff --git a/cogl/cogl/cogl-x11-onscreen.h b/cogl/cogl/cogl-x11-onscreen.h deleted file mode 100644 index 93abecccc75..00000000000 --- a/cogl/cogl/cogl-x11-onscreen.h +++ /dev/null @@ -1,44 +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 . - * - */ - -#pragma once - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#include -#include - -#include "cogl/cogl-macros.h" - -#define COGL_TYPE_X11_ONSCREEN (cogl_x11_onscreen_get_type ()) -COGL_EXPORT -G_DECLARE_INTERFACE (CoglX11Onscreen, cogl_x11_onscreen, - COGL, X11_ONSCREEN, - GObject) - -struct _CoglX11OnscreenInterface -{ - GTypeInterface parent_iface; - - Window (* get_x11_window) (CoglX11Onscreen *x11_onscreen); -}; - -COGL_EXPORT -Window cogl_x11_onscreen_get_x11_window (CoglX11Onscreen *x11_onscreen); diff --git a/cogl/cogl/cogl-xlib-renderer-private.h b/cogl/cogl/cogl-xlib-renderer-private.h deleted file mode 100644 index a7545e51676..00000000000 --- a/cogl/cogl/cogl-xlib-renderer-private.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include -#include - -#include "cogl/cogl-context.h" - -typedef struct _CoglXlibOutput -{ - char *name; - int x; - int y; - int width; - int height; - int mm_width; - int mm_height; - float refresh_rate; - SubpixelOrder subpixel_order; -} CoglXlibOutput; - -typedef struct _CoglXlibRenderer -{ - int damage_base; - int randr_base; - - Display *xdpy; - - GList *outputs; - - unsigned long outputs_update_serial; -} CoglXlibRenderer; - -gboolean -_cogl_xlib_renderer_connect (CoglRenderer *renderer, GError **error); - -void -_cogl_xlib_renderer_disconnect (CoglRenderer *renderer); - -CoglXlibRenderer * -_cogl_xlib_renderer_get_data (CoglRenderer *renderer); - -float -_cogl_xlib_renderer_refresh_rate_for_rectangle (CoglRenderer *renderer, - int x, - int y, - int width, - int height); - -Display * -cogl_xlib_renderer_get_display (CoglRenderer *renderer); diff --git a/cogl/cogl/cogl-xlib-renderer.c b/cogl/cogl/cogl-xlib-renderer.c deleted file mode 100644 index f5961db3fbc..00000000000 --- a/cogl/cogl/cogl-xlib-renderer.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-xlib-renderer.h" -#include "cogl/cogl-util.h" - -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-xlib-renderer-private.h" -#include "cogl/winsys/cogl-winsys-private.h" -#include "mtk/mtk-x11.h" - -#include -#include -#include - -#include -#include - -CoglXlibRenderer * -_cogl_xlib_renderer_get_data (CoglRenderer *renderer) -{ - /* Constructs a CoglXlibRenderer struct on demand and attaches it to - the object using user data. It's done this way instead of using a - subclassing hierarchy in the winsys data because all EGL winsys's - need the EGL winsys data but only one of them wants the Xlib - data. */ - - if (!cogl_renderer_get_custom_winsys_data (renderer)) - cogl_renderer_set_custom_winsys_data (renderer, g_new0 (CoglXlibRenderer, 1)); - - return cogl_renderer_get_custom_winsys_data (renderer); -} - -static void -free_xlib_output (CoglXlibOutput *output) -{ - if (!output) - return; - - g_clear_pointer (&output->name, g_free); - g_clear_pointer (&output, g_free); -} - -static gboolean -output_values_equal (CoglXlibOutput *output, - CoglXlibOutput *other) -{ - if (output == other) - return TRUE; - - return memcmp ((const char *)output + G_STRUCT_OFFSET (CoglXlibOutput, x), - (const char *)other + G_STRUCT_OFFSET (CoglXlibOutput, x), - sizeof (CoglXlibOutput) - G_STRUCT_OFFSET (CoglXlibOutput, x)) == 0; -} - -static int -compare_outputs (CoglXlibOutput *a, - CoglXlibOutput *b) -{ - return strcmp (a->name, b->name); -} - -#define CSO(X) SubPixel ## X -static SubpixelOrder subpixel_map[6][6] = { - { CSO(Unknown), CSO(None), CSO(HorizontalRGB), CSO(HorizontalBGR), - CSO(VerticalRGB), CSO(VerticalBGR) }, /* 0 */ - { CSO(Unknown), CSO(None), CSO(VerticalRGB), CSO(VerticalBGR), - CSO(HorizontalBGR), CSO(HorizontalRGB) }, /* 90 */ - { CSO(Unknown), CSO(None), CSO(HorizontalBGR), CSO(HorizontalRGB), - CSO(VerticalBGR), CSO(VerticalRGB) }, /* 180 */ - { CSO(Unknown), CSO(None), CSO(VerticalBGR), CSO(VerticalRGB), - CSO(HorizontalRGB), CSO(HorizontalBGR) }, /* 270 */ - { CSO(Unknown), CSO(None), CSO(HorizontalBGR), CSO(HorizontalRGB), - CSO(VerticalRGB), CSO(VerticalBGR) }, /* Reflect_X */ - { CSO(Unknown), CSO(None), CSO(HorizontalRGB), CSO(HorizontalBGR), - CSO(VerticalBGR), CSO(VerticalRGB) }, /* Reflect_Y */ -}; -#undef CSO - -static void -update_outputs (CoglRenderer *renderer, - gboolean notify) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - XRRScreenResources *resources; - gboolean error = FALSE; - GList *new_outputs = NULL; - GList *l, *m; - gboolean changed = FALSE; - int i; - - xlib_renderer->outputs_update_serial = XNextRequest (xlib_renderer->xdpy); - - resources = XRRGetScreenResources (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy)); - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - for (i = 0; resources && i < resources->ncrtc && !error; i++) - { - XRRCrtcInfo *crtc_info = NULL; - XRROutputInfo *output_info = NULL; - CoglXlibOutput *output; - float refresh_rate = 0; - int j; - - crtc_info = XRRGetCrtcInfo (xlib_renderer->xdpy, - resources, resources->crtcs[i]); - if (crtc_info == NULL) - { - error = TRUE; - goto next; - } - - if (crtc_info->mode == None) - goto next; - - for (j = 0; j < resources->nmode; j++) - { - if (resources->modes[j].id == crtc_info->mode) - refresh_rate = (resources->modes[j].dotClock / - ((float)resources->modes[j].hTotal * - resources->modes[j].vTotal)); - } - - output_info = XRRGetOutputInfo (xlib_renderer->xdpy, - resources, - crtc_info->outputs[0]); - if (output_info == NULL) - { - error = TRUE; - goto next; - } - - output = g_new0 (CoglXlibOutput, 1); - output->name = g_strdup (output_info->name); - output->x = crtc_info->x; - output->y = crtc_info->y; - output->width = crtc_info->width; - output->height = crtc_info->height; - if ((crtc_info->rotation & (RR_Rotate_90 | RR_Rotate_270)) != 0) - { - output->mm_width = output_info->mm_height; - output->mm_height = output_info->mm_width; - } - else - { - output->mm_width = output_info->mm_width; - output->mm_height = output_info->mm_height; - } - - output->refresh_rate = refresh_rate; - output->subpixel_order = output_info->subpixel_order; - - /* Handle the effect of rotation and reflection on subpixel order (ugh) */ - for (j = 0; j < 6; j++) - { - if ((crtc_info->rotation & (1 << j)) != 0) - output->subpixel_order = subpixel_map[j][output->subpixel_order]; - } - - new_outputs = g_list_prepend (new_outputs, output); - - next: - g_clear_pointer (&crtc_info, XRRFreeCrtcInfo); - g_clear_pointer (&output_info, XRRFreeOutputInfo); - } - - XFree (resources); - - if (!error) - { - new_outputs = g_list_sort (new_outputs, (GCompareFunc)compare_outputs); - - l = new_outputs; - m = xlib_renderer->outputs; - - while (l || m) - { - int cmp; - CoglXlibOutput *output_l = l ? (CoglXlibOutput *)l->data : NULL; - CoglXlibOutput *output_m = m ? (CoglXlibOutput *)m->data : NULL; - - if (l && m) - cmp = compare_outputs (output_l, output_m); - else if (l) - cmp = -1; - else - cmp = 1; - - if (cmp == 0) - { - GList *m_next = m->next; - - if (!output_values_equal (output_l, output_m)) - { - xlib_renderer->outputs = - g_list_remove_link (xlib_renderer->outputs, m); - - xlib_renderer->outputs = - g_list_insert_before (xlib_renderer->outputs, - m_next, - g_steal_pointer (&l->data)); - - g_clear_pointer (&output_m, free_xlib_output); - - changed = TRUE; - } - - l = l->next; - m = m_next; - } - else if (cmp < 0) - { - xlib_renderer->outputs = - g_list_insert_before (xlib_renderer->outputs, - m, - g_steal_pointer (&l->data)); - changed = TRUE; - l = l->next; - } - else - { - GList *m_next = m->next; - xlib_renderer->outputs = - g_list_remove_link (xlib_renderer->outputs, m); - g_clear_pointer (&output_m, free_xlib_output); - changed = TRUE; - m = m_next; - } - } - } - - g_list_free_full (new_outputs, (GDestroyNotify) free_xlib_output); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - - if (changed) - { - const CoglWinsysVtable *winsys = cogl_renderer_get_winsys_vtable (renderer); - - if (notify) - COGL_NOTE (WINSYS, "Outputs changed:"); - else - COGL_NOTE (WINSYS, "Outputs:"); - - for (l = xlib_renderer->outputs; l; l = l->next) - { - CoglXlibOutput *output = l->data; - const char *subpixel_string; - - switch (output->subpixel_order) - { - case SubPixelUnknown: - default: - subpixel_string = "unknown"; - break; - case SubPixelNone: - subpixel_string = "none"; - break; - case SubPixelHorizontalRGB: - subpixel_string = "horizontal_rgb"; - break; - case SubPixelHorizontalBGR: - subpixel_string = "horizontal_bgr"; - break; - case SubPixelVerticalRGB: - subpixel_string = "vertical_rgb"; - break; - case SubPixelVerticalBGR: - subpixel_string = "vertical_bgr"; - break; - } - - COGL_NOTE (WINSYS, - " %10s: +%d+%dx%dx%d mm=%dx%d dpi=%.1fx%.1f " - "subpixel_order=%s refresh_rate=%.3f", - output->name, - output->x, output->y, output->width, output->height, - output->mm_width, output->mm_height, - output->width / (output->mm_width / 25.4), - output->height / (output->mm_height / 25.4), - subpixel_string, - output->refresh_rate); - } - - if (notify && winsys->renderer_outputs_changed != NULL) - winsys->renderer_outputs_changed (renderer); - } -} - -static CoglFilterReturn -randr_filter (XEvent *event, - void *data) -{ - CoglRenderer *renderer = data; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - - if (xlib_renderer->randr_base != -1 && - (event->xany.type == xlib_renderer->randr_base + RRScreenChangeNotify || - event->xany.type == xlib_renderer->randr_base + RRNotify) && - event->xany.serial >= xlib_renderer->outputs_update_serial) - update_outputs (renderer, TRUE); - - return COGL_FILTER_CONTINUE; -} - -gboolean -_cogl_xlib_renderer_connect (CoglRenderer *renderer, GError **error) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - int damage_error; - int randr_error; - - g_return_val_if_fail (xlib_renderer->xdpy != NULL, FALSE); - - /* Check whether damage events are supported on this display */ - if (!XDamageQueryExtension (xlib_renderer->xdpy, - &xlib_renderer->damage_base, - &damage_error)) - xlib_renderer->damage_base = -1; - - /* Check whether randr is supported on this display */ - if (!XRRQueryExtension (xlib_renderer->xdpy, - &xlib_renderer->randr_base, - &randr_error)) - xlib_renderer->randr_base = -1; - - XRRSelectInput(xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - RRScreenChangeNotifyMask - | RRCrtcChangeNotifyMask - | RROutputPropertyNotifyMask); - update_outputs (renderer, FALSE); - - _cogl_renderer_add_native_filter (renderer, - (CoglNativeFilterFunc)randr_filter, - renderer); - - return TRUE; -} - -void -_cogl_xlib_renderer_disconnect (CoglRenderer *renderer) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - - g_list_free_full (xlib_renderer->outputs, (GDestroyNotify) free_xlib_output); - xlib_renderer->outputs = NULL; -} - -Display * -cogl_xlib_renderer_get_display (CoglRenderer *renderer) -{ - CoglXlibRenderer *xlib_renderer; - - g_return_val_if_fail (COGL_IS_RENDERER (renderer), NULL); - - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - return xlib_renderer->xdpy; -} - -float -_cogl_xlib_renderer_refresh_rate_for_rectangle (CoglRenderer *renderer, - int x, - int y, - int width, - int height) -{ - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - int max_overlap = 0; - CoglXlibOutput *max_overlapped = NULL; - GList *l; - int xa1 = x, xa2 = x + width; - int ya1 = y, ya2 = y + height; - - for (l = xlib_renderer->outputs; l; l = l->next) - { - CoglXlibOutput *output = l->data; - int xb1 = output->x, xb2 = output->x + output->width; - int yb1 = output->y, yb2 = output->y + output->height; - - int overlap_x = MIN(xa2, xb2) - MAX(xa1, xb1); - int overlap_y = MIN(ya2, yb2) - MAX(ya1, yb1); - - if (overlap_x > 0 && overlap_y > 0) - { - int overlap = overlap_x * overlap_y; - if (overlap > max_overlap) - { - max_overlap = overlap; - max_overlapped = output; - } - } - } - - if (max_overlapped) - return max_overlapped->refresh_rate; - else - return 0.0; -} diff --git a/cogl/cogl/cogl-xlib-renderer.h b/cogl/cogl/cogl-xlib-renderer.h deleted file mode 100644 index 7c5944c5d21..00000000000 --- a/cogl/cogl/cogl-xlib-renderer.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#include -#include - -#include "cogl/cogl-renderer.h" - -G_BEGIN_DECLS - -/** - * cogl_xlib_renderer_set_foreign_display: (skip) - * @renderer: a #CoglRenderer - * - * Sets a foreign Xlib display that Cogl will use for and Xlib based winsys - * backend. - * - * Note that calling this function will automatically disable Cogl's - * event retrieval. Cogl still needs to see all of the X events so the - * application should also use cogl_renderer_handle_event() if it - * uses this function. - */ -COGL_EXPORT void -cogl_xlib_renderer_set_foreign_display (CoglRenderer *renderer, - Display *display); - -G_END_DECLS diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build index 47cf2dccf1b..2eec9a13a20 100644 --- a/cogl/cogl/meson.build +++ b/cogl/cogl/meson.build @@ -281,36 +281,6 @@ cogl_sources = [ 'winsys/cogl-winsys.c', ] -if have_x11 - cogl_gir_includes += ['xlib-2.0'] - cogl_nonintrospected_headers += [ - 'winsys/cogl-texture-pixmap-x11.h', - ] - cogl_sources += [ - 'cogl-x11-onscreen.c', - 'cogl-x11-onscreen.h', - 'cogl-xlib-renderer-private.h', - 'cogl-xlib-renderer.c', - 'winsys/cogl-texture-pixmap-x11-private.h', - 'winsys/cogl-texture-pixmap-x11.c', - ] - cogl_headers += [ - 'cogl-xlib-renderer.h' - ] -endif - -if have_glx - cogl_sources += [ - 'winsys/cogl-glx-display-private.h', - 'winsys/cogl-glx-renderer-private.h', - 'winsys/cogl-onscreen-glx.c', - 'winsys/cogl-onscreen-glx.h', - 'winsys/cogl-winsys-glx-feature-functions.h', - 'winsys/cogl-winsys-glx-private.h', - 'winsys/cogl-winsys-glx.c', - ] -endif - if have_egl cogl_sources += [ 'winsys/cogl-onscreen-egl.c', @@ -321,15 +291,6 @@ if have_egl ] endif -if have_egl_xlib - cogl_sources += [ - 'winsys/cogl-onscreen-xlib.c', - 'winsys/cogl-onscreen-xlib.h', - 'winsys/cogl-winsys-egl-x11-private.h', - 'winsys/cogl-winsys-egl-x11.c', - ] -endif - cogl_enum_headers = [ 'cogl-buffer.h', 'cogl-pixel-format.h', diff --git a/cogl/cogl/winsys/cogl-glx-display-private.h b/cogl/cogl/winsys/cogl-glx-display-private.h deleted file mode 100644 index 87767cd45bb..00000000000 --- a/cogl/cogl/winsys/cogl-glx-display-private.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - - -typedef struct _CoglGLXCachedConfig -{ - /* This will be -1 if there is no cached config in this slot */ - int depth; - gboolean found; - GLXFBConfig fb_config; - gboolean stereo; - gboolean can_mipmap; -} CoglGLXCachedConfig; - -#define COGL_GLX_N_CACHED_CONFIGS 6 - -typedef struct _CoglGLXDisplay -{ - CoglGLXCachedConfig glx_cached_configs[COGL_GLX_N_CACHED_CONFIGS]; - - gboolean found_fbconfig; - gboolean is_direct; - gboolean have_vblank_counter; - gboolean can_vblank_wait; - GLXFBConfig fbconfig; - - /* Single context for all wins */ - GLXContext glx_context; - GLXWindow dummy_glxwin; - Window dummy_xwin; -} CoglGLXDisplay; diff --git a/cogl/cogl/winsys/cogl-glx-renderer-private.h b/cogl/cogl/winsys/cogl-glx-renderer-private.h deleted file mode 100644 index db82d2f58f4..00000000000 --- a/cogl/cogl/winsys/cogl-glx-renderer-private.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include - -#include "cogl/cogl-xlib-renderer-private.h" - -typedef struct _CoglGLXRenderer -{ - int glx_major; - int glx_minor; - - int glx_error_base; - int glx_event_base; - - /* Vblank stuff */ - int dri_fd; - - /* enumeration with relatioship between OML_sync_control - * UST (unadjusted-system-time) and the system clock */ - enum -{ - COGL_GLX_UST_IS_UNKNOWN, - COGL_GLX_UST_IS_GETTIMEOFDAY, - COGL_GLX_UST_IS_MONOTONIC_TIME, - COGL_GLX_UST_IS_OTHER - } ust_type; - - CoglClosure *flush_notifications_idle; - - /* Copy of the winsys features that are based purely on the - * information we can get without using a GL context. We want to - * determine this before we have a context so that we can use the - * function pointers from the extensions earlier. This is necessary - * to use the glXCreateContextAttribs function. */ - unsigned long base_winsys_features - [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_WINSYS_FEATURE_N_FEATURES)]; - - /* Function pointers for core GLX functionality. We can't just link - against these directly because we need to conditionally load - libGL when we are using GLX so that it won't conflict with a GLES - library if we are using EGL + GLES. These are just the functions - that we want to use before calling glXGetProcAddress */ - Bool - (* glXQueryExtension) (Display *dpy, int *errorb, int *event); - const char * - (* glXQueryExtensionsString) (Display *dpy, int screen); - Bool - (* glXQueryVersion) (Display *dpy, int *maj, int *min); - void * - (* glXGetProcAddress) (const GLubyte *procName); - - int - (* glXQueryDrawable) (Display *dpy, GLXDrawable drawable, - int attribute, unsigned int *value); - - /* Function pointers for GLX specific extensions */ -#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f, g) - -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - ret (APIENTRY * name) args; - -#define COGL_WINSYS_FEATURE_END() - -#include "cogl/winsys/cogl-winsys-glx-feature-functions.h" - -#undef COGL_WINSYS_FEATURE_BEGIN -#undef COGL_WINSYS_FEATURE_FUNCTION -#undef COGL_WINSYS_FEATURE_END -} CoglGLXRenderer; diff --git a/cogl/cogl/winsys/cogl-onscreen-glx.c b/cogl/cogl/winsys/cogl-onscreen-glx.c deleted file mode 100644 index 1499d255b60..00000000000 --- a/cogl/cogl/winsys/cogl-onscreen-glx.c +++ /dev/null @@ -1,1088 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * Copyright (C) 2020 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 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 "cogl/winsys/cogl-onscreen-glx.h" - -#include -#include - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-frame-info-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-x11-onscreen.h" -#include "cogl/cogl-xlib-renderer-private.h" -#include "cogl/winsys/cogl-glx-display-private.h" -#include "cogl/winsys/cogl-glx-renderer-private.h" -#include "cogl/winsys/cogl-winsys-glx-private.h" -#include "mtk/mtk-x11.h" - -struct _CoglOnscreenGlx -{ - CoglOnscreen parent; - - Window xwin; - int x, y; - float refresh_rate; - - GLXDrawable glxwin; - uint32_t last_swap_vsync_counter; - uint32_t pending_sync_notify; - uint32_t pending_complete_notify; -}; - -static void -x11_onscreen_init_iface (CoglX11OnscreenInterface *iface); - -G_DEFINE_FINAL_TYPE_WITH_CODE (CoglOnscreenGlx, cogl_onscreen_glx, - COGL_TYPE_ONSCREEN, - G_IMPLEMENT_INTERFACE (COGL_TYPE_X11_ONSCREEN, - x11_onscreen_init_iface)) - -#define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask) - -static gboolean -cogl_onscreen_glx_allocate (CoglFramebuffer *framebuffer, - GError **error) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (framebuffer); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - CoglGLXDisplay *glx_display = display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (display->renderer); - Window xwin; - GLXFBConfig fbconfig; - GError *fbconfig_error = NULL; - - g_return_val_if_fail (glx_display->glx_context, FALSE); - - if (!cogl_display_glx_find_fbconfig (display, - &fbconfig, - &fbconfig_error)) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to find suitable fbconfig for the GLX context: %s", - fbconfig_error->message); - g_error_free (fbconfig_error); - return FALSE; - } - - /* FIXME: We need to explicitly Select for ConfigureNotify events. - * We need to document that for windows we create then toolkits - * must be careful not to clear event mask bits that we select. - */ - { - int width; - int height; - XVisualInfo *xvisinfo; - XSetWindowAttributes xattr; - unsigned long mask; - int xerror; - - width = cogl_framebuffer_get_width (framebuffer); - height = cogl_framebuffer_get_height (framebuffer); - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - xvisinfo = glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy, - fbconfig); - if (xvisinfo == NULL) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Unable to retrieve the X11 visual of context's " - "fbconfig"); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - return FALSE; - } - - /* window attributes */ - xattr.background_pixel = WhitePixel (xlib_renderer->xdpy, - DefaultScreen (xlib_renderer->xdpy)); - xattr.border_pixel = 0; - /* XXX: is this an X resource that we are leaking‽... */ - xattr.colormap = XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK; - - mask = CWBorderPixel | CWColormap | CWEventMask; - - xwin = XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - 0, 0, - width, height, - 0, - xvisinfo->depth, - InputOutput, - xvisinfo->visual, - mask, &xattr); - - XFree (xvisinfo); - - XSync (xlib_renderer->xdpy, False); - xerror = mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy); - if (xerror) - { - char message[1000]; - XGetErrorText (xlib_renderer->xdpy, xerror, - message, sizeof (message)); - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "X error while creating Window for CoglOnscreen: %s", - message); - return FALSE; - } - } - - onscreen_glx->xwin = xwin; - - /* Try and create a GLXWindow to use with extensions dependent on - * GLX versions >= 1.3 that don't accept regular X Windows as GLX - * drawables. */ - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 3) - { - onscreen_glx->glxwin = - glx_renderer->glXCreateWindow (xlib_renderer->xdpy, - fbconfig, - onscreen_glx->xwin, - NULL); - } - -#ifdef GLX_INTEL_swap_event - if (cogl_context_has_winsys_feature (context, COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - GLXDrawable drawable = - onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - - /* similarly to above, we unconditionally select this event - * because we rely on it to advance the master clock, and - * drive redraw/relayout, animations and event handling. - */ - glx_renderer->glXSelectEvent (xlib_renderer->xdpy, - drawable, - GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK); - } -#endif /* GLX_INTEL_swap_event */ - - return TRUE; -} - -static void -cogl_onscreen_glx_dispose (GObject *object) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (object); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglGLXDisplay *glx_display = context->display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (context->display->renderer); - GLXDrawable drawable; - - G_OBJECT_CLASS (cogl_onscreen_glx_parent_class)->dispose (object); - - if (onscreen_glx->glxwin != None || - onscreen_glx->xwin != None) - { - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - drawable = - onscreen_glx->glxwin == None ? onscreen_glx->xwin : onscreen_glx->glxwin; - - /* Cogl always needs a valid context bound to something so if we are - * destroying the onscreen that is currently bound we'll switch back - * to the dummy drawable. Although the documentation for - * glXDestroyWindow states that a currently bound window won't - * actually be destroyed until it is unbound, it looks like this - * doesn't work if the X window itself is destroyed */ - if (drawable == cogl_context_glx_get_current_drawable (context)) - { - GLXDrawable dummy_drawable = (glx_display->dummy_glxwin == None ? - glx_display->dummy_xwin : - glx_display->dummy_glxwin); - - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - dummy_drawable, - dummy_drawable, - glx_display->glx_context); - cogl_context_glx_set_current_drawable (context, dummy_drawable); - } - - if (onscreen_glx->glxwin != None) - { - glx_renderer->glXDestroyWindow (xlib_renderer->xdpy, - onscreen_glx->glxwin); - onscreen_glx->glxwin = None; - } - - if (onscreen_glx->xwin != None) - { - XDestroyWindow (xlib_renderer->xdpy, onscreen_glx->xwin); - onscreen_glx->xwin = None; - } - else - { - onscreen_glx->xwin = None; - } - - XSync (xlib_renderer->xdpy, False); - - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - } -} - -static void -cogl_onscreen_glx_bind (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglGLXDisplay *glx_display = context->display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (context->display->renderer); - GLXDrawable drawable; - - drawable = - onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - - if (cogl_context_glx_get_current_drawable (context) == drawable) - return; - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - COGL_NOTE (WINSYS, - "MakeContextCurrent dpy: %p, window: 0x%x, context: %p", - xlib_renderer->xdpy, - (unsigned int) drawable, - glx_display->glx_context); - - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - drawable, - drawable, - glx_display->glx_context); - - /* In case we are using GLX_SGI_swap_control for vblank syncing - * we need call glXSwapIntervalSGI here to make sure that it - * affects the current drawable. - * - * Note: we explicitly set to 0 when we aren't using the swap - * interval to synchronize since some drivers have a default - * swap interval of 1. Sadly some drivers even ignore requests - * to disable the swap interval. - * - * NB: glXSwapIntervalSGI applies to the context not the - * drawable which is why we can't just do this once when the - * framebuffer is allocated. - * - * FIXME: We should check for GLX_EXT_swap_control which allows - * per framebuffer swap intervals. GLX_MESA_swap_control also - * allows per-framebuffer swap intervals but the semantics tend - * to be more muddled since Mesa drivers tend to expose both the - * MESA and SGI extensions which should technically be mutually - * exclusive. - */ - if (glx_renderer->glXSwapInterval) - glx_renderer->glXSwapInterval (1); - - XSync (xlib_renderer->xdpy, False); - - /* FIXME: We should be reporting a GError here */ - if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy)) - { - g_warning ("X Error received while making drawable 0x%08lX current", - drawable); - return; - } - - cogl_context_glx_set_current_drawable (context, drawable); -} - -static void -ensure_ust_type (CoglRenderer *renderer, - GLXDrawable drawable) -{ - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (renderer); - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - int64_t ust; - int64_t msc; - int64_t sbc; - struct timeval tv; - int64_t current_system_time; - int64_t current_monotonic_time; - - if (glx_renderer->ust_type != COGL_GLX_UST_IS_UNKNOWN) - return; - - glx_renderer->ust_type = COGL_GLX_UST_IS_OTHER; - - if (glx_renderer->glXGetSyncValues == NULL) - goto out; - - if (!glx_renderer->glXGetSyncValues (xlib_renderer->xdpy, drawable, - &ust, &msc, &sbc)) - goto out; - - /* This is the time source that existing (buggy) linux drm drivers - * use */ - gettimeofday (&tv, NULL); - current_system_time = (tv.tv_sec * G_GINT64_CONSTANT (1000000)) + tv.tv_usec; - - if (current_system_time > ust - 1000000 && - current_system_time < ust + 1000000) - { - glx_renderer->ust_type = COGL_GLX_UST_IS_GETTIMEOFDAY; - goto out; - } - - /* This is the time source that the newer (fixed) linux drm - * drivers use (Linux >= 3.8) */ - current_monotonic_time = g_get_monotonic_time (); - - if (current_monotonic_time > ust - 1000000 && - current_monotonic_time < ust + 1000000) - { - glx_renderer->ust_type = COGL_GLX_UST_IS_MONOTONIC_TIME; - goto out; - } - - out: - COGL_NOTE (WINSYS, "Classified OML system time as: %s", - glx_renderer->ust_type == COGL_GLX_UST_IS_GETTIMEOFDAY ? "gettimeofday" : - (glx_renderer->ust_type == COGL_GLX_UST_IS_MONOTONIC_TIME ? "monotonic" : - "other")); - return; -} - -static int64_t -ust_to_microseconds (CoglRenderer *renderer, - GLXDrawable drawable, - int64_t ust) -{ - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (renderer); - - ensure_ust_type (renderer, drawable); - - switch (glx_renderer->ust_type) - { - case COGL_GLX_UST_IS_UNKNOWN: - g_assert_not_reached (); - break; - case COGL_GLX_UST_IS_GETTIMEOFDAY: - case COGL_GLX_UST_IS_MONOTONIC_TIME: - return ust; - case COGL_GLX_UST_IS_OTHER: - /* In this case the scale of UST is undefined so we can't easily - * scale to microseconds. - * - * For example the driver may be reporting the rdtsc CPU counter - * as UST values and so the scale would need to be determined - * empirically. - * - * Potentially we could block for a known duration within - * ensure_ust_type() to measure the timescale of UST but for now - * we just ignore unknown time sources */ - return 0; - } - - return 0; -} - -static gboolean -is_ust_monotonic (CoglRenderer *renderer, - GLXDrawable drawable) -{ - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (renderer); - - ensure_ust_type (renderer, drawable); - - return (glx_renderer->ust_type == COGL_GLX_UST_IS_MONOTONIC_TIME); -} - -static void -_cogl_winsys_wait_for_vblank (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglGLXRenderer *glx_renderer; - CoglXlibRenderer *xlib_renderer; - CoglGLXDisplay *glx_display; - - glx_renderer = cogl_renderer_get_winsys (ctx->display->renderer); - xlib_renderer = _cogl_xlib_renderer_get_data (ctx->display->renderer); - glx_display = ctx->display->winsys; - - if (glx_display->can_vblank_wait) - { - CoglFrameInfo *info = cogl_onscreen_peek_tail_frame_info (onscreen); - info->flags |= COGL_FRAME_INFO_FLAG_VSYNC; - - if (glx_renderer->glXWaitForMsc) - { - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - Drawable drawable = onscreen_glx->glxwin; - int64_t ust; - int64_t msc; - int64_t sbc; - - glx_renderer->glXWaitForMsc (xlib_renderer->xdpy, drawable, - 0, 1, 0, - &ust, &msc, &sbc); - - if (is_ust_monotonic (ctx->display->renderer, drawable)) - { - info->presentation_time_us = - ust_to_microseconds (ctx->display->renderer, - drawable, - ust); - info->flags |= COGL_FRAME_INFO_FLAG_HW_CLOCK; - } - else - { - info->presentation_time_us = g_get_monotonic_time (); - } - - /* Intentionally truncating to lower 32 bits, same as DRM. */ - info->sequence = msc; - } - else - { - uint32_t current_count; - - glx_renderer->glXGetVideoSync (¤t_count); - glx_renderer->glXWaitVideoSync (2, - (current_count + 1) % 2, - ¤t_count); - - info->presentation_time_us = g_get_monotonic_time (); - } - } -} - -static uint32_t -_cogl_winsys_get_vsync_counter (CoglContext *ctx) -{ - uint32_t video_sync_count; - CoglGLXRenderer *glx_renderer; - - glx_renderer = cogl_renderer_get_winsys (ctx->display->renderer); - - glx_renderer->glXGetVideoSync (&video_sync_count); - - return video_sync_count; -} - -#ifndef GLX_BACK_BUFFER_AGE_EXT -#define GLX_BACK_BUFFER_AGE_EXT 0x20F4 -#endif - -static int -cogl_onscreen_glx_get_buffer_age (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (context->display->renderer); - GLXDrawable drawable; - unsigned int age = 0; - - if (!cogl_context_has_winsys_feature (context, COGL_WINSYS_FEATURE_BUFFER_AGE)) - return 0; - - cogl_onscreen_bind (onscreen); - - drawable = onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - mtk_x11_error_trap_push (xlib_renderer->xdpy); - glx_renderer->glXQueryDrawable (xlib_renderer->xdpy, drawable, GLX_BACK_BUFFER_AGE_EXT, &age); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - - return age; -} - -static gboolean -cogl_onscreen_glx_get_window_handles (CoglOnscreen *onscreen, - gpointer *device_out, - gpointer *window_out) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer); - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (cogl_context->display->renderer); - GLXDrawable drawable; - - drawable = onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - - *device_out = xlib_renderer->xdpy; - *window_out = (gpointer) drawable; - - return TRUE; -} - -static void -cogl_onscreen_glx_flush_notification (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - - while (onscreen_glx->pending_sync_notify > 0 || - onscreen_glx->pending_complete_notify > 0) - { - if (onscreen_glx->pending_sync_notify > 0) - { - CoglFrameInfo *info; - - info = cogl_onscreen_peek_head_frame_info (onscreen); - _cogl_onscreen_notify_frame_sync (onscreen, info); - onscreen_glx->pending_sync_notify--; - } - - if (onscreen_glx->pending_complete_notify > 0) - { - CoglFrameInfo *info; - - info = cogl_onscreen_pop_head_frame_info (onscreen); - _cogl_onscreen_notify_complete (onscreen, info); - g_object_unref (info); - onscreen_glx->pending_complete_notify--; - } - } -} - -static void -flush_pending_notifications_cb (void *data, - void *user_data) -{ - CoglFramebuffer *framebuffer = data; - - if (COGL_IS_ONSCREEN (framebuffer)) - { - CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); - - cogl_onscreen_glx_flush_notification (onscreen); - } -} - -static void -flush_pending_notifications_idle (void *user_data) -{ - CoglContext *context = user_data; - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (renderer); - - /* This needs to be disconnected before invoking the callbacks in - * case the callbacks cause it to be queued again */ - _cogl_closure_disconnect (glx_renderer->flush_notifications_idle); - glx_renderer->flush_notifications_idle = NULL; - - g_list_foreach (context->framebuffers, - flush_pending_notifications_cb, - NULL); -} - -static void -set_sync_pending (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (renderer); - - /* We only want to dispatch sync events when the application calls - * cogl_context_dispatch so instead of immediately notifying we - * queue an idle callback */ - if (!glx_renderer->flush_notifications_idle) - { - glx_renderer->flush_notifications_idle = - cogl_renderer_add_idle_closure (renderer, - flush_pending_notifications_idle, - context); - } - - onscreen_glx->pending_sync_notify++; -} - -static void -set_complete_pending (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (renderer); - - /* We only want to notify swap completion when the application calls - * cogl_context_dispatch so instead of immediately notifying we - * queue an idle callback */ - if (!glx_renderer->flush_notifications_idle) - { - glx_renderer->flush_notifications_idle = - cogl_renderer_add_idle_closure (renderer, - flush_pending_notifications_idle, - context); - } - - onscreen_glx->pending_complete_notify++; -} - -static void -cogl_onscreen_glx_swap_region (CoglOnscreen *onscreen, - const MtkRegion *region, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (context->display->renderer); - CoglGLXDisplay *glx_display = context->display->winsys; - uint32_t end_frame_vsync_counter = 0; - gboolean have_counter; - gboolean can_wait; - int x_min = 0, x_max = 0, y_min = 0, y_max = 0; - - /* - * We assume that glXCopySubBuffer is synchronized which means it won't prevent multiple - * blits per retrace if they can all be performed in the blanking period. If that's the - * case then we still want to use the vblank sync menchanism but - * we only need it to throttle redraws. - */ - gboolean blit_sub_buffer_is_synchronized = - cogl_context_has_winsys_feature (context, COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED); - - int framebuffer_width = cogl_framebuffer_get_width (framebuffer); - int framebuffer_height = cogl_framebuffer_get_height (framebuffer); - int n_rectangles = mtk_region_num_rectangles (region); - int *rectangles = g_alloca (sizeof (int) * n_rectangles * 4); - MtkRectangle extents; - - extents = mtk_region_get_extents (region); - x_min = extents.x; - y_min = extents.y; - x_max = extents.x + extents.width; - y_max = extents.y + extents.height; - - /* glXCopySubBuffer expects rectangles relative to the bottom left corner but - * we are given rectangles relative to the top left so we need to flip - * them... */ - cogl_region_to_flipped_array (region, framebuffer_height, rectangles); - - cogl_context_flush_framebuffer_state (context, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - - have_counter = glx_display->have_vblank_counter; - can_wait = glx_display->can_vblank_wait; - - /* We need to ensure that all the rendering is done, otherwise - * redraw operations that are slower than the framerate can - * queue up in the pipeline during a heavy animation, causing a - * larger and larger backlog of rendering visible as lag to the - * user. - * - * For an exaggerated example consider rendering at 60fps (so 16ms - * per frame) and you have a really slow frame that takes 160ms to - * render, even though painting the scene and issuing the commands - * to the GPU takes no time at all. If all we did was use the - * video_sync extension to throttle the painting done by the CPU - * then every 16ms we would have another frame queued up even though - * the GPU has only rendered one tenth of the current frame. By the - * time the GPU would get to the 2nd frame there would be 9 frames - * waiting to be rendered. - * - * The problem is that we don't currently have a good way to throttle - * the GPU, only the CPU so we have to resort to synchronizing the - * GPU with the CPU to throttle it. - * - * Note: calling glFinish() and synchronizing the CPU with the GPU is far - * from ideal. One idea is to use sync objects to track render completion - * so we can throttle the backlog (ideally with an additional extension that - * lets us get notifications in our mainloop instead of having to busy wait - * for the completion). - */ - cogl_framebuffer_finish (framebuffer); - - if (blit_sub_buffer_is_synchronized && have_counter && can_wait) - { - end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context); - - /* If we have the GLX_SGI_video_sync extension then we can - * be a bit smarter about how we throttle blits by avoiding - * any waits if we can see that the video sync count has - * already progressed. */ - if (onscreen_glx->last_swap_vsync_counter == end_frame_vsync_counter) - _cogl_winsys_wait_for_vblank (onscreen); - } - else if (can_wait) - _cogl_winsys_wait_for_vblank (onscreen); - - if (glx_renderer->glXCopySubBuffer) - { - Display *xdpy = xlib_renderer->xdpy; - GLXDrawable drawable; - int i; - - drawable = - onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - for (i = 0; i < n_rectangles; i++) - { - int *rect = &rectangles[4 * i]; - glx_renderer->glXCopySubBuffer (xdpy, drawable, - rect[0], rect[1], rect[2], rect[3]); - } - } - else if (context->glBlitFramebuffer) - { - int i; - - /* XXX: checkout how this state interacts with the code to use - * glBlitFramebuffer in Neil's texture atlasing branch */ - - /* glBlitFramebuffer is affected by the scissor so we need to - * ensure we have flushed an empty clip stack to get rid of it. - * We also mark that the clip state is dirty so that it will be - * flushed to the correct state the next time something is - * drawn */ - _cogl_clip_stack_flush (NULL, framebuffer); - context->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP; - - context->glDrawBuffer (GL_FRONT); - for (i = 0; i < n_rectangles; i++) - { - int *rect = &rectangles[4 * i]; - int x2 = rect[0] + rect[2]; - int y2 = rect[1] + rect[3]; - context->glBlitFramebuffer (rect[0], rect[1], x2, y2, - rect[0], rect[1], x2, y2, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } - context->glDrawBuffer (GL_BACK); - } - - /* NB: unlike glXSwapBuffers, glXCopySubBuffer and - * glBlitFramebuffer don't issue an implicit glFlush() so we - * have to flush ourselves if we want the request to complete in - * a finite amount of time since otherwise the driver can batch - * the command indefinitely. */ - context->glFlush (); - - /* NB: It's important we save the counter we read before acting on - * the swap request since if we are mixing and matching different - * swap methods between frames we don't want to read the timer e.g. - * after calling glFinish() some times and not for others. - * - * In other words; this way we consistently save the time at the end - * of the applications frame such that the counter isn't muddled by - * the varying costs of different swap methods. - */ - if (have_counter) - onscreen_glx->last_swap_vsync_counter = end_frame_vsync_counter; - - { - float refresh_rate; - - x_min = CLAMP (x_min, 0, framebuffer_width); - x_max = CLAMP (x_max, 0, framebuffer_width); - y_min = CLAMP (y_min, 0, framebuffer_height); - y_max = CLAMP (y_max, 0, framebuffer_height); - - refresh_rate = - _cogl_xlib_renderer_refresh_rate_for_rectangle (context->display->renderer, - onscreen_glx->x + x_min, - onscreen_glx->y + y_min, - x_max - x_min, - y_max - y_min); - - if (refresh_rate != 0.0) - info->refresh_rate = refresh_rate; - } - - /* XXX: we don't get SwapComplete events based on how we implement - * the _swap_region() API but if cogl-onscreen.c knows we are - * handling _SYNC and _COMPLETE events in the winsys then we need to - * send fake events in this case. - */ - if (cogl_context_has_winsys_feature (context, COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - set_sync_pending (onscreen); - set_complete_pending (onscreen); - } -} - -static void -cogl_onscreen_glx_swap_buffers_with_damage (CoglOnscreen *onscreen, - const MtkRegion *region, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (context->display->renderer); - CoglGLXDisplay *glx_display = context->display->winsys; - gboolean have_counter; - GLXDrawable drawable; - - /* XXX: theoretically this shouldn't be necessary but at least with - * the Intel drivers we have see that if we don't call - * glXMakeContextCurrent for the drawable we are swapping then - * we get a BadDrawable error from the X server. */ - cogl_context_flush_framebuffer_state (context, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - - drawable = onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - - have_counter = glx_display->have_vblank_counter; - - if (!glx_renderer->glXSwapInterval) - { - gboolean can_wait = have_counter || glx_display->can_vblank_wait; - - uint32_t end_frame_vsync_counter = 0; - - /* If the swap_region API is also being used then we need to track - * the vsync counter for each swap request so we can manually - * throttle swap_region requests. */ - if (have_counter) - end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context); - - /* If we are going to wait for VBLANK manually, we not only - * need to flush out pending drawing to the GPU before we - * sleep, we need to wait for it to finish. Otherwise, we - * may end up with the situation: - * - * - We finish drawing - GPU drawing continues - * - We go to sleep - GPU drawing continues - * VBLANK - We call glXSwapBuffers - GPU drawing continues - * - GPU drawing continues - * - Swap buffers happens - * - * Producing a tear. Calling glFinish() first will cause us - * to properly wait for the next VBLANK before we swap. This - * obviously does not happen when we use _GLX_SWAP and let - * the driver do the right thing - */ - cogl_framebuffer_finish (framebuffer); - - if (have_counter && can_wait) - { - if (onscreen_glx->last_swap_vsync_counter == - end_frame_vsync_counter) - _cogl_winsys_wait_for_vblank (onscreen); - } - else if (can_wait) - _cogl_winsys_wait_for_vblank (onscreen); - } - - glx_renderer->glXSwapBuffers (xlib_renderer->xdpy, drawable); - - if (have_counter) - onscreen_glx->last_swap_vsync_counter = - _cogl_winsys_get_vsync_counter (context); - - if (onscreen_glx->refresh_rate != 0.0) - info->refresh_rate = onscreen_glx->refresh_rate; -} - -static Window -cogl_onscreen_glx_get_x11_window (CoglX11Onscreen *x11_onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (x11_onscreen); - - return onscreen_glx->xwin; -} - -void -cogl_onscreen_glx_notify_swap_buffers (CoglOnscreen *onscreen, - GLXBufferSwapComplete *swap_event) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - gboolean ust_is_monotonic; - CoglFrameInfo *info; - - /* We only want to notify that the swap is complete when the - application calls cogl_context_dispatch so instead of immediately - notifying we'll set a flag to remember to notify later */ - set_sync_pending (onscreen); - - info = cogl_onscreen_peek_head_frame_info (onscreen); - info->flags |= COGL_FRAME_INFO_FLAG_VSYNC; - - ust_is_monotonic = is_ust_monotonic (context->display->renderer, - onscreen_glx->glxwin); - - if (swap_event->ust != 0 && ust_is_monotonic) - { - info->presentation_time_us = - ust_to_microseconds (context->display->renderer, - onscreen_glx->glxwin, - swap_event->ust); - info->flags |= COGL_FRAME_INFO_FLAG_HW_CLOCK; - } - - /* Intentionally truncating to lower 32 bits, same as DRM. */ - info->sequence = swap_event->msc; - - set_complete_pending (onscreen); -} - -void -cogl_onscreen_glx_update_output (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - int width, height; - - width = cogl_framebuffer_get_width (framebuffer); - height = cogl_framebuffer_get_height (framebuffer); - - onscreen_glx->refresh_rate = - _cogl_xlib_renderer_refresh_rate_for_rectangle (display->renderer, - onscreen_glx->x, - onscreen_glx->y, - width, height); -} - -void -cogl_onscreen_glx_resize (CoglOnscreen *onscreen, - XConfigureEvent *configure_event) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (renderer); - int x, y; - - - _cogl_framebuffer_winsys_update_size (framebuffer, - configure_event->width, - configure_event->height); - - /* We only want to notify that a resize happened when the - * application calls cogl_context_dispatch so instead of immediately - * notifying we queue an idle callback */ - if (!glx_renderer->flush_notifications_idle) - { - glx_renderer->flush_notifications_idle = - cogl_renderer_add_idle_closure (renderer, - flush_pending_notifications_idle, - context); - } - - if (configure_event->send_event) - { - x = configure_event->x; - y = configure_event->y; - } - else - { - Window child; - XTranslateCoordinates (configure_event->display, - configure_event->window, - DefaultRootWindow (configure_event->display), - 0, 0, &x, &y, &child); - } - - onscreen_glx->x = x; - onscreen_glx->y = y; - - cogl_onscreen_glx_update_output (onscreen); -} - -gboolean -cogl_onscreen_glx_is_for_window (CoglOnscreen *onscreen, - Window window) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - - return onscreen_glx->xwin == window; -} - -CoglOnscreenGlx * -cogl_onscreen_glx_new (CoglContext *context, - int width, - int height) -{ - CoglFramebufferDriverConfig driver_config; - - driver_config = (CoglFramebufferDriverConfig) { - .type = COGL_FRAMEBUFFER_DRIVER_TYPE_BACK, - }; - return g_object_new (COGL_TYPE_ONSCREEN_GLX, - "context", context, - "driver-config", &driver_config, - "width", width, - "height", height, - NULL); -} - -static void -cogl_onscreen_glx_init (CoglOnscreenGlx *onscreen_glx) -{ -} - -static void -x11_onscreen_init_iface (CoglX11OnscreenInterface *iface) -{ - iface->get_x11_window = cogl_onscreen_glx_get_x11_window; -} - -static void -cogl_onscreen_glx_class_init (CoglOnscreenGlxClass *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 = cogl_onscreen_glx_dispose; - - framebuffer_class->allocate = cogl_onscreen_glx_allocate; - - onscreen_class->bind = cogl_onscreen_glx_bind; - onscreen_class->swap_buffers_with_damage = - cogl_onscreen_glx_swap_buffers_with_damage; - onscreen_class->swap_region = cogl_onscreen_glx_swap_region; - onscreen_class->get_buffer_age = cogl_onscreen_glx_get_buffer_age; - onscreen_class->get_window_handles = cogl_onscreen_glx_get_window_handles; -} diff --git a/cogl/cogl/winsys/cogl-onscreen-glx.h b/cogl/cogl/winsys/cogl-onscreen-glx.h deleted file mode 100644 index 266595aac4f..00000000000 --- a/cogl/cogl/winsys/cogl-onscreen-glx.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * Copyright (C) 2020 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 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. - */ - -#pragma once - -#include -#include - -#include "cogl/cogl-onscreen.h" - -#define COGL_TYPE_ONSCREEN_GLX (cogl_onscreen_glx_get_type ()) -G_DECLARE_FINAL_TYPE (CoglOnscreenGlx, cogl_onscreen_glx, - COGL, ONSCREEN_GLX, - CoglOnscreen) - -COGL_EXPORT CoglOnscreenGlx * -cogl_onscreen_glx_new (CoglContext *context, - int width, - int height); - -void -cogl_onscreen_glx_resize (CoglOnscreen *onscreen, - XConfigureEvent *configure_event); - -void -cogl_onscreen_glx_update_output (CoglOnscreen *onscreen); - -void -cogl_onscreen_glx_notify_swap_buffers (CoglOnscreen *onscreen, - GLXBufferSwapComplete *swap_event); - -gboolean -cogl_onscreen_glx_is_for_window (CoglOnscreen *onscreen, - Window window); diff --git a/cogl/cogl/winsys/cogl-onscreen-xlib.c b/cogl/cogl/winsys/cogl-onscreen-xlib.c deleted file mode 100644 index 29734f001f3..00000000000 --- a/cogl/cogl/winsys/cogl-onscreen-xlib.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (C) 2011,2013 Intel Corporation. - * Copyright (C) 2020 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 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 "cogl/winsys/cogl-onscreen-xlib.h" - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-x11-onscreen.h" -#include "cogl/cogl-xlib-renderer-private.h" -#include "cogl/winsys/cogl-onscreen-egl.h" -#include "cogl/winsys/cogl-winsys-egl-x11-private.h" -#include "mtk/mtk-x11.h" - -struct _CoglOnscreenXlib -{ - CoglOnscreenEgl parent; - - Window xwin; -}; - -static void -x11_onscreen_init_iface (CoglX11OnscreenInterface *iface); - -G_DEFINE_FINAL_TYPE_WITH_CODE (CoglOnscreenXlib, cogl_onscreen_xlib, - COGL_TYPE_ONSCREEN_EGL, - G_IMPLEMENT_INTERFACE (COGL_TYPE_X11_ONSCREEN, - x11_onscreen_init_iface)) - -#define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask) - - -static Window -create_xwindow (CoglOnscreenXlib *onscreen_xlib, - EGLConfig egl_config, - GError **error) -{ - CoglOnscreen *onscreen = COGL_ONSCREEN (onscreen_xlib); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - CoglRenderer *renderer = display->renderer; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - Window xwin; - int width; - int height; - XVisualInfo *xvisinfo; - XSetWindowAttributes xattr; - unsigned long mask; - int xerror; - - width = cogl_framebuffer_get_width (framebuffer); - height = cogl_framebuffer_get_height (framebuffer); - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - xvisinfo = cogl_display_xlib_get_visual_info (display, egl_config); - if (xvisinfo == NULL) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Unable to retrieve the X11 visual of context's " - "fbconfig"); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - return None; - } - - /* window attributes */ - xattr.background_pixel = - WhitePixel (xlib_renderer->xdpy, - DefaultScreen (xlib_renderer->xdpy)); - xattr.border_pixel = 0; - /* XXX: is this an X resource that we are leaking‽... */ - xattr.colormap = - XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK; - - mask = CWBorderPixel | CWColormap | CWEventMask; - - xwin = XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - 0, 0, - width, height, - 0, - xvisinfo->depth, - InputOutput, - xvisinfo->visual, - mask, &xattr); - - XFree (xvisinfo); - - XSync (xlib_renderer->xdpy, False); - xerror = mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy); - if (xerror) - { - char message[1000]; - XGetErrorText (xlib_renderer->xdpy, xerror, - message, sizeof (message)); - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "X error while creating Window for CoglOnscreen: %s", - message); - return None; - } - - return xwin; -} - -static gboolean -cogl_onscreen_xlib_allocate (CoglFramebuffer *framebuffer, - GError **error) -{ - CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (framebuffer); - CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (framebuffer); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - CoglRenderer *renderer = display->renderer; - CoglRendererEGL *egl_renderer = cogl_renderer_get_winsys (renderer); - EGLConfig egl_config; - Window xwin; - EGLSurface egl_surface; - CoglFramebufferClass *parent_class; - - if (!cogl_onscreen_egl_choose_config (onscreen_egl, &egl_config, error)) - return FALSE; - - xwin = create_xwindow (onscreen_xlib, egl_config, error); - if (xwin == None) - return FALSE; - - onscreen_xlib->xwin = xwin; - - egl_surface = - eglCreateWindowSurface (egl_renderer->edpy, - egl_config, - (EGLNativeWindowType) onscreen_xlib->xwin, - NULL); - cogl_onscreen_egl_set_egl_surface (onscreen_egl, - egl_surface); - - parent_class = COGL_FRAMEBUFFER_CLASS (cogl_onscreen_xlib_parent_class); - return parent_class->allocate (framebuffer, error); -} - -static gboolean -cogl_onscreen_xlib_get_window_handles (CoglOnscreen *onscreen, - gpointer *device_out, - gpointer *window_out) -{ - CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer); - CoglDisplayEGL *cogl_display_egl = cogl_context->display->winsys; - - *device_out = cogl_display_egl->egl_context; - *window_out = (gpointer) onscreen_xlib->xwin; - - return TRUE; -} - -static void -cogl_onscreen_xlib_dispose (GObject *object) -{ - CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (object); - - G_OBJECT_CLASS (cogl_onscreen_xlib_parent_class)->dispose (object); - - if (onscreen_xlib->xwin != None) - { - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - XDestroyWindow (xlib_renderer->xdpy, onscreen_xlib->xwin); - onscreen_xlib->xwin = None; - XSync (xlib_renderer->xdpy, False); - - if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy)) - g_warning ("X Error while destroying X window"); - - onscreen_xlib->xwin = None; - } -} - -static Window -cogl_onscreen_xlib_get_x11_window (CoglX11Onscreen *x11_onscreen) -{ - CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (x11_onscreen); - - return onscreen_xlib->xwin; -} - -gboolean -cogl_onscreen_xlib_is_for_window (CoglOnscreen *onscreen, - Window window) -{ - CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (onscreen); - - return onscreen_xlib->xwin == window; -} - -void -cogl_onscreen_xlib_resize (CoglOnscreen *onscreen, - int width, - int height) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - - _cogl_framebuffer_winsys_update_size (framebuffer, width, height); -} - -CoglOnscreenXlib * -cogl_onscreen_xlib_new (CoglContext *context, - int width, - int height) -{ - CoglFramebufferDriverConfig driver_config; - - driver_config = (CoglFramebufferDriverConfig) { - .type = COGL_FRAMEBUFFER_DRIVER_TYPE_BACK, - }; - return g_object_new (COGL_TYPE_ONSCREEN_XLIB, - "context", context, - "driver-config", &driver_config, - "width", width, - "height", height, - NULL); -} - -static void -cogl_onscreen_xlib_init (CoglOnscreenXlib *onscreen_xlib) -{ -} - -static void -x11_onscreen_init_iface (CoglX11OnscreenInterface *iface) -{ - iface->get_x11_window = cogl_onscreen_xlib_get_x11_window; -} - -static void -cogl_onscreen_xlib_class_init (CoglOnscreenXlibClass *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 = cogl_onscreen_xlib_dispose; - - framebuffer_class->allocate = cogl_onscreen_xlib_allocate; - onscreen_class->get_window_handles = cogl_onscreen_xlib_get_window_handles; -} diff --git a/cogl/cogl/winsys/cogl-onscreen-xlib.h b/cogl/cogl/winsys/cogl-onscreen-xlib.h deleted file mode 100644 index b35cbe964c8..00000000000 --- a/cogl/cogl/winsys/cogl-onscreen-xlib.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2011,2013 Intel Corporation. - * Copyright (C) 2020 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 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. - * - */ - -#pragma once - -#include "cogl/cogl-onscreen.h" -#include "cogl/winsys/cogl-onscreen-egl.h" - -#define COGL_TYPE_ONSCREEN_XLIB (cogl_onscreen_xlib_get_type ()) -G_DECLARE_FINAL_TYPE (CoglOnscreenXlib, cogl_onscreen_xlib, - COGL, ONSCREEN_XLIB, - CoglOnscreenEgl) - -COGL_EXPORT CoglOnscreenXlib * -cogl_onscreen_xlib_new (CoglContext *context, - int width, - int height); - -gboolean -cogl_onscreen_xlib_is_for_window (CoglOnscreen *onscreen, - Window window); - -void -cogl_onscreen_xlib_resize (CoglOnscreen *onscreen, - int width, - int height); diff --git a/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h b/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h deleted file mode 100644 index e42560738d5..00000000000 --- a/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include -#include -#include - -#include - -#ifdef HAVE_GLX -#include -#endif - -#include "cogl/cogl-texture-private.h" -#include "cogl/winsys/cogl-texture-pixmap-x11.h" -#include "mtk/mtk-rectangle.h" - -/* For stereo, there are a pair of textures, but we want to share most - * other state (the GLXPixmap, visual, etc.) The way we do this is that - * the left-eye texture has all the state (there is in fact, no internal - * difference between the a MONO and a LEFT texture ), and the - * right-eye texture simply points to the left eye texture, with all - * other fields ignored. - */ -typedef enum -{ - COGL_TEXTURE_PIXMAP_MONO, - COGL_TEXTURE_PIXMAP_LEFT, - COGL_TEXTURE_PIXMAP_RIGHT -} CoglTexturePixmapStereoMode; - -struct _CoglTexturePixmapX11 -{ - CoglTexture parent_instance; - - CoglTexturePixmapStereoMode stereo_mode; - CoglTexturePixmapX11 *left; /* Set only if stereo_mode=RIGHT */ - - Pixmap pixmap; - CoglTexture *tex; - - unsigned int depth; - Visual *visual; - - XImage *image; - - XShmSegmentInfo shm_info; - - Damage damage; - CoglTexturePixmapX11ReportLevel damage_report_level; - gboolean damage_owned; - MtkRectangle damage_rect; - - void *winsys; - - /* During the pre_paint method, this will be set to TRUE if we - should use the winsys texture, otherwise we will use the regular - texture */ - gboolean use_winsys_texture; -}; - -struct _CoglTexturePixmapX11Class -{ - CoglTextureClass parent_class; -}; diff --git a/cogl/cogl/winsys/cogl-texture-pixmap-x11.c b/cogl/cogl/winsys/cogl-texture-pixmap-x11.c deleted file mode 100644 index 3e226f76495..00000000000 --- a/cogl/cogl/winsys/cogl-texture-pixmap-x11.c +++ /dev/null @@ -1,1178 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - * Johan Bilien - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-debug.h" -#include "cogl/cogl-util.h" -#include "cogl/winsys/cogl-texture-pixmap-x11.h" -#include "cogl/winsys/cogl-texture-pixmap-x11-private.h" -#include "cogl/cogl-bitmap-private.h" -#include "cogl/cogl-texture-private.h" -#include "cogl/cogl-texture-driver.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/cogl-texture-2d-sliced.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-display-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-xlib-renderer.h" -#include "cogl/cogl-xlib-renderer-private.h" -#include "cogl/cogl-private.h" -#include "cogl/driver/gl/cogl-texture-gl-private.h" -#include "cogl/winsys/cogl-winsys-private.h" - -#include -#include - -#include -#include -#include - -#include -#include - -G_DEFINE_FINAL_TYPE (CoglTexturePixmapX11, cogl_texture_pixmap_x11, COGL_TYPE_TEXTURE) - -static const CoglWinsysVtable * -_cogl_texture_pixmap_x11_get_winsys (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglContext *ctx; - - ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - return cogl_renderer_get_winsys_vtable (ctx->display->renderer) ; -} - -static int -_cogl_xlib_get_damage_base (CoglContext *ctx) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (ctx->display->renderer); - - return xlib_renderer->damage_base; -} - -static void -process_damage_event (CoglTexturePixmapX11 *tex_pixmap, - XDamageNotifyEvent *damage_event) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - Display *display; - enum -{ DO_NOTHING, NEEDS_SUBTRACT, NEED_BOUNDING_BOX } handle_mode; - const CoglWinsysVtable *winsys; - CoglContext *ctx; - MtkRectangle damage_rect; - - ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - display = cogl_xlib_renderer_get_display (ctx->display->renderer); - - COGL_NOTE (TEXTURE_PIXMAP, "Damage event received for %p", tex_pixmap); - - switch (tex_pixmap->damage_report_level) - { - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_RAW_RECTANGLES: - /* For raw rectangles we don't need do look at the damage region - at all because the damage area is directly given in the event - struct and the reporting of events is not affected by - clearing the damage region */ - handle_mode = DO_NOTHING; - break; - - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_DELTA_RECTANGLES: - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_NON_EMPTY: - /* For delta rectangles and non empty we'll query the damage - region for the bounding box */ - handle_mode = NEED_BOUNDING_BOX; - break; - - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX: - /* For bounding box we need to clear the damage region but we - don't actually care what it was because the damage event - itself contains the bounding box of the region */ - handle_mode = NEEDS_SUBTRACT; - break; - - default: - g_assert_not_reached (); - } - - /* If the damage already covers the whole rectangle then we don't - need to request the bounding box of the region because we're - going to update the whole texture anyway. */ - damage_rect = MTK_RECTANGLE_INIT (0, 0, - cogl_texture_get_width (tex), - cogl_texture_get_height (tex)); - if (mtk_rectangle_equal (&tex_pixmap->damage_rect, &damage_rect)) - { - if (handle_mode != DO_NOTHING) - XDamageSubtract (display, tex_pixmap->damage, None, None); - } - else if (handle_mode == NEED_BOUNDING_BOX) - { - XserverRegion parts; - int r_count; - XRectangle r_bounds; - XRectangle *r_damage; - - /* We need to extract the damage region so we can get the - bounding box */ - - parts = XFixesCreateRegion (display, 0, 0); - XDamageSubtract (display, tex_pixmap->damage, None, parts); - r_damage = XFixesFetchRegionAndBounds (display, - parts, - &r_count, - &r_bounds); - damage_rect = MTK_RECTANGLE_INIT (r_bounds.x, r_bounds.y, - r_bounds.width, r_bounds.height); - mtk_rectangle_union (&tex_pixmap->damage_rect, - &damage_rect, - &tex_pixmap->damage_rect); - if (r_damage) - XFree (r_damage); - - XFixesDestroyRegion (display, parts); - } - else - { - if (handle_mode == NEEDS_SUBTRACT) - /* We still need to subtract from the damage region but we - don't care what the region actually was */ - XDamageSubtract (display, tex_pixmap->damage, None, None); - - damage_rect = MTK_RECTANGLE_INIT (damage_event->area.x, - damage_event->area.y, - damage_event->area.width, - damage_event->area.height); - mtk_rectangle_union (&tex_pixmap->damage_rect, - &damage_rect, - &tex_pixmap->damage_rect); - } - - if (tex_pixmap->winsys) - { - /* If we're using the texture from pixmap extension then there's no - point in getting the region and we can just mark that the texture - needs updating */ - winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - winsys->texture_pixmap_x11_damage_notify (tex_pixmap); - } -} - -static CoglFilterReturn -_cogl_texture_pixmap_x11_filter (XEvent *event, void *data) -{ - CoglTexturePixmapX11 *tex_pixmap = data; - int damage_base; - CoglContext *ctx; - - ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - damage_base = _cogl_xlib_get_damage_base (ctx); - if (event->type == damage_base + XDamageNotify) - { - XDamageNotifyEvent *damage_event = (XDamageNotifyEvent *) event; - - if (damage_event->damage == tex_pixmap->damage) - process_damage_event (tex_pixmap, damage_event); - } - - return COGL_FILTER_CONTINUE; -} - -static void -set_damage_object_internal (CoglContext *ctx, - CoglTexturePixmapX11 *tex_pixmap, - Damage damage, - CoglTexturePixmapX11ReportLevel report_level) -{ - Display *display = cogl_xlib_renderer_get_display (ctx->display->renderer); - - if (tex_pixmap->damage) - { - _cogl_renderer_remove_native_filter (ctx->display->renderer, - (CoglNativeFilterFunc)_cogl_texture_pixmap_x11_filter, - tex_pixmap); - - if (tex_pixmap->damage_owned) - { - XDamageDestroy (display, tex_pixmap->damage); - tex_pixmap->damage_owned = FALSE; - } - } - - tex_pixmap->damage = damage; - tex_pixmap->damage_report_level = report_level; - - if (damage) - _cogl_renderer_add_native_filter (ctx->display->renderer, - (CoglNativeFilterFunc)_cogl_texture_pixmap_x11_filter, - tex_pixmap); -} - -static void -cogl_texture_pixmap_x11_dispose (GObject *object) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (object); - CoglContext *ctx; - Display *display; - - ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - - if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - { - g_object_unref (tex_pixmap->left); - G_OBJECT_CLASS (cogl_texture_pixmap_x11_parent_class)->dispose (object); - return; - } - - display = cogl_xlib_renderer_get_display (ctx->display->renderer); - - set_damage_object_internal (ctx, tex_pixmap, 0, 0); - - if (tex_pixmap->image) - XDestroyImage (tex_pixmap->image); - - if (tex_pixmap->shm_info.shmid != -1) - { - XShmDetach (display, &tex_pixmap->shm_info); - shmdt (tex_pixmap->shm_info.shmaddr); - shmctl (tex_pixmap->shm_info.shmid, IPC_RMID, 0); - } - - if (tex_pixmap->tex) - g_object_unref (tex_pixmap->tex); - - if (tex_pixmap->winsys) - { - const CoglWinsysVtable *winsys = - _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - winsys->texture_pixmap_x11_free (tex_pixmap); - } - - G_OBJECT_CLASS (cogl_texture_pixmap_x11_parent_class)->dispose (object); -} - -static void -_cogl_texture_pixmap_x11_set_use_winsys_texture (CoglTexturePixmapX11 *tex_pixmap, - gboolean new_value) -{ - if (tex_pixmap->use_winsys_texture != new_value) - { - /* Notify cogl-pipeline.c that the texture's underlying GL texture - * storage is changing so it knows it may need to bind a new texture - * if the CoglTexture is reused with the same texture unit. */ - _cogl_pipeline_texture_storage_change_notify (COGL_TEXTURE (tex_pixmap)); - - tex_pixmap->use_winsys_texture = new_value; - } -} - -static CoglTexture * -create_fallback_texture (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format) -{ - CoglTexture *tex; - GError *skip_error = NULL; - - /* First try creating a fast-path non-sliced texture */ - tex = cogl_texture_2d_new_with_size (ctx, width, height); - - _cogl_texture_set_internal_format (tex, internal_format); - - /* TODO: instead of allocating storage here it would be better - * if we had some api that let us just check that the size is - * supported by the hardware so storage could be allocated - * lazily when uploading data. */ - if (!cogl_texture_allocate (tex, &skip_error)) - { - g_error_free (skip_error); - g_object_unref (tex); - tex = NULL; - } - - if (!tex) - { - tex = - cogl_texture_2d_sliced_new_with_size (ctx, - width, - height, - COGL_TEXTURE_MAX_WASTE); - _cogl_texture_set_internal_format (tex, internal_format); - } - - return tex; -} - - -/* Tries to allocate enough shared mem to handle a full size - * update size of the X Pixmap. */ -static void -try_alloc_shm (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - XImage *dummy_image; - CoglContext *ctx; - Display *display; - - ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - display = cogl_xlib_renderer_get_display (ctx->display->renderer); - - if (!XShmQueryExtension (display)) - return; - - /* We are creating a dummy_image so we can have Xlib calculate - * image->bytes_per_line - including any magic padding it may - * want - for the largest possible ximage we might need to use - * when handling updates to the texture. - * - * Note: we pass a NULL shminfo here, but that has no bearing - * on the setup of the XImage, except that ximage->obdata will - * == NULL. - */ - dummy_image = - XShmCreateImage (display, - tex_pixmap->visual, - tex_pixmap->depth, - ZPixmap, - NULL, - NULL, /* shminfo, */ - cogl_texture_get_width (tex), - cogl_texture_get_height (tex)); - if (!dummy_image) - goto failed_image_create; - - tex_pixmap->shm_info.shmid = shmget (IPC_PRIVATE, - dummy_image->bytes_per_line - * dummy_image->height, - IPC_CREAT | 0777); - if (tex_pixmap->shm_info.shmid == -1) - goto failed_shmget; - - tex_pixmap->shm_info.shmaddr = shmat (tex_pixmap->shm_info.shmid, 0, 0); - if (tex_pixmap->shm_info.shmaddr == (void *) -1) - goto failed_shmat; - - tex_pixmap->shm_info.readOnly = False; - - if (XShmAttach (display, &tex_pixmap->shm_info) == 0) - goto failed_xshmattach; - - XDestroyImage (dummy_image); - - return; - - failed_xshmattach: - g_warning ("XShmAttach failed"); - shmdt (tex_pixmap->shm_info.shmaddr); - - failed_shmat: - g_warning ("shmat failed"); - shmctl (tex_pixmap->shm_info.shmid, IPC_RMID, 0); - - failed_shmget: - g_warning ("shmget failed"); - XDestroyImage (dummy_image); - - failed_image_create: - tex_pixmap->shm_info.shmid = -1; -} - -/* Given a set of red, green and blue component masks, a depth and - * bits per pixel this function tries to determine a corresponding - * CoglPixelFormat. - * - * The depth is measured in bits not including padding for un-used - * alpha. The bits per pixel (bpp) does include padding for un-used - * alpha. - * - * This function firstly aims to match formats with RGB ordered - * components and only considers alpha coming first, in the most - * significant bits. If the function fails to match then it recurses - * by either switching the r and b masks around to check for BGR - * ordered formats or it recurses with the masks shifted to check for - * formats where the alpha component is the least significant bits. - */ -static CoglPixelFormat -_cogl_util_pixel_format_from_masks_real (unsigned long r_mask, - unsigned long g_mask, - unsigned long b_mask, - int depth, int bpp, - gboolean check_bgr, - gboolean check_afirst, - int recursion_depth) -{ - CoglPixelFormat image_format; - - if (depth == 24 && bpp == 24 && - r_mask == 0xff0000 && g_mask == 0xff00 && b_mask == 0xff) - { - return COGL_PIXEL_FORMAT_RGB_888; - } - else if ((depth == 24 || depth == 32) && bpp == 32 && - r_mask == 0xff0000 && g_mask == 0xff00 && b_mask == 0xff) - { - return COGL_PIXEL_FORMAT_ARGB_8888_PRE; - } - else if ((depth == 30 || depth == 32) && - r_mask == 0x3ff00000 && g_mask == 0xffc00 && b_mask == 0x3ff) - { - return COGL_PIXEL_FORMAT_ARGB_2101010_PRE; - } - else if (depth == 16 && bpp == 16 && - r_mask == 0xf800 && g_mask == 0x7e0 && b_mask == 0x1f) - { - return COGL_PIXEL_FORMAT_RGB_565; - } - - if (recursion_depth == 2) - return 0; - - /* Check for BGR ordering if we didn't find a match */ - if (check_bgr) - { - image_format = - _cogl_util_pixel_format_from_masks_real (b_mask, g_mask, r_mask, - depth, bpp, - FALSE, - TRUE, - recursion_depth + 1); - if (image_format) - return image_format ^ COGL_BGR_BIT; - } - - /* Check for alpha in the least significant bits if we still - * haven't found a match... */ - if (check_afirst && depth != bpp) - { - int shift = bpp - depth; - - image_format = - _cogl_util_pixel_format_from_masks_real (r_mask >> shift, - g_mask >> shift, - b_mask >> shift, - depth, bpp, - TRUE, - FALSE, - recursion_depth + 1); - if (image_format) - return image_format ^ COGL_AFIRST_BIT; - } - - return 0; -} - - -/* Match a CoglPixelFormat according to channel masks, color depth, - * bits per pixel and byte order. These information are provided by - * the Visual and XImage structures. - * - * If no specific pixel format could be found, COGL_PIXEL_FORMAT_ANY - * is returned. - */ -static CoglPixelFormat -_cogl_util_pixel_format_from_masks (unsigned long r_mask, - unsigned long g_mask, - unsigned long b_mask, - int depth, int bpp, - gboolean byte_order_is_lsb_first) -{ - CoglPixelFormat image_format = - _cogl_util_pixel_format_from_masks_real (r_mask, g_mask, b_mask, - depth, bpp, - TRUE, - TRUE, - 0); - - if (!image_format) - { - const char *byte_order[] = { "MSB first", "LSB first" }; - g_warning ("Could not find a matching pixel format for red mask=0x%lx," - "green mask=0x%lx, blue mask=0x%lx at depth=%d, bpp=%d " - "and byte order=%s\n", r_mask, g_mask, b_mask, depth, bpp, - byte_order[!!byte_order_is_lsb_first]); - return 0; - } - - /* If the image is in little-endian then the order in memory is - reversed */ - if (byte_order_is_lsb_first && - _cogl_pixel_format_is_endian_dependant (image_format)) - { - image_format ^= COGL_BGR_BIT; - if (image_format & COGL_A_BIT) - image_format ^= COGL_AFIRST_BIT; - } - - return image_format; -} - -static void -_cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - Display *display; - Visual *visual; - CoglContext *ctx; - CoglPixelFormat image_format; - XImage *image; - int src_x, src_y; - int x, y, width, height; - int bpp; - int offset; - GError *ignore = NULL; - - ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - display = cogl_xlib_renderer_get_display (ctx->display->renderer); - visual = tex_pixmap->visual; - - /* If the damage region is empty then there's nothing to do */ - if (tex_pixmap->damage_rect.x == tex_pixmap->damage_rect.width) - return; - - x = tex_pixmap->damage_rect.x; - y = tex_pixmap->damage_rect.y; - width = tex_pixmap->damage_rect.width; - height = tex_pixmap->damage_rect.height; - - /* We lazily create the texture the first time it is needed in case - this texture can be entirely handled using the GLX texture - instead */ - if (tex_pixmap->tex == NULL) - { - CoglPixelFormat texture_format; - - texture_format = (tex_pixmap->depth >= 32 - ? COGL_PIXEL_FORMAT_RGBA_8888_PRE - : COGL_PIXEL_FORMAT_RGB_888); - - tex_pixmap->tex = create_fallback_texture (ctx, - cogl_texture_get_width (tex), - cogl_texture_get_height (tex), - texture_format); - } - - if (tex_pixmap->image == NULL) - { - /* If we also haven't got a shm segment then this must be the - first time we've tried to update, so lets try allocating shm - first */ - if (tex_pixmap->shm_info.shmid == -1) - try_alloc_shm (tex_pixmap); - - if (tex_pixmap->shm_info.shmid == -1) - { - COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetImage", tex_pixmap); - - /* We'll fallback to using a regular XImage. We'll download - the entire area instead of a sub region because presumably - if this is the first update then the entire pixmap is - needed anyway and it saves trying to manually allocate an - XImage at the right size */ - tex_pixmap->image = XGetImage (display, - tex_pixmap->pixmap, - 0, 0, - cogl_texture_get_width (tex), - cogl_texture_get_height (tex), - AllPlanes, ZPixmap); - image = tex_pixmap->image; - src_x = x; - src_y = y; - } - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XShmGetImage", - tex_pixmap); - - /* Create a temporary image using the beginning of the - shared memory segment and the right size for the region - we want to update. We need to reallocate the XImage every - time because there is no XShmGetSubImage. */ - image = XShmCreateImage (display, - tex_pixmap->visual, - tex_pixmap->depth, - ZPixmap, - NULL, - &tex_pixmap->shm_info, - width, - height); - image->data = tex_pixmap->shm_info.shmaddr; - src_x = 0; - src_y = 0; - - XShmGetImage (display, tex_pixmap->pixmap, image, x, y, AllPlanes); - } - } - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetSubImage", tex_pixmap); - - image = tex_pixmap->image; - src_x = x; - src_y = y; - - XGetSubImage (display, - tex_pixmap->pixmap, - x, y, width, height, - AllPlanes, ZPixmap, - image, - x, y); - } - - image_format = - _cogl_util_pixel_format_from_masks (visual->red_mask, - visual->green_mask, - visual->blue_mask, - image->depth, - image->bits_per_pixel, - image->byte_order == LSBFirst); - g_return_if_fail (cogl_pixel_format_get_n_planes (image_format) == 1); - - bpp = cogl_pixel_format_get_bytes_per_pixel (image_format, 0); - offset = image->bytes_per_line * src_y + bpp * src_x; - - _cogl_texture_set_region (tex_pixmap->tex, - width, - height, - image_format, - image->bytes_per_line, - ((const uint8_t *) image->data) + offset, - x, y, - 0, /* level */ - &ignore); - - /* If we have a shared memory segment then the XImage would be a - temporary one with no data allocated so we can just XFree it */ - if (tex_pixmap->shm_info.shmid != -1) - XFree (image); - - memset (&tex_pixmap->damage_rect, 0, sizeof (MtkRectangle)); -} - -static void -_cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, - gboolean needs_mipmap) -{ - CoglTexturePixmapStereoMode stereo_mode = tex_pixmap->stereo_mode; - if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - tex_pixmap = tex_pixmap->left; - - if (tex_pixmap->winsys) - { - const CoglWinsysVtable *winsys = - _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - - if (winsys->texture_pixmap_x11_update (tex_pixmap, stereo_mode, needs_mipmap)) - { - _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, TRUE); - return; - } - } - - /* If it didn't work then fallback to using XGetImage. This may be - temporary */ - _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, FALSE); - - _cogl_texture_pixmap_x11_update_image_texture (tex_pixmap); -} - -static CoglTexture * -_cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapX11 *original_pixmap = tex_pixmap; - CoglTexture *tex; - int i; - CoglTexturePixmapStereoMode stereo_mode = tex_pixmap->stereo_mode; - - if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - tex_pixmap = tex_pixmap->left; - - /* We try getting the texture twice, once without flushing the - updates and once with. If pre_paint has been called already then - we should have a good idea of which texture to use so we don't - want to mess with that by ensuring the updates. However, if we - couldn't find a texture then we'll just make a best guess by - flushing without expecting mipmap support and try again. This - would happen for example if an application calls - get_gl_texture before the first paint */ - - for (i = 0; i < 2; i++) - { - if (tex_pixmap->use_winsys_texture) - { - const CoglWinsysVtable *winsys = - _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - tex = winsys->texture_pixmap_x11_get_texture (tex_pixmap, stereo_mode); - } - else - tex = tex_pixmap->tex; - - if (tex) - return tex; - - _cogl_texture_pixmap_x11_update (original_pixmap, FALSE); - } - - g_assert_not_reached (); - - return NULL; -} - -static gboolean -_cogl_texture_pixmap_x11_allocate (CoglTexture *tex, - GError **error) -{ - return TRUE; -} - -static gboolean -_cogl_texture_pixmap_x11_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int dst_width, - int dst_height, - int level, - CoglBitmap *bmp, - GError **error) -{ - /* This doesn't make much sense for texture from pixmap so it's not - supported */ - g_set_error_literal (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Explicitly setting a region of a TFP texture " - "unsupported"); - return FALSE; -} - -static gboolean -_cogl_texture_pixmap_x11_get_data (CoglTexture *tex, - CoglPixelFormat format, - int rowstride, - uint8_t *data) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return cogl_texture_get_data (child_tex, format, rowstride, data); -} - -static void -_cogl_texture_pixmap_x11_foreach_sub_texture_in_region - (CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglTextureForeachCallback callback, - void *user_data) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - cogl_texture_foreach_in_region (child_tex, - virtual_tx_1, - virtual_ty_1, - virtual_tx_2, - virtual_ty_2, - COGL_PIPELINE_WRAP_MODE_REPEAT, - COGL_PIPELINE_WRAP_MODE_REPEAT, - callback, - user_data); -} - -static gboolean -_cogl_texture_pixmap_x11_is_sliced (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - return cogl_texture_is_sliced (child_tex); -} - -static gboolean -_cogl_texture_pixmap_x11_can_hardware_repeat (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - return _cogl_texture_can_hardware_repeat (child_tex); -} - -static void -_cogl_texture_pixmap_x11_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - COGL_TEXTURE_GET_CLASS (child_tex)->transform_coords_to_gl (child_tex, s, t); -} - -static CoglTransformResult -_cogl_texture_pixmap_x11_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return COGL_TEXTURE_GET_CLASS (child_tex)->transform_quad_coords_to_gl (child_tex, - coords); -} - -static gboolean -_cogl_texture_pixmap_x11_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return cogl_texture_get_gl_texture (child_tex, - out_gl_handle, - out_gl_target); -} - -static void -_cogl_texture_pixmap_x11_gl_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - _cogl_texture_gl_flush_legacy_texobj_filters (child_tex, - min_filter, mag_filter); -} - -static void -_cogl_texture_pixmap_x11_pre_paint (CoglTexture *tex, - CoglTexturePrePaintFlags flags) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex; - - _cogl_texture_pixmap_x11_update (tex_pixmap, - !!(flags & COGL_TEXTURE_NEEDS_MIPMAP)); - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - _cogl_texture_pre_paint (child_tex, flags); -} - -static void -_cogl_texture_pixmap_x11_ensure_non_quad_rendering (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - COGL_TEXTURE_GET_CLASS (child_tex)->ensure_non_quad_rendering (child_tex); -} - -static void -_cogl_texture_pixmap_x11_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - _cogl_texture_gl_flush_legacy_texobj_wrap_modes (child_tex, - wrap_mode_s, - wrap_mode_t); -} - -static CoglPixelFormat -_cogl_texture_pixmap_x11_get_format (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return cogl_texture_get_format (child_tex); -} - -static GLenum -_cogl_texture_pixmap_x11_get_gl_format (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - return _cogl_texture_gl_get_format (child_tex); -} - -static void -cogl_texture_pixmap_x11_class_init (CoglTexturePixmapX11Class *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - CoglTextureClass *texture_class = COGL_TEXTURE_CLASS (klass); - - gobject_class->dispose = cogl_texture_pixmap_x11_dispose; - - texture_class->allocate = _cogl_texture_pixmap_x11_allocate; - texture_class->set_region = _cogl_texture_pixmap_x11_set_region; - texture_class->get_data = _cogl_texture_pixmap_x11_get_data; - texture_class->foreach_sub_texture_in_region = _cogl_texture_pixmap_x11_foreach_sub_texture_in_region; - texture_class->is_sliced = _cogl_texture_pixmap_x11_is_sliced; - texture_class->can_hardware_repeat = _cogl_texture_pixmap_x11_can_hardware_repeat; - texture_class->transform_coords_to_gl = _cogl_texture_pixmap_x11_transform_coords_to_gl; - texture_class->transform_quad_coords_to_gl = _cogl_texture_pixmap_x11_transform_quad_coords_to_gl; - texture_class->get_gl_texture = _cogl_texture_pixmap_x11_get_gl_texture; - texture_class->gl_flush_legacy_texobj_filters = _cogl_texture_pixmap_x11_gl_flush_legacy_texobj_filters; - texture_class->pre_paint = _cogl_texture_pixmap_x11_pre_paint; - texture_class->ensure_non_quad_rendering = _cogl_texture_pixmap_x11_ensure_non_quad_rendering; - texture_class->gl_flush_legacy_texobj_wrap_modes = _cogl_texture_pixmap_x11_gl_flush_legacy_texobj_wrap_modes; - texture_class->get_format = _cogl_texture_pixmap_x11_get_format; - texture_class->get_gl_format = _cogl_texture_pixmap_x11_get_gl_format; -} - -static void -cogl_texture_pixmap_x11_init (CoglTexturePixmapX11 *self) -{ -} - -uint32_t -cogl_texture_pixmap_x11_error_quark (void) -{ - return g_quark_from_static_string ("cogl-texture-pixmap-error-quark"); -} - -static CoglTexture * -_cogl_texture_pixmap_x11_new (CoglContext *ctx, - uint32_t pixmap, - gboolean automatic_updates, - CoglTexturePixmapStereoMode stereo_mode, - GError **error) -{ - CoglTexturePixmapX11 *tex_pixmap; - Display *display = cogl_xlib_renderer_get_display (ctx->display->renderer); - CoglDriver *driver = cogl_context_get_driver (ctx); - Window pixmap_root_window; - int pixmap_x, pixmap_y; - unsigned int pixmap_width, pixmap_height; - unsigned int pixmap_border_width; - unsigned int pixmap_depth; - CoglPixelFormat internal_format; - XWindowAttributes window_attributes; - int damage_base; - const CoglWinsysVtable *winsys; - - if (!XGetGeometry (display, pixmap, &pixmap_root_window, - &pixmap_x, &pixmap_y, - &pixmap_width, &pixmap_height, - &pixmap_border_width, &pixmap_depth)) - { - g_set_error_literal (error, - COGL_TEXTURE_PIXMAP_X11_ERROR, - COGL_TEXTURE_PIXMAP_X11_ERROR_X11, - "Unable to query pixmap size"); - return NULL; - } - - /* Note: the detailed pixel layout doesn't matter here, we are just - * interested in RGB vs RGBA... */ - internal_format = (pixmap_depth >= 32 - ? COGL_PIXEL_FORMAT_RGBA_8888_PRE - : COGL_PIXEL_FORMAT_RGB_888); - - tex_pixmap = g_object_new (COGL_TYPE_TEXTURE_PIXMAP_X11, - "context", ctx, - "texture-driver", cogl_driver_create_texture_driver (driver), - "width", pixmap_width, - "height", pixmap_height, - "format", internal_format, - NULL); - - tex_pixmap->depth = pixmap_depth; - tex_pixmap->pixmap = pixmap; - tex_pixmap->stereo_mode = stereo_mode; - tex_pixmap->left = NULL; - tex_pixmap->image = NULL; - tex_pixmap->shm_info.shmid = -1; - tex_pixmap->tex = NULL; - tex_pixmap->damage_owned = FALSE; - tex_pixmap->damage = 0; - - /* We need a visual to use for shared memory images so we'll query - it from the pixmap's root window */ - if (!XGetWindowAttributes (display, pixmap_root_window, &window_attributes)) - { - g_free (tex_pixmap); - g_set_error_literal (error, - COGL_TEXTURE_PIXMAP_X11_ERROR, - COGL_TEXTURE_PIXMAP_X11_ERROR_X11, - "Unable to query root window attributes"); - return NULL; - } - - tex_pixmap->visual = window_attributes.visual; - - /* If automatic updates are requested and the Xlib connection - supports damage events then we'll register a damage object on the - pixmap */ - damage_base = _cogl_xlib_get_damage_base (ctx); - if (automatic_updates && damage_base >= 0) - { - Damage damage = XDamageCreate (display, - pixmap, - XDamageReportBoundingBox); - set_damage_object_internal (ctx, - tex_pixmap, - damage, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX); - tex_pixmap->damage_owned = TRUE; - } - - /* Assume the entire pixmap is damaged to begin with */ - tex_pixmap->damage_rect.x = 0; - tex_pixmap->damage_rect.width = pixmap_width; - tex_pixmap->damage_rect.y = 0; - tex_pixmap->damage_rect.height = pixmap_height; - - winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - if (winsys->texture_pixmap_x11_create) - { - tex_pixmap->use_winsys_texture = - winsys->texture_pixmap_x11_create (tex_pixmap); - } - else - tex_pixmap->use_winsys_texture = FALSE; - - if (!tex_pixmap->use_winsys_texture) - tex_pixmap->winsys = NULL; - - _cogl_texture_set_allocated (COGL_TEXTURE (tex_pixmap), internal_format, - pixmap_width, pixmap_height); - - return COGL_TEXTURE (tex_pixmap); -} - -CoglTexture * -cogl_texture_pixmap_x11_new (CoglContext *ctxt, - uint32_t pixmap, - gboolean automatic_updates, - GError **error) - -{ - return _cogl_texture_pixmap_x11_new (ctxt, pixmap, - automatic_updates, COGL_TEXTURE_PIXMAP_MONO, - error); -} - -CoglTexture * -cogl_texture_pixmap_x11_new_left (CoglContext *ctxt, - uint32_t pixmap, - gboolean automatic_updates, - GError **error) -{ - return _cogl_texture_pixmap_x11_new (ctxt, pixmap, - automatic_updates, COGL_TEXTURE_PIXMAP_LEFT, - error); -} - -CoglTexture * -cogl_texture_pixmap_x11_new_right (CoglTexturePixmapX11 *tfp_left) -{ - CoglTexture *texture_left = COGL_TEXTURE (tfp_left); - CoglContext *ctx = cogl_texture_get_context (texture_left); - CoglDriver *driver = cogl_context_get_driver (ctx); - CoglTexturePixmapX11 *tfp_right; - CoglPixelFormat internal_format; - - g_return_val_if_fail (tfp_left->stereo_mode == COGL_TEXTURE_PIXMAP_LEFT, NULL); - - internal_format = (tfp_left->depth >= 32 - ? COGL_PIXEL_FORMAT_RGBA_8888_PRE - : COGL_PIXEL_FORMAT_RGB_888); - - tfp_right = g_object_new (COGL_TYPE_TEXTURE_PIXMAP_X11, - "context", ctx, - "texture-driver", cogl_driver_create_texture_driver (driver), - "width", cogl_texture_get_width (texture_left), - "height", cogl_texture_get_height (texture_left), - "format", internal_format, - NULL); - tfp_right->stereo_mode = COGL_TEXTURE_PIXMAP_RIGHT; - tfp_right->left = g_object_ref (tfp_left); - - _cogl_texture_set_allocated (COGL_TEXTURE (tfp_right), internal_format, - cogl_texture_get_width (texture_left), - cogl_texture_get_height (texture_left)); - - return COGL_TEXTURE (tfp_right); -} - -void -cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *tex_pixmap, - const MtkRectangle *area) -{ - /* We'll queue the update for both the GLX texture and the regular - texture because we can't determine which will be needed until we - actually render something */ - - if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - tex_pixmap = tex_pixmap->left; - - if (tex_pixmap->winsys) - { - const CoglWinsysVtable *winsys; - winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - winsys->texture_pixmap_x11_damage_notify (tex_pixmap); - } - mtk_rectangle_union (&tex_pixmap->damage_rect, - area, - &tex_pixmap->damage_rect); -} - -gboolean -cogl_texture_pixmap_x11_is_using_tfp_extension (CoglTexturePixmapX11 *tex_pixmap) -{ - if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - tex_pixmap = tex_pixmap->left; - - return !!tex_pixmap->winsys; -} diff --git a/cogl/cogl/winsys/cogl-texture-pixmap-x11.h b/cogl/cogl/winsys/cogl-texture-pixmap-x11.h deleted file mode 100644 index 900b538fb99..00000000000 --- a/cogl/cogl/winsys/cogl-texture-pixmap-x11.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -/* NB: this is a top-level header that can be included directly but we - * want to be careful not to define __COGL_H_INSIDE__ when this is - * included internally while building Cogl itself since - * __COGL_H_INSIDE__ is used in headers to guard public vs private api - * definitions - */ -#ifndef COGL_COMPILATION - -/* Note: When building Cogl .gir we explicitly define - * __COGL_H_INSIDE__ */ -#ifndef __COGL_H_INSIDE__ -#define __COGL_H_INSIDE__ -#define __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_TEXTURE_PIXMAP_X11_ -#endif - -#endif /* COGL_COMPILATION */ - -#include "cogl/cogl-context.h" - -#include - -G_BEGIN_DECLS - -/** - * CoglTexturePixmapX11: - * - * Functions for creating and manipulating 2D meta - * textures derived from X11 pixmaps. - * - * These functions allow high-level textures that - * derive their contents from an X11 - * pixmap. - */ -#define COGL_TYPE_TEXTURE_PIXMAP_X11 (cogl_texture_pixmap_x11_get_type ()) -#define COGL_TEXTURE_PIXMAP_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_TEXTURE_PIXMAP_X11, CoglTexturePixmapX11)) -#define COGL_TEXTURE_PIXMAP_X11_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_TYPE_TEXTURE_PIXMAP_X11, CoglTexturePixmapX11 const)) -#define COGL_TEXTURE_PIXMAP_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_TYPE_TEXTURE_PIXMAP_X11, CoglTexturePixmapX11Class)) -#define COGL_IS_TEXTURE_PIXMAP_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_TYPE_TEXTURE_PIXMAP_X11)) -#define COGL_IS_TEXTURE_PIXMAP_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_TYPE_TEXTURE_PIXMAP_X11)) -#define COGL_TEXTURE_PIXMAP_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_TYPE_TEXTURE_PIXMAP_X11, CoglTexturePixmapX11Class)) - -typedef struct _CoglTexturePixmapX11Class CoglTexturePixmapX11Class; -typedef struct _CoglTexturePixmapX11 CoglTexturePixmapX11; - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglTexturePixmapX11, g_object_unref) - -COGL_EXPORT -GType cogl_texture_pixmap_x11_get_type (void) G_GNUC_CONST; - -typedef enum -{ - COGL_TEXTURE_PIXMAP_X11_DAMAGE_RAW_RECTANGLES, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_DELTA_RECTANGLES, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_NON_EMPTY -} CoglTexturePixmapX11ReportLevel; - -/** - * COGL_TEXTURE_PIXMAP_X11_ERROR: - * - * #GError domain for texture-pixmap-x11 errors. - */ -#define COGL_TEXTURE_PIXMAP_X11_ERROR (cogl_texture_pixmap_x11_error_quark ()) - -/** - * CoglTexturePixmapX11Error: - * @COGL_TEXTURE_PIXMAP_X11_ERROR_X11: An X11 protocol error - * - * Error codes that can be thrown when performing texture-pixmap-x11 - * operations. - */ -typedef enum -{ - COGL_TEXTURE_PIXMAP_X11_ERROR_X11, -} CoglTexturePixmapX11Error; - -COGL_EXPORT -uint32_t cogl_texture_pixmap_x11_error_quark (void); - -/** - * cogl_texture_pixmap_x11_new: - * @context: A #CoglContext - * @pixmap: A X11 pixmap ID - * @automatic_updates: Whether to automatically copy the contents of - * the pixmap to the texture. - * @error: A #GError for exceptions - * - * Creates a texture that contains the contents of @pixmap. If - * @automatic_updates is %TRUE then Cogl will attempt to listen for - * damage events on the pixmap and automatically update the texture - * when it changes. - * - * Return value: a new #CoglTexturePixmapX11 instance - */ -COGL_EXPORT CoglTexture * -cogl_texture_pixmap_x11_new (CoglContext *context, - uint32_t pixmap, - gboolean automatic_updates, - GError **error); - -/** - * cogl_texture_pixmap_x11_new_left: - * @context: A #CoglContext - * @pixmap: A X11 pixmap ID - * @automatic_updates: Whether to automatically copy the contents of - * the pixmap to the texture. - * @error: A #GError for exceptions - * - * Creates one of a pair of textures to contain the contents of @pixmap, - * which has stereo content. (Different images for the right and left eyes.) - * The left image is drawn using this texture; the right image is drawn - * using a texture created by calling - * cogl_texture_pixmap_x11_new_right() and passing in this texture as an - * argument. - * - * In general, you should not use this function unless you have - * queried the %GLX_STEREO_TREE_EXT attribute of the corresponding - * window using glXQueryDrawable() and determined that the window is - * stereo. Note that this attribute can change over time and - * notification is also provided through events defined in the - * EXT_stereo_tree GLX extension. As long as the system has support for - * stereo content, drawing using the left and right pixmaps will not - * produce an error even if the window doesn't have stereo - * content any more, but drawing with the right pixmap will produce - * undefined output, so you need to listen for these events and - * re-render to avoid race conditions. (Recreating a non-stereo - * pixmap is not necessary, but may save resources.) - * - * Return value: a new #CoglTexturePixmapX11 instance - */ -COGL_EXPORT CoglTexture * -cogl_texture_pixmap_x11_new_left (CoglContext *context, - uint32_t pixmap, - gboolean automatic_updates, - GError **error); - -/** - * cogl_texture_pixmap_x11_new_right: - * @left_texture: A #CoglTexturePixmapX11 instance created with - * cogl_texture_pixmap_x11_new_left(). - * - * Creates a texture object that corresponds to the right-eye image - * of a pixmap with stereo content. @left_texture must have been - * created using cogl_texture_pixmap_x11_new_left(). - * - * Return value: a new #CoglTexturePixmapX11 instance - */ -COGL_EXPORT CoglTexture * -cogl_texture_pixmap_x11_new_right (CoglTexturePixmapX11 *left_texture); - -/** - * cogl_texture_pixmap_x11_update_area: - * @texture: A #CoglTexturePixmapX11 instance - * @area: The area to update - * - * Forces an update of the given @texture so that it is refreshed with - * the contents of the pixmap that was given to - * cogl_texture_pixmap_x11_new(). - */ -COGL_EXPORT void -cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *texture, - const MtkRectangle *area); - -/** - * cogl_texture_pixmap_x11_is_using_tfp_extension: - * @texture: A #CoglTexturePixmapX11 instance - * - * Checks whether the given @texture is using the - * GLX_EXT_texture_from_pixmap or similar extension to copy the - * contents of the pixmap to the texture. This extension is usually - * implemented as zero-copy operation so it implies the updates are - * working efficiently. - * - * Return value: %TRUE if the texture is using an efficient extension - * and %FALSE otherwise - */ -COGL_EXPORT gboolean -cogl_texture_pixmap_x11_is_using_tfp_extension (CoglTexturePixmapX11 *texture); - -G_END_DECLS - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_TEXTURE_PIXMAP_X11_ -#undef __COGL_H_INSIDE__ -#undef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_TEXTURE_PIXMAP_X11_ -#endif diff --git a/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h b/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h index a0d03a3c4f9..9a1cb805dee 100644 --- a/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h +++ b/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h @@ -76,11 +76,7 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglDestroyImage, EGLImageKHR image)) COGL_WINSYS_FEATURE_END () #endif -COGL_WINSYS_FEATURE_BEGIN (image_pixmap, - "KHR\0", - "image_pixmap\0", - COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP) -COGL_WINSYS_FEATURE_END () + #ifdef EGL_WL_bind_wayland_display COGL_WINSYS_FEATURE_BEGIN (bind_wayland_display, "WL\0", diff --git a/cogl/cogl/winsys/cogl-winsys-egl-private.h b/cogl/cogl/winsys/cogl-winsys-egl-private.h index 1e3e4f21167..ee041a84aa4 100644 --- a/cogl/cogl/winsys/cogl-winsys-egl-private.h +++ b/cogl/cogl/winsys/cogl-winsys-egl-private.h @@ -94,7 +94,6 @@ typedef struct _CoglWinsysEGLVtable typedef enum _CoglEGLWinsysFeature { COGL_EGL_WINSYS_FEATURE_SWAP_REGION = 1L << 0, - COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP = 1L << 1, COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_WAYLAND_BUFFER = 1L << 2, COGL_EGL_WINSYS_FEATURE_CREATE_CONTEXT = 1L << 3, COGL_EGL_WINSYS_FEATURE_BUFFER_AGE = 1L << 4, diff --git a/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h b/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h deleted file mode 100644 index 70b11360ba1..00000000000 --- a/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include "cogl/winsys/cogl-winsys-private.h" - -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_egl_xlib_get_vtable (void); - -XVisualInfo * -cogl_display_xlib_get_visual_info (CoglDisplay *display, - EGLConfig egl_config); diff --git a/cogl/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/cogl/winsys/cogl-winsys-egl-x11.c deleted file mode 100644 index 347562370b3..00000000000 --- a/cogl/cogl/winsys/cogl-winsys-egl-x11.c +++ /dev/null @@ -1,638 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - * Neil Roberts - */ - -#include "config.h" - -#include - -#include "cogl/cogl-xlib-renderer-private.h" -#include "cogl/cogl-xlib-renderer.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-onscreen-private.h" -#include "cogl/cogl-display-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/winsys/cogl-texture-pixmap-x11-private.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/driver/gl/cogl-texture-2d-gl-private.h" -#include "cogl/cogl-texture-2d.h" -#include "cogl/winsys/cogl-onscreen-egl.h" -#include "cogl/winsys/cogl-onscreen-xlib.h" -#include "cogl/winsys/cogl-winsys-egl-x11-private.h" -#include "cogl/winsys/cogl-winsys-egl-private.h" - -static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable; - -typedef struct _CoglDisplayXlib -{ - Window dummy_xwin; -} CoglDisplayXlib; - -#ifdef EGL_KHR_image_pixmap -typedef struct _CoglTexturePixmapEGL -{ - EGLImageKHR image; - CoglTexture *texture; - gboolean bind_tex_image_queued; -} CoglTexturePixmapEGL; -#endif - -static CoglOnscreen * -find_onscreen_for_xid (CoglContext *context, uint32_t xid) -{ - GList *l; - - for (l = context->framebuffers; l; l = l->next) - { - CoglFramebuffer *framebuffer = l->data; - CoglOnscreen *onscreen; - - if (!COGL_IS_ONSCREEN (framebuffer)) - continue; - - onscreen = COGL_ONSCREEN (framebuffer); - if (cogl_onscreen_xlib_is_for_window (onscreen, (Window) xid)) - return onscreen; - } - - return NULL; -} - -static void -notify_resize (CoglContext *context, - Window drawable, - int width, - int height) -{ - CoglOnscreen *onscreen; - - onscreen = find_onscreen_for_xid (context, drawable); - if (!onscreen) - return; - - cogl_onscreen_xlib_resize (onscreen, width, height); -} - -static CoglFilterReturn -event_filter_cb (XEvent *xevent, void *data) -{ - CoglContext *context = data; - - if (xevent->type == ConfigureNotify) - { - notify_resize (context, - xevent->xconfigure.window, - xevent->xconfigure.width, - xevent->xconfigure.height); - } - else if (xevent->type == Expose) - { - CoglOnscreen *onscreen = - find_onscreen_for_xid (context, xevent->xexpose.window); - - if (onscreen) - { - MtkRectangle info; - - info.x = xevent->xexpose.x; - info.y = xevent->xexpose.y; - info.width = xevent->xexpose.width; - info.height = xevent->xexpose.height; - - _cogl_onscreen_queue_dirty (onscreen, &info); - } - } - - return COGL_FILTER_CONTINUE; -} - -XVisualInfo * -cogl_display_xlib_get_visual_info (CoglDisplay *display, - EGLConfig egl_config) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglRendererEGL *egl_renderer = cogl_renderer_get_winsys (display->renderer); - XVisualInfo visinfo_template; - int template_mask = 0; - XVisualInfo *visinfo = NULL; - int visinfos_count; - EGLint visualid, red_size, green_size, blue_size, alpha_size; - - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_NATIVE_VISUAL_ID, &visualid); - - if (visualid != 0) - { - visinfo_template.visualid = visualid; - template_mask |= VisualIDMask; - } - else - { - /* some EGL drivers don't implement the EGL_NATIVE_VISUAL_ID - * attribute, so attempt to find the closest match. */ - - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_RED_SIZE, &red_size); - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_GREEN_SIZE, &green_size); - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_BLUE_SIZE, &blue_size); - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_ALPHA_SIZE, &alpha_size); - - visinfo_template.depth = red_size + green_size + blue_size + alpha_size; - template_mask |= VisualDepthMask; - - visinfo_template.screen = DefaultScreen (xlib_renderer->xdpy); - template_mask |= VisualScreenMask; - } - - visinfo = XGetVisualInfo (xlib_renderer->xdpy, - template_mask, - &visinfo_template, - &visinfos_count); - - return visinfo; -} - -static void -_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) -{ - CoglRendererEGL *egl_renderer = cogl_renderer_get_winsys (renderer); - - _cogl_xlib_renderer_disconnect (renderer); - - eglTerminate (egl_renderer->edpy); -} - -static EGLDisplay -_cogl_winsys_egl_get_display (void *native) -{ - EGLDisplay dpy = NULL; - const char *client_exts = eglQueryString (NULL, EGL_EXTENSIONS); - - if (g_strstr_len (client_exts, -1, "EGL_KHR_platform_base")) - { - PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = - (void *) eglGetProcAddress ("eglGetPlatformDisplay"); - - if (get_platform_display) - dpy = get_platform_display (EGL_PLATFORM_X11_KHR, native, NULL); - - if (dpy) - return dpy; - } - - if (g_strstr_len (client_exts, -1, "EGL_EXT_platform_base")) - { - PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = - (void *) eglGetProcAddress ("eglGetPlatformDisplayEXT"); - - if (get_platform_display) - dpy = get_platform_display (EGL_PLATFORM_X11_KHR, native, NULL); - - if (dpy) - return dpy; - } - - return eglGetDisplay ((EGLNativeDisplayType) native); -} - -static gboolean -_cogl_winsys_renderer_connect (CoglRenderer *renderer, - GError **error) -{ - CoglRendererEGL *egl_renderer; - CoglXlibRenderer *xlib_renderer; - - cogl_renderer_set_winsys (renderer, g_new0 (CoglRendererEGL, 1)); - egl_renderer = cogl_renderer_get_winsys (renderer); - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable; - egl_renderer->sync = EGL_NO_SYNC_KHR; - egl_renderer->needs_config = TRUE; - - if (!_cogl_xlib_renderer_connect (renderer, error)) - goto error; - - egl_renderer->edpy = _cogl_winsys_egl_get_display (xlib_renderer->xdpy); - - if (!_cogl_winsys_egl_renderer_connect_common (renderer, error)) - goto error; - - return TRUE; - -error: - _cogl_winsys_renderer_disconnect (renderer); - return FALSE; -} - -static int -_cogl_winsys_egl_add_config_attributes (CoglDisplay *display, - EGLint *attributes) -{ - int i = 0; - - attributes[i++] = EGL_SURFACE_TYPE; - attributes[i++] = EGL_WINDOW_BIT; - - return i; -} - -static gboolean -_cogl_winsys_egl_choose_config (CoglDisplay *display, - EGLint *attributes, - EGLConfig *out_config, - GError **error) -{ - CoglRenderer *renderer = display->renderer; - CoglRendererEGL *egl_renderer = cogl_renderer_get_winsys (renderer); - EGLint config_count = 0; - EGLBoolean status; - - status = eglChooseConfig (egl_renderer->edpy, - attributes, - out_config, 1, - &config_count); - if (status != EGL_TRUE || config_count == 0) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "No compatible EGL configs found"); - return FALSE; - } - - return TRUE; -} - -static gboolean -_cogl_winsys_egl_display_setup (CoglDisplay *display, - GError **error) -{ - CoglDisplayEGL *egl_display = display->winsys; - CoglDisplayXlib *xlib_display; - - xlib_display = g_new0 (CoglDisplayXlib, 1); - egl_display->platform = xlib_display; - - return TRUE; -} - -static void -_cogl_winsys_egl_display_destroy (CoglDisplay *display) -{ - CoglDisplayEGL *egl_display = display->winsys; - - g_free (egl_display->platform); -} - -static gboolean -_cogl_winsys_egl_context_init (CoglContext *context, - GError **error) -{ - _cogl_renderer_add_native_filter (context->display->renderer, - (CoglNativeFilterFunc)event_filter_cb, - context); - - /* We'll manually handle queueing dirty events in response to - * Expose events from X */ - COGL_FLAGS_SET (context->private_features, - COGL_PRIVATE_FEATURE_DIRTY_EVENTS, - TRUE); - - return TRUE; -} - -static void -_cogl_winsys_egl_context_deinit (CoglContext *context) -{ - _cogl_renderer_remove_native_filter (context->display->renderer, - (CoglNativeFilterFunc)event_filter_cb, - context); -} - -static gboolean -_cogl_winsys_egl_context_created (CoglDisplay *display, - GError **error) -{ - CoglRenderer *renderer = display->renderer; - CoglDisplayEGL *egl_display = display->winsys; - CoglRendererEGL *egl_renderer = cogl_renderer_get_winsys (renderer); - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - CoglDisplayXlib *xlib_display = egl_display->platform; - XVisualInfo *xvisinfo; - XSetWindowAttributes attrs; - const char *error_message; - - xvisinfo = cogl_display_xlib_get_visual_info (display, - egl_display->egl_config); - if (xvisinfo == NULL) - { - error_message = "Unable to find suitable X visual"; - goto fail; - } - - attrs.override_redirect = True; - attrs.colormap = XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - attrs.border_pixel = 0; - - if ((egl_renderer->private_features & - COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT) == 0) - { - xlib_display->dummy_xwin = - XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - -100, -100, 1, 1, - 0, - xvisinfo->depth, - CopyFromParent, - xvisinfo->visual, - CWOverrideRedirect | - CWColormap | - CWBorderPixel, - &attrs); - - egl_display->dummy_surface = - eglCreateWindowSurface (egl_renderer->edpy, - egl_display->egl_config, - (EGLNativeWindowType) xlib_display->dummy_xwin, - NULL); - - if (egl_display->dummy_surface == EGL_NO_SURFACE) - { - error_message = "Unable to create an EGL surface"; - XFree (xvisinfo); - goto fail; - } - } - - g_clear_pointer (&xvisinfo, XFree); - - if (!_cogl_winsys_egl_make_current (display, - egl_display->dummy_surface, - egl_display->dummy_surface, - egl_display->egl_context)) - { - if (egl_display->dummy_surface == EGL_NO_SURFACE) - error_message = "Unable to eglMakeCurrent with no surface"; - else - error_message = "Unable to eglMakeCurrent with dummy surface"; - goto fail; - } - - return TRUE; - -fail: - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "%s", error_message); - return FALSE; -} - -static void -_cogl_winsys_egl_cleanup_context (CoglDisplay *display) -{ - CoglDisplayEGL *egl_display = display->winsys; - CoglDisplayXlib *xlib_display = egl_display->platform; - CoglRenderer *renderer = display->renderer; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - CoglRendererEGL *egl_renderer = cogl_renderer_get_winsys (renderer); - - if (egl_display->dummy_surface != EGL_NO_SURFACE) - { - eglDestroySurface (egl_renderer->edpy, egl_display->dummy_surface); - egl_display->dummy_surface = EGL_NO_SURFACE; - } - - if (xlib_display->dummy_xwin) - { - XDestroyWindow (xlib_renderer->xdpy, xlib_display->dummy_xwin); - xlib_display->dummy_xwin = None; - } -} - -#ifdef EGL_KHR_image_pixmap - -static gboolean -_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - CoglContext *ctx = cogl_texture_get_context (tex); - CoglTexturePixmapEGL *egl_tex_pixmap; - EGLint attribs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; - CoglPixelFormat texture_format; - CoglRendererEGL *egl_renderer; - - egl_renderer = cogl_renderer_get_winsys (ctx->display->renderer); - - if (!(egl_renderer->private_features & - COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP) || - !_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE)) - { - tex_pixmap->winsys = NULL; - return FALSE; - } - - egl_tex_pixmap = g_new0 (CoglTexturePixmapEGL, 1); - - egl_tex_pixmap->image = - _cogl_egl_create_image (ctx, - EGL_NATIVE_PIXMAP_KHR, - (EGLClientBuffer)tex_pixmap->pixmap, - attribs); - if (egl_tex_pixmap->image == EGL_NO_IMAGE_KHR) - { - g_free (egl_tex_pixmap); - return FALSE; - } - - texture_format = (tex_pixmap->depth >= 32 ? - COGL_PIXEL_FORMAT_RGBA_8888_PRE : - COGL_PIXEL_FORMAT_RGB_888); - - egl_tex_pixmap->texture = - cogl_texture_2d_new_from_egl_image (ctx, - cogl_texture_get_width (tex), - cogl_texture_get_height (tex), - texture_format, - egl_tex_pixmap->image, - COGL_EGL_IMAGE_FLAG_NONE, - NULL); - - /* The image is initially bound as part of the creation */ - egl_tex_pixmap->bind_tex_image_queued = FALSE; - - tex_pixmap->winsys = egl_tex_pixmap; - - return TRUE; -} - -static void -_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapEGL *egl_tex_pixmap; - CoglContext *ctx; - - ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - - if (!tex_pixmap->winsys) - return; - - egl_tex_pixmap = tex_pixmap->winsys; - - if (egl_tex_pixmap->texture) - g_object_unref (egl_tex_pixmap->texture); - - if (egl_tex_pixmap->image != EGL_NO_IMAGE_KHR) - _cogl_egl_destroy_image (ctx, egl_tex_pixmap->image); - - tex_pixmap->winsys = NULL; - g_free (egl_tex_pixmap); -} - -static gboolean -_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode, - gboolean needs_mipmap) -{ - CoglTexturePixmapEGL *egl_tex_pixmap = tex_pixmap->winsys; - CoglTexture2D *tex_2d; - GError *error = NULL; - - if (needs_mipmap) - return FALSE; - - if (egl_tex_pixmap->bind_tex_image_queued) - { - COGL_NOTE (TEXTURE_PIXMAP, "Rebinding GLXPixmap for %p", tex_pixmap); - - tex_2d = COGL_TEXTURE_2D (egl_tex_pixmap->texture); - - if (cogl_texture_2d_gl_bind_egl_image (tex_2d, - egl_tex_pixmap->image, - &error)) - { - egl_tex_pixmap->bind_tex_image_queued = FALSE; - } - else - { - g_warning ("Failed to rebind EGLImage to CoglTexture2D: %s", - error->message); - g_error_free (error); - } - } - - return TRUE; -} - -static void -_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapEGL *egl_tex_pixmap = tex_pixmap->winsys; - - egl_tex_pixmap->bind_tex_image_queued = TRUE; -} - -static CoglTexture * -_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode) -{ - CoglTexturePixmapEGL *egl_tex_pixmap = tex_pixmap->winsys; - - return egl_tex_pixmap->texture; -} - -#endif /* EGL_KHR_image_pixmap */ - -static const CoglWinsysEGLVtable -_cogl_winsys_egl_vtable = - { - .add_config_attributes = _cogl_winsys_egl_add_config_attributes, - .choose_config = _cogl_winsys_egl_choose_config, - .display_setup = _cogl_winsys_egl_display_setup, - .display_destroy = _cogl_winsys_egl_display_destroy, - .context_created = _cogl_winsys_egl_context_created, - .cleanup_context = _cogl_winsys_egl_cleanup_context, - .context_init = _cogl_winsys_egl_context_init, - .context_deinit = _cogl_winsys_egl_context_deinit, - }; - -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_egl_xlib_get_vtable (void) -{ - static gboolean vtable_inited = FALSE; - static CoglWinsysVtable vtable; - - if (!vtable_inited) - { - /* The EGL_X11 winsys is a subclass of the EGL winsys so we - start by copying its vtable */ - - vtable = *_cogl_winsys_egl_get_vtable (); - - vtable.id = COGL_WINSYS_ID_EGL_XLIB; - vtable.name = "EGL_XLIB"; - vtable.constraints |= (COGL_RENDERER_CONSTRAINT_USES_X11 | - COGL_RENDERER_CONSTRAINT_USES_XLIB); - - vtable.renderer_connect = _cogl_winsys_renderer_connect; - vtable.renderer_disconnect = _cogl_winsys_renderer_disconnect; - -#ifdef EGL_KHR_image_pixmap - /* X11 tfp support... */ - /* XXX: instead of having a rather monolithic winsys vtable we could - * perhaps look for a way to separate these... */ - vtable.texture_pixmap_x11_create = - _cogl_winsys_texture_pixmap_x11_create; - vtable.texture_pixmap_x11_free = - _cogl_winsys_texture_pixmap_x11_free; - vtable.texture_pixmap_x11_update = - _cogl_winsys_texture_pixmap_x11_update; - vtable.texture_pixmap_x11_damage_notify = - _cogl_winsys_texture_pixmap_x11_damage_notify; - vtable.texture_pixmap_x11_get_texture = - _cogl_winsys_texture_pixmap_x11_get_texture; -#endif /* EGL_KHR_image_pixmap) */ - - vtable_inited = TRUE; - } - - return &vtable; -} diff --git a/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h b/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h deleted file mode 100644 index 31e73dbc278..00000000000 --- a/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This can be included multiple times with different definitions for - * the COGL_WINSYS_FEATURE_* functions. - */ - -/* Macro prototypes: - * COGL_WINSYS_FEATURE_BEGIN (major_glx_version, minor_glx_version, - * name, namespaces, extension_names, - * implied_legacy_feature_flags, - * implied_winsys_feature) - * COGL_WINSYS_FEATURE_FUNCTION (return_type, function_name, - * (arguments)) - * ... - * COGL_WINSYS_FEATURE_END () - * - * Note: You can list multiple namespace and extension names if the - * corresponding _FEATURE_FUNCTIONS have the same semantics across - * the different extension variants. - * - * XXX: NB: Don't add a trailing semicolon when using these macros - */ - -/* Base functions that we assume are always available */ -COGL_WINSYS_FEATURE_BEGIN (0, 0, /* always available */ - base_glx_functions, - "\0", - "\0", - 0, /* no implied public feature */ - 0 /* no winsys feature */) -COGL_WINSYS_FEATURE_FUNCTION (void, glXDestroyContext, - (Display *dpy, GLXContext ctx)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXSwapBuffers, - (Display *dpy, GLXDrawable drawable)) -COGL_WINSYS_FEATURE_FUNCTION (Bool, glXIsDirect, - (Display *dpy, GLXContext ctx)) -COGL_WINSYS_FEATURE_FUNCTION (int, glXGetFBConfigAttrib, - (Display *dpy, GLXFBConfig config, - int attribute, int *value)) -COGL_WINSYS_FEATURE_FUNCTION (GLXWindow, glXCreateWindow, - (Display *dpy, GLXFBConfig config, - Window win, const int *attribList)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXDestroyWindow, - (Display *dpy, GLXWindow window)) -COGL_WINSYS_FEATURE_FUNCTION (GLXPixmap, glXCreatePixmap, - (Display *dpy, GLXFBConfig config, - Pixmap pixmap, const int *attribList)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXDestroyPixmap, - (Display *dpy, GLXPixmap pixmap)) -COGL_WINSYS_FEATURE_FUNCTION (GLXContext, glXCreateNewContext, - (Display *dpy, GLXFBConfig config, - int renderType, GLXContext shareList, - Bool direct)) -COGL_WINSYS_FEATURE_FUNCTION (Bool, glXMakeContextCurrent, - (Display *dpy, GLXDrawable draw, - GLXDrawable read, GLXContext ctx)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXSelectEvent, - (Display *dpy, GLXDrawable drawable, - unsigned long mask)) -COGL_WINSYS_FEATURE_FUNCTION (GLXFBConfig *, glXGetFBConfigs, - (Display *dpy, int screen, int *nelements)) -COGL_WINSYS_FEATURE_FUNCTION (GLXFBConfig *, glXChooseFBConfig, - (Display *dpy, int screen, - const int *attrib_list, int *nelements)) -COGL_WINSYS_FEATURE_FUNCTION (XVisualInfo *, glXGetVisualFromFBConfig, - (Display *dpy, GLXFBConfig config)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - texture_from_pixmap, - "EXT\0", - "texture_from_pixmap\0", - 0, - COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP) -COGL_WINSYS_FEATURE_FUNCTION (void, glXBindTexImage, - (Display *display, - GLXDrawable drawable, - int buffer, - int *attribList)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXReleaseTexImage, - (Display *display, - GLXDrawable drawable, - int buffer)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - video_sync, - "SGI\0", - "video_sync\0", - 0, - COGL_WINSYS_FEATURE_VBLANK_COUNTER) -COGL_WINSYS_FEATURE_FUNCTION (int, glXGetVideoSync, - (unsigned int *count)) -COGL_WINSYS_FEATURE_FUNCTION (int, glXWaitVideoSync, - (int divisor, - int remainder, - unsigned int *count)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - swap_control, - "SGI\0", - "swap_control\0", - 0, - 0) -COGL_WINSYS_FEATURE_FUNCTION (int, glXSwapInterval, - (int interval)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - sync_control, - "OML\0", - "sync_control\0", - 0, - 0) -COGL_WINSYS_FEATURE_FUNCTION (Bool, glXGetSyncValues, - (Display* dpy, - GLXDrawable drawable, - int64_t* ust, - int64_t* msc, - int64_t* sbc)) -COGL_WINSYS_FEATURE_FUNCTION (Bool, glXWaitForMsc, - (Display* dpy, - GLXDrawable drawable, - int64_t target_msc, - int64_t divisor, - int64_t remainder, - int64_t* ust, - int64_t* msc, - int64_t* sbc)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - copy_sub_buffer, - "MESA\0", - "copy_sub_buffer\0", - 0, -/* We initially assumed that copy_sub_buffer is synchronized on - * which is only the case for a subset of GPUs for example it is not - * synchronized on INTEL gen6 and gen7, so we remove this assumption - * for now - */ -#if 0 - COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED) -#endif - 0) -COGL_WINSYS_FEATURE_FUNCTION (void, glXCopySubBuffer, - (Display *dpy, - GLXDrawable drawable, - int x, int y, int width, int height)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - swap_event, - "INTEL\0", - "swap_event\0", - 0, - COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT) - -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - create_context, - "ARB\0", - "create_context", - 0, - 0) -COGL_WINSYS_FEATURE_FUNCTION (GLXContext, glXCreateContextAttribs, - (Display *dpy, - GLXFBConfig config, - GLXContext share_context, - Bool direct, - const int *attrib_list)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - buffer_age, - "EXT\0", - "buffer_age\0", - 0, - COGL_WINSYS_FEATURE_BUFFER_AGE) -COGL_WINSYS_FEATURE_END () diff --git a/cogl/cogl/winsys/cogl-winsys-glx-private.h b/cogl/cogl/winsys/cogl-winsys-glx-private.h deleted file mode 100644 index 9b28584a08a..00000000000 --- a/cogl/cogl/winsys/cogl-winsys-glx-private.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_glx_get_vtable (void); - -gboolean -cogl_display_glx_find_fbconfig (CoglDisplay *display, - GLXFBConfig *config_ret, - GError **error); - -void -cogl_context_glx_set_current_drawable (CoglContext *context, - GLXDrawable drawable); - -GLXDrawable -cogl_context_glx_get_current_drawable (CoglContext *context); diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c deleted file mode 100644 index d8cbda89c20..00000000000 --- a/cogl/cogl/winsys/cogl-winsys-glx.c +++ /dev/null @@ -1,1397 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-util.h" -#include "cogl/cogl-feature-private.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/cogl-frame-info-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-onscreen-private.h" -#include "cogl/cogl-xlib-renderer.h" -#include "cogl/cogl-util.h" -#include "cogl/driver/gl/cogl-pipeline-gl-private.h" -#include "cogl/winsys/cogl-glx-renderer-private.h" -#include "cogl/winsys/cogl-glx-display-private.h" -#include "cogl/winsys/cogl-onscreen-glx.h" -#include "cogl/winsys/cogl-winsys-private.h" -#include "cogl/winsys/cogl-winsys-glx-private.h" -#include "mtk/mtk-x11.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -/* This is a relatively new extension */ -#ifndef GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV -#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7 -#endif - -#define MAX_GLX_CONFIG_ATTRIBS 30 - -typedef struct _CoglOnscreenGlx CoglOnscreenGlx; - -typedef struct _CoglContextGLX -{ - GLXDrawable current_drawable; -} CoglContextGLX; - -typedef struct _CoglPixmapTextureEyeGLX -{ - CoglTexture *glx_tex; - gboolean bind_tex_image_queued; - gboolean pixmap_bound; -} CoglPixmapTextureEyeGLX; - -typedef struct _CoglTexturePixmapGLX -{ - GLXPixmap glx_pixmap; - gboolean has_mipmap_space; - gboolean can_mipmap; - - CoglPixmapTextureEyeGLX left; - CoglPixmapTextureEyeGLX right; -} CoglTexturePixmapGLX; - -/* Define a set of arrays containing the functions required from GL - for each winsys feature */ -#define COGL_WINSYS_FEATURE_BEGIN(major_version, minor_version, \ - name, namespaces, extension_names, \ - feature_flags, \ - winsys_feature) \ - static const CoglFeatureFunction \ - cogl_glx_feature_ ## name ## _funcs[] = { -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - { G_STRINGIFY (name), G_STRUCT_OFFSET (CoglGLXRenderer, name) }, -#define COGL_WINSYS_FEATURE_END() \ - { NULL, 0 }, \ - }; -#include "cogl/winsys/cogl-winsys-glx-feature-functions.h" - -/* Define an array of features */ -#undef COGL_WINSYS_FEATURE_BEGIN -#define COGL_WINSYS_FEATURE_BEGIN(major_version, minor_version, \ - name, namespaces, extension_names, \ - feature_flags, \ - winsys_feature) \ - { major_version, minor_version, \ - 0, namespaces, extension_names, \ - 0, \ - winsys_feature, \ - cogl_glx_feature_ ## name ## _funcs }, -#undef COGL_WINSYS_FEATURE_FUNCTION -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) -#undef COGL_WINSYS_FEATURE_END -#define COGL_WINSYS_FEATURE_END() - -static const CoglFeatureData winsys_feature_data[] = - { -#include "cogl/winsys/cogl-winsys-glx-feature-functions.h" - }; - -static GCallback -_cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer, - const char *name) -{ - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (renderer); - - return glx_renderer->glXGetProcAddress ((const GLubyte *) name); -} - -static CoglOnscreen * -find_onscreen_for_xid (CoglContext *context, uint32_t xid) -{ - GList *l; - - for (l = context->framebuffers; l; l = l->next) - { - CoglFramebuffer *framebuffer = l->data; - CoglOnscreen *onscreen; - - if (!COGL_IS_ONSCREEN (framebuffer)) - continue; - - onscreen = COGL_ONSCREEN (framebuffer); - if (cogl_onscreen_glx_is_for_window (onscreen, (Window) xid)) - return onscreen; - } - - return NULL; -} - -static void -notify_swap_buffers (CoglContext *context, GLXBufferSwapComplete *swap_event) -{ - CoglOnscreen *onscreen = find_onscreen_for_xid (context, (uint32_t)swap_event->drawable); - - if (!onscreen) - return; - - cogl_onscreen_glx_notify_swap_buffers (onscreen, swap_event); -} - -static void -notify_resize (CoglContext *context, - XConfigureEvent *configure_event) -{ - CoglOnscreen *onscreen; - - onscreen = find_onscreen_for_xid (context, configure_event->window); - if (!onscreen) - return; - - cogl_onscreen_glx_resize (onscreen, configure_event); -} - -static CoglFilterReturn -glx_event_filter_cb (XEvent *xevent, void *data) -{ - CoglContext *context = data; -#ifdef GLX_INTEL_swap_event - CoglGLXRenderer *glx_renderer; -#endif - - if (xevent->type == ConfigureNotify) - { - notify_resize (context, - &xevent->xconfigure); - - /* we let ConfigureNotify pass through */ - return COGL_FILTER_CONTINUE; - } - -#ifdef GLX_INTEL_swap_event - glx_renderer = cogl_renderer_get_winsys (context->display->renderer); - - if (xevent->type == (glx_renderer->glx_event_base + GLX_BufferSwapComplete)) - { - GLXBufferSwapComplete *swap_event = (GLXBufferSwapComplete *) xevent; - - notify_swap_buffers (context, swap_event); - - /* remove SwapComplete events from the queue */ - return COGL_FILTER_REMOVE; - } -#endif /* GLX_INTEL_swap_event */ - - if (xevent->type == Expose) - { - CoglOnscreen *onscreen = - find_onscreen_for_xid (context, xevent->xexpose.window); - - if (onscreen) - { - MtkRectangle info; - - info.x = xevent->xexpose.x; - info.y = xevent->xexpose.y; - info.width = xevent->xexpose.width; - info.height = xevent->xexpose.height; - - _cogl_onscreen_queue_dirty (onscreen, &info); - } - - return COGL_FILTER_CONTINUE; - } - - return COGL_FILTER_CONTINUE; -} - -static gboolean -update_all_outputs (CoglRenderer *renderer) -{ - GList *l; - CoglContext *context = cogl_renderer_get_display (renderer)->context; - - if (context->display == NULL) /* during connection */ - return FALSE; - - if (context->display->renderer != renderer) - return FALSE; - - for (l = context->framebuffers; l; l = l->next) - { - CoglFramebuffer *framebuffer = l->data; - - if (!COGL_IS_ONSCREEN (framebuffer)) - continue; - - cogl_onscreen_glx_update_output (COGL_ONSCREEN (framebuffer)); - } - - return TRUE; -} - -static void -_cogl_winsys_renderer_outputs_changed (CoglRenderer *renderer) -{ - update_all_outputs (renderer); -} - -static void -_cogl_winsys_renderer_bind_api (CoglRenderer *renderer) -{ -} - -static gboolean -resolve_core_glx_functions (CoglRenderer *renderer, - GError **error) -{ - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (renderer); - - if (!g_module_symbol (cogl_renderer_get_gl_module (renderer), "glXQueryExtension", - (void **) &glx_renderer->glXQueryExtension) || - !g_module_symbol (cogl_renderer_get_gl_module (renderer), "glXQueryVersion", - (void **) &glx_renderer->glXQueryVersion) || - !g_module_symbol (cogl_renderer_get_gl_module (renderer), "glXQueryExtensionsString", - (void **) &glx_renderer->glXQueryExtensionsString) || - (!g_module_symbol (cogl_renderer_get_gl_module (renderer), "glXGetProcAddress", - (void **) &glx_renderer->glXGetProcAddress) && - !g_module_symbol (cogl_renderer_get_gl_module (renderer), "glXGetProcAddressARB", - (void **) &glx_renderer->glXGetProcAddress)) || - !g_module_symbol (cogl_renderer_get_gl_module (renderer), "glXQueryDrawable", - (void **) &glx_renderer->glXQueryDrawable)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "Failed to resolve required GLX symbol"); - return FALSE; - } - - return TRUE; -} - -static void -update_base_winsys_features (CoglRenderer *renderer) -{ - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (renderer); - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - const char *glx_extensions; - int default_screen; - char **split_extensions; - int i; - - default_screen = DefaultScreen (xlib_renderer->xdpy); - glx_extensions = - glx_renderer->glXQueryExtensionsString (xlib_renderer->xdpy, - default_screen); - - COGL_NOTE (WINSYS, " GLX Extensions: %s", glx_extensions); - - split_extensions = g_strsplit (glx_extensions, " ", 0 /* max_tokens */); - - for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++) - if (_cogl_feature_check (renderer, - "GLX", winsys_feature_data + i, - glx_renderer->glx_major, - glx_renderer->glx_minor, - COGL_DRIVER_ID_GL3, /* the driver isn't used */ - split_extensions, - glx_renderer)) - { - if (winsys_feature_data[i].winsys_feature) - COGL_FLAGS_SET (glx_renderer->base_winsys_features, - winsys_feature_data[i].winsys_feature, - TRUE); - } - - g_strfreev (split_extensions); - - /* The GLX_SGI_video_sync spec explicitly states this extension - * only works for direct contexts; we don't know per-renderer - * if the context is direct or not, so we turn off the feature - * flag; we still use the extension within this file looking - * instead at glx_display->have_vblank_counter. - */ - COGL_FLAGS_SET (glx_renderer->base_winsys_features, - COGL_WINSYS_FEATURE_VBLANK_COUNTER, - FALSE); - - /* Because of the direct-context dependency, the VBLANK_WAIT feature - * doesn't reflect the presence of GLX_SGI_video_sync. - */ - if (glx_renderer->glXWaitForMsc) - COGL_FLAGS_SET (glx_renderer->base_winsys_features, - COGL_WINSYS_FEATURE_VBLANK_WAIT, - TRUE); -} - -static gboolean -_cogl_winsys_renderer_connect (CoglRenderer *renderer, - GError **error) -{ - CoglGLXRenderer *glx_renderer; - CoglXlibRenderer *xlib_renderer; - - cogl_renderer_set_winsys (renderer, g_new0 (CoglGLXRenderer, 1)); - - glx_renderer = cogl_renderer_get_winsys (renderer); - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - if (!_cogl_xlib_renderer_connect (renderer, error)) - goto error; - - if (cogl_renderer_get_driver_id (renderer) != COGL_DRIVER_ID_GL3) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "GLX Backend can only be used in conjunction with OpenGL"); - goto error; - } - - if (!resolve_core_glx_functions (renderer, error)) - goto error; - - if (!glx_renderer->glXQueryExtension (xlib_renderer->xdpy, - &glx_renderer->glx_error_base, - &glx_renderer->glx_event_base)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "XServer appears to lack required GLX support"); - goto error; - } - - /* XXX: Note: For a long time Mesa exported a hybrid GLX, exporting - * extensions specified to require GLX 1.3, but still reporting 1.2 - * via glXQueryVersion. */ - if (!glx_renderer->glXQueryVersion (xlib_renderer->xdpy, - &glx_renderer->glx_major, - &glx_renderer->glx_minor) - || !(glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 2)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "XServer appears to lack required GLX 1.2 support"); - goto error; - } - - update_base_winsys_features (renderer); - - glx_renderer->dri_fd = -1; - - return TRUE; - -error: - _cogl_xlib_renderer_disconnect (renderer); - return FALSE; -} - -static gboolean -update_winsys_features (CoglContext *context, GError **error) -{ - CoglGLXDisplay *glx_display = context->display->winsys; - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (context->display->renderer); - - g_return_val_if_fail (glx_display->glx_context, FALSE); - - if (!_cogl_context_update_features (context, error)) - return FALSE; - - memcpy (context->winsys_features, - glx_renderer->base_winsys_features, - sizeof (context->winsys_features)); - - if (glx_renderer->glXCopySubBuffer || context->glBlitFramebuffer) - COGL_FLAGS_SET (context->winsys_features, COGL_WINSYS_FEATURE_SWAP_REGION, TRUE); - - /* Note: glXCopySubBuffer and glBlitFramebuffer won't be throttled - * by the SwapInterval so we have to throttle swap_region requests - * manually... */ - if (cogl_context_has_winsys_feature (context, COGL_WINSYS_FEATURE_SWAP_REGION) && - (glx_display->have_vblank_counter || glx_display->can_vblank_wait)) - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE); - - if (cogl_context_has_winsys_feature (context, COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT, TRUE); - } - - /* We'll manually handle queueing dirty events in response to - * Expose events from X */ - COGL_FLAGS_SET (context->private_features, - COGL_PRIVATE_FEATURE_DIRTY_EVENTS, - TRUE); - - if (cogl_context_has_winsys_feature (context, COGL_WINSYS_FEATURE_BUFFER_AGE)) - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_BUFFER_AGE, TRUE); - - return TRUE; -} - -static void -glx_attributes_from_framebuffer_config (CoglDisplay *display, - int *attributes) -{ - int i = 0; - - attributes[i++] = GLX_DRAWABLE_TYPE; - attributes[i++] = GLX_WINDOW_BIT; - - attributes[i++] = GLX_RENDER_TYPE; - attributes[i++] = GLX_RGBA_BIT; - - attributes[i++] = GLX_DOUBLEBUFFER; - attributes[i++] = GL_TRUE; - - attributes[i++] = GLX_RED_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_GREEN_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_BLUE_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_ALPHA_SIZE; - attributes[i++] = GLX_DONT_CARE; - attributes[i++] = GLX_DEPTH_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_STENCIL_SIZE; - attributes[i++] = 2; - - attributes[i++] = None; - - g_assert (i < MAX_GLX_CONFIG_ATTRIBS); -} - -/* It seems the GLX spec never defined an invalid GLXFBConfig that - * we could overload as an indication of error, so we have to return - * an explicit boolean status. */ -gboolean -cogl_display_glx_find_fbconfig (CoglDisplay *display, - GLXFBConfig *config_ret, - GError **error) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (display->renderer); - GLXFBConfig *configs = NULL; - int n_configs; - static int attributes[MAX_GLX_CONFIG_ATTRIBS]; - gboolean ret = TRUE; - int xscreen_num = DefaultScreen (xlib_renderer->xdpy); - - glx_attributes_from_framebuffer_config (display, attributes); - - configs = glx_renderer->glXChooseFBConfig (xlib_renderer->xdpy, - xscreen_num, - attributes, - &n_configs); - - if (!configs || n_configs == 0) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Failed to find any compatible fbconfigs"); - ret = FALSE; - goto done; - } - - COGL_NOTE (WINSYS, "Using the first available FBConfig"); - *config_ret = configs[0]; - -done: - XFree (configs); - return ret; -} - -static GLXContext -create_gl3_context (CoglDisplay *display, - GLXFBConfig fb_config) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (display->renderer); - - /* We want a core profile 3.1 context with no deprecated features */ - static const int attrib_list[] = - { - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 1, - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, - None - }; - /* NV_robustness_video_memory_purge relies on GLX_ARB_create_context - and in part on ARB_robustness. Namely, it needs the notification - strategy to be set to GLX_LOSE_CONTEXT_ON_RESET_ARB and that the - driver exposes the GetGraphicsResetStatusARB function. This means - we don't actually enable robust buffer access. */ - static const int attrib_list_reset_on_purge[] = - { - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 1, - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, - GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV, - GL_TRUE, - GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, - GLX_LOSE_CONTEXT_ON_RESET_ARB, - None - }; - - /* Make sure that the display supports the GLX_ARB_create_context - extension */ - if (glx_renderer->glXCreateContextAttribs == NULL) - return NULL; - - /* We can't check the presence of this extension with the usual - COGL_WINSYS_FEATURE machinery because that only gets initialized - later when the CoglContext is created. */ - if (strstr (glx_renderer->glXQueryExtensionsString (xlib_renderer->xdpy, - DefaultScreen (xlib_renderer->xdpy)), - "GLX_NV_robustness_video_memory_purge")) - { - GLXContext ctx; - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - ctx = glx_renderer->glXCreateContextAttribs (xlib_renderer->xdpy, - fb_config, - NULL /* share_context */, - True, /* direct */ - attrib_list_reset_on_purge); - if (!mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy) && ctx) - return ctx; - } - - return glx_renderer->glXCreateContextAttribs (xlib_renderer->xdpy, - fb_config, - NULL /* share_context */, - True, /* direct */ - attrib_list); -} - -static gboolean -create_context (CoglDisplay *display, GError **error) -{ - CoglGLXDisplay *glx_display = display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (display->renderer); - GLXFBConfig config; - GError *fbconfig_error = NULL; - XSetWindowAttributes attrs; - XVisualInfo *xvisinfo; - GLXDrawable dummy_drawable; - - g_return_val_if_fail (glx_display->glx_context == NULL, TRUE); - - glx_display->found_fbconfig = - cogl_display_glx_find_fbconfig (display, - &config, - &fbconfig_error); - if (!glx_display->found_fbconfig) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to find suitable fbconfig for the GLX context: %s", - fbconfig_error->message); - g_error_free (fbconfig_error); - return FALSE; - } - - glx_display->fbconfig = config; - - COGL_NOTE (WINSYS, "Creating GLX Context (display: %p)", - xlib_renderer->xdpy); - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - if (cogl_renderer_get_driver_id (display->renderer) == COGL_DRIVER_ID_GL3) - glx_display->glx_context = create_gl3_context (display, config); - else - glx_display->glx_context = - glx_renderer->glXCreateNewContext (xlib_renderer->xdpy, - config, - GLX_RGBA_TYPE, - NULL, - True); - - if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy) || - glx_display->glx_context == NULL) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to create suitable GL context"); - return FALSE; - } - - glx_display->is_direct = - glx_renderer->glXIsDirect (xlib_renderer->xdpy, glx_display->glx_context); - glx_display->have_vblank_counter = glx_display->is_direct && glx_renderer->glXWaitVideoSync; - glx_display->can_vblank_wait = glx_renderer->glXWaitForMsc || glx_display->have_vblank_counter; - - COGL_NOTE (WINSYS, "Setting %s context", - glx_display->is_direct ? "direct" : "indirect"); - - /* XXX: GLX doesn't let us make a context current without a window - * so we create a dummy window that we can use while no CoglOnscreen - * framebuffer is in use. - */ - - xvisinfo = glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy, - config); - if (xvisinfo == NULL) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to retrieve the X11 visual"); - return FALSE; - } - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - attrs.override_redirect = True; - attrs.colormap = XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - attrs.border_pixel = 0; - - glx_display->dummy_xwin = - XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - -100, -100, 1, 1, - 0, - xvisinfo->depth, - CopyFromParent, - xvisinfo->visual, - CWOverrideRedirect | CWColormap | CWBorderPixel, - &attrs); - - /* Try and create a GLXWindow to use with extensions dependent on - * GLX versions >= 1.3 that don't accept regular X Windows as GLX - * drawables. */ - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 3) - { - glx_display->dummy_glxwin = - glx_renderer->glXCreateWindow (xlib_renderer->xdpy, - config, - glx_display->dummy_xwin, - NULL); - } - - if (glx_display->dummy_glxwin) - dummy_drawable = glx_display->dummy_glxwin; - else - dummy_drawable = glx_display->dummy_xwin; - - COGL_NOTE (WINSYS, "Selecting dummy 0x%x for the GLX context", - (unsigned int) dummy_drawable); - - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - dummy_drawable, - dummy_drawable, - glx_display->glx_context); - - g_clear_pointer (&xvisinfo, XFree); - - if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to select the newly created GLX context"); - return FALSE; - } - - return TRUE; -} - -static void -_cogl_winsys_display_destroy (CoglDisplay *display) -{ - CoglGLXDisplay *glx_display = display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = cogl_renderer_get_winsys (display->renderer); - - g_return_if_fail (glx_display != NULL); - - if (glx_display->glx_context) - { - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - None, None, NULL); - glx_renderer->glXDestroyContext (xlib_renderer->xdpy, - glx_display->glx_context); - glx_display->glx_context = NULL; - } - - if (glx_display->dummy_glxwin) - { - glx_renderer->glXDestroyWindow (xlib_renderer->xdpy, - glx_display->dummy_glxwin); - glx_display->dummy_glxwin = None; - } - - if (glx_display->dummy_xwin) - { - XDestroyWindow (xlib_renderer->xdpy, glx_display->dummy_xwin); - glx_display->dummy_xwin = None; - } - - g_free (display->winsys); - display->winsys = NULL; -} - -static gboolean -_cogl_winsys_display_setup (CoglDisplay *display, - GError **error) -{ - CoglGLXDisplay *glx_display; - int i; - - g_return_val_if_fail (display->winsys == NULL, FALSE); - - glx_display = g_new0 (CoglGLXDisplay, 1); - display->winsys = glx_display; - - if (!create_context (display, error)) - goto error; - - for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++) - glx_display->glx_cached_configs[i].depth = -1; - - return TRUE; - -error: - _cogl_winsys_display_destroy (display); - return FALSE; -} - -static gboolean -_cogl_winsys_context_init (CoglContext *context, GError **error) -{ - context->winsys = g_new0 (CoglContextGLX, 1); - - _cogl_renderer_add_native_filter (context->display->renderer, - (CoglNativeFilterFunc)glx_event_filter_cb, - context); - return update_winsys_features (context, error); -} - -static void -_cogl_winsys_context_deinit (CoglContext *context) -{ - _cogl_renderer_remove_native_filter (context->display->renderer, - (CoglNativeFilterFunc)glx_event_filter_cb, - context); - g_free (context->winsys); -} - -static gboolean -get_fbconfig_for_depth (CoglContext *context, - unsigned int depth, - gboolean stereo, - GLXFBConfig *fbconfig_ret, - gboolean *can_mipmap_ret) -{ - CoglXlibRenderer *xlib_renderer; - CoglGLXRenderer *glx_renderer; - CoglGLXDisplay *glx_display; - Display *dpy; - GLXFBConfig *fbconfigs; - int n_elements, i; - int db, stencil, alpha, mipmap, rgba, value; - int spare_cache_slot = 0; - gboolean found = FALSE; - - xlib_renderer = _cogl_xlib_renderer_get_data (context->display->renderer); - glx_renderer = cogl_renderer_get_winsys (context->display->renderer); - glx_display = context->display->winsys; - - /* Check if we've already got a cached config for this depth and stereo */ - for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++) - if (glx_display->glx_cached_configs[i].depth == -1) - spare_cache_slot = i; - else if (glx_display->glx_cached_configs[i].depth == depth && - glx_display->glx_cached_configs[i].stereo == stereo) - { - *fbconfig_ret = glx_display->glx_cached_configs[i].fb_config; - *can_mipmap_ret = glx_display->glx_cached_configs[i].can_mipmap; - return glx_display->glx_cached_configs[i].found; - } - - dpy = xlib_renderer->xdpy; - - fbconfigs = glx_renderer->glXGetFBConfigs (dpy, DefaultScreen (dpy), - &n_elements); - - db = G_MAXSHORT; - stencil = G_MAXSHORT; - mipmap = 0; - rgba = 0; - - for (i = 0; i < n_elements; i++) - { - XVisualInfo *vi; - int visual_depth; - - vi = glx_renderer->glXGetVisualFromFBConfig (dpy, fbconfigs[i]); - if (vi == NULL) - continue; - - visual_depth = vi->depth; - - XFree (vi); - - if (visual_depth != depth) - continue; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_ALPHA_SIZE, - &alpha); - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BUFFER_SIZE, - &value); - if (value != depth && (value - alpha) != depth) - continue; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_STEREO, - &value); - if (!!value != !!stereo) - continue; - - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 4) - { - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_SAMPLES, - &value); - if (value > 1) - continue; - } - - value = 0; - if (depth == 32) - { - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_TEXTURE_RGBA_EXT, - &value); - if (value) - rgba = 1; - } - - if (!value) - { - if (rgba) - continue; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_TEXTURE_RGB_EXT, - &value); - if (!value) - continue; - } - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_DOUBLEBUFFER, - &value); - if (value > db) - continue; - - db = value; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_STENCIL_SIZE, - &value); - if (value > stencil) - continue; - - stencil = value; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_MIPMAP_TEXTURE_EXT, - &value); - - if (value < mipmap) - continue; - - mipmap = value; - - *fbconfig_ret = fbconfigs[i]; - *can_mipmap_ret = mipmap; - found = TRUE; - } - - if (n_elements) - XFree (fbconfigs); - - glx_display->glx_cached_configs[spare_cache_slot].depth = depth; - glx_display->glx_cached_configs[spare_cache_slot].found = found; - glx_display->glx_cached_configs[spare_cache_slot].fb_config = *fbconfig_ret; - glx_display->glx_cached_configs[spare_cache_slot].can_mipmap = mipmap; - - return found; -} - -static gboolean -try_create_glx_pixmap (CoglContext *context, - CoglTexturePixmapX11 *tex_pixmap, - gboolean mipmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - CoglRenderer *renderer; - CoglXlibRenderer *xlib_renderer; - CoglGLXRenderer *glx_renderer; - Display *dpy; - /* We have to initialize this *opaque* variable because gcc tries to - * be too smart for its own good and warns that the variable may be - * used uninitialized otherwise. */ - GLXFBConfig fb_config = (GLXFBConfig)0; - int attribs[7]; - int i = 0; - - unsigned int depth = tex_pixmap->depth; - Visual* visual = tex_pixmap->visual; - - renderer = context->display->renderer; - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - glx_renderer = cogl_renderer_get_winsys (renderer); - dpy = xlib_renderer->xdpy; - - if (!get_fbconfig_for_depth (context, depth, - tex_pixmap->stereo_mode != COGL_TEXTURE_PIXMAP_MONO, - &fb_config, - &glx_tex_pixmap->can_mipmap)) - { - COGL_NOTE (TEXTURE_PIXMAP, "No suitable FBConfig found for depth %i", - depth); - return FALSE; - } - - if (!glx_tex_pixmap->can_mipmap) - mipmap = FALSE; - - attribs[i++] = GLX_TEXTURE_FORMAT_EXT; - - /* Check whether an alpha channel is used by comparing the total - * number of 1-bits in color masks against the color depth requested - * by the client. - */ - if (__builtin_popcountl (visual->red_mask | - visual->green_mask | - visual->blue_mask) == depth) - attribs[i++] = GLX_TEXTURE_FORMAT_RGB_EXT; - else - attribs[i++] = GLX_TEXTURE_FORMAT_RGBA_EXT; - - attribs[i++] = GLX_MIPMAP_TEXTURE_EXT; - attribs[i++] = mipmap; - - attribs[i++] = GLX_TEXTURE_TARGET_EXT; - attribs[i++] = GLX_TEXTURE_2D_EXT; - - attribs[i++] = None; - - /* We need to trap errors from glXCreatePixmap because it can - * sometimes fail during normal usage. For example on NVidia it gets - * upset if you try to create two GLXPixmaps for the same drawable. - */ - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - glx_tex_pixmap->glx_pixmap = - glx_renderer->glXCreatePixmap (dpy, - fb_config, - tex_pixmap->pixmap, - attribs); - glx_tex_pixmap->has_mipmap_space = mipmap; - - XSync (dpy, False); - - if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy)) - { - COGL_NOTE (TEXTURE_PIXMAP, "Failed to create pixmap for %p", tex_pixmap); - mtk_x11_error_trap_push (xlib_renderer->xdpy); - glx_renderer->glXDestroyPixmap (dpy, glx_tex_pixmap->glx_pixmap); - XSync (dpy, False); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - - glx_tex_pixmap->glx_pixmap = None; - return FALSE; - } - - return TRUE; -} - -static gboolean -_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap; - CoglContext *ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - - if (!cogl_context_has_winsys_feature (ctx, COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP)) - { - tex_pixmap->winsys = NULL; - return FALSE; - } - - glx_tex_pixmap = g_new0 (CoglTexturePixmapGLX, 1); - - glx_tex_pixmap->glx_pixmap = None; - glx_tex_pixmap->can_mipmap = FALSE; - glx_tex_pixmap->has_mipmap_space = FALSE; - - glx_tex_pixmap->left.glx_tex = NULL; - glx_tex_pixmap->right.glx_tex = NULL; - - glx_tex_pixmap->left.bind_tex_image_queued = TRUE; - glx_tex_pixmap->right.bind_tex_image_queued = TRUE; - glx_tex_pixmap->left.pixmap_bound = FALSE; - glx_tex_pixmap->right.pixmap_bound = FALSE; - - tex_pixmap->winsys = glx_tex_pixmap; - - if (!try_create_glx_pixmap (ctx, tex_pixmap, FALSE)) - { - tex_pixmap->winsys = NULL; - g_free (glx_tex_pixmap); - return FALSE; - } - - return TRUE; -} - -static void -free_glx_pixmap (CoglContext *context, - CoglTexturePixmapGLX *glx_tex_pixmap) -{ - CoglRenderer *renderer; - CoglXlibRenderer *xlib_renderer; - CoglGLXRenderer *glx_renderer; - - renderer = context->display->renderer; - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - glx_renderer = cogl_renderer_get_winsys (renderer); - - if (glx_tex_pixmap->left.pixmap_bound) - glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - GLX_FRONT_LEFT_EXT); - if (glx_tex_pixmap->right.pixmap_bound) - glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - GLX_FRONT_RIGHT_EXT); - - /* FIXME - we need to trap errors and synchronize here because - * of ordering issues between the XPixmap destruction and the - * GLXPixmap destruction. - * - * If the X pixmap is destroyed, the GLX pixmap is destroyed as - * well immediately, and thus, when Cogl calls glXDestroyPixmap() - * it'll cause a BadDrawable error. - * - * this is technically a bug in the X server, which should not - * destroy either pixmaps until the call to glXDestroyPixmap(); so - * at some point we should revisit this code and remove the - * trap+sync after verifying that the destruction is indeed safe. - * - * for reference, see: - * http://bugzilla.clutter-project.org/show_bug.cgi?id=2324 - */ - mtk_x11_error_trap_push (xlib_renderer->xdpy); - glx_renderer->glXDestroyPixmap (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap); - XSync (xlib_renderer->xdpy, False); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - - glx_tex_pixmap->glx_pixmap = None; - glx_tex_pixmap->left.pixmap_bound = FALSE; - glx_tex_pixmap->right.pixmap_bound = FALSE; -} - -static void -_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap; - - if (!tex_pixmap->winsys) - return; - - glx_tex_pixmap = tex_pixmap->winsys; - - free_glx_pixmap (cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)), - glx_tex_pixmap); - - if (glx_tex_pixmap->left.glx_tex) - g_object_unref (glx_tex_pixmap->left.glx_tex); - - if (glx_tex_pixmap->right.glx_tex) - g_object_unref (glx_tex_pixmap->right.glx_tex); - - tex_pixmap->winsys = NULL; - g_free (glx_tex_pixmap); -} - -static gboolean -_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode, - gboolean needs_mipmap) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - CoglContext *ctx = cogl_texture_get_context (tex); - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - CoglPixmapTextureEyeGLX *texture_info; - int buffer; - CoglGLXRenderer *glx_renderer; - - if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - { - texture_info = &glx_tex_pixmap->right; - buffer = GLX_FRONT_RIGHT_EXT; - } - else - { - texture_info = &glx_tex_pixmap->left; - buffer = GLX_FRONT_LEFT_EXT; - } - - /* If we don't have a GLX pixmap then fallback */ - if (glx_tex_pixmap->glx_pixmap == None) - return FALSE; - - glx_renderer = cogl_renderer_get_winsys (ctx->display->renderer); - - /* Lazily create a texture to hold the pixmap */ - if (texture_info->glx_tex == NULL) - { - CoglPixelFormat texture_format; - GError *error = NULL; - - texture_format = (tex_pixmap->depth >= 32 ? - COGL_PIXEL_FORMAT_RGBA_8888_PRE : - COGL_PIXEL_FORMAT_RGB_888); - - texture_info->glx_tex = - cogl_texture_2d_new_with_size (ctx, - cogl_texture_get_width (tex), - cogl_texture_get_height (tex)); - - _cogl_texture_set_internal_format (tex, texture_format); - - if (cogl_texture_allocate (texture_info->glx_tex, &error)) - COGL_NOTE (TEXTURE_PIXMAP, "Created a texture 2d for %p", tex_pixmap); - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Falling back for %p because a " - "texture 2d could not be created: %s", - tex_pixmap, error->message); - g_error_free (error); - free_glx_pixmap (ctx, glx_tex_pixmap); - return FALSE; - } - } - - if (needs_mipmap) - { - /* If we can't support mipmapping then temporarily fallback */ - if (!glx_tex_pixmap->can_mipmap) - return FALSE; - - /* Recreate the GLXPixmap if it wasn't previously created with a - * mipmap tree */ - if (!glx_tex_pixmap->has_mipmap_space) - { - free_glx_pixmap (ctx, glx_tex_pixmap); - - COGL_NOTE (TEXTURE_PIXMAP, "Recreating GLXPixmap with mipmap " - "support for %p", tex_pixmap); - if (!try_create_glx_pixmap (ctx, tex_pixmap, TRUE)) - - { - /* If the pixmap failed then we'll permanently fallback - * to using XImage. This shouldn't happen. */ - COGL_NOTE (TEXTURE_PIXMAP, "Falling back to XGetImage " - "updates for %p because creating the GLXPixmap " - "with mipmap support failed", tex_pixmap); - - if (texture_info->glx_tex) - g_object_unref (texture_info->glx_tex); - return FALSE; - } - - glx_tex_pixmap->left.bind_tex_image_queued = TRUE; - glx_tex_pixmap->right.bind_tex_image_queued = TRUE; - } - } - - if (texture_info->bind_tex_image_queued) - { - GLuint gl_handle, gl_target; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (ctx->display->renderer); - - cogl_texture_get_gl_texture (texture_info->glx_tex, - &gl_handle, &gl_target); - - COGL_NOTE (TEXTURE_PIXMAP, "Rebinding GLXPixmap for %p", tex_pixmap); - - _cogl_bind_gl_texture_transient (ctx, gl_target, gl_handle); - - if (texture_info->pixmap_bound) - glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - buffer); - - glx_renderer->glXBindTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - buffer, - NULL); - - /* According to the recommended usage in the spec for - * GLX_EXT_texture_pixmap we should release the texture after - * we've finished drawing with it and it is undefined what - * happens if you render to a pixmap that is bound to a texture. - * However that would require the texture backend to know when - * Cogl has finished painting and it may be more expensive to - * keep unbinding the texture. Leaving it bound appears to work - * on Mesa and NVidia drivers and it is also what Compiz does so - * it is probably ok */ - - texture_info->bind_tex_image_queued = FALSE; - texture_info->pixmap_bound = TRUE; - - _cogl_texture_2d_externally_modified (texture_info->glx_tex); - } - - return TRUE; -} - -static void -_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - - glx_tex_pixmap->left.bind_tex_image_queued = TRUE; - glx_tex_pixmap->right.bind_tex_image_queued = TRUE; -} - -static CoglTexture * -_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - - if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - return glx_tex_pixmap->right.glx_tex; - else - return glx_tex_pixmap->left.glx_tex; -} - -void -cogl_context_glx_set_current_drawable (CoglContext *context, - GLXDrawable drawable) -{ - CoglContextGLX *glx_context = context->winsys; - - glx_context->current_drawable = drawable; -} - -GLXDrawable -cogl_context_glx_get_current_drawable (CoglContext *context) -{ - CoglContextGLX *glx_context = context->winsys; - - return glx_context->current_drawable; -} - -static CoglWinsysVtable _cogl_winsys_vtable = - { - .id = COGL_WINSYS_ID_GLX, - .name = "GLX", - .constraints = (COGL_RENDERER_CONSTRAINT_USES_X11 | - COGL_RENDERER_CONSTRAINT_USES_XLIB), - - .renderer_get_proc_address = _cogl_winsys_renderer_get_proc_address, - .renderer_connect = _cogl_winsys_renderer_connect, - .renderer_disconnect = _cogl_xlib_renderer_disconnect, - .renderer_outputs_changed = _cogl_winsys_renderer_outputs_changed, - .renderer_bind_api = _cogl_winsys_renderer_bind_api, - .display_setup = _cogl_winsys_display_setup, - .display_destroy = _cogl_winsys_display_destroy, - .context_init = _cogl_winsys_context_init, - .context_deinit = _cogl_winsys_context_deinit, - - /* X11 tfp support... */ - /* XXX: instead of having a rather monolithic winsys vtable we could - * perhaps look for a way to separate these... */ - .texture_pixmap_x11_create = - _cogl_winsys_texture_pixmap_x11_create, - .texture_pixmap_x11_free = - _cogl_winsys_texture_pixmap_x11_free, - .texture_pixmap_x11_update = - _cogl_winsys_texture_pixmap_x11_update, - .texture_pixmap_x11_damage_notify = - _cogl_winsys_texture_pixmap_x11_damage_notify, - .texture_pixmap_x11_get_texture = - _cogl_winsys_texture_pixmap_x11_get_texture, - }; - -/* XXX: we use a function because no doubt someone will complain - * about using c99 member initializers because they aren't portable - * to windows. We want to avoid having to rigidly follow the real - * order of members since some members are #ifdefd and we'd have - * to mirror the #ifdefing to add padding etc. For any winsys that - * can assume the platform has a sane compiler then we can just use - * c99 initializers for insane platforms they can initialize - * the members by name in a function. - */ -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_glx_get_vtable (void) -{ - return &_cogl_winsys_vtable; -} diff --git a/cogl/cogl/winsys/cogl-winsys-private.h b/cogl/cogl/winsys/cogl-winsys-private.h index aeb2dd204b6..d14592c5d07 100644 --- a/cogl/cogl/winsys/cogl-winsys-private.h +++ b/cogl/cogl/winsys/cogl-winsys-private.h @@ -33,10 +33,6 @@ #include "cogl/cogl-renderer.h" #include "cogl/cogl-scanout.h" -#ifdef HAVE_X11 -#include -#include "cogl/winsys/cogl-texture-pixmap-x11-private.h" -#endif COGL_EXPORT uint32_t _cogl_winsys_error_quark (void); @@ -138,27 +134,6 @@ typedef struct _CoglWinsysVtable void (*context_deinit) (CoglContext *context); - /* Optional functions */ - -#ifdef HAVE_X11 - gboolean - (*texture_pixmap_x11_create) (CoglTexturePixmapX11 *tex_pixmap); - void - (*texture_pixmap_x11_free) (CoglTexturePixmapX11 *tex_pixmap); - - gboolean - (*texture_pixmap_x11_update) (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode, - gboolean needs_mipmap); - - void - (*texture_pixmap_x11_damage_notify) (CoglTexturePixmapX11 *tex_pixmap); - - CoglTexture * - (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode); -#endif - void (*update_sync) (CoglContext *ctx); diff --git a/cogl/meson.build b/cogl/meson.build index 180120b6294..9cec31ddcff 100644 --- a/cogl/meson.build +++ b/cogl/meson.build @@ -34,17 +34,6 @@ if have_egl ] endif -if have_x11 - cogl_pkg_deps += [ - x11_dep, - ] - cogl_pkg_private_deps += [ - xext_dep, - xdamage_dep, - xrandr_dep, - ] -endif - if have_gl cogl_pkg_deps += [ gl_dep, diff --git a/config.h.meson b/config.h.meson index 655227ce372..c9d1003643a 100644 --- a/config.h.meson +++ b/config.h.meson @@ -28,11 +28,6 @@ /* Defined if EGLDevice support is enabled */ #mesondefine HAVE_EGL_DEVICE -/* Have GLX for rendering */ -#mesondefine HAVE_GLX - -#mesondefine HAVE_EGL_PLATFORM_XLIB - /* Have GL for rendering */ #mesondefine HAVE_GL @@ -63,9 +58,6 @@ /* Define if you want to enable XWayland support */ #mesondefine HAVE_XWAYLAND -/* Define if you want to enable X11 backend support */ -#mesondefine HAVE_X11 - /* Define if either XWayland or X11 backend are enabled */ #mesondefine HAVE_X11_CLIENT diff --git a/doc/mutter-relationships.md b/doc/mutter-relationships.md index 7d6dcc7209c..ee176d95814 100644 --- a/doc/mutter-relationships.md +++ b/doc/mutter-relationships.md @@ -37,7 +37,6 @@ erDiagram ```mermaid classDiagram MetaBackend <-- MetaBackendNative - MetaBackend <-- MetaBackendX11 class MetaBackend{ MetaMonitorManager monitor_manager List~MetaGpu~ gpus diff --git a/doc/website/index.html b/doc/website/index.html index e7a4fb97502..822e87a98fe 100644 --- a/doc/website/index.html +++ b/doc/website/index.html @@ -46,13 +46,12 @@ -

Mutter is a Wayland display server and X11 window manager and compositor library.

+

Mutter is a Wayland display server compositor library.

When used as a Wayland display server, it runs on top of KMS and libinput. It implements the compositor side of the Wayland core protocol as well as various protocol extensions. It also has functionality related to running X11 applications using Xwayland. - When used on top of Xorg it acts as a X11 window manager and compositing manager. It contains functionality - related to, among other things, window management, window compositing, focus tracking, workspace management, + It contains functionality related to, among other things, window management, window compositing, focus tracking, workspace management, keybindings and monitor configuration.

Mutter is used by, for example, GNOME Shell, the GNOME @@ -94,15 +93,14 @@

  • Meta

    -

    The display server and window manager library. Contains a X11 window manager and compositing manager - implementation, as well as a Wayland display server implementation.

    +

    The display server and window manager library. Contains a Wayland display server implementation.

  • Clutter

    Compositing toolkit, containing an actor and render node based scene graph, and has features such as input - event routing, transformation and animation. Handles compositing, both Wayland surfaces, X11 windows, and is + event routing, transformation and animation. Handles compositing, and is the basis of the UI toolkit implemented by GNOME Shell.

  • diff --git a/meson.build b/meson.build index 84f0fad06bc..76f16065bb5 100644 --- a/meson.build +++ b/meson.build @@ -141,16 +141,15 @@ gvdb_dep = dependency('gvdb') libdisplay_info_dep = dependency('libdisplay-info', version: libdisplay_info_req) have_wayland = get_option('wayland') -have_x11 = get_option('x11') have_xwayland = get_option('xwayland') -have_x11_client = have_x11 or have_xwayland +have_x11_client = have_xwayland if have_xwayland and not have_wayland error('XWayland support requires Wayland support enabled') endif -if not have_wayland and not have_x11 - error('A Wayland/X11 backend must be enabled') +if not have_wayland + error('A Wayland backend must be enabled') endif have_fonts = get_option('fonts') @@ -161,7 +160,7 @@ if have_fonts harfbuzz_dep = dependency('harfbuzz', version: harfbuzz_req) endif -if have_fonts or have_x11 +if have_fonts fribidi_dep = dependency('fribidi', version: fribidi_req) endif @@ -183,13 +182,6 @@ if have_x11_client xcb_res_dep = dependency('xcb-res') xinerama_dep = dependency('xinerama') xau_dep = dependency('xau') - - if have_x11 - xcb_randr_dep = dependency('xcb-randr') - xkbcommon_x11_dep = dependency('xkbcommon-x11') - xkbfile_dep = dependency('xkbfile') - xtst_dep = dependency('xtst') - endif endif have_gnome_desktop = get_option('libgnome_desktop') @@ -213,15 +205,6 @@ if have_egl egl_dep = dependency('egl') endif -have_glx = get_option('glx') and have_x11 -if have_glx - if not have_gl - error('GLX support requires OpenGL to be enabled') - endif -endif - -have_egl_xlib = have_egl and have_x11 - have_gles2 = get_option('gles2') if have_gles2 gles2_dep = dependency('glesv2') @@ -402,7 +385,6 @@ have_clutter_tests = false have_kvm_tests = false have_tty_tests = false have_installed_tests = false -have_x11_tests = false have_bash_completion = get_option('bash_completion') if have_tests @@ -470,13 +452,6 @@ if have_tests ) add_test_setup('plain') - - if have_x11 - xvfb = find_program('xvfb-run', required: false) - if xvfb.found() - have_x11_tests = true - endif - endif endif have_profiler = get_option('profiler') @@ -594,13 +569,10 @@ cdata.set_quoted('PACKAGE_NAME', meson.project_name()) cdata.set_quoted('PACKAGE_VERSION', meson.project_version()) cdata.set('HAVE_EGL', have_egl) -cdata.set('HAVE_GLX', have_glx) -cdata.set('HAVE_EGL_PLATFORM_XLIB', have_egl_xlib) cdata.set('HAVE_GL', have_gl) cdata.set('HAVE_GLES2', have_gles2) cdata.set('HAVE_WAYLAND', have_wayland) cdata.set('HAVE_XWAYLAND', have_xwayland) -cdata.set('HAVE_X11', have_x11) cdata.set('HAVE_X11_CLIENT', have_x11_client) cdata.set('HAVE_LOGIND', have_logind) cdata.set('HAVE_NATIVE_BACKEND', have_native_backend) @@ -789,11 +761,9 @@ summary('Bash completion', have_bash_completion, section: 'Shell integration') summary('OpenGL', have_gl, section: 'Rendering APIs') summary('GLES2', have_gles2, section: 'Rendering APIs') summary('EGL', have_egl, section: 'Rendering APIs') -summary('GLX', have_glx, section: 'Rendering APIs') summary('Wayland', have_wayland, section: 'Options') summary('Wayland EGLStream', have_wayland_eglstream, section: 'Options') -summary('X11', have_x11, section: 'Options') summary('XWayland', have_xwayland, section: 'Options') summary('Native Backend', have_native_backend, section: 'Options') summary('EGL Device', have_egl_device, section: 'Options') @@ -819,6 +789,5 @@ summary('Mutter tests', have_mutter_tests, section: 'Tests') summary('Cogl tests', have_cogl_tests, section: 'Tests') summary('Clutter tests', have_clutter_tests, section: 'Tests') summary('KVM tests', have_kvm_tests, section: 'Tests') -summary('X11 backend', have_x11_tests, section: 'Tests') summary('Installed tests', have_installed_tests, section: 'Tests') summary('Coverage', get_option('b_coverage'), section: 'Tests') diff --git a/meson.options b/meson.options index 581aac2f0ad..a30a0b9d03a 100644 --- a/meson.options +++ b/meson.options @@ -27,11 +27,6 @@ option('egl', value: true, description: 'Enable EGL support' ) -option('glx', - type: 'boolean', - value: true, - description: 'Enable GLX support' -) option('wayland', type: 'boolean', @@ -45,12 +40,6 @@ option('xwayland', description: 'Enable Xwayland support' ) -option('x11', - type: 'boolean', - value: false, - description: 'Enable X11 support' -) - option('logind', type: 'boolean', value: true, diff --git a/src/backends/meta-barrier.c b/src/backends/meta-barrier.c index fcd4da0ae7b..51db6cb527e 100644 --- a/src/backends/meta-barrier.c +++ b/src/backends/meta-barrier.c @@ -16,10 +16,6 @@ #include "meta/meta-enum-types.h" #include "meta/util.h" -#ifdef HAVE_X11 -#include "backends/x11/meta-backend-x11.h" -#include "backends/x11/meta-barrier-x11.h" -#endif #ifdef HAVE_NATIVE_BACKEND #include "backends/native/meta-backend-native.h" @@ -249,11 +245,6 @@ init_barrier_impl (MetaBarrier *barrier) if (META_IS_BACKEND_NATIVE (priv->backend)) priv->impl = meta_barrier_impl_native_new (barrier); #endif -#ifdef HAVE_X11 - if (META_IS_BACKEND_X11 (priv->backend) && - !meta_is_wayland_compositor ()) - priv->impl = meta_barrier_impl_x11_new (barrier); -#endif g_warn_if_fail (priv->impl); } diff --git a/src/backends/meta-dnd-private.h b/src/backends/meta-dnd-private.h index 33e2e9c9684..bb1cdbdb0d7 100644 --- a/src/backends/meta-dnd-private.h +++ b/src/backends/meta-dnd-private.h @@ -21,23 +21,8 @@ #include -#ifdef HAVE_X11 -#include -#include "compositor/meta-compositor-x11.h" -#include "meta/meta-x11-types.h" -#endif - #include "backends/meta-backend-private.h" -#ifdef HAVE_X11 -gboolean meta_dnd_handle_xdnd_event (MetaBackend *backend, - MetaCompositorX11 *compositor_x11, - Display *xdisplay, - XEvent *xev); - -void meta_dnd_init_xdnd (MetaX11Display *x11_display); -#endif - #ifdef HAVE_WAYLAND void meta_dnd_wayland_handle_begin_modal (MetaCompositor *compositor); diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 7c4622cf023..827df6ee52c 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -64,10 +64,6 @@ #include "meta-dbus-display-config.h" -#ifdef HAVE_X11 -#include "backends/x11/meta-monitor-manager-xrandr.h" -#endif - #define DEFAULT_DISPLAY_CONFIGURATION_TIMEOUT 20 enum diff --git a/src/backends/meta-renderdoc.c b/src/backends/meta-renderdoc.c index 0de86d1e124..4f123773019 100644 --- a/src/backends/meta-renderdoc.c +++ b/src/backends/meta-renderdoc.c @@ -25,9 +25,6 @@ #ifdef HAVE_NATIVE_BACKEND #include "backends/native/meta-stage-native.h" #endif -#ifdef HAVE_X11 -#include "backends/x11/meta-stage-x11.h" -#endif #include @@ -117,17 +114,6 @@ meta_renderdoc_capture_start (MetaRenderdoc *renderdoc, COGL_ONSCREEN (framebuffer)); } else -#endif -#ifdef HAVE_X11 - if (META_IS_STAGE_X11 (stage_window)) - { - MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); - - capture_onscreen_start (renderdoc, - stage_view, - COGL_ONSCREEN (stage_x11->onscreen)); - } - else #endif { g_warning ("capturing stage of type %s is not supported", @@ -161,21 +147,7 @@ meta_renderdoc_capture_end (MetaRenderdoc *renderdoc, stage_view, COGL_ONSCREEN (framebuffer)); } - else -#endif -#ifdef HAVE_X11 - if (META_IS_STAGE_X11 (stage_window)) - { - MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); - - capture_onscreen_end (renderdoc, - stage_view, - COGL_ONSCREEN (stage_x11->onscreen)); - } - else #endif - { - } } static void 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 bc8ad6dfe2f..00000000000 --- a/src/backends/x11/cm/meta-backend-x11-cm.c +++ /dev/null @@ -1,584 +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 . - */ - -#include "config.h" - -#include "backends/x11/cm/meta-backend-x11-cm.h" - -#include -#include -#include -#include - -#include "backends/meta-backend-private.h" -#include "backends/meta-dnd-private.h" -#include "backends/x11/meta-barrier-x11.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; - char *keymap_model; - int locked_group; - - MetaInputSettings *input_settings; -}; - -G_DEFINE_FINAL_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 gboolean -meta_backend_x11_cm_init_basic (MetaBackend *backend, - GError **error) -{ - MetaBackendClass *parent_backend_class = - META_BACKEND_CLASS (meta_backend_x11_cm_parent_class); - MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (backend); - MetaGpuXrandr *gpu_xrandr; - - if (x11_cm->display_name) - g_setenv ("DISPLAY", x11_cm->display_name, TRUE); - - /* - * 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 (x11_cm)); - meta_backend_add_gpu (backend, META_GPU (gpu_xrandr)); - - return parent_backend_class->init_basic (backend, error); -} - -static gboolean -meta_backend_x11_cm_init_render (MetaBackend *backend, - GError **error) -{ - 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 (meta_backend_get_clutter_backend (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, - "backend", backend, - NULL); - - if (!parent_backend_class->init_render (backend, error)) - return FALSE; - - take_touch_grab (backend); - - return TRUE; -} - -static MetaBackendCapabilities -meta_backend_x11_cm_get_capabilities (MetaBackend *backend) -{ - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); - MetaBackendCapabilities capabilities = META_BACKEND_CAPABILITY_NONE; - MetaX11Barriers *barriers; - - barriers = meta_backend_x11_get_barriers (backend_x11); - if (barriers) - capabilities |= META_BACKEND_CAPABILITY_BARRIERS; - - return capabilities; -} - -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, - ClutterSprite *sprite) -{ - 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, - "sprite", sprite, - 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_stage (MetaBackend *backend) -{ - MetaBackendX11 *x11 = META_BACKEND_X11 (backend); - Display *xdisplay = meta_backend_x11_get_xdisplay (x11); - Window xwin = meta_backend_x11_get_xwindow (x11); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); - int width, height; - - meta_monitor_manager_get_screen_size (monitor_manager, &width, &height); - 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, - const char *model, - 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 = NULL; - 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); - free (var_defs->model); - var_defs->model = strdup (model); - - /* 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 || - !x11_cm->keymap_model) - return; - - get_xkbrf_var_defs (xdisplay, - x11_cm->keymap_layouts, - x11_cm->keymap_variants, - x11_cm->keymap_options, - x11_cm->keymap_model, - &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_async (MetaBackend *backend, - const char *layouts, - const char *variants, - const char *options, - const char *model, - GTask *task) -{ - 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); - g_free (x11_cm->keymap_model); - x11_cm->keymap_model = g_strdup (model); - - apply_keymap (x11); - - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -static void -meta_backend_x11_cm_set_keymap_layout_group_async (MetaBackend *backend, - xkb_layout_index_t idx, - GTask *task) -{ - 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); - - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -static gboolean -meta_backend_x11_cm_handle_host_xevent (MetaBackendX11 *x11, - XEvent *event) -{ - MetaBackend *backend = META_BACKEND (x11); - MetaContext *context = meta_backend_get_context (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); - MetaDisplay *display; - - display = meta_context_get_display (context); - if (display) - { - MetaCompositor *compositor = display->compositor; - MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); - - if (meta_dnd_handle_xdnd_event (backend, compositor_x11, - xdisplay, event)) - return 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; - } - } - } - - if (meta_monitor_manager_xrandr_handle_xevent (monitor_manager_xrandr, event)) - return TRUE; - - return FALSE; -} - -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_init (MetaBackendX11Cm *backend_x11_cm) -{ -} - -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; - - backend_class->init_basic = meta_backend_x11_cm_init_basic; - backend_class->init_render = meta_backend_x11_cm_init_render; - backend_class->get_capabilities = meta_backend_x11_cm_get_capabilities; - 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_stage = meta_backend_x11_cm_update_stage; - backend_class->select_stage_events = meta_backend_x11_cm_select_stage_events; - backend_class->set_keymap_async = meta_backend_x11_cm_set_keymap_async; - backend_class->set_keymap_layout_group_async = meta_backend_x11_cm_set_keymap_layout_group_async; - - 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", NULL, NULL, - 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 02ed196d61e..00000000000 --- a/src/backends/x11/cm/meta-backend-x11-cm.h +++ /dev/null @@ -1,28 +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 . - */ - -#pragma once - -#include - -#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) 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 fbee194ce44..00000000000 --- a/src/backends/x11/cm/meta-cursor-sprite-xfixes.c +++ /dev/null @@ -1,237 +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 . - * - */ - -#include "config.h" - -#include "backends/x11/cm/meta-cursor-sprite-xfixes.h" - -#include - -#include "compositor/compositor-private.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 gboolean -meta_cursor_sprite_xfixes_realize_texture (MetaCursorSprite *sprite) -{ - return TRUE; -} - -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, - MetaCursorTracker *cursor_tracker, - GError **error) -{ - return g_initable_new (META_TYPE_CURSOR_SPRITE_XFIXES, - NULL, error, - "display", display, - "cursor-tracker", cursor_tracker, - 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; - CoglTexture *texture; - uint8_t *cursor_data; - gboolean free_cursor_data; - MetaCompositor *compositor; - MetaBackend *backend; - 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; - } - - compositor = meta_display_get_compositor (sprite_xfixes->display); - backend = meta_compositor_get_backend (compositor); - clutter_backend = meta_backend_get_clutter_backend (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, - COGL_PIXEL_FORMAT_CAIRO_ARGB32_COMPAT, - 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, - texture, - cursor_image->xhot, - cursor_image->yhot); - g_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", NULL, NULL, - 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 4a4cd72f862..00000000000 --- a/src/backends/x11/cm/meta-cursor-sprite-xfixes.h +++ /dev/null @@ -1,34 +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 . - * - */ - -#pragma once - -#include - -#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, - MetaCursorTracker *cursor_tracker, - GError **error); 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 494b985fb87..00000000000 --- a/src/backends/x11/cm/meta-renderer-x11-cm.c +++ /dev/null @@ -1,112 +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 . - * - */ - -#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); - MtkRectangle view_layout; - - g_return_if_fail (!renderer_x11_cm->screen_view); - - view_layout = (MtkRectangle) { - .width = width, - .height = height, - }; - renderer_x11_cm->screen_view = g_object_new (META_TYPE_RENDERER_VIEW, - "name", "X11 screen", - "backend", backend, - "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) -{ - MtkRectangle view_layout; - - view_layout = (MtkRectangle) { - .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 d5449208ee9..00000000000 --- a/src/backends/x11/cm/meta-renderer-x11-cm.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 . - * - */ - -#pragma once - -#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); diff --git a/src/backends/x11/meta-backend-x11-types.h b/src/backends/x11/meta-backend-x11-types.h deleted file mode 100644 index 60464ef0c2c..00000000000 --- a/src/backends/x11/meta-backend-x11-types.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2022 Red Hat - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - */ - -#pragma once -typedef struct _MetaBackendX11 MetaBackendX11; - -typedef struct _MetaX11Barriers MetaX11Barriers; diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c deleted file mode 100644 index f9fa0ff5cf3..00000000000 --- a/src/backends/x11/meta-backend-x11.c +++ /dev/null @@ -1,1365 +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, see . - * - * Written by: - * Jasper St. Pierre - */ - -/** - * MetaBackendX11: - * - * 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 -#include -#include -#include -#include -#include - -#include "backends/meta-color-manager.h" -#include "backends/meta-idle-monitor-private.h" -#include "backends/meta-keymap-utils.h" -#include "backends/meta-stage-private.h" -#include "backends/x11/meta-barrier-x11.h" -#include "backends/x11/meta-clutter-backend-x11.h" -#include "backends/x11/meta-color-manager-x11.h" -#include "backends/x11/meta-event-x11.h" -#include "backends/x11/meta-input-device-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" -#include "mtk/mtk-x11.h" -#include "x11/window-x11.h" - -#ifdef HAVE_LOGIND -#include "backends/meta-launcher.h" -#endif - -typedef struct _MetaBackendX11Private -{ - /* The host X11 display */ - Display *xdisplay; - Screen *xscreen; - xcb_connection_t *xcb; - GSource *source; - Window root_window; - - 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; - gboolean have_xinput_23; - - 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; - - MetaX11Barriers *barriers; -} MetaBackendX11Private; - -G_DEFINE_TYPE_WITH_PRIVATE (MetaBackendX11, - meta_backend_x11, - META_TYPE_BACKEND) - -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; - - 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); - - idle_monitor = meta_backend_get_core_idle_monitor (backend); - 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); -} - -/* 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 gboolean -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; - MetaX11Barriers *barriers; - - barriers = meta_backend_x11_get_barriers (x11); - if (barriers && - meta_x11_barriers_process_xevent (barriers, input_event)) - return TRUE; - - maybe_spoof_event_as_stage_event (x11, input_event); - } - - return FALSE; -} - -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); - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); - gboolean bypass_clutter = FALSE; -#ifdef HAVE_X11 - MetaContext *context = meta_backend_get_context (backend); - MetaDisplay *display; -#endif - - 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); - -#ifdef HAVE_X11 - display = meta_context_get_display (context); - 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; - } -#endif - - 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; - case XkbControlsNotify: - /* '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 our settings when it's in response to an - * explicit user input event, so require a non-zero event_type. - */ - if (xkb_ev->ctrls.event_type != 0) - meta_seat_x11_check_xkb_a11y_settings_changed (seat); - default: - break; - } - } - } - - if (!bypass_clutter) - { - if (handle_input_event (x11, event)) - goto done; - - meta_backend_x11_handle_event (backend, event); - } - -done: - 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)); - g_source_set_name (source, "[mutter] X events"); - 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); - - meta_backend_x11_reset_cached_logical_monitor (x11); -} - -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 gboolean -meta_backend_x11_init_render (MetaBackend *backend, - GError **error) -{ - MetaBackendX11 *x11 = META_BACKEND_X11 (backend); - MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); - int major, minor; - - 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 (!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); - - return TRUE; -} - -static gboolean -meta_backend_x11_init_post (MetaBackend *backend, - GError **error) -{ - 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; - - 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); - } - } - - return TRUE; -} - -#ifdef HAVE_LOGIND -static gboolean -meta_backend_x11_create_launcher (MetaBackend *backend, - MetaLauncher **launcher_out, - GError **error) -{ - g_autoptr (MetaLauncher) launcher = NULL; - g_autoptr (GError) local_error = NULL; - - *launcher_out = NULL; - - launcher = meta_launcher_new (backend, &local_error); - - if (!launcher) - { - meta_topic (META_DEBUG_BACKEND, - "Creating launcher for the X11 backend failed: %s", - local_error->message); - - return TRUE; - } - - *launcher_out = g_steal_pointer (&launcher); - return TRUE; -} -#endif - -static ClutterBackend * -meta_backend_x11_create_clutter_backend (MetaBackend *backend, - ClutterContext *context) -{ - return CLUTTER_BACKEND (meta_clutter_backend_x11_new (backend, context)); -} - -static MetaColorManager * -meta_backend_x11_create_color_manager (MetaBackend *backend) -{ - return g_object_new (META_TYPE_COLOR_MANAGER_X11, - "backend", backend, - 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 (backend, - 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_freeze_keyboard (MetaBackend *backend, - uint32_t timestamp) -{ - MetaBackendX11 *backend_x11; - Window xwindow; - Display *xdisplay; - - 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); - - /* Grab the keyboard, so we get key releases and all key - * presses - */ - - backend_x11 = META_BACKEND_X11 (backend); - xwindow = meta_backend_x11_get_xwindow (backend_x11); - xdisplay = meta_backend_x11_get_xdisplay (backend_x11); - - /* 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 - */ - XIGrabDevice (xdisplay, - META_VIRTUAL_CORE_KEYBOARD_ID, - xwindow, - timestamp, - None, - XIGrabModeSync, XIGrabModeSync, - False, /* owner_events */ - &mask); -} - -static void -meta_backend_x11_unfreeze_keyboard (MetaBackend *backend, - uint32_t timestamp) -{ - 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 void -meta_backend_x11_ungrab_keyboard (MetaBackend *backend, - uint32_t timestamp) -{ - Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); - - XIUngrabDevice (xdisplay, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp); -} - -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; - int err; - - if (state == META_SEQUENCE_ACCEPTED) - event_mode = XIAcceptTouch; - else if (state == META_SEQUENCE_REJECTED) - event_mode = XIRejectTouch; - else - g_return_if_reached (); - - mtk_x11_error_trap_push (priv->xdisplay); - XIAllowTouchEvents (priv->xdisplay, - META_VIRTUAL_CORE_POINTER_ID, - clutter_event_sequence_get_slot (sequence), - DefaultRootWindow (priv->xdisplay), event_mode); - err = mtk_x11_error_trap_pop_with_return (priv->xdisplay); - if (err) - { - g_debug ("XIAllowTouchEvents failed event_mode %d with error %d", - event_mode, err); - } - - 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_reset_cached_logical_monitor (MetaBackendX11 *backend_x11) -{ - MetaBackendX11Private *priv = - meta_backend_x11_get_instance_private (backend_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 -init_xinput (MetaBackendX11 *backend_x11, - GError **error) -{ - MetaBackendX11Private *priv = - meta_backend_x11_get_instance_private (backend_x11); - gboolean has_xi = FALSE; - - if (XQueryExtension (priv->xdisplay, - "XInputExtension", - &priv->xinput_opcode, - &priv->xinput_error_base, - &priv->xinput_event_base)) - { - int major, minor; - - major = 2; minor = 3; - if (XIQueryVersion (priv->xdisplay, &major, &minor) == Success) - { - int version; - - version = (major * 10) + minor; - if (version >= 22) - has_xi = TRUE; - - if (version >= 23) - priv->have_xinput_23 = TRUE; - } - } - - if (!has_xi) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "X server doesn't have the XInput extension, " - "version 2.2 or newer"); - return FALSE; - } - - return TRUE; -} - -static gboolean -meta_backend_x11_init_basic (MetaBackend *backend, - GError **error) -{ - MetaContext *context = meta_backend_get_context (backend); - MetaBackendX11 *x11 = META_BACKEND_X11 (backend); - 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; - } - - XSynchronize (xdisplay, meta_context_is_x11_sync (context)); - - priv->xdisplay = xdisplay; - priv->xscreen = DefaultScreenOfDisplay (xdisplay); - priv->xcb = XGetXCBConnection (priv->xdisplay); - priv->root_window = DefaultRootWindow (xdisplay); - - init_xkb_state (x11); - - if (!init_xinput (x11, error)) - return FALSE; - - if (priv->have_xinput_23) - priv->barriers = meta_x11_barriers_new (x11); - - return TRUE; -} - -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); - - g_clear_pointer (&priv->barriers, meta_x11_barriers_free); - g_clear_pointer (&priv->xdisplay, XCloseDisplay); -} - -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); - - mtk_x11_errors_deinit (); - - 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->init_basic = meta_backend_x11_init_basic; - backend_class->init_render = meta_backend_x11_init_render; - backend_class->init_post = meta_backend_x11_init_post; - -#ifdef HAVE_LOGIND - backend_class->create_launcher = meta_backend_x11_create_launcher; -#endif - backend_class->create_clutter_backend = meta_backend_x11_create_clutter_backend; - backend_class->create_color_manager = meta_backend_x11_create_color_manager; - backend_class->create_default_seat = meta_backend_x11_create_default_seat; - backend_class->grab_device = meta_backend_x11_grab_device; - backend_class->ungrab_device = meta_backend_x11_ungrab_device; - backend_class->freeze_keyboard = meta_backend_x11_freeze_keyboard; - backend_class->unfreeze_keyboard = meta_backend_x11_unfreeze_keyboard; - backend_class->ungrab_keyboard = meta_backend_x11_ungrab_keyboard; - 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 (); - mtk_x11_errors_init (); -} - -Display * -meta_backend_x11_get_xdisplay (MetaBackendX11 *x11) -{ - MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); - - return priv->xdisplay; -} - -Screen * -meta_backend_x11_get_xscreen (MetaBackendX11 *x11) -{ - MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); - - return priv->xscreen; -} - -Window -meta_backend_x11_get_root_xwindow (MetaBackendX11 *backend_x11) -{ - MetaBackendX11Private *priv = - meta_backend_x11_get_instance_private (backend_x11); - - return priv->root_window; -} - -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 = - meta_seat_x11_get_core_pointer (META_SEAT_X11 (seat)); - ClutterModifierType modifiers; - ClutterEvent *event; - graphene_point_t pos; - - clutter_seat_query_state (seat, NULL, &pos, &modifiers); - - event = clutter_event_motion_new (CLUTTER_EVENT_FLAG_SYNTHETIC, - CLUTTER_CURRENT_TIME, - pointer, - NULL, - modifiers, - pos, - GRAPHENE_POINT_INIT (0, 0), - GRAPHENE_POINT_INIT (0, 0), - GRAPHENE_POINT_INIT (0, 0), - NULL); - - clutter_event_put (event); - clutter_event_free (event); -} - -MetaX11Barriers * -meta_backend_x11_get_barriers (MetaBackendX11 *backend_x11) -{ - MetaBackendX11Private *priv = - meta_backend_x11_get_instance_private (backend_x11); - - return priv->barriers; -} - -void -meta_backend_x11_passive_button_grab (MetaBackendX11 *backend_x11, - Window xwindow, - int button, - MetaPassiveGrabMode grab_mode, - ClutterModifierType modmask) -{ - MetaBackendX11Private *priv = - meta_backend_x11_get_instance_private (backend_x11); - unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; - XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; - XIGrabModifiers mods = { 0, }; - - mtk_x11_error_trap_push (priv->xdisplay); - - XISetMask (mask.mask, XI_ButtonPress); - XISetMask (mask.mask, XI_ButtonRelease); - XISetMask (mask.mask, XI_Motion); - - if (modmask == 0) - mods.modifiers = XIAnyModifier; - else - mods.modifiers = modmask; - - XIGrabButton (priv->xdisplay, - META_VIRTUAL_CORE_POINTER_ID, - button, xwindow, None, - (grab_mode == META_GRAB_MODE_SYNC ? - XIGrabModeSync : - XIGrabModeAsync), - XIGrabModeAsync, False, - &mask, 1, &mods); - - XSync (priv->xdisplay, False); - - mtk_x11_error_trap_pop (priv->xdisplay); -} - -void -meta_backend_x11_passive_button_ungrab (MetaBackendX11 *backend_x11, - Window xwindow, - int button, - ClutterModifierType modmask) -{ - MetaBackendX11Private *priv = - meta_backend_x11_get_instance_private (backend_x11); - XIGrabModifiers mods = { 0, }; - - mtk_x11_error_trap_push (priv->xdisplay); - - if (modmask == 0) - mods.modifiers = XIAnyModifier; - else - mods.modifiers = modmask; - - XIUngrabButton (priv->xdisplay, - META_VIRTUAL_CORE_POINTER_ID, - button, xwindow, - 1, &mods); - - XSync (priv->xdisplay, False); - - mtk_x11_error_trap_pop (priv->xdisplay); -} - -void -meta_backend_x11_passive_key_grab (MetaBackendX11 *backend_x11, - Window xwindow, - int keycode, - MetaPassiveGrabMode grab_mode, - ClutterModifierType modmask) -{ - MetaBackendX11Private *priv = - meta_backend_x11_get_instance_private (backend_x11); - unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; - XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; - XIGrabModifiers mods = { 0, }; - - mtk_x11_error_trap_push (priv->xdisplay); - - XISetMask (mask.mask, XI_KeyPress); - XISetMask (mask.mask, XI_KeyRelease); - - if (modmask == 0) - mods.modifiers = XIAnyModifier; - else - mods.modifiers = modmask; - - XIGrabKeycode (priv->xdisplay, - META_VIRTUAL_CORE_KEYBOARD_ID, - keycode, xwindow, - (grab_mode == META_GRAB_MODE_SYNC ? - XIGrabModeSync : - XIGrabModeAsync), - XIGrabModeAsync, False, - &mask, 1, &mods); - - XSync (priv->xdisplay, False); - - mtk_x11_error_trap_pop (priv->xdisplay); -} - -void -meta_backend_x11_passive_key_ungrab (MetaBackendX11 *backend_x11, - Window xwindow, - int keycode, - ClutterModifierType modmask) -{ - MetaBackendX11Private *priv = - meta_backend_x11_get_instance_private (backend_x11); - unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; - XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; - XIGrabModifiers mods = { 0, }; - - mtk_x11_error_trap_push (priv->xdisplay); - - XISetMask (mask.mask, XI_KeyPress); - XISetMask (mask.mask, XI_KeyRelease); - - if (modmask == 0) - mods.modifiers = XIAnyModifier; - else - mods.modifiers = modmask; - - XIUngrabKeycode (priv->xdisplay, - META_VIRTUAL_CORE_KEYBOARD_ID, - keycode, xwindow, - 1, &mods); - - XSync (priv->xdisplay, False); - - mtk_x11_error_trap_pop (priv->xdisplay); -} - -void -meta_backend_x11_allow_events (MetaBackendX11 *backend_x11, - const ClutterEvent *event, - MetaEventMode event_mode) -{ - MetaBackendX11Private *priv = - meta_backend_x11_get_instance_private (backend_x11); - ClutterInputDevice *device; - int xi_event_mode, device_id; - uint32_t time_ms; - - device = clutter_event_get_device (event); - device_id = meta_input_device_x11_get_device_id (device); - time_ms = clutter_event_get_time (event); - - switch (event_mode) - { - case META_EVENT_MODE_KEEP_FROZEN: - xi_event_mode = XISyncDevice; - meta_topic (META_DEBUG_X11, - "Events kept frozen, time %u device %i", - (unsigned int) time_ms, device_id); - break; - case META_EVENT_MODE_REPLAY: - xi_event_mode = XIReplayDevice; - meta_topic (META_DEBUG_X11, - "Replaying events time %u device %i", - (unsigned int) time_ms, device_id); - break; - case META_EVENT_MODE_THAW: - xi_event_mode = XIAsyncDevice; - meta_topic (META_DEBUG_X11, - "Keeping events grabbed, time %u device %i", - (unsigned int) time_ms, device_id); - break; - default: - g_assert_not_reached (); - return; - } - - XIAllowEvents (priv->xdisplay, device_id, xi_event_mode, time_ms); -} diff --git a/src/backends/x11/meta-backend-x11.h b/src/backends/x11/meta-backend-x11.h deleted file mode 100644 index f42a9d2223b..00000000000 --- a/src/backends/x11/meta-backend-x11.h +++ /dev/null @@ -1,100 +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, see . - * - * Written by: - * Jasper St. Pierre - */ - -#pragma once - -#include -#include -#include -#include - -#include "backends/meta-backend-private.h" -#include "backends/x11/meta-backend-x11-types.h" -#include "backends/x11/meta-clutter-backend-x11.h" - -typedef enum _MetaPassiveGrabMode MetaPassiveGrabMode; - -enum _MetaPassiveGrabMode -{ - META_GRAB_MODE_SYNC, - META_GRAB_MODE_ASYNC, -}; - -#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); - -Screen * meta_backend_x11_get_xscreen (MetaBackendX11 *backend); - -Window meta_backend_x11_get_root_xwindow (MetaBackendX11 *backend_x11); - -Window meta_backend_x11_get_xwindow (MetaBackendX11 *backend); - -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); - -MetaX11Barriers * meta_backend_x11_get_barriers (MetaBackendX11 *backend_x11); - -void meta_backend_x11_reset_cached_logical_monitor (MetaBackendX11 *backend_x11); - -void meta_backend_x11_passive_button_grab (MetaBackendX11 *backend_x11, - Window xwindow, - int button, - MetaPassiveGrabMode grab_mode, - ClutterModifierType modifiers); - -void meta_backend_x11_passive_button_ungrab (MetaBackendX11 *backend_x11, - Window xwindow, - int button, - ClutterModifierType modifiers); - -void meta_backend_x11_passive_key_grab (MetaBackendX11 *backend_x11, - Window xwindow, - int keycode, - MetaPassiveGrabMode grab_mode, - ClutterModifierType modmask); - -void meta_backend_x11_passive_key_ungrab (MetaBackendX11 *backend_x11, - Window xwindow, - int keycode, - ClutterModifierType modmask); - -void meta_backend_x11_allow_events (MetaBackendX11 *backend_x11, - const ClutterEvent *event, - MetaEventMode event_mode); diff --git a/src/backends/x11/meta-backlight-x11.c b/src/backends/x11/meta-backlight-x11.c deleted file mode 100644 index 9a0b08f28be..00000000000 --- a/src/backends/x11/meta-backlight-x11.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2024 Red Hat - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include "config.h" - -#include "backends/x11/meta-backlight-x11.h" - -#include - -#include -#include -#include - -#include "backends/x11/meta-output-xrandr.h" - -struct _MetaBacklightX11 -{ - MetaBacklight parent; - - Display *xdisplay; - RROutput output_id; -}; - -G_DEFINE_FINAL_TYPE (MetaBacklightX11, - meta_backlight_x11, - META_TYPE_BACKLIGHT) - -static void -meta_backlight_x11_update (MetaBacklightX11 *backlight) -{ - Atom atom, actual_type; - int actual_format; - unsigned long nitems, bytes_after; - g_autofree unsigned char *buffer = NULL; - - atom = XInternAtom (backlight->xdisplay, "Backlight", False); - XRRGetOutputProperty (backlight->xdisplay, - (XID) backlight->output_id, - atom, - 0, G_MAXLONG, False, False, XA_INTEGER, - &actual_type, &actual_format, - &nitems, &bytes_after, &buffer); - - if (actual_type != XA_INTEGER || actual_format != 32 || nitems < 1) - { - g_warning ("Backlight %s: Bad XRandr `Backlight` property format", - meta_backlight_get_name (META_BACKLIGHT (backlight))); - return; - } - - meta_backlight_update_brightness_target (META_BACKLIGHT (backlight), - ((int *) buffer)[0]); -} - -static void -meta_backlight_x11_set_brightness (MetaBacklight *backlight, - int brightness_target, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - MetaBacklightX11 *backlight_x11 = META_BACKLIGHT_X11 (backlight); - g_autoptr (GTask) task = NULL; - Atom atom; - - task = g_task_new (backlight_x11, cancellable, callback, user_data); - g_task_set_task_data (task, GINT_TO_POINTER (brightness_target), NULL); - - atom = XInternAtom (backlight_x11->xdisplay, "Backlight", False); - - xcb_randr_change_output_property (XGetXCBConnection (backlight_x11->xdisplay), - (XID) backlight_x11->output_id, - atom, XCB_ATOM_INTEGER, 32, - XCB_PROP_MODE_REPLACE, - 1, &brightness_target); - - g_task_return_int (task, brightness_target); -} - -static int -meta_backlight_x11_set_brightness_finish (MetaBacklight *backlight, - GAsyncResult *result, - GError **error) -{ - g_return_val_if_fail (g_task_is_valid (result, backlight), -1); - - return g_task_propagate_int (G_TASK (result), error); -} - -static void -meta_backlight_x11_class_init (MetaBacklightX11Class *klass) -{ - MetaBacklightClass *backlight_class = META_BACKLIGHT_CLASS (klass); - - backlight_class->set_brightness = meta_backlight_x11_set_brightness; - backlight_class->set_brightness_finish = meta_backlight_x11_set_brightness_finish; -} - -static void -meta_backlight_x11_init (MetaBacklightX11 *backlight) -{ -} - -static gboolean -get_backlight_info (Display *xdisplay, - RROutput output_id, - int *brightness_min_out, - int *brightness_max_out, - GError **error) -{ - 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; - int32_t *values; - - 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) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "No backlight found"); - return FALSE; - } - - if (!reply->range || reply->length != 2) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Backlight is not in range"); - return FALSE; - } - - values = xcb_randr_query_output_property_valid_values (reply); - - if (brightness_min_out) - *brightness_min_out = values[0]; - if (brightness_max_out) - *brightness_max_out = values[1]; - - return TRUE; -} - -MetaBacklightX11 * -meta_backlight_x11_new (MetaBackend *backend, - Display *xdisplay, - RROutput output_id, - const MetaOutputInfo *output_info, - GError **error) -{ - g_autoptr (MetaBacklightX11) backlight = NULL; - int min, max; - - /* we currently only support backlights for built-in panels */ - if (!meta_output_info_is_builtin (output_info)) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "External displays are not supported"); - return NULL; - } - - if (!get_backlight_info (xdisplay, output_id, &min, &max, error)) - return NULL; - - backlight = g_object_new (META_TYPE_BACKLIGHT_X11, - "backend", backend, - "name", output_info->name, - "brightness-min", min, - "brightness-max", max, - NULL); - backlight->xdisplay = xdisplay; - backlight->output_id = output_id; - - meta_backlight_x11_update (backlight); - - return g_steal_pointer (&backlight); -} diff --git a/src/backends/x11/meta-backlight-x11.h b/src/backends/x11/meta-backlight-x11.h deleted file mode 100644 index 13ea27aaea3..00000000000 --- a/src/backends/x11/meta-backlight-x11.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2024 Red Hat - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#pragma once - -#include - -#include "backends/meta-backend-types.h" -#include "backends/meta-backlight-private.h" -#include "backends/meta-output.h" - -#include - -#define META_TYPE_BACKLIGHT_X11 (meta_backlight_x11_get_type ()) -G_DECLARE_FINAL_TYPE (MetaBacklightX11, - meta_backlight_x11, - META, BACKLIGHT_X11, - MetaBacklight) - -MetaBacklightX11 * meta_backlight_x11_new (MetaBackend *backend, - Display *xdisplay, - RROutput output_id, - const MetaOutputInfo *output_info, - GError **error); diff --git a/src/backends/x11/meta-barrier-x11.c b/src/backends/x11/meta-barrier-x11.c deleted file mode 100644 index a4967d9e86c..00000000000 --- a/src/backends/x11/meta-barrier-x11.c +++ /dev/null @@ -1,234 +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, see . - * - * Written by: - * Jasper St. Pierre - * Jonas Ă…dahl - */ - -/** - * MetaBarrierImplX11: - * - * Pointer barriers implementation for X11 - */ - -#include "config.h" - -#include -#include -#include - -#include "backends/x11/meta-backend-x11.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 _MetaX11Barriers -{ - GHashTable *barriers; -}; - -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); - MetaBackend *backend = meta_barrier_get_backend (self->barrier); - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); - Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11); - - if (!event) - { - g_warning ("X11 barriers always need barrier events to release"); - return; - } - - XIBarrierReleasePointer (xdisplay, - 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); - MetaBackend *backend = meta_barrier_get_backend (self->barrier); - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); - MetaX11Barriers *barriers = meta_backend_x11_get_barriers (backend_x11); - Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11); - - if (!meta_barrier_is_active (self->barrier)) - return; - - XFixesDestroyPointerBarrier (xdisplay, self->xbarrier); - g_hash_table_remove (barriers->barriers, &self->xbarrier); - self->xbarrier = 0; -} - -MetaBarrierImpl * -meta_barrier_impl_x11_new (MetaBarrier *barrier) -{ - MetaBarrierImplX11 *self; - MetaBackend *backend; - MetaBackendX11 *backend_x11; - MetaX11Barriers *barriers; - Display *xdisplay; - Window root; - MetaBorder *border; - unsigned int allowed_motion_dirs; - - self = g_object_new (META_TYPE_BARRIER_IMPL_X11, NULL); - self->barrier = barrier; - - backend = meta_barrier_get_backend (self->barrier); - backend_x11 = META_BACKEND_X11 (backend); - xdisplay = meta_backend_x11_get_xdisplay (backend_x11); - root = DefaultRootWindow (xdisplay); - - border = meta_barrier_get_border (barrier); - allowed_motion_dirs = meta_border_get_allows_directions (border); - self->xbarrier = XFixesCreatePointerBarrier (xdisplay, root, - (int) border->line.a.x, - (int) border->line.a.y, - (int) border->line.b.x, - (int) border->line.b.y, - allowed_motion_dirs, - 0, NULL); - - barriers = meta_backend_x11_get_barriers (backend_x11); - g_hash_table_insert (barriers->barriers, &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_barriers_process_xevent (MetaX11Barriers *barriers, - XIEvent *event) -{ - MetaBarrier *barrier; - XIBarrierEvent *xev; - - switch (event->evtype) - { - case XI_BarrierHit: - case XI_BarrierLeave: - break; - default: - return FALSE; - } - - xev = (XIBarrierEvent *) event; - barrier = g_hash_table_lookup (barriers->barriers, &xev->barrier); - if (barrier) - { - 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) -{ -} - -MetaX11Barriers * -meta_x11_barriers_new (MetaBackendX11 *backend_x11) -{ - MetaX11Barriers *x11_barriers; - - x11_barriers = g_new0 (MetaX11Barriers, 1); - x11_barriers->barriers = g_hash_table_new (meta_unsigned_long_hash, - meta_unsigned_long_equal); - - return x11_barriers; -} - -void -meta_x11_barriers_free (MetaX11Barriers *x11_barriers) -{ - g_assert (g_hash_table_size (x11_barriers->barriers) == 0); - g_hash_table_unref (x11_barriers->barriers); - g_free (x11_barriers); -} diff --git a/src/backends/x11/meta-barrier-x11.h b/src/backends/x11/meta-barrier-x11.h deleted file mode 100644 index 3dc827eaaae..00000000000 --- a/src/backends/x11/meta-barrier-x11.h +++ /dev/null @@ -1,45 +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, see . - * - * Written by: - * Jonas Ă…dahl - */ - -#pragma once - -#include "backends/meta-barrier-private.h" -#include "backends/x11/meta-backend-x11-types.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); - -MetaX11Barriers * meta_x11_barriers_new (MetaBackendX11 *backend_x11); - -void meta_x11_barriers_free (MetaX11Barriers *x11_barriers); - -gboolean meta_x11_barriers_process_xevent (MetaX11Barriers *barriers, - XIEvent *event); - -G_END_DECLS 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 fd5e6a69659..00000000000 --- a/src/backends/x11/meta-clutter-backend-x11.c +++ /dev/null @@ -1,372 +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 . - * - * Written by: - * Jonas Ă…dahl - */ - -#include "config.h" - -#include -#include - -#include "backends/meta-backend-private.h" -#include "backends/meta-renderer.h" -#include "backends/x11/meta-backend-x11.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-sprite-x11.h" -#include "backends/x11/meta-xkb-a11y-x11.h" -#include "backends/x11/nested/meta-sprite-x11-nested.h" -#include "backends/x11/nested/meta-stage-x11-nested.h" -#include "clutter/clutter-mutter.h" -#include "clutter/clutter.h" -#include "cogl/cogl-xlib-renderer.h" -#include "core/bell.h" -#include "meta/meta-backend.h" - -typedef struct _MetaClutterBackendX11Private -{ - MetaBackend *backend; - ClutterSprite *virtual_core_pointer; - ClutterKeyFocus *virtual_core_keyboard; - GHashTable *touch_sprites; -} MetaClutterBackendX11Private; - -G_DEFINE_TYPE_WITH_PRIVATE (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) - -static CoglRenderer * -meta_clutter_backend_x11_get_renderer (ClutterBackend *clutter_backend, - GError **error) -{ - MetaClutterBackendX11 *clutter_backend_x11 = - META_CLUTTER_BACKEND_X11 (clutter_backend); - MetaClutterBackendX11Private *priv = - meta_clutter_backend_x11_get_instance_private (clutter_backend_x11); - MetaRenderer *renderer = meta_backend_get_renderer (priv->backend); - - return meta_renderer_create_cogl_renderer (renderer); -} - -static ClutterStageWindow * -meta_clutter_backend_x11_create_stage (ClutterBackend *clutter_backend, - ClutterStage *wrapper, - GError **error) -{ - MetaClutterBackendX11 *clutter_backend_x11 = - META_CLUTTER_BACKEND_X11 (clutter_backend); - MetaClutterBackendX11Private *priv = - meta_clutter_backend_x11_get_instance_private (clutter_backend_x11); - 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", priv->backend, - "wrapper", wrapper, - NULL); - return stage; -} - -static ClutterSeat * -meta_clutter_backend_x11_get_default_seat (ClutterBackend *clutter_backend) -{ - MetaClutterBackendX11 *clutter_backend_x11 = - META_CLUTTER_BACKEND_X11 (clutter_backend); - MetaClutterBackendX11Private *priv = - meta_clutter_backend_x11_get_instance_private (clutter_backend_x11); - - return meta_backend_get_default_seat (priv->backend); -} - -static gboolean -meta_clutter_backend_x11_is_display_server (ClutterBackend *clutter_backend) -{ - return meta_is_wayland_compositor (); -} - -static ClutterSprite * -lookup_sprite (ClutterBackend *clutter_backend, - ClutterStage *stage, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - gboolean create) -{ - MetaClutterBackendX11 *clutter_backend_x11 = - META_CLUTTER_BACKEND_X11 (clutter_backend); - MetaClutterBackendX11Private *priv = - meta_clutter_backend_x11_get_instance_private (clutter_backend_x11); - ClutterInputDeviceType device_type; - GType sprite_type; - - if (meta_is_wayland_compositor ()) - sprite_type = META_TYPE_SPRITE_X11_NESTED; - else - sprite_type = META_TYPE_SPRITE_X11; - - device_type = clutter_input_device_get_device_type (device); - - if (sequence) - { - ClutterSprite *touch_sprite; - - touch_sprite = g_hash_table_lookup (priv->touch_sprites, sequence); - - if (!touch_sprite && create) - { - touch_sprite = - g_object_new (sprite_type, - "backend", priv->backend, - "stage", stage, - "device", device, - "sequence", sequence, - NULL); - - g_hash_table_insert (priv->touch_sprites, sequence, touch_sprite); - } - - return touch_sprite; - } - - if (device_type == CLUTTER_POINTER_DEVICE || - device_type == CLUTTER_TOUCHPAD_DEVICE || - device_type == CLUTTER_TOUCHSCREEN_DEVICE || - device_type == CLUTTER_TABLET_DEVICE || - device_type == CLUTTER_PEN_DEVICE || - device_type == CLUTTER_ERASER_DEVICE) - { - if (!priv->virtual_core_pointer && create) - { - priv->virtual_core_pointer = - g_object_new (sprite_type, - "backend", priv->backend, - "stage", stage, - "device", device, - "sequence", sequence, - NULL); - } - return priv->virtual_core_pointer; - } - - return NULL; -} - -static ClutterSprite * -meta_clutter_backend_x11_get_sprite (ClutterBackend *clutter_backend, - ClutterStage *stage, - const ClutterEvent *for_event) -{ - ClutterInputDevice *source_device; - ClutterEventSequence *sequence; - - sequence = clutter_event_get_event_sequence (for_event); - if (sequence && - (clutter_event_get_flags (for_event) & CLUTTER_EVENT_FLAG_POINTER_EMULATED) == 0) - return NULL; - - source_device = clutter_event_get_source_device (for_event); - - return lookup_sprite (clutter_backend, stage, - source_device, sequence, TRUE); -} - -static ClutterSprite * -meta_clutter_backend_x11_lookup_sprite (ClutterBackend *clutter_backend, - ClutterStage *stage, - ClutterInputDevice *device, - ClutterEventSequence *sequence) -{ - return lookup_sprite (clutter_backend, stage, device, sequence, FALSE); -} - -static ClutterSprite * -meta_clutter_backend_x11_get_pointer_sprite (ClutterBackend *clutter_backend, - ClutterStage *stage) -{ - ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); - - return lookup_sprite (clutter_backend, stage, - clutter_seat_get_pointer (seat), - NULL, TRUE); -} - -static void -meta_clutter_backend_x11_destroy_sprite (ClutterBackend *clutter_backend, - ClutterSprite *sprite) -{ - MetaClutterBackendX11 *clutter_backend_x11 = - META_CLUTTER_BACKEND_X11 (clutter_backend); - MetaClutterBackendX11Private *priv = - meta_clutter_backend_x11_get_instance_private (clutter_backend_x11); - - if (sprite == priv->virtual_core_pointer) - g_clear_object (&priv->virtual_core_pointer); - - g_hash_table_remove (priv->touch_sprites, - clutter_sprite_get_sequence (sprite)); -} - -static gboolean -meta_clutter_backend_x11_foreach_sprite (ClutterBackend *clutter_backend, - ClutterStage *stage, - ClutterStageInputForeachFunc func, - gpointer user_data) -{ - MetaClutterBackendX11 *clutter_backend_x11 = - META_CLUTTER_BACKEND_X11 (clutter_backend); - MetaClutterBackendX11Private *priv = - meta_clutter_backend_x11_get_instance_private (clutter_backend_x11); - ClutterSprite *touch_sprite; - GHashTableIter iter; - - if (priv->virtual_core_pointer && - !func (stage, priv->virtual_core_pointer, user_data)) - return FALSE; - - g_hash_table_iter_init (&iter, priv->touch_sprites); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &touch_sprite)) - { - if (!func (stage, touch_sprite, user_data)) - return FALSE; - } - - return TRUE; -} - -static ClutterKeyFocus * -meta_clutter_backend_x11_get_key_focus (ClutterBackend *clutter_backend, - ClutterStage *stage) -{ - MetaClutterBackendX11 *clutter_backend_x11 = - META_CLUTTER_BACKEND_X11 (clutter_backend); - MetaClutterBackendX11Private *priv = - meta_clutter_backend_x11_get_instance_private (clutter_backend_x11); - - if (!priv->virtual_core_keyboard) - { - priv->virtual_core_keyboard = - g_object_new (CLUTTER_TYPE_KEY_FOCUS, - "stage", stage, - NULL); - } - - return priv->virtual_core_keyboard; -} - -static void -meta_clutter_backend_x11_finalize (GObject *object) -{ - MetaClutterBackendX11 *clutter_backend_x11 = - META_CLUTTER_BACKEND_X11 (object); - MetaClutterBackendX11Private *priv = - meta_clutter_backend_x11_get_instance_private (clutter_backend_x11); - - g_clear_pointer (&priv->touch_sprites, g_hash_table_unref); - - G_OBJECT_CLASS (meta_clutter_backend_x11_parent_class)->finalize (object); -} - -static void -meta_clutter_backend_x11_init (MetaClutterBackendX11 *clutter_backend_x11) -{ - MetaClutterBackendX11Private *priv = - meta_clutter_backend_x11_get_instance_private (clutter_backend_x11); - - priv->touch_sprites = - g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_object_unref); -} - -static void -meta_clutter_backend_x11_class_init (MetaClutterBackendX11Class *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - ClutterBackendClass *clutter_backend_class = CLUTTER_BACKEND_CLASS (klass); - - object_class->finalize = meta_clutter_backend_x11_finalize; - - 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->get_default_seat = meta_clutter_backend_x11_get_default_seat; - clutter_backend_class->is_display_server = meta_clutter_backend_x11_is_display_server; - clutter_backend_class->get_sprite = meta_clutter_backend_x11_get_sprite; - clutter_backend_class->lookup_sprite = meta_clutter_backend_x11_lookup_sprite; - clutter_backend_class->get_pointer_sprite = meta_clutter_backend_x11_get_pointer_sprite; - clutter_backend_class->destroy_sprite = meta_clutter_backend_x11_destroy_sprite; - clutter_backend_class->foreach_sprite = meta_clutter_backend_x11_foreach_sprite; - clutter_backend_class->get_key_focus = meta_clutter_backend_x11_get_key_focus; -} - -MetaClutterBackendX11 * -meta_clutter_backend_x11_new (MetaBackend *backend, - ClutterContext *context) -{ - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); - Atom atoms[N_ATOM_NAMES]; - MetaClutterBackendX11 *clutter_backend_x11; - MetaClutterBackendX11Private *priv; - - clutter_backend_x11 = g_object_new (META_TYPE_CLUTTER_BACKEND_X11, - "context", context, - NULL); - priv = meta_clutter_backend_x11_get_instance_private (clutter_backend_x11); - priv->backend = backend; - - clutter_backend_x11->xdisplay = meta_backend_x11_get_xdisplay (backend_x11); - - XInternAtoms (clutter_backend_x11->xdisplay, - (char **) atom_names, N_ATOM_NAMES, - False, atoms); - - clutter_backend_x11->atom_NET_WM_PID = atoms[0]; - clutter_backend_x11->atom_NET_WM_PING = atoms[1]; - clutter_backend_x11->atom_NET_WM_STATE = atoms[2]; - clutter_backend_x11->atom_NET_WM_USER_TIME = atoms[3]; - clutter_backend_x11->atom_WM_PROTOCOLS = atoms[4]; - clutter_backend_x11->atom_WM_DELETE_WINDOW = atoms[5]; - clutter_backend_x11->atom_XEMBED = atoms[6]; - clutter_backend_x11->atom_XEMBED_INFO = atoms[7]; - clutter_backend_x11->atom_NET_WM_NAME = atoms[8]; - clutter_backend_x11->atom_UTF8_STRING = atoms[9]; - - return clutter_backend_x11; -} 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 982372cd271..00000000000 --- a/src/backends/x11/meta-clutter-backend-x11.h +++ /dev/null @@ -1,60 +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 . - * - * Written by: - * Jonas Ă…dahl - */ - -#pragma once - -#include - -#include "backends/meta-backend-types.h" -#include "clutter/clutter-mutter.h" - -struct _MetaClutterBackendX11 -{ - ClutterBackend parent_instance; - - Display *xdisplay; - - /* 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) - -MetaClutterBackendX11 * meta_clutter_backend_x11_new (MetaBackend *backend, - ClutterContext *context); diff --git a/src/backends/x11/meta-color-manager-x11.c b/src/backends/x11/meta-color-manager-x11.c deleted file mode 100644 index 4732a4d80e6..00000000000 --- a/src/backends/x11/meta-color-manager-x11.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2007 William Jon McCann - * Copyright (C) 2011-2013 Richard Hughes - * Copyright (C) 2020 NVIDIA CORPORATION - * 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 . - */ - -#include "config.h" - -#include "backends/x11/meta-color-manager-x11.h" - -#include -#include - -#include "backends/meta-color-device.h" -#include "backends/meta-color-profile.h" -#include "backends/meta-monitor-private.h" -#include "backends/x11/meta-backend-x11.h" -#include "backends/x11/meta-output-xrandr.h" - -struct _MetaColorManagerX11 -{ - MetaColorManager parent; -}; - -G_DEFINE_TYPE (MetaColorManagerX11, meta_color_manager_x11, - META_TYPE_COLOR_MANAGER) - -/* see http://www.oyranos.org/wiki/index.php?title=ICC_Profiles_in_X_Specification_0.3 */ -#define ICC_PROFILE_IN_X_VERSION_MAJOR 0 -#define ICC_PROFILE_IN_X_VERSION_MINOR 3 - -static void -update_root_window_atom (MetaColorManager *color_manager, - MetaColorDevice *color_device) -{ - MetaBackend *backend = meta_color_manager_get_backend (color_manager); - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); - Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11); - Window xroot = meta_backend_x11_get_root_xwindow (backend_x11); - Atom icc_profile_atom; - Atom icc_profile_version_atom; - MetaMonitor *monitor; - MetaColorProfile *color_profile; - const uint8_t *profile_contents = NULL; - size_t profile_size; - - monitor = meta_color_device_get_monitor (color_device); - if (!meta_monitor_is_primary (monitor)) - return; - - color_profile = meta_color_device_get_assigned_profile (color_device); - if (color_profile) - { - profile_contents = meta_color_profile_get_data (color_profile); - profile_size = meta_color_profile_get_data_size (color_profile); - } - - icc_profile_atom = XInternAtom (xdisplay, "_ICC_PROFILE", False); - icc_profile_version_atom = XInternAtom (xdisplay, - "_ICC_PROFILE_IN_X_VERSION", False); - if (profile_contents) - { - unsigned int version_data; - - XChangeProperty (xdisplay, xroot, - icc_profile_atom, - XA_CARDINAL, 8, - PropModeReplace, - profile_contents, profile_size); - - version_data = - ICC_PROFILE_IN_X_VERSION_MAJOR * 100 + - ICC_PROFILE_IN_X_VERSION_MINOR * 1; - - XChangeProperty (xdisplay, xroot, - icc_profile_version_atom, - XA_CARDINAL, 8, - PropModeReplace, - (uint8_t *) &version_data, 1); - } - else - { - XDeleteProperty (xdisplay, xroot, icc_profile_atom); - XDeleteProperty (xdisplay, xroot, icc_profile_version_atom); - } -} - -static uint64_t -double_to_ctmval (double value) -{ - uint64_t sign = value < 0; - double integer, fractional; - - if (sign) - value = -value; - - fractional = modf (value, &integer); - - return - sign << 63 | - (uint64_t) integer << 32 | - (uint64_t) (fractional * 0xffffffffUL); -} - -static MetaOutputCtm -mat33_to_ctm (const CdMat3x3 *matrix) -{ - MetaOutputCtm ctm; - - /* - * libcolord generates a matrix containing double values. RandR's CTM - * property expects values in S31.32 fixed-point sign-magnitude format - */ - ctm.matrix[0] = double_to_ctmval (matrix->m00); - ctm.matrix[1] = double_to_ctmval (matrix->m01); - ctm.matrix[2] = double_to_ctmval (matrix->m02); - ctm.matrix[3] = double_to_ctmval (matrix->m10); - ctm.matrix[4] = double_to_ctmval (matrix->m11); - ctm.matrix[5] = double_to_ctmval (matrix->m12); - ctm.matrix[6] = double_to_ctmval (matrix->m20); - ctm.matrix[7] = double_to_ctmval (matrix->m21); - ctm.matrix[8] = double_to_ctmval (matrix->m22); - - return ctm; -} - -static void -update_device_ctm (MetaColorDevice *color_device) -{ - MetaMonitor *monitor; - MetaColorProfile *color_profile; - const MetaColorCalibration *color_calibration; - MetaOutputCtm ctm; - MetaOutput *output; - MetaOutputXrandr *output_xrandr; - - monitor = meta_color_device_get_monitor (color_device); - if (!meta_monitor_supports_color_transform (monitor)) - return; - - color_profile = meta_color_device_get_assigned_profile (color_device); - if (!color_profile) - return; - - color_calibration = meta_color_profile_get_calibration (color_profile); - - if (!color_calibration->has_adaptation_matrix) - return; - - ctm = mat33_to_ctm (&color_calibration->adaptation_matrix); - - output = meta_monitor_get_main_output (monitor); - output_xrandr = META_OUTPUT_XRANDR (output); - meta_output_xrandr_set_ctm (output_xrandr, &ctm); -} - -static void -on_color_device_calibration_changed (MetaColorManager *color_manager, - MetaColorDevice *color_device) -{ - update_root_window_atom (color_manager, color_device); - update_device_ctm (color_device); -} - -static void -meta_color_manager_x11_constructed (GObject *object) -{ - MetaColorManager *color_manager = META_COLOR_MANAGER (object); - - g_signal_connect (color_manager, "device-calibration-changed", - G_CALLBACK (on_color_device_calibration_changed), NULL); - - G_OBJECT_CLASS (meta_color_manager_x11_parent_class)->constructed (object); -} - -static void -meta_color_manager_x11_class_init (MetaColorManagerX11Class *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->constructed = meta_color_manager_x11_constructed; -} - -static void -meta_color_manager_x11_init (MetaColorManagerX11 *color_manager_x11) -{ -} diff --git a/src/backends/x11/meta-color-manager-x11.h b/src/backends/x11/meta-color-manager-x11.h deleted file mode 100644 index a0b911dbb07..00000000000 --- a/src/backends/x11/meta-color-manager-x11.h +++ /dev/null @@ -1,27 +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 . - */ - -#pragma once - -#include - -#include "backends/meta-color-manager-private.h" - -#define META_TYPE_COLOR_MANAGER_X11 (meta_color_manager_x11_get_type ()) -G_DECLARE_FINAL_TYPE (MetaColorManagerX11, meta_color_manager_x11, - META, COLOR_MANAGER_X11, - MetaColorManager) diff --git a/src/backends/x11/meta-crtc-xrandr.c b/src/backends/x11/meta-crtc-xrandr.c deleted file mode 100644 index 985a09b4de0..00000000000 --- a/src/backends/x11/meta-crtc-xrandr.c +++ /dev/null @@ -1,377 +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, see . - */ - -#include "config.h" - -#include "backends/x11/meta-crtc-xrandr.h" - -#include -#include -#include - -#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; - - MtkRectangle rect; - MtkMonitorTransform 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 MtkMonitorTransform -mtk_monitor_transform_from_xrandr (Rotation rotation) -{ - static const MtkMonitorTransform y_reflected_map[4] = { - MTK_MONITOR_TRANSFORM_FLIPPED_180, - MTK_MONITOR_TRANSFORM_FLIPPED_90, - MTK_MONITOR_TRANSFORM_FLIPPED, - MTK_MONITOR_TRANSFORM_FLIPPED_270 - }; - MtkMonitorTransform ret; - - switch (rotation & 0x7F) - { - default: - case RR_Rotate_0: - ret = MTK_MONITOR_TRANSFORM_NORMAL; - break; - case RR_Rotate_90: - ret = MTK_MONITOR_TRANSFORM_90; - break; - case RR_Rotate_180: - ret = MTK_MONITOR_TRANSFORM_180; - break; - case RR_Rotate_270: - ret = MTK_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 MtkMonitorTransform -mtk_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 << MTK_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 MTK_MONITOR_ALL_TRANSFORMS; - - ret = 1 << MTK_MONITOR_TRANSFORM_NORMAL; - if (rotation & RR_Rotate_90) - ret |= 1 << MTK_MONITOR_TRANSFORM_90; - if (rotation & RR_Rotate_180) - ret |= 1 << MTK_MONITOR_TRANSFORM_180; - if (rotation & RR_Rotate_270) - ret |= 1 << MTK_MONITOR_TRANSFORM_270; - if (rotation & (RR_Rotate_0 | RR_Reflect_X)) - ret |= 1 << MTK_MONITOR_TRANSFORM_FLIPPED; - if (rotation & (RR_Rotate_90 | RR_Reflect_X)) - ret |= 1 << MTK_MONITOR_TRANSFORM_FLIPPED_90; - if (rotation & (RR_Rotate_180 | RR_Reflect_X)) - ret |= 1 << MTK_MONITOR_TRANSFORM_FLIPPED_180; - if (rotation & (RR_Rotate_270 | RR_Reflect_X)) - ret |= 1 << MTK_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); - MtkMonitorTransform all_transforms; - MetaCrtcXrandr *crtc_xrandr; - XRRPanning *panning; - unsigned int i; - GList *modes; - - all_transforms = - mtk_monitor_transform_from_xrandr_all (xrandr_crtc->rotations); - crtc_xrandr = g_object_new (META_TYPE_CRTC_XRANDR, - "id", (uint64_t) crtc_id, - "backend", backend, - "gpu", gpu, - "all-transforms", all_transforms, - NULL); - - crtc_xrandr->transform = - mtk_monitor_transform_from_xrandr (xrandr_crtc->rotation); - - panning = XRRGetPanning (xdisplay, resources, crtc_id); - if (panning && panning->width > 0 && panning->height > 0) - { - crtc_xrandr->rect = (MtkRectangle) { - .x = panning->left, - .y = panning->top, - .width = panning->width, - .height = panning->height, - }; - } - else - { - crtc_xrandr->rect = (MtkRectangle) { - .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) - { - MetaCrtcConfig *crtc_config; - - crtc_config = - meta_crtc_config_new (&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); - meta_crtc_set_config (META_CRTC (crtc_xrandr), crtc_config, NULL); - } - - return crtc_xrandr; -} - -static MetaGammaLut * -meta_crtc_xrandr_get_gamma_lut (MetaCrtc *crtc) -{ - MetaGpu *gpu = meta_crtc_get_gpu (crtc); - MetaBackend *backend = meta_gpu_get_backend (gpu); - Display *xdisplay = - meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); - XRRCrtcGamma *gamma; - MetaGammaLut *lut; - - gamma = XRRGetCrtcGamma (xdisplay, (XID) meta_crtc_get_id (crtc)); - - lut = g_new0 (MetaGammaLut, 1); - lut->size = gamma->size; - lut->red = g_memdup2 (gamma->red, sizeof (unsigned short) * gamma->size); - lut->green = g_memdup2 (gamma->green, sizeof (unsigned short) * gamma->size); - lut->blue = g_memdup2 (gamma->blue, sizeof (unsigned short) * gamma->size); - - XRRFreeGamma (gamma); - - return lut; -} - -static size_t -meta_crtc_xrandr_get_gamma_lut_size (MetaCrtc *crtc) -{ - MetaGpu *gpu = meta_crtc_get_gpu (crtc); - MetaBackend *backend = meta_gpu_get_backend (gpu); - Display *xdisplay = - meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); - XRRCrtcGamma *gamma; - size_t size; - - gamma = XRRGetCrtcGamma (xdisplay, (XID) meta_crtc_get_id (crtc)); - - size = gamma->size; - - XRRFreeGamma (gamma); - - return size; -} - -static void -meta_crtc_xrandr_set_gamma_lut (MetaCrtc *crtc, - const MetaGammaLut *lut) -{ - MetaGpu *gpu = meta_crtc_get_gpu (crtc); - MetaBackend *backend = meta_gpu_get_backend (gpu); - Display *xdisplay = - meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); - XRRCrtcGamma *gamma; - - gamma = XRRAllocGamma (lut->size); - memcpy (gamma->red, lut->red, sizeof (uint16_t) * lut->size); - memcpy (gamma->green, lut->green, sizeof (uint16_t) * lut->size); - memcpy (gamma->blue, lut->blue, sizeof (uint16_t) * lut->size); - - XRRSetCrtcGamma (xdisplay, (XID) meta_crtc_get_id (crtc), gamma); - - XRRFreeGamma (gamma); -} - -static void -meta_crtc_xrandr_init (MetaCrtcXrandr *crtc_xrandr) -{ -} - -static void -meta_crtc_xrandr_class_init (MetaCrtcXrandrClass *klass) -{ - MetaCrtcClass *crtc_class = META_CRTC_CLASS (klass); - - crtc_class->get_gamma_lut_size = meta_crtc_xrandr_get_gamma_lut_size; - crtc_class->get_gamma_lut = meta_crtc_xrandr_get_gamma_lut; - crtc_class->set_gamma_lut = meta_crtc_xrandr_set_gamma_lut; -} diff --git a/src/backends/x11/meta-crtc-xrandr.h b/src/backends/x11/meta-crtc-xrandr.h deleted file mode 100644 index f490a16825f..00000000000 --- a/src/backends/x11/meta-crtc-xrandr.h +++ /dev/null @@ -1,52 +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, see . - */ - -#pragma once - -#include -#include - -#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); 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 b941fb9d6d3..00000000000 --- a/src/backends/x11/meta-cursor-renderer-x11.c +++ /dev/null @@ -1,157 +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, see . - * - * Written by: - * Jasper St. Pierre - */ - -#include "config.h" - -#include "backends/x11/meta-cursor-renderer-x11.h" - -#include - -#include "backends/meta-cursor-sprite-xcursor.h" -#include "backends/meta-stage-private.h" -#include "backends/x11/meta-backend-x11.h" - -struct _MetaCursorRendererX11 -{ - MetaCursorRenderer parent_instance; - - gboolean server_cursor_visible; -}; - -G_DEFINE_FINAL_TYPE (MetaCursorRendererX11, meta_cursor_renderer_x11, META_TYPE_CURSOR_RENDERER); - - -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 Cursor -create_x_cursor (Display *xdisplay, - MetaCursor cursor) -{ - Cursor result; - - if (cursor == META_CURSOR_NONE) - return create_blank_cursor (xdisplay); - - result = XcursorLibraryLoadCursor (xdisplay, meta_cursor_get_name (cursor)); - if (!result) - result = XcursorLibraryLoadCursor (xdisplay, meta_cursor_get_legacy_name (cursor)); - - return result; -} - -static gboolean -meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer, - MetaCursorSprite *cursor_sprite) -{ - MetaCursorRendererX11 *x11 = META_CURSOR_RENDERER_X11 (renderer); - MetaBackend *backend = meta_cursor_renderer_get_backend (renderer); - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); - Window xwindow = meta_backend_x11_get_xwindow (backend_x11); - Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11); - - if (xwindow == None) - { - if (cursor_sprite) - meta_cursor_sprite_realize_texture (cursor_sprite); - return TRUE; - } - - 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_INVALID) - { - Cursor xcursor; - - xcursor = create_x_cursor (xdisplay, cursor); - if (xcursor) - { - XDefineCursor (xdisplay, xwindow, xcursor); - XFlush (xdisplay); - XFreeCursor (xdisplay, xcursor); - - has_server_cursor = TRUE; - } - } - } - - if (has_server_cursor != x11->server_cursor_visible) - { - if (has_server_cursor) - XFixesShowCursor (xdisplay, xwindow); - else - XFixesHideCursor (xdisplay, xwindow); - - x11->server_cursor_visible = has_server_cursor; - } - - if (cursor_sprite) - meta_cursor_sprite_realize_texture (cursor_sprite); - - return !x11->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) -{ - /* XFixes has no way to retrieve the current cursor visibility. */ - x11->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 5bb2acf4fef..00000000000 --- a/src/backends/x11/meta-cursor-renderer-x11.h +++ /dev/null @@ -1,34 +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, see . - * - * Written by: - * Jasper St. Pierre - */ - -#pragma once - -#include "backends/meta-cursor-renderer.h" - -#define META_TYPE_CURSOR_RENDERER_X11 (meta_cursor_renderer_x11_get_type ()) - -typedef struct _MetaCursorRendererX11 MetaCursorRendererX11; - -G_DECLARE_FINAL_TYPE (MetaCursorRendererX11, - meta_cursor_renderer_x11, - META, CURSOR_RENDERER_X11, - MetaCursorRenderer) 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 5f84b74f718..00000000000 --- a/src/backends/x11/meta-cursor-tracker-x11.c +++ /dev/null @@ -1,194 +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, see . - * - */ - -#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 "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) -{ - MetaCursorTracker *tracker = META_CURSOR_TRACKER (tracker_x11); - MetaBackend *backend = meta_cursor_tracker_get_backend (tracker); - MetaContext *context = meta_backend_get_context (backend); - MetaDisplay *display = meta_context_get_display (context); - MetaX11Display *x11_display = meta_display_get_x11_display (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) -{ - MetaCursorTracker *tracker = META_CURSOR_TRACKER (tracker_x11); - MetaBackend *backend = meta_cursor_tracker_get_backend (tracker); - MetaContext *context = meta_backend_get_context (backend); - MetaDisplay *display = meta_context_get_display (context); - MetaCursorTracker *cursor_tracker; - g_autoptr (GError) error = NULL; - - if (tracker_x11->xfixes_cursor) - return FALSE; - - cursor_tracker = META_CURSOR_TRACKER (tracker_x11); - tracker_x11->xfixes_cursor = meta_cursor_sprite_xfixes_new (display, - cursor_tracker, - &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 06e0ff780e2..00000000000 --- a/src/backends/x11/meta-cursor-tracker-x11.h +++ /dev/null @@ -1,29 +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, see . - * - */ - -#pragma once - -#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); diff --git a/src/backends/x11/meta-event-x11.c b/src/backends/x11/meta-event-x11.c deleted file mode 100644 index 743bf6f2c36..00000000000 --- a/src/backends/x11/meta-event-x11.c +++ /dev/null @@ -1,99 +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 . - * - * - * - * Authored by: - * Matthew Allum - * Emmanuele Bassi - */ - -#include "config.h" - -#include -#include - -#include "backends/x11/meta-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 "clutter/clutter-mutter.h" -#include "cogl/cogl-xlib-renderer.h" - -/** - * meta_backend_x11_handle_event: - * @backend: backend - * @xevent: pointer to XEvent structure - * - * This function processes a single X event; it can be used to hook - * into external X11 event processing. - */ -void -meta_backend_x11_handle_event (MetaBackend *backend, - XEvent *xevent) -{ - ClutterBackend *clutter_backend; - ClutterEvent *event; - MetaSeatX11 *seat_x11; - MetaStageX11 *stage_x11; - gint spin = 1; - Display *xdisplay; - gboolean allocated_event; - - clutter_backend = meta_backend_get_clutter_backend (backend); - - xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); - - allocated_event = XGetEventData (xdisplay, &xevent->xcookie); - - if (cogl_renderer_handle_event (clutter_backend->cogl_renderer, - xevent) == COGL_FILTER_REMOVE) - goto out; - - stage_x11 = - META_STAGE_X11 (clutter_backend_get_stage_window (clutter_backend)); - meta_stage_x11_handle_event (stage_x11, xevent); - - seat_x11 = META_SEAT_X11 (meta_backend_get_default_seat (backend)); - event = meta_seat_x11_translate_event (seat_x11, xevent); - if (!event) - goto out; - - _clutter_event_push (event, FALSE); - - /* - * 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 (clutter_event_type (event) == CLUTTER_MOTION) - spin += 2; - - while (spin > 0 && (event = clutter_event_get ())) - { - /* forward the event into clutter for emission etc. */ - clutter_stage_handle_event (CLUTTER_STAGE (meta_backend_get_stage (backend)), - event); - meta_backend_update_from_event (backend, event); - clutter_event_free (event); - --spin; - } - -out: - if (allocated_event) - XFreeEventData (xdisplay, &xevent->xcookie); -} diff --git a/src/backends/x11/meta-event-x11.h b/src/backends/x11/meta-event-x11.h deleted file mode 100644 index 0330c6e5ce2..00000000000 --- a/src/backends/x11/meta-event-x11.h +++ /dev/null @@ -1,31 +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 . - * - * - * - * Authored by: - * Matthew Allum - * Emmanuele Bassi - */ - -#pragma once - -#include - -#include "backends/x11/meta-backend-x11.h" - -void meta_backend_x11_handle_event (MetaBackend *backend, - XEvent *xevent); diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c deleted file mode 100644 index cc9cf7028ce..00000000000 --- a/src/backends/x11/meta-gpu-xrandr.c +++ /dev/null @@ -1,297 +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 . - */ - -#include "config.h" - -#include "backends/x11/meta-gpu-xrandr.h" - -#include -#include -#include - -#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 float -calculate_xrandr_refresh_rate (XRRModeInfo *xmode) -{ - float h_total; - float v_total; - - if (xmode->hTotal == 0 || xmode->vTotal == 0) - return 0.0; - - h_total = (float) xmode->hTotal; - v_total = (float) xmode->vTotal; - - if (xmode->modeFlags & RR_DoubleScan) - v_total *= 2.0f; - - if (xmode->modeFlags & RR_Interlace) - v_total /= 2.0f; - - return xmode->dotClock / (h_total * v_total); -} - -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 = calculate_xrandr_refresh_rate (xmode); - 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 87c6d3cf846..00000000000 --- a/src/backends/x11/meta-gpu-xrandr.h +++ /dev/null @@ -1,37 +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, see . - */ - -#pragma once - -#include -#include - -#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); 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 564df4913a7..00000000000 --- a/src/backends/x11/meta-input-device-tool-x11.c +++ /dev/null @@ -1,61 +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 . - * - * Author: Carlos Garnacho - */ - -#include "config.h" - -#include "meta-input-device-tool-x11.h" - -struct _MetaInputDeviceToolX11 -{ - ClutterInputDeviceTool parent_instance; -}; - -G_DEFINE_FINAL_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 12dc935cd8d..00000000000 --- a/src/backends/x11/meta-input-device-tool-x11.h +++ /dev/null @@ -1,34 +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 . - * - * Author: Carlos Garnacho - */ - -#pragma once - -#include "clutter/clutter.h" - -#define META_TYPE_INPUT_DEVICE_TOOL_X11 (meta_input_device_tool_x11_get_type ()) - -G_DECLARE_FINAL_TYPE (MetaInputDeviceToolX11, - meta_input_device_tool_x11, - META, INPUT_DEVICE_TOOL_X11, - ClutterInputDeviceTool) - -typedef struct _MetaInputDeviceToolX11 MetaInputDeviceToolX11; - -ClutterInputDeviceTool * meta_input_device_tool_x11_new (guint serial, - ClutterInputDeviceToolType type); 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 5f3b9ec924d..00000000000 --- a/src/backends/x11/meta-input-device-x11.c +++ /dev/null @@ -1,810 +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 . - * - * Author: Emmanuele Bassi - */ - -#include "config.h" - -#include - -#include "clutter/clutter-mutter.h" -#include "backends/x11/meta-backend-x11.h" -#include "backends/x11/meta-clutter-backend-x11.h" -#include "backends/x11/meta-input-device-x11.h" -#include "backends/x11/meta-seat-x11.h" -#include "mtk/mtk-x11.h" - -struct _MetaInputDeviceX11 -{ - MetaInputDevice parent_instance; - - 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; - - -#define N_BUTTONS 5 - -enum -{ - PROP_0, - PROP_ID, - N_PROPS -}; - -static GParamSpec *props[N_PROPS] = { 0 }; - -G_DEFINE_FINAL_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 - - return clutter_input_device_get_vendor_id (device) == - clutter_input_device_get_vendor_id (other_device) && - clutter_input_device_get_product_id (device) == - clutter_input_device_get_product_id (other_device); -} - -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); - } -} - -#ifdef HAVE_LIBWACOM -#ifndef HAVE_LIBWACOM_GET_NUM_RINGS -static int -libwacom_get_num_rings (WacomDevice *device) -{ - if (libwacom_has_ring2 (device)) - return 2; - - if (libwacom_has_ring (device)) - return 1; - - return 0; -} -#endif -#endif - -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_get_num_rings (wacom_device) >= 1) - 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_get_num_rings (wacom_device) >= 2) - 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 gboolean -meta_input_device_x11_get_dimensions (ClutterInputDevice *device, - unsigned int *width, - unsigned int *height) -{ - MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device); - ClutterSeat *seat = clutter_input_device_get_seat (device); - MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); - MetaBackendX11 *backend_x11 = - META_BACKEND_X11 (meta_seat_x11_get_backend (seat_x11)); - Display *xdisplay = - meta_backend_x11_get_xdisplay (backend_x11); - XIDeviceInfo *info; - uint *value, w, h; - int i, n_info; - static gboolean atoms_initialized = FALSE; - static Atom abs_axis_atoms[4] = { 0, }; - - mtk_x11_error_trap_push (xdisplay); - - info = XIQueryDevice (xdisplay, device_x11->device_id, &n_info); - *width = *height = w = h = 0; - - if (mtk_x11_error_trap_pop_with_return (xdisplay)) - return FALSE; - - if (!info) - return FALSE; - - if (G_UNLIKELY (!atoms_initialized)) - { - const char *abs_axis_atom_names[4] = { - "Abs X", - "Abs MT Position X", - "Abs Y", - "Abs MT Position Y", - }; - - XInternAtoms (xdisplay, - (char **) abs_axis_atom_names, - G_N_ELEMENTS (abs_axis_atom_names), - False, - abs_axis_atoms); - atoms_initialized = TRUE; - } - - for (i = 0; i < info->num_classes; i++) - { - XIValuatorClassInfo *valuator_info; - - if (info->classes[i]->type != XIValuatorClass) - continue; - - valuator_info = (XIValuatorClassInfo *) info->classes[i]; - - if (valuator_info->label == abs_axis_atoms[0] || /* Abs X */ - valuator_info->label == abs_axis_atoms[1]) /* Abs MT X */ - value = &w; - else if (valuator_info->label == abs_axis_atoms[2] || /* Abs Y */ - valuator_info->label == abs_axis_atoms[3]) /* Abs MT Y */ - value = &h; - else - continue; - - *value = (unsigned int) ((valuator_info->max - valuator_info->min) * - 1000 / - valuator_info->resolution); - } - - *width = w; - *height = h; - - XIFreeDeviceInfo (info); - - return (w != 0 && h != 0); -} - -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; - device_class->get_dimensions = meta_input_device_x11_get_dimensions; - - props[PROP_ID] = - g_param_spec_int ("id", NULL, NULL, - -1, G_MAXINT, - 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - - g_object_class_install_properties (gobject_class, N_PROPS, props); -} - -static void -meta_input_device_x11_init (MetaInputDeviceX11 *self) -{ -} - -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) -{ - ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_xi2); - ClutterSeat *seat = clutter_input_device_get_seat (device); - MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); - MetaBackendX11 *backend_x11 = - META_BACKEND_X11 (meta_seat_x11_get_backend (seat_x11)); - Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11); - 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; - - mtk_x11_error_trap_push (xdisplay); - result = XIQueryPointer (meta_backend_x11_get_xdisplay (backend_x11), - device_xi2->device_id, - meta_backend_x11_get_root_xwindow (backend_x11), - &xroot_window, - &xchild_window, - &xroot_x, &xroot_y, - &xwin_x, &xwin_y, - &button_state, - &mod_state, - &group_state); - mtk_x11_error_trap_pop (xdisplay); - - 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 void -clear_inhibit_pointer_query_cb (gpointer data) -{ - MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (data); - - device_xi2->inhibit_pointer_query_timer = 0; -} - -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 = - g_idle_add_once (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)); - - if (!wacom_device) - return FALSE; - - 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 aa9dbf37e87..00000000000 --- a/src/backends/x11/meta-input-device-x11.h +++ /dev/null @@ -1,92 +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 . - * - * Author: Emmanuele Bassi - */ - -#pragma once - -#include - -#ifdef HAVE_LIBWACOM -#include -#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 ()) - -G_DECLARE_FINAL_TYPE (MetaInputDeviceX11, - meta_input_device_x11, - META, INPUT_DEVICE_X11, - MetaInputDevice) - -typedef struct _MetaInputDeviceX11 MetaInputDeviceX11; - -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 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 2807a93c73f..00000000000 --- a/src/backends/x11/meta-input-settings-x11.c +++ /dev/null @@ -1,955 +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, see . - * - * Author: Carlos Garnacho - */ - -#include "config.h" - -#include "backends/x11/meta-input-settings-x11.h" - -#include -#include -#include -#include - -#include "backends/x11/meta-backend-x11.h" -#include "backends/x11/meta-input-device-x11.h" -#include "x11/meta-x11-display-private.h" -#include "mtk/mtk-x11.h" - -typedef struct -{ - MetaInputSettings *settings; - XDevice *xdev; -} DeviceHandle; - -struct _MetaInputSettingsX11 -{ - MetaInputSettings parent_instance; -}; - -G_DEFINE_FINAL_TYPE (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 MetaBackend * -get_backend (MetaInputSettings *settings) -{ - return meta_input_settings_get_backend (settings); -} - -static void -device_handle_free (gpointer user_data) -{ - DeviceHandle *handle = user_data; - MetaInputSettings *settings = handle->settings; - MetaBackend *backend = get_backend (settings); - Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); - - mtk_x11_error_trap_push (xdisplay); - XCloseDevice (xdisplay, handle->xdev); - mtk_x11_error_trap_pop (xdisplay); - - g_free (handle); -} - -static XDevice * -device_ensure_xdevice (MetaInputSettings *settings, - ClutterInputDevice *device) -{ - MetaBackend *backend = get_backend (settings); - Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); - int device_id = meta_input_device_x11_get_device_id (device); - DeviceHandle *handle; - XDevice *xdev; - - handle = g_object_get_data (G_OBJECT (device), "meta-input-settings-xdevice"); - if (handle) - return handle->xdev; - - mtk_x11_error_trap_push (xdisplay); - xdev = XOpenDevice (xdisplay, device_id); - mtk_x11_error_trap_pop (xdisplay); - - if (xdev) - { - handle = g_new0 (DeviceHandle, 1); - handle->settings = settings; - handle->xdev = xdev; - g_object_set_data_full (G_OBJECT (device), - "meta-input-settings-xdevice", - handle, device_handle_free); - } - - return xdev; -} - -static void * -get_property (ClutterInputDevice *device, - const gchar *property, - Atom type, - int format, - gulong nitems) -{ - MetaInputDevice *input_device = META_INPUT_DEVICE (device); - MetaBackend *backend = meta_input_device_get_backend (input_device); - 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); - - mtk_x11_error_trap_push (xdisplay); - rc = XIGetProperty (xdisplay, device_id, property_atom, - 0, 10, False, type, &type_ret, &format_ret, - &nitems_ret, &bytes_after_ret, &data_ret); - mtk_x11_error_trap_pop (xdisplay); - - if (rc == Success && type_ret == type && format_ret == format && nitems_ret >= nitems) - return data_ret; - - meta_XFree (data_ret); - return NULL; -} - -static void -change_property (MetaInputSettings *settings, - ClutterInputDevice *device, - const gchar *property, - Atom type, - int format, - void *data, - gulong nitems) -{ - MetaBackend *backend = get_backend (settings); - Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); - int device_id; - Atom property_atom; - guchar *data_ret; - int err; - - 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; - - mtk_x11_error_trap_push (xdisplay); - XIChangeProperty (xdisplay, device_id, property_atom, type, - format, XIPropModeReplace, data, nitems); - XSync (xdisplay, False); - - err = mtk_x11_error_trap_pop_with_return (xdisplay); - if (err) - { - g_warning ("XIChangeProperty failed on device %d property \"%s\" with X error %d", - device_id, - property, - err); - } - - 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 (settings, 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 = get_backend (settings); - 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 (settings, 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 = get_backend (settings); - Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); - gfloat value = (float) speed; - - change_property (settings, 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 (settings, device, "Wacom Rotation", - XA_INTEGER, 8, &value, 1); - } - else - { - value = enabled ? 1 : 0; - change_property (settings, 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 (settings, 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 (settings, 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 (settings, 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 (settings, 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 (settings, device, "libinput Natural Scrolling Enabled", - XA_INTEGER, 8, &value, 1); -} - -static void -change_scroll_method (MetaInputSettings *settings, - 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 (settings, 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 (settings, 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 (settings, 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 (settings, device, - SCROLL_METHOD_FIELD_BUTTON, button != 0); - change_property (settings, device, "libinput Button Scrolling Button", - XA_CARDINAL, 32, &button, 1); - change_property (settings, 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 (settings, 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 (settings, 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 = get_backend (settings); - Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); - - if (enabled) - { - XAutoRepeatOn (xdisplay); - XkbSetAutoRepeatRate (xdisplay, XkbUseCoreKbd, delay, interval); - } - else - { - XAutoRepeatOff (xdisplay); - } -} - -static void -set_device_accel_profile (MetaInputSettings *settings, - 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 (); - G_GNUC_FALLTHROUGH; - case G_DESKTOP_POINTER_ACCEL_PROFILE_DEFAULT: - values[0] = defaults[0]; - values[1] = defaults[1]; - break; - } - - change_property (settings, 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) -{ - ClutterInputCapabilities caps = clutter_input_device_get_capabilities (device); - - if ((caps & CLUTTER_INPUT_CAPABILITY_POINTER) == 0) - return; - if ((caps & - (CLUTTER_INPUT_CAPABILITY_TRACKBALL | - CLUTTER_INPUT_CAPABILITY_TOUCHPAD | - CLUTTER_INPUT_CAPABILITY_TRACKPOINT)) != 0) - return; - - set_device_accel_profile (settings, device, profile); -} - -static void -meta_input_settings_x11_set_touchpad_accel_profile (MetaInputSettings *settings, - ClutterInputDevice *device, - GDesktopPointerAccelProfile profile) -{ - ClutterInputCapabilities caps = clutter_input_device_get_capabilities (device); - - if ((caps & CLUTTER_INPUT_CAPABILITY_TOUCHPAD) == 0) - return; - - set_device_accel_profile (settings, device, profile); -} - -static void -meta_input_settings_x11_set_trackball_accel_profile (MetaInputSettings *settings, - ClutterInputDevice *device, - GDesktopPointerAccelProfile profile) -{ - ClutterInputCapabilities caps = clutter_input_device_get_capabilities (device); - - if ((caps & CLUTTER_INPUT_CAPABILITY_TRACKBALL) == 0) - return; - - set_device_accel_profile (settings, device, profile); -} - -static void -meta_input_settings_x11_set_pointing_stick_accel_profile (MetaInputSettings *settings, - ClutterInputDevice *device, - GDesktopPointerAccelProfile profile) -{ - ClutterInputCapabilities caps = clutter_input_device_get_capabilities (device); - - if ((caps & CLUTTER_INPUT_CAPABILITY_TRACKPOINT) == 0) - return; - - set_device_accel_profile (settings, device, profile); -} - -static void -meta_input_settings_x11_set_pointing_stick_scroll_method (MetaInputSettings *settings, - ClutterInputDevice *device, - GDesktopPointingStickScrollMethod method) -{ - ClutterInputCapabilities caps = clutter_input_device_get_capabilities (device); - guchar *defaults; - guchar values[3] = { 0 }; /* 2fg, edge, on-button */ - - if ((caps & CLUTTER_INPUT_CAPABILITY_TRACKPOINT) == 0) - return; - - defaults = get_property (device, "libinput Scroll Method Enabled Default", - XA_INTEGER, 8, 3); - if (!defaults) - return; - - switch (method) - { - case G_DESKTOP_POINTING_STICK_SCROLL_METHOD_DEFAULT: - values[0] = defaults[0]; - values[1] = defaults[1]; - values[2] = defaults[2]; - break; - case G_DESKTOP_POINTING_STICK_SCROLL_METHOD_NONE: - values[0] = 0; - values[1] = 0; - values[2] = 0; - break; - case G_DESKTOP_POINTING_STICK_SCROLL_METHOD_ON_BUTTON_DOWN: - values[0] = 0; - values[1] = 0; - values[2] = 1; - break; - default: - g_assert_not_reached (); - return; - } - - change_property (settings, device, "libinput Scroll Method Enabled", - XA_INTEGER, 8, &values, 3); - - meta_XFree (defaults); -} - -static void -meta_input_settings_x11_set_tablet_mapping (MetaInputSettings *settings, - ClutterInputDevice *device, - GDesktopTabletMapping mapping) -{ - MetaBackend *backend = get_backend (settings); - Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); - XDevice *xdev; - - /* Grab the puke bucket! */ - mtk_x11_error_trap_push (xdisplay); - xdev = device_ensure_xdevice (settings, device); - if (xdev) - { - XSetDeviceMode (xdisplay, xdev, - mapping == G_DESKTOP_TABLET_MAPPING_ABSOLUTE ? - Absolute : Relative); - } - - mtk_x11_error_trap_pop (xdisplay); -} - -static gboolean -device_query_area (MetaInputSettings *settings, - ClutterInputDevice *device, - gint *x, - gint *y, - gint *width, - gint *height) -{ - MetaBackend *backend = get_backend (settings); - 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 = (int) valuator->min; - *width = (int) (valuator->max - valuator->min); - } - else if (valuator->label == abs_y) - { - *y = (int) valuator->min; - *height = (int) (valuator->max - valuator->min); - } - } - - XIFreeDeviceInfo (info); - return TRUE; -} - -static void -update_tablet_area (MetaInputSettings *settings, - ClutterInputDevice *device, - gint32 *area) -{ - change_property (settings, 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 (settings, device, &x, &y, &width, &height)) - return; - - area[0] = (int32_t) ((width * padding_left) + x); - area[1] = (int32_t) ((height * padding_top) + y); - area[2] = (int32_t) (width - (width * padding_right) + x); - area[3] = (int32_t) (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 (settings, 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 = (int) (dev_height * aspect_ratio); - else if (dev_aspect < aspect_ratio) - dev_height = (int) (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 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) -{ - MetaBackend *backend = get_backend (settings); - Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); - XDevice *xdev; - - /* Grab the puke bucket! */ - mtk_x11_error_trap_push (xdisplay); - xdev = device_ensure_xdevice (settings, 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)); - } - - mtk_x11_error_trap_pop (xdisplay); -} - -static void -meta_input_settings_x11_set_mouse_middle_click_emulation (MetaInputSettings *settings, - ClutterInputDevice *device, - gboolean enabled) -{ - guchar value = enabled ? 1 : 0; - ClutterInputCapabilities caps = clutter_input_device_get_capabilities (device); - - if ((caps & CLUTTER_INPUT_CAPABILITY_POINTER) == 0) - return; - if ((caps & - (CLUTTER_INPUT_CAPABILITY_TRACKBALL | - CLUTTER_INPUT_CAPABILITY_TOUCHPAD | - CLUTTER_INPUT_CAPABILITY_TRACKPOINT)) != 0) - return; - - change_property (settings, device, "libinput Middle 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; - ClutterInputCapabilities caps = clutter_input_device_get_capabilities (device); - - if ((caps & CLUTTER_INPUT_CAPABILITY_TOUCHPAD) == 0) - return; - - change_property (settings, device, "libinput Middle 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; - ClutterInputCapabilities caps = clutter_input_device_get_capabilities (device); - - if ((caps & CLUTTER_INPUT_CAPABILITY_TRACKBALL) == 0) - return; - - change_property (settings, device, "libinput Middle 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], - const gdouble range[2]) -{ - guint32 values[4] = { pressure[0], pressure[1], pressure[2], pressure[3] }; - guint32 threshold = (guint32) MAX (2048 * range[0], 1.0); - - change_property (settings, device, "Wacom Pressurecurve", XA_INTEGER, 32, - &values, G_N_ELEMENTS (values)); - - /* The wacom driver doesn't have a full equivalent to the pressure range. - * Threshold only applies to the tip down event but that's better than nothing */ - change_property (settings, device, "Wacom Pressure Threshold", XA_INTEGER, 32, - &threshold, 1); -} - -static void -meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass) -{ - MetaInputSettingsClass *input_settings_class = META_INPUT_SETTINGS_CLASS (klass); - - 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_touchpad_accel_profile = meta_input_settings_x11_set_touchpad_accel_profile; - input_settings_class->set_trackball_accel_profile = meta_input_settings_x11_set_trackball_accel_profile; - input_settings_class->set_pointing_stick_accel_profile = meta_input_settings_x11_set_pointing_stick_accel_profile; - input_settings_class->set_pointing_stick_scroll_method = meta_input_settings_x11_set_pointing_stick_scroll_method; - - 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; -} - -static void -meta_input_settings_x11_init (MetaInputSettingsX11 *settings) -{ -} 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 1657d231d05..00000000000 --- a/src/backends/x11/meta-input-settings-x11.h +++ /dev/null @@ -1,33 +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 . - * - * Author: Carlos Garnacho - */ - -#pragma once - -#include "backends/meta-input-settings-private.h" - -#define META_TYPE_INPUT_SETTINGS_X11 (meta_input_settings_x11_get_type ()) - -G_DECLARE_FINAL_TYPE (MetaInputSettingsX11, - meta_input_settings_x11, - META, INPUT_SETTINGS_X11, - MetaInputSettings) - -typedef struct _MetaInputSettingsX11 MetaInputSettingsX11; diff --git a/src/backends/x11/meta-keymap-x11.c b/src/backends/x11/meta-keymap-x11.c deleted file mode 100644 index 01107af07c8..00000000000 --- a/src/backends/x11/meta-keymap-x11.c +++ /dev/null @@ -1,946 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#include "config.h" - -#include -#include -#include - -#include "backends/meta-backend-private.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-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; - ClutterTextDirection direction; -}; - -struct _MetaKeymapX11 -{ - ClutterKeymap parent_instance; - - MetaBackend *backend; - - int min_keycode; - int max_keycode; - - ClutterModifierType modmap[8]; - - ClutterModifierType num_lock_mask; - ClutterModifierType scroll_lock_mask; - ClutterModifierType level3_shift_mask; - - ClutterTextDirection 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) - -static Display * -xdisplay_from_keymap (MetaKeymapX11 *keymap_x11) -{ - return meta_backend_x11_get_xdisplay (META_BACKEND_X11 (keymap_x11->backend)); -} - -/* 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 = xdisplay_from_keymap (keymap_x11); - - 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_modifiers (MetaKeymapX11 *keymap_x11, - XkbEvent *xkb_event) -{ - ClutterKeymap *keymap = CLUTTER_KEYMAP (keymap_x11); - gboolean caps_lock_state; - gboolean num_lock_state; - gboolean old_num_lock_state; - - caps_lock_state = !!(xkb_event->state.locked_mods & CLUTTER_LOCK_MASK); - num_lock_state = !!(xkb_event->state.locked_mods & keymap_x11->num_lock_mask); - - old_num_lock_state = clutter_keymap_get_num_lock_state (keymap); - clutter_keymap_update_state (CLUTTER_KEYMAP (keymap_x11), - caps_lock_state, - num_lock_state, - keymap_x11->current_group, - xkb_event->state.base_mods, - xkb_event->state.latched_mods, - xkb_event->state.locked_mods); - - if (num_lock_state != old_num_lock_state) - { - MetaBackend *backend; - MetaInputSettings *input_settings; - - backend = keymap_x11->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 ClutterTextDirection -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); - uint32_t unicode = clutter_keysym_to_unicode (sym); - FriBidiCharType fribidi_ch_type = fribidi_get_bidi_type (unicode); - ClutterTextDirection dir = CLUTTER_TEXT_DIRECTION_LTR; - - if (!FRIBIDI_IS_STRONG (fribidi_ch_type)) - dir = CLUTTER_TEXT_DIRECTION_DEFAULT; - else if (FRIBIDI_IS_RTL (fribidi_ch_type)) - dir = CLUTTER_TEXT_DIRECTION_RTL; - - switch (dir) - { - case CLUTTER_TEXT_DIRECTION_RTL: - rtl_minus_ltr++; - break; - - case CLUTTER_TEXT_DIRECTION_LTR: - rtl_minus_ltr--; - break; - - default: - break; - } - } - - if (rtl_minus_ltr > 0) - return CLUTTER_TEXT_DIRECTION_RTL; - - return CLUTTER_TEXT_DIRECTION_LTR; -} - -static ClutterTextDirection -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; - ClutterTextDirection direction = CLUTTER_TEXT_DIRECTION_DEFAULT; - 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 = CLUTTER_TEXT_DIRECTION_DEFAULT; - 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 = xdisplay_from_keymap (keymap_x11); - 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 | - XkbModifierBaseMask | - XkbModifierLatchMask | - 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 = xdisplay_from_keymap (keymap_x11); - 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 = xdisplay_from_keymap (keymap_x11); - 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); - } - - 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 ClutterTextDirection -meta_keymap_x11_get_direction (ClutterKeymap *keymap) -{ - MetaKeymapX11 *keymap_x11; - - g_return_val_if_fail (META_IS_KEYMAP_X11 (keymap), CLUTTER_TEXT_DIRECTION_DEFAULT); - - keymap_x11 = META_KEYMAP_X11 (keymap); - - if (keymap_x11->use_xkb) - { - if (!keymap_x11->has_direction) - { - XkbStateRec state_rec; - - XkbGetState (xdisplay_from_keymap (keymap_x11), - XkbUseCoreKbd, &state_rec); - update_direction (keymap_x11, XkbStateGroup (&state_rec)); - } - - return keymap_x11->current_direction; - } - else - { - return CLUTTER_TEXT_DIRECTION_DEFAULT; - } -} - -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", NULL, NULL, - META_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 = CLUTTER_TEXT_DIRECTION_DEFAULT; - 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_modifiers (keymap_x11, xkb_event); - 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; -} - -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_x11, - uint32_t hardware_keycode) -{ - int retval; - - retval = XKeycodeToKeysym (xdisplay_from_keymap (keymap_x11), - 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 -matches_group (XkbDescRec *xkb, - uint32_t keycode, - uint32_t group, - uint32_t target_group) -{ - unsigned char group_info = XkbKeyGroupInfo (xkb, keycode); - unsigned char action = XkbOutOfRangeGroupAction (group_info); - unsigned char num_groups = XkbNumGroups (group_info); - - if (num_groups == 0) - return FALSE; - - if (target_group >= num_groups) - { - switch (action) - { - case XkbRedirectIntoRange: - target_group = XkbOutOfRangeGroupNumber (group_info); - if (target_group >= num_groups) - target_group = 0; - break; - - case XkbClampIntoRange: - target_group = num_groups - 1; - break; - - default: - target_group %= num_groups; - break; - } - } - - return group == target_group; -} - -static gboolean -meta_keymap_x11_get_entry_for_keyval (MetaKeymapX11 *keymap_x11, - uint32_t keyval, - uint32_t target_group, - ClutterKeymapKey *key) -{ - if (keymap_x11->use_xkb) - { - XkbDescRec *xkb = get_xkb (keymap_x11); - int keycode = keymap_x11->min_keycode; - - 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 && - matches_group (xkb, keycode, group, target_group)) - { - key->keycode = keycode; - key->group = group; - key->level = level; - - g_assert (XkbKeySymEntry (xkb, keycode, level, group) == - keyval); - - return TRUE; - } - - ++level; - - if (level == max_shift_levels) - { - level = 0; - ++group; - } - - ++i; - } - - ++keycode; - } - - return FALSE; - } - 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 = xdisplay_from_keymap (keymap_x11); - 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_lock_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; - - XkbLockModifiers (xdisplay_from_keymap (keymap_x11), - 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 (xdisplay_from_keymap (keymap_x11), - 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 key; - int group; - - 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_entry_for_keyval (keymap_x11, keyval, group, &key)) - { - *keycode_out = key.keycode; - *level_out = key.level; - return TRUE; - } - - return FALSE; -} diff --git a/src/backends/x11/meta-keymap-x11.h b/src/backends/x11/meta-keymap-x11.h deleted file mode 100644 index e3534cbe778..00000000000 --- a/src/backends/x11/meta-keymap-x11.h +++ /dev/null @@ -1,55 +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 . - * - * Author: Emmanuele Bassi - */ - -#pragma once - -#include - -#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_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_lock_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 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 6e46a7cac9b..00000000000 --- a/src/backends/x11/meta-monitor-manager-xrandr.c +++ /dev/null @@ -1,1023 +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 . - */ - -/** - * MetaMonitorManagerXrandr: - * - * 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 -#include -#include -#include -#include -#include -#include - -#include "backends/meta-crtc.h" -#include "backends/meta-logical-monitor-private.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 "mtk/mtk-x11.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; -}; - -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; - MetaPowerSaveChangeReason reason; - - 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; - - - reason = META_POWER_SAVE_CHANGE_REASON_HOTPLUG; - meta_monitor_manager_power_save_mode_changed (manager, - power_save_mode, - reason); - - 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; - } - - mtk_x11_error_trap_push (manager_xrandr->xdisplay); - DPMSForceLevel (manager_xrandr->xdisplay, state); - DPMSSetTimeouts (manager_xrandr->xdisplay, 0, 0, 0); - mtk_x11_error_trap_pop (manager_xrandr->xdisplay); -} - -static xcb_randr_rotation_t -mtk_monitor_transform_to_xrandr (MtkMonitorTransform transform) -{ - switch (transform) - { - case MTK_MONITOR_TRANSFORM_NORMAL: - return XCB_RANDR_ROTATION_ROTATE_0; - case MTK_MONITOR_TRANSFORM_90: - return XCB_RANDR_ROTATION_ROTATE_90; - case MTK_MONITOR_TRANSFORM_180: - return XCB_RANDR_ROTATION_ROTATE_180; - case MTK_MONITOR_TRANSFORM_270: - return XCB_RANDR_ROTATION_ROTATE_270; - case MTK_MONITOR_TRANSFORM_FLIPPED: - return XCB_RANDR_ROTATION_REFLECT_X | XCB_RANDR_ROTATION_ROTATE_0; - case MTK_MONITOR_TRANSFORM_FLIPPED_90: - return XCB_RANDR_ROTATION_REFLECT_X | XCB_RANDR_ROTATION_ROTATE_90; - case MTK_MONITOR_TRANSFORM_FLIPPED_180: - return XCB_RANDR_ROTATION_REFLECT_X | XCB_RANDR_ROTATION_ROTATE_180; - case MTK_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]; - unsigned int max_bpc; - - 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; - - if (meta_output_get_max_bpc (output, &max_bpc)) - { - if (!output_assignment->has_max_bpc || - max_bpc != output_assignment->max_bpc) - return TRUE; - } - else if (output_assignment->has_max_bpc) - { - 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 = (int) ((width / DPI_FALLBACK) * 25.4 + 0.5); - height_mm = (int) ((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; - MetaCrtcConfig *crtc_config; - - 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 = - mtk_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); - - g_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; - } - - crtc_config = meta_crtc_config_new (&crtc_assignment->layout, - crtc_mode, - crtc_assignment->transform); - meta_crtc_set_config (crtc, crtc_config, - crtc_assignment->backend_private); - } - } - - 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, NULL); -} - -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_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_rebuild_derived (manager, config); - } - } - - g_ptr_array_free (crtc_assignments, TRUE); - g_ptr_array_free (output_assignments, TRUE); - - return TRUE; -} - -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); - } - - mtk_x11_error_trap_push (manager_xrandr->xdisplay); - XRRSetMonitor (manager_xrandr->xdisplay, - DefaultRootWindow (manager_xrandr->xdisplay), - xrandr_monitor_info); - mtk_x11_error_trap_pop (manager_xrandr->xdisplay); - 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 float -meta_monitor_manager_xrandr_calculate_monitor_mode_scale (MetaMonitorManager *manager, - MetaLogicalMonitorLayoutMode layout_mode, - MetaMonitor *monitor, - MetaMonitorMode *monitor_mode) -{ - MetaMonitorScalesConstraint constraints; - - constraints = META_MONITOR_SCALES_CONSTRAINT_NO_FRAC; - return meta_monitor_calculate_mode_scale (monitor, monitor_mode, constraints); -} - -static float * -meta_monitor_manager_xrandr_calculate_supported_scales (MetaMonitorManager *manager, - MetaLogicalMonitorLayoutMode layout_mode, - MetaMonitor *monitor, - MetaMonitorMode *monitor_mode, - int *n_supported_scales) -{ - MetaMonitorScalesConstraint constraints; - - constraints = META_MONITOR_SCALES_CONSTRAINT_NO_FRAC; - return meta_monitor_calculate_supported_scales (monitor, monitor_mode, - constraints, - n_supported_scales); -} - -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_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->tiled_monitor_added = meta_monitor_manager_xrandr_tiled_monitor_added; - manager_class->tiled_monitor_removed = meta_monitor_manager_xrandr_tiled_monitor_removed; - 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_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 f2d25bdff53..00000000000 --- a/src/backends/x11/meta-monitor-manager-xrandr.h +++ /dev/null @@ -1,38 +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 . - */ - -#pragma once - -#include - -#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); diff --git a/src/backends/x11/meta-output-xrandr.c b/src/backends/x11/meta-output-xrandr.c deleted file mode 100644 index 5d8c84016d5..00000000000 --- a/src/backends/x11/meta-output-xrandr.c +++ /dev/null @@ -1,1065 +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, see . - */ - -#include "config.h" - -#include "backends/x11/meta-output-xrandr.h" - -#include -#include -#include -#include -#include - -#include "backends/meta-backend-private.h" -#include "backends/meta-backlight-sysfs-private.h" -#include "backends/meta-crtc.h" -#include "backends/meta-monitor-private.h" -#include "backends/x11/meta-monitor-manager-xrandr.h" -#include "backends/x11/meta-backlight-x11.h" -#include "meta/util.h" -#include "mtk/mtk-x11.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 = (uint32_t) (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 = (uint32_t) (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); - } -} - -static void -output_set_max_bpc_xrandr (MetaOutput *output, - unsigned int max_bpc) -{ - Display *xdisplay = xdisplay_from_output (output); - Atom prop = XInternAtom (xdisplay, "max bpc", False); - uint32_t value = max_bpc; - - xcb_randr_change_output_property (XGetXCBConnection (xdisplay), - (XID) meta_output_get_id (output), - prop, XCB_ATOM_INTEGER, 32, - XCB_PROP_MODE_REPLACE, - 1, &value); -} - -void -meta_output_xrandr_apply_mode (MetaOutputXrandr *output_xrandr) -{ - MetaOutput *output = META_OUTPUT (output_xrandr); - Display *xdisplay = xdisplay_from_output (output); - const MetaOutputInfo *output_info = meta_output_get_info (output); - unsigned int max_bpc; - - 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)); - } - - if (meta_output_get_max_bpc (output, &max_bpc) && - max_bpc >= output_info->max_bpc_min && - max_bpc <= output_info->max_bpc_max) - { - output_set_max_bpc_xrandr (output, max_bpc); - } -} - -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_max_bpc_xrandr (MetaOutput *output, - unsigned int *max_bpc) -{ - 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, "max bpc", False); - XRRGetOutputProperty (xdisplay, - (XID) meta_output_get_id (output), - atom, - 0, G_MAXLONG, False, False, XCB_ATOM_INTEGER, - &actual_type, &actual_format, - &nitems, &bytes_after, &buffer); - - if (actual_type != XCB_ATOM_INTEGER || actual_format != 32 || nitems < 1) - return FALSE; - - if (max_bpc) - *max_bpc = *((uint32_t*) buffer); - - return TRUE; -} - -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_max_bpc_range_xrandr (Display *xdisplay, - RROutput output_id, - unsigned int *min, - unsigned int *max) -{ - Atom atom; - XRRPropertyInfo *property_info; - long *values; - - atom = XInternAtom (xdisplay, "max bpc", False); - - mtk_x11_error_trap_push (xdisplay); - property_info = XRRQueryOutputProperty (xdisplay, - (XID) output_id, - atom); - mtk_x11_error_trap_pop (xdisplay); - - if (!property_info) - return FALSE; - - if (property_info->num_values != 2) - { - XFree (property_info); - return FALSE; - } - - values = (long *) property_info->values; - if (min) - *min = values[0]; - if (max) - *max = values[1]; - - XFree (property_info); - - return TRUE; -} - -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 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; - if (g_str_has_prefix (name, "DPI")) - return META_CONNECTOR_TYPE_DPI; - /* 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 MTK_MONITOR_TRANSFORM_NORMAL; - - str = XGetAtomName (xdisplay, *(Atom *)buffer); - if (strcmp (str, "Upside Down") == 0) - return MTK_MONITOR_TRANSFORM_180; - - if (strcmp (str, "Left Side Up") == 0) - return MTK_MONITOR_TRANSFORM_90; - - if (strcmp (str, "Right Side Up") == 0) - return MTK_MONITOR_TRANSFORM_270; - - return MTK_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 gboolean -sanity_check_duplicate (MetaCrtcMode **modes, - size_t n_modes, - MetaCrtcMode *mode) -{ - size_t i; - - for (i = 0; i < n_modes; i++) - { - if (meta_crtc_mode_get_id (modes[i]) == meta_crtc_mode_get_id (mode)) - return FALSE; - } - - return TRUE; -} - -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)) - { - if (sanity_check_duplicate (output_info->modes, n_actual_modes, mode)) - { - output_info->modes[n_actual_modes] = g_object_ref (mode); - n_actual_modes += 1; - } - else - { - g_warning ("X11 server advertized duplicate identical modes " - "(0x%" G_GINT64_MODIFIER "x)", - meta_crtc_mode_get_id (mode)); - } - 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; -} - -static MetaBacklight * -meta_output_xrandr_create_backlight (MetaOutput *output, - GError **error) -{ - MetaMonitor *monitor = meta_output_get_monitor (output); - MetaBackend *backend = meta_monitor_get_backend (monitor); - MetaBacklight *old_backlight = meta_monitor_get_backlight (monitor); - const MetaOutputInfo *output_info = meta_output_get_info (output); - Display *xdisplay = xdisplay_from_output (output); - XID output_id = meta_output_get_id (output); - g_autoptr (MetaBacklightSysfs) backlight_sysfs = NULL; - g_autoptr (MetaBacklightX11) backlight_x11 = NULL; - g_autoptr (GError) local_error = NULL; - -#ifdef HAVE_LIBGUDEV - if (META_IS_BACKLIGHT_SYSFS (old_backlight)) - return g_object_ref (old_backlight); - - backlight_sysfs = meta_backlight_sysfs_new (backend, - output_info, - &local_error); - if (backlight_sysfs) - return META_BACKLIGHT (g_steal_pointer (&backlight_sysfs)); - - if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) - { - g_propagate_error (error, g_steal_pointer (&local_error)); - return NULL; - } - - meta_topic (META_DEBUG_BACKEND, - "Trying X11 backlight on output %s, because sysfs based " - "backlight is not supported.", output_info->name); - g_clear_error (&local_error); -#endif - - if (META_IS_BACKLIGHT_X11 (old_backlight)) - return g_object_ref (old_backlight); - - backlight_x11 = meta_backlight_x11_new (backend, - xdisplay, - output_id, - output_info, - &local_error); - if (backlight_x11) - return META_BACKLIGHT (g_steal_pointer (&backlight_x11)); - - g_propagate_error (error, g_steal_pointer (&local_error)); - 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); - if (edid) - { - meta_output_info_parse_edid (output_info, edid); - g_bytes_unref (edid); - } - - output_info->subpixel_order = META_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 (mtk_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_get_max_bpc_range_xrandr (xdisplay, - output_id, - &output_info->max_bpc_min, - &output_info->max_bpc_max); - output_info->supports_color_transform = - output_get_supports_color_transform_xrandr (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), - }; - output_assignment.has_max_bpc = - output_get_max_bpc_xrandr (output, &output_assignment.max_bpc); - - meta_output_assign_crtc (output, assigned_crtc, &output_assignment); - } - else - { - meta_output_unassign_crtc (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) -{ - MetaOutputClass *output_class = META_OUTPUT_CLASS (klass); - - output_class->create_backlight = meta_output_xrandr_create_backlight; -} diff --git a/src/backends/x11/meta-output-xrandr.h b/src/backends/x11/meta-output-xrandr.h deleted file mode 100644 index 3e3e6c27f8e..00000000000 --- a/src/backends/x11/meta-output-xrandr.h +++ /dev/null @@ -1,44 +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, see . - */ - -#pragma once - -#include - -#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_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); diff --git a/src/backends/x11/meta-renderer-x11.c b/src/backends/x11/meta-renderer-x11.c deleted file mode 100644 index 4477dc07200..00000000000 --- a/src/backends/x11/meta-renderer-x11.c +++ /dev/null @@ -1,106 +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 . - * - * Written by: - * Jonas Ă…dahl - */ - -#include "config.h" - -#include - -#include "backends/meta-backend-private.h" -#include "backends/meta-logical-monitor-private.h" -#include "backends/meta-renderer-view.h" -#include "backends/meta-renderer.h" -#include "backends/x11/meta-backend-x11.h" -#include "backends/x11/meta-clutter-backend-x11.h" -#include "backends/x11/meta-renderer-x11.h" -#include "cogl/cogl-xlib-renderer.h" -#include "cogl/cogl.h" -#include "core/boxes-private.h" -#include "meta/meta-backend.h" -#include "meta/util.h" - -#ifdef HAVE_EGL -#include "cogl/winsys/cogl-winsys-egl-x11-private.h" -#endif -#ifdef HAVE_GLX -#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 HAVE_EGL_PLATFORM_XLIB - if (meta_is_wayland_compositor ()) - return _cogl_winsys_egl_xlib_get_vtable (); -#endif - - switch (cogl_renderer_get_driver_id (renderer)) - { - case COGL_DRIVER_ID_GLES2: -#ifdef HAVE_EGL_PLATFORM_XLIB - return _cogl_winsys_egl_xlib_get_vtable (); -#else - break; -#endif - case COGL_DRIVER_ID_GL3: -#ifdef HAVE_GLX - return _cogl_winsys_glx_get_vtable (); -#else - break; -#endif - case COGL_DRIVER_ID_ANY: - case COGL_DRIVER_ID_NOP: - break; - } - g_assert_not_reached (); - return NULL; -} - -static CoglRenderer * -meta_renderer_x11_create_cogl_renderer (MetaRenderer *renderer) -{ - MetaBackend *backend = meta_renderer_get_backend (renderer); - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); - Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11); - CoglRenderer *cogl_renderer; - - 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); - - 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 bd57bd8d17b..00000000000 --- a/src/backends/x11/meta-renderer-x11.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 . - * - * Written by: - * Jonas Ă…dahl - */ - -#pragma once - -#include - -#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) diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c deleted file mode 100644 index 74a8b24f0c2..00000000000 --- a/src/backends/x11/meta-seat-x11.c +++ /dev/null @@ -1,2738 +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 . - * - * Author: Carlos Garnacho - */ -#include "config.h" - -#include -#include -#include - -#ifdef HAVE_LIBGUDEV -#include -#endif - -#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" -#include "mtk/mtk-x11.h" - -enum -{ - PROP_0, - PROP_BACKEND, - 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; - - MetaBackend *backend; - - ClutterInputDevice *core_pointer; - ClutterInputDevice *core_keyboard; - GList *devices; - GHashTable *devices_by_id; - GHashTable *tools_by_serial; - GHashTable *touch_coords; - MetaKeymapX11 *keymap; - -#ifdef HAVE_LIBGUDEV - GUdevClient *udev_client; -#endif - - ClutterEventSequence *pointer_emulating_sequence; - - int pointer_id; - int keyboard_id; - int opcode; - ClutterGrabState grab_state; - 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 Display * -xdisplay_from_seat (MetaSeatX11 *seat_x11) -{ - return meta_backend_x11_get_xdisplay (META_BACKEND_X11 (seat_x11->backend)); -} - -static Window -root_xwindow_from_seat (MetaSeatX11 *seat_x11) -{ - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (seat_x11->backend); - - return meta_backend_x11_get_root_xwindow (backend_x11); -} - -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", - axis == CLUTTER_INPUT_AXIS_IGNORE ? - "Ignored" : - clutter_input_axis_atom_names[axis - 1], - 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, - ClutterInputCapabilities *capabilities, - 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; - *capabilities = CLUTTER_INPUT_CAPABILITY_TOUCH; - } - else if (class->mode == XIDependentTouch) - { - *device_type = CLUTTER_TOUCHPAD_DEVICE; - *capabilities = - CLUTTER_INPUT_CAPABILITY_POINTER | - CLUTTER_INPUT_CAPABILITY_TOUCHPAD; - } - else - { - continue; - } - - *n_touch_points = class->num_touches; - - return TRUE; - } - } - - return FALSE; -} - -static gboolean -is_touchpad_device (MetaSeatX11 *seat_x11, - XIDeviceInfo *info) -{ - Display *xdisplay = xdisplay_from_seat (seat_x11); - gulong nitems, bytes_after; - uint32_t *data = NULL; - int rc, format; - Atom type; - Atom prop; - - prop = XInternAtom (xdisplay, - "libinput Tapping Enabled", True); - if (prop == None) - return FALSE; - - mtk_x11_error_trap_push (xdisplay); - rc = XIGetProperty (xdisplay, - info->deviceid, - prop, - 0, 1, False, XA_INTEGER, &type, &format, &nitems, &bytes_after, - (guchar **) &data); - mtk_x11_error_trap_pop (xdisplay); - - /* 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 (MetaSeatX11 *seat_x11, - XIDeviceInfo *info, - guint *vendor_id, - guint *product_id) -{ - Display *xdisplay = xdisplay_from_seat (seat_x11); - gulong nitems, bytes_after; - uint32_t *data = NULL; - int rc, format; - Atom type; - - mtk_x11_error_trap_push (xdisplay); - rc = XIGetProperty (xdisplay, - info->deviceid, - XInternAtom (xdisplay, "Device Product ID", False), - 0, 2, False, XA_INTEGER, &type, &format, &nitems, &bytes_after, - (guchar **) &data); - mtk_x11_error_trap_pop (xdisplay); - - if (rc != Success || type != XA_INTEGER || format != 32 || nitems != 2) - { - XFree (data); - return FALSE; - } - - if (vendor_id) - *vendor_id = data[0]; - if (product_id) - *product_id = data[1]; - - XFree (data); - - return TRUE; -} - -static char * -get_device_node_path (MetaSeatX11 *seat_x11, - XIDeviceInfo *info) -{ - Display *xdisplay = xdisplay_from_seat (seat_x11); - gulong nitems, bytes_after; - guchar *data; - int rc, format; - Atom prop, type; - char *node_path; - - prop = XInternAtom (xdisplay, "Device Node", False); - if (prop == None) - return NULL; - - mtk_x11_error_trap_push (xdisplay); - - rc = XIGetProperty (xdisplay, - info->deviceid, prop, 0, 1024, False, - XA_STRING, &type, &format, &nitems, &bytes_after, - (guchar **) &data); - - if (mtk_x11_error_trap_pop_with_return (xdisplay)) - 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; -} - -static gboolean -guess_serial_from_libinput_prop (MetaSeatX11 *seat_x11, - ClutterInputDevice *device, - unsigned int *serial_out) -{ - Display *xdisplay = xdisplay_from_seat (seat_x11); - int device_id = meta_input_device_x11_get_device_id (device); - gulong nitems, bytes_after; - uint32_t *data = NULL; - int rc, format; - Atom type; - Atom prop; - - prop = XInternAtom (xdisplay, "libinput Tablet Tool Serial", True); - if (prop != None) - { - mtk_x11_error_trap_push (xdisplay); - rc = XIGetProperty (xdisplay, - device_id, - prop, - 0, 1, False, XA_CARDINAL, &type, &format, &nitems, &bytes_after, - (guchar **) &data); - mtk_x11_error_trap_pop (xdisplay); - - if (rc != Success || type != XA_CARDINAL || format != 32 || nitems != 1) - { - XFree (data); - return FALSE; - } - - *serial_out = *data; - XFree (data); - return TRUE; - } - - /* xf86-input-libinput < 1.5.0 doesn't have the serial prop, let's check - * for a generic property that tells us if it's libinput handling this device. - * If that's the case we give the tool a "random" fixed serial to pass through - * the code that assumes 0 == no tool. - */ - prop = XInternAtom (xdisplay, "libinput Send Events Mode Enabled", True); - if (prop == None) - return FALSE; - - mtk_x11_error_trap_push (xdisplay); - rc = XIGetProperty (xdisplay, - device_id, - prop, - 0, 1, False, XA_INTEGER, &type, &format, &nitems, &bytes_after, - (guchar **) &data); - mtk_x11_error_trap_pop (xdisplay); - XFree (data); - - if (rc != Success) - return FALSE; - - *serial_out = 0xffffffaa; - - return TRUE; -} - - -/* 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 (MetaSeatX11 *seat_x11, - XIDeviceInfo *info, - ClutterInputDeviceType *source_out, - ClutterInputCapabilities *capabilities_out) -{ - Display *xdisplay = xdisplay_from_seat (seat_x11); - 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 (xdisplay, "Wacom Tool Type", True); - if (prop == None) - return FALSE; - - mtk_x11_error_trap_push (xdisplay); - rc = XIGetProperty (xdisplay, - info->deviceid, - prop, - 0, 1, False, XA_ATOM, &type, &format, &nitems, &bytes_after, - (guchar **) &data); - mtk_x11_error_trap_pop (xdisplay); - - 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 (xdisplay, - (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; - *capabilities_out = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL; - } - else if (device_type == types[WACOM_TYPE_CURSOR]) - { - *source_out = CLUTTER_CURSOR_DEVICE; - *capabilities_out = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL; - } - else if (device_type == types[WACOM_TYPE_ERASER]) - { - *source_out = CLUTTER_ERASER_DEVICE; - *capabilities_out = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL; - } - else if (device_type == types[WACOM_TYPE_PAD]) - { - *source_out = CLUTTER_PAD_DEVICE; - *capabilities_out = CLUTTER_INPUT_CAPABILITY_TABLET_PAD; - } - else if (device_type == types[WACOM_TYPE_TOUCH]) - { - uint32_t num_touches = 0; - - if (!is_touch_device (info->classes, info->num_classes, - source_out, capabilities_out, &num_touches)) - { - *source_out = CLUTTER_TOUCHSCREEN_DEVICE; - *capabilities_out = CLUTTER_INPUT_CAPABILITY_TOUCH; - } - } - else - { - return FALSE; - } - - return TRUE; -} - -#ifdef HAVE_LIBGUDEV -static gboolean -has_udev_property (GUdevDevice *udev_device, - const char *property_name) -{ - g_autoptr (GUdevDevice) parent_udev_device = NULL; - - if (NULL != g_udev_device_get_property (udev_device, property_name)) - return TRUE; - - parent_udev_device = g_udev_device_get_parent (udev_device); - - if (!parent_udev_device) - return FALSE; - - return g_udev_device_get_property (parent_udev_device, property_name) != NULL; -} -#endif - -static ClutterInputDevice * -create_device (MetaSeatX11 *seat_x11, - ClutterBackend *clutter_backend, - XIDeviceInfo *info) -{ - Display *xdisplay = xdisplay_from_seat (seat_x11); - ClutterInputDeviceType source, touch_source; - ClutterInputCapabilities capabilities = 0; - ClutterInputDevice *retval; - ClutterInputMode mode; - uint32_t num_touches = 0, num_rings = 0, num_strips = 0; - guint vendor_id = 0, product_id = 0; - char *node_path = NULL; - - if (info->use == XIMasterKeyboard || info->use == XISlaveKeyboard) - { - source = CLUTTER_KEYBOARD_DEVICE; - capabilities = CLUTTER_INPUT_CAPABILITY_KEYBOARD; - } - else if (is_touchpad_device (seat_x11, info)) - { - source = CLUTTER_TOUCHPAD_DEVICE; - } - else if (info->use == XISlavePointer && - is_touch_device (info->classes, info->num_classes, - &touch_source, &capabilities, - &num_touches)) - { - source = touch_source; - } - else if (!guess_source_from_wacom_type (seat_x11, info, &source, &capabilities)) - { - char *name; - - name = g_ascii_strdown (info->name, -1); - - if (strstr (name, "eraser") != NULL) - { - source = CLUTTER_ERASER_DEVICE; - capabilities = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL; - } - else if (strstr (name, "cursor") != NULL) - { - source = CLUTTER_CURSOR_DEVICE; - capabilities = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL; - } - else if (strstr (name, " pad") != NULL) - { - source = CLUTTER_PAD_DEVICE; - capabilities = CLUTTER_INPUT_CAPABILITY_TABLET_PAD; - } - else if (strstr (name, "wacom") != NULL || strstr (name, "pen") != NULL) - { - source = CLUTTER_PEN_DEVICE; - capabilities = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL; - } - else if (strstr (name, "touchpad") != NULL) - { - source = CLUTTER_TOUCHPAD_DEVICE; - capabilities = - CLUTTER_INPUT_CAPABILITY_POINTER | - CLUTTER_INPUT_CAPABILITY_TOUCHPAD; - } - else - { - source = CLUTTER_POINTER_DEVICE; - capabilities = CLUTTER_INPUT_CAPABILITY_POINTER; - } - - 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 (seat_x11, info, &vendor_id, &product_id); - node_path = get_device_node_path (seat_x11, info); - } - -#ifdef HAVE_LIBGUDEV - if (node_path) - { - g_autoptr (GUdevDevice) udev_device = NULL; - - udev_device = g_udev_client_query_by_device_file (seat_x11->udev_client, - node_path); - if (udev_device) - { - if (has_udev_property (udev_device, "ID_INPUT_TRACKBALL")) - capabilities |= CLUTTER_INPUT_CAPABILITY_TRACKBALL; - if (has_udev_property (udev_device, "ID_INPUT_POINTINGSTICK")) - capabilities |= CLUTTER_INPUT_CAPABILITY_TRACKPOINT; - } - } -#endif - - if (source == CLUTTER_PAD_DEVICE) - get_pad_features (info, &num_rings, &num_strips); - - retval = g_object_new (META_TYPE_INPUT_DEVICE_X11, - "backend", seat_x11->backend, - "name", info->name, - "id", info->deviceid, - "has-cursor", (info->use == XIMasterPointer), - "device-type", source, - "capabilities", capabilities, - "device-mode", mode, - "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 (xdisplay, retval, - info->classes, - info->num_classes); - - 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 (MetaSeatX11 *seat_x11, - ClutterInputDevice *device) -{ - Display *xdisplay = xdisplay_from_seat (seat_x11); - Window root_xwindow = root_xwindow_from_seat (seat_x11); - 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); - - mtk_x11_error_trap_push (xdisplay); - rc = XIGrabButton (xdisplay, - device_id, XIAnyButton, - root_xwindow, 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 (xdisplay, device_id, XIAsyncDevice, CLUTTER_CURRENT_TIME); - } - - mtk_x11_error_trap_pop (xdisplay); - - 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 *clutter_backend, - XIDeviceInfo *info) -{ - ClutterInputDevice *device; - - device = create_device (seat_x11, clutter_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 (seat_x11, 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 void -update_tool (MetaSeatX11 *seat_x11, - ClutterInputDevice *device, - int serial_id) -{ - ClutterInputDeviceTool *tool = NULL; - ClutterInputDeviceToolType type; - MetaInputSettings *input_settings; - int lookup_serial; - - if (serial_id != 0) - { - /* stylus and eraser share the same serial, so bitflip the eraser's - * serial to make them distinct in the hashtable */ - if (clutter_input_device_get_device_type (device) == CLUTTER_ERASER_DEVICE) - { - lookup_serial = ~serial_id; - type = CLUTTER_INPUT_DEVICE_TOOL_ERASER; - } - else - { - lookup_serial = serial_id; - type = CLUTTER_INPUT_DEVICE_TOOL_PEN; - } - - tool = g_hash_table_lookup (seat_x11->tools_by_serial, - GUINT_TO_POINTER (lookup_serial)); - if (!tool) - { - tool = meta_input_device_tool_x11_new (serial_id, type); - g_hash_table_insert (seat_x11->tools_by_serial, - GUINT_TO_POINTER (lookup_serial), - tool); - } - } - - meta_input_device_x11_update_tool (device, tool); - input_settings = meta_backend_get_input_settings (seat_x11->backend); - meta_input_settings_notify_tool_change (input_settings, device, tool); -} - -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; - ClutterEventType event_type; - gboolean is_touch, is_tablet_tool; - unsigned int serial; - ClutterInputDeviceType type; - - event_type = clutter_event_type (event); - - if (event_type != CLUTTER_DEVICE_ADDED && - event_type != CLUTTER_DEVICE_REMOVED) - return TRUE; - - device = clutter_event_get_device (event); - type = clutter_input_device_get_device_type (device); - is_touch = type == CLUTTER_TOUCHSCREEN_DEVICE; - is_tablet_tool = type == CLUTTER_PEN_DEVICE || type == CLUTTER_ERASER_DEVICE; - input_settings = meta_backend_get_input_settings (seat_x11->backend); - - switch (event_type) - { - case CLUTTER_DEVICE_ADDED: - meta_input_settings_add_device (input_settings, device); - seat_x11->has_touchscreens |= is_touch; - if (is_tablet_tool && guess_serial_from_libinput_prop (seat_x11, device, &serial)) - update_tool(seat_x11, device, serial); - 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 (MetaSeatX11 *seat_x11, - ClutterInputDevice *device) -{ - Display *xdisplay = xdisplay_from_seat (seat_x11); - gulong nitems, bytes_after; - uint32_t *data = NULL; - int serial_id = 0; - int rc, format; - Atom type; - Atom prop; - - prop = XInternAtom (xdisplay, "Wacom Serial IDs", True); - if (prop == None) - return 0; - - mtk_x11_error_trap_push (xdisplay); - rc = XIGetProperty (xdisplay, - meta_input_device_x11_get_device_id (device), - prop, 0, 4, FALSE, XA_INTEGER, &type, &format, &nitems, &bytes_after, - (guchar **) &data); - mtk_x11_error_trap_pop (xdisplay); - - if (rc == Success && type == XA_INTEGER && format == 32 && nitems >= 4) - serial_id = data[3]; - - XFree (data); - - return serial_id; -} - -static ClutterEvent * -translate_hierarchy_event (ClutterBackend *clutter_backend, - MetaSeatX11 *seat_x11, - XIHierarchyEvent *ev) -{ - Display *xdisplay = xdisplay_from_seat (seat_x11); - int i; - ClutterEvent *event = NULL; - - 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"); - - mtk_x11_error_trap_push (xdisplay); - info = XIQueryDevice (xdisplay, - ev->info[i].deviceid, - &n_devices); - mtk_x11_error_trap_pop (xdisplay); - if (info != NULL) - { - ClutterInputDevice *device; - - device = add_device (seat_x11, clutter_backend, &info[0]); - - event = clutter_event_device_notify_new (CLUTTER_DEVICE_ADDED, - CLUTTER_EVENT_NONE, - ms2us (ev->time), - device); - 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 = clutter_event_device_notify_new (CLUTTER_DEVICE_REMOVED, - CLUTTER_EVENT_NONE, - ms2us (ev->time), - device); - } - } - 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 event; -} - -static void -translate_property_event (MetaSeatX11 *seat_x11, - XIEvent *event) -{ - Display *xdisplay = xdisplay_from_seat (seat_x11); - XIPropertyEvent *xev = (XIPropertyEvent *) event; - Atom serial_ids_prop; - ClutterInputDevice *device; - - serial_ids_prop = XInternAtom (xdisplay, "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) - { - int serial_id; - - serial_id = device_get_tool_serial (seat_x11, device); - update_tool(seat_x11, device, serial_id); - } -} - -static void -emulate_motion (MetaSeatX11 *seat_x11, - double x, - double y) -{ - ClutterEvent *event; - - event = clutter_event_motion_new (CLUTTER_EVENT_FLAG_SYNTHETIC, - CLUTTER_CURRENT_TIME, - seat_x11->core_pointer, - NULL, 0, - GRAPHENE_POINT_INIT ((float) x, (float) y), - GRAPHENE_POINT_INIT (0, 0), - GRAPHENE_POINT_INIT (0, 0), - GRAPHENE_POINT_INIT (0, 0), - NULL); - - clutter_event_put (event); - clutter_event_free (event); -} - -static void -translate_raw_event (MetaSeatX11 *seat_x11, - XEvent *xevent) -{ - ClutterSeat *seat = CLUTTER_SEAT (seat_x11); - 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_seat_is_pointer_a11y_enabled (seat)) - _clutter_seat_a11y_on_motion_event (seat, 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_seat_is_pointer_a11y_enabled (seat)) - { - _clutter_seat_a11y_on_button_event (seat, - 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 ClutterEvent * -translate_pad_axis_event (XIDeviceEvent *xev, - ClutterInputDevice *device) -{ - double value; - uint32_t number, mode = 0; - ClutterEventType evtype; - ClutterEvent *event = NULL; - - if (!translate_pad_axis (device, &xev->valuators, - &evtype, &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 (evtype == CLUTTER_PAD_RING) - { - event = clutter_event_pad_ring_new (CLUTTER_EVENT_NONE, - ms2us (xev->time), - device, - CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN, - number, - 0, - value, - mode); - } - else - { - event = clutter_event_pad_strip_new (CLUTTER_EVENT_NONE, - ms2us (xev->time), - device, - CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN, - number, - 0, - value, - mode); - } - - g_debug ("%s: win:0x%x, device:%d '%s', time:%lu " - "(value:%f)", - evtype == 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), - xev->time, value); - - return event; -} - -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 (seat_x11->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 = (float) CLAMP (event_x, 0, stage_width); - *y_out = (float) CLAMP (event_y, 0, stage_height); -} - -static void -on_keymap_state_change (MetaKeymapX11 *keymap_x11, - gpointer data) -{ - ClutterSeat *seat = data; - MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); - 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 (seat_x11->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_BACKEND: - seat_x11->backend = g_value_get_object (value); - break; - 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_BACKEND: - g_value_set_object (value, seat_x11->backend); - break; - 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_device_notify_new (CLUTTER_DEVICE_ADDED, - CLUTTER_EVENT_NONE, - CLUTTER_CURRENT_TIME, - device); - clutter_event_put (event); - clutter_event_free (event); - } -} - -static void -meta_seat_x11_constructed (GObject *object) -{ - MetaSeatX11 *seat_x11 = META_SEAT_X11 (object); - Display *xdisplay = xdisplay_from_seat (seat_x11); - Window root_xwindow = root_xwindow_from_seat (seat_x11); - ClutterBackend *clutter_backend = - meta_backend_get_clutter_backend (seat_x11->backend); - XIDeviceInfo *info; - XIEventMask event_mask; - unsigned char mask[XIMaskLen(XI_LASTEVENT)] = { 0, }; - int n_devices, i; -#ifdef HAVE_LIBGUDEV - const char *udev_subsystems[] = { "input", NULL }; - - seat_x11->udev_client = g_udev_client_new (udev_subsystems); -#endif - - 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, clutter_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, root_xwindow, - &event_mask, 1); - - memset(mask, 0, sizeof (mask)); - XISetMask (mask, XI_RawMotion); - XISetMask (mask, XI_RawButtonPress); - XISetMask (mask, XI_RawButtonRelease); - - if (meta_backend_x11_get_barriers (META_BACKEND_X11 (seat_x11->backend))) - { - XISetMask (mask, XI_BarrierHit); - XISetMask (mask, XI_BarrierLeave); - } - - event_mask.deviceid = XIAllMasterDevices; - event_mask.mask_len = sizeof (mask); - event_mask.mask = mask; - - XISelectEvents (xdisplay, root_xwindow, - &event_mask, 1); - - XSync (xdisplay, False); - - seat_x11->keymap = g_object_new (META_TYPE_KEYMAP_X11, - "backend", seat_x11->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); - -#ifdef HAVE_LIBGUDEV - g_clear_object (&seat_x11->udev_client); -#endif - - 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) -{ - MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); - MetaContext *context = meta_backend_get_context (seat_x11->backend); - MetaDisplay *display = meta_context_get_display (context); - - 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); - Display *xdisplay = xdisplay_from_seat (seat_x11); - Window root_xwindow = root_xwindow_from_seat (seat_x11); - - mtk_x11_error_trap_push (xdisplay); - XIWarpPointer (xdisplay, - seat_x11->pointer_id, - None, - root_xwindow, - 0, 0, 0, 0, - x, y); - mtk_x11_error_trap_pop (xdisplay); -} - -static void -meta_seat_x11_init_pointer_position (ClutterSeat *seat, - float x, - float y) -{ - MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); - Display *xdisplay = xdisplay_from_seat (seat_x11); - Window root_xwindow = root_xwindow_from_seat (seat_x11); - - mtk_x11_error_trap_push (xdisplay); - XIWarpPointer (xdisplay, - seat_x11->pointer_id, - None, - root_xwindow, - 0, 0, 0, 0, - (int) x, (int) y); - mtk_x11_error_trap_pop (xdisplay); -} - -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, - ClutterSprite *sprite, - graphene_point_t *coords, - ClutterModifierType *modifiers) -{ - MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (seat_x11->backend); - Display *xdisplay = xdisplay_from_seat (seat_x11); - ClutterEventSequence *sequence = NULL; - Window root_ret, child_ret; - double root_x, root_y, win_x, win_y; - XIButtonState button_state = { 0 }; - XIModifierState modifier_state; - XIGroupState group_state; - - mtk_x11_error_trap_push (xdisplay); - XIQueryPointer (xdisplay, - 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 (mtk_x11_error_trap_pop_with_return (xdisplay)) - { - g_free (button_state.mask); - return FALSE; - } - - if (sprite) - sequence = clutter_sprite_get_sequence (sprite); - - 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 = (float) touch_info->x; - coords->y = (float) touch_info->y; - } - } - else - { - if (coords) - { - coords->x = (float) win_x; - coords->y = (float) 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 ClutterGrabState -meta_seat_x11_grab (ClutterSeat *seat, - uint32_t time) -{ - MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); - MetaBackend *backend = seat_x11->backend; - ClutterGrabState state = CLUTTER_GRAB_STATE_NONE; - - g_return_val_if_fail (seat_x11->grab_state == CLUTTER_GRAB_STATE_NONE, - seat_x11->grab_state); - - if (meta_backend_grab_device (backend, - META_VIRTUAL_CORE_POINTER_ID, - time)) - state |= CLUTTER_GRAB_STATE_POINTER; - - if (meta_backend_grab_device (backend, - META_VIRTUAL_CORE_KEYBOARD_ID, - time)) - state |= CLUTTER_GRAB_STATE_KEYBOARD; - - seat_x11->grab_state = state; - - meta_backend_x11_sync_pointer (META_BACKEND_X11 (backend)); - - return state; -} - -static void -meta_seat_x11_ungrab (ClutterSeat *seat, - uint32_t time) -{ - MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); - MetaBackend *backend = seat_x11->backend; - - if ((seat_x11->grab_state & CLUTTER_GRAB_STATE_POINTER) != 0) - { - meta_backend_ungrab_device (backend, - META_VIRTUAL_CORE_POINTER_ID, - time); - } - - if ((seat_x11->grab_state & CLUTTER_GRAB_STATE_KEYBOARD) != 0) - { - meta_backend_ungrab_device (backend, - META_VIRTUAL_CORE_KEYBOARD_ID, - time); - } - - seat_x11->grab_state = CLUTTER_GRAB_STATE_NONE; - - meta_backend_x11_sync_pointer (META_BACKEND_X11 (backend)); -} - -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->init_pointer_position = meta_seat_x11_init_pointer_position; - seat_class->handle_event_post = meta_seat_x11_handle_event_post; - seat_class->query_state = meta_seat_x11_query_state; - seat_class->grab = meta_seat_x11_grab; - seat_class->ungrab = meta_seat_x11_ungrab; - - props[PROP_BACKEND] = - g_param_spec_object ("backend", NULL, NULL, - META_TYPE_BACKEND, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY); - props[PROP_OPCODE] = - g_param_spec_int ("opcode", NULL, NULL, - 0, G_MAXINT, 0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY); - props[PROP_POINTER_ID] = - g_param_spec_int ("pointer-id", NULL, NULL, - 2, G_MAXINT, 2, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY); - props[PROP_KEYBOARD_ID] = - g_param_spec_int ("keyboard-id", NULL, NULL, - 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 (MetaBackend *backend, - int opcode, - int logical_pointer, - int logical_keyboard) -{ - MetaSeatX11 *seat_x11; - ClutterContext *clutter_context = - meta_backend_get_clutter_context (backend); - - seat_x11 = g_object_new (META_TYPE_SEAT_X11, - "backend", backend, - "context", clutter_context, - "opcode", opcode, - "pointer-id", logical_pointer, - "keyboard-id", logical_keyboard, - NULL); - - return seat_x11; -} - -MetaBackend * -meta_seat_x11_get_backend (MetaSeatX11 *seat_x11) -{ - return seat_x11->backend; -} - -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; -} - -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; - } -} - -ClutterEvent * -meta_seat_x11_translate_event (MetaSeatX11 *seat, - XEvent *xevent) -{ - Display *xdisplay = xdisplay_from_seat (seat); - ClutterBackend *clutter_backend = - meta_backend_get_clutter_backend (seat->backend); - ClutterStage *stage = NULL; - MetaStageX11 *stage_x11 = NULL; - ClutterInputDevice *device, *source_device; - XGenericEventCookie *cookie; - ClutterEvent *event = NULL; - XIEvent *xi_event; - - if (meta_keymap_x11_handle_event (seat->keymap, xevent)) - return NULL; - - cookie = &xevent->xcookie; - - if (cookie->type != GenericEvent || - cookie->extension != seat->opcode) - return NULL; - - xi_event = (XIEvent *) cookie->data; - - if (!xi_event) - return NULL; - - if (cookie->evtype == XI_RawMotion || - cookie->evtype == XI_RawButtonPress || - cookie->evtype == XI_RawButtonRelease) - { - translate_raw_event (seat, xevent); - return NULL; - } - - 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 NULL; - else - stage_x11 = META_STAGE_X11 (_clutter_stage_get_window (stage)); - } - - switch (xi_event->evtype) - { - case XI_HierarchyChanged: - { - XIHierarchyEvent *xev = (XIHierarchyEvent *) xi_event; - - event = translate_hierarchy_event (clutter_backend, seat, xev); - } - 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 (xdisplay, - device, - xev->classes, - xev->num_classes); - } - - if (source_device) - meta_input_device_x11_reset_scroll_info (source_device); - } - break; - case XI_KeyPress: - case XI_KeyRelease: - { - XIDeviceEvent *xev = (XIDeviceEvent *) xi_event; - MetaKeymapX11 *keymap_x11 = seat->keymap; - char buffer[7] = { 0, }; - uint32_t keyval, evcode, keycode; - ClutterModifierSet raw_modifiers; - ClutterModifierType state; - int len; - gunichar unicode_value; - - source_device = get_source_device_checked (seat, xev); - if (!source_device) - return NULL; - - raw_modifiers = (ClutterModifierSet) { - .pressed = xev->mods.base, - .latched = xev->mods.latched, - .locked = xev->mods.locked, - }; - - state = translate_state (&xev->buttons, &xev->mods, &xev->group); - - 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. */ - evcode = keycode - 8; - - /* keyval is the key ignoring all modifiers ('1' vs. '!') */ - keyval = meta_keymap_x11_translate_key_state (keymap_x11, - keycode, - &state, - NULL); - - /* XXX keep this in sync with the evdev device manager */ - len = print_keysym (keyval, buffer, sizeof (buffer)); - if (len == 0) - { - /* not printable */ - unicode_value = (gunichar) '\0'; - } - else - { - unicode_value = g_utf8_get_char_validated (buffer, len); - if (unicode_value == -1 || - unicode_value == -2) - unicode_value = (gunichar) '\0'; - } - - event = clutter_event_key_new ((xev->evtype == XI_KeyPress) ? - CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE, - (xev->evtype == XI_KeyPress && - xev->flags & XIKeyRepeat) ? - CLUTTER_EVENT_FLAG_REPEATED : - CLUTTER_EVENT_NONE, - ms2us (xev->time), - source_device, - raw_modifiers, - state, - keyval, - evcode, - keycode, - unicode_value); - - g_debug ("%s: win:0x%x device:%d source:%d, key: %12s (%d)", - clutter_event_type (event) == CLUTTER_KEY_PRESS - ? "key press " - : "key release", - (unsigned int) stage_x11->xwin, - xev->deviceid, - xev->sourceid, - keyval ? buffer : "(none)", - keyval); - - if (xi_event->evtype == XI_KeyPress) - meta_stage_x11_set_user_time (stage_x11, xev->time); - } - break; - - case XI_ButtonPress: - case XI_ButtonRelease: - { - XIDeviceEvent *xev = (XIDeviceEvent *) xi_event; - ClutterScrollDirection scroll_direction; - ClutterModifierType state; - ClutterInputDeviceTool *tool; - float x, y; - int button; - uint32_t evdev_code; - double *axes; - - source_device = get_source_device_checked (seat, xev); - if (!source_device) - return NULL; - - 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) - { - uint32_t pad_button, group = 0, mode = 0; - - /* We got these events because of the passive button grab */ - XIAllowEvents (xdisplay, xev->sourceid, XIAsyncDevice, xev->time); - - if (xev->detail >= 4 && xev->detail <= 7) - { - if (xi_event->evtype == XI_ButtonPress) - event = translate_pad_axis_event (xev, source_device); - break; - } - - /* 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 */ - pad_button = xev->detail - 1; - -#ifdef HAVE_LIBWACOM - meta_input_device_x11_update_pad_state (device, - pad_button, - (xi_event->evtype == XI_ButtonPress), - &group, - &mode); -#endif - - event = clutter_event_pad_button_new ((xi_event->evtype == XI_ButtonPress) ? - CLUTTER_PAD_BUTTON_PRESS : - CLUTTER_PAD_BUTTON_RELEASE, - CLUTTER_EVENT_NONE, - us2ms (xev->time), - source_device, - pad_button, - group, - mode); - - g_debug ("%s: win:0x%x, device:%d '%s', time:%lu " - "(button:%d)", - (xi_event->evtype == XI_ButtonPress) - ? "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), - xev->time, - pad_button); - 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 NULL; - - if (xev->detail == 4) - scroll_direction = CLUTTER_SCROLL_UP; - else if (xev->detail == 5) - scroll_direction = CLUTTER_SCROLL_DOWN; - else if (xev->detail == 6) - scroll_direction = CLUTTER_SCROLL_LEFT; - else - scroll_direction = CLUTTER_SCROLL_RIGHT; - - translate_coords (stage_x11, xev->event_x, xev->event_y, &x, &y); - state = translate_state (&xev->buttons, &xev->mods, &xev->group); - tool = meta_input_device_x11_get_current_tool (source_device); - - event = clutter_event_scroll_discrete_new (CLUTTER_EVENT_NONE, - ms2us (xev->time), - source_device, - tool, - state, - GRAPHENE_POINT_INIT (x, y), - CLUTTER_SCROLL_NONE, - CLUTTER_SCROLL_SOURCE_UNKNOWN, - scroll_direction); - - 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), - clutter_event_get_time (event), - scroll_direction == CLUTTER_SCROLL_UP ? "up" : - scroll_direction == CLUTTER_SCROLL_DOWN ? "down" : - scroll_direction == CLUTTER_SCROLL_LEFT ? "left" : - scroll_direction == CLUTTER_SCROLL_RIGHT ? "right" : - "invalid", - x, y, - (xev->flags & XIPointerEmulated) ? "yes" : "no"); - break; - - default: - translate_coords (stage_x11, xev->event_x, xev->event_y, &x, &y); - button = xev->detail; - evdev_code = evdev_button_code (xev->detail); - state = translate_state (&xev->buttons, &xev->mods, &xev->group); - tool = meta_input_device_x11_get_current_tool (source_device); - axes = translate_axes (device, x, y, &xev->valuators); - - /* 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 (xi_event->evtype) - { - case XI_ButtonPress: - state |= (get_modifier_for_button (button)); - break; - case XI_ButtonRelease: - state &= ~(get_modifier_for_button (button)); - break; - default: - break; - } - - event = clutter_event_button_new ((xi_event->evtype == XI_ButtonPress) ? - CLUTTER_BUTTON_PRESS : - CLUTTER_BUTTON_RELEASE, - (xev->flags & XIPointerEmulated) ? - CLUTTER_EVENT_FLAG_POINTER_EMULATED : - CLUTTER_EVENT_NONE, - ms2us (xev->time), - source_device, - tool, - state, - GRAPHENE_POINT_INIT (x, y), - button, - evdev_code, - axes); - - g_debug ("%s: win:0x%x, device:%d '%s', time:%lu " - "(button:%d, " - "x:%.2f, y:%.2f, " - "axes:%s, " - "emulated:%s)", - (xi_event->evtype == XI_ButtonPress) - ? "button press " - : "button release", - (unsigned int) stage_x11->xwin, - meta_input_device_x11_get_device_id (device), - clutter_input_device_get_device_name (device), - xev->time, - xev->detail, - x, y, - axes != NULL ? "yes" : "no", - (xev->flags & XIPointerEmulated) ? "yes" : "no"); - break; - } - - if (xi_event->evtype == XI_ButtonPress) - meta_stage_x11_set_user_time (stage_x11, xev->time); - } - break; - - case XI_Motion: - { - XIDeviceEvent *xev = (XIDeviceEvent *) xi_event; - double delta_x, delta_y; - ClutterModifierType state; - ClutterInputDeviceTool *tool; - float x, y; - double *axes; - - source_device = get_source_device_checked (seat, xev); - if (!source_device) - break; - - 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 = translate_pad_axis_event (xev, source_device); - break; - } - - translate_coords (stage_x11, xev->event_x, xev->event_y, &x, &y); - state = translate_state (&xev->buttons, &xev->mods, &xev->group); - tool = meta_input_device_x11_get_current_tool (source_device); - - if (scroll_valuators_changed (source_device, - &xev->valuators, - &delta_x, &delta_y)) - { - event = clutter_event_scroll_smooth_new (CLUTTER_EVENT_NONE, - ms2us (xev->time), - source_device, - tool, - state, - GRAPHENE_POINT_INIT (x, y), - GRAPHENE_POINT_INIT ((float) delta_x, - (float) delta_y), - CLUTTER_SCROLL_NONE, - CLUTTER_SCROLL_SOURCE_UNKNOWN, - CLUTTER_SCROLL_FINISHED_NONE); - - 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 (source_device), - clutter_input_device_get_device_name (source_device), - x, y, - delta_x, delta_y); - break; - } - - axes = translate_axes (device, x, y, &xev->valuators); - event = clutter_event_motion_new ((xev->flags & XIPointerEmulated) ? - CLUTTER_EVENT_FLAG_POINTER_EMULATED : - CLUTTER_EVENT_NONE, - ms2us (xev->time), - source_device, - tool, - state, - GRAPHENE_POINT_INIT (x, y), - GRAPHENE_POINT_INIT (0, 0), - GRAPHENE_POINT_INIT (0, 0), - GRAPHENE_POINT_INIT (0, 0), - axes); - - 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 (source_device), - clutter_input_device_get_device_name (source_device), - x, y, - axes != NULL ? "yes" : "no"); - } - break; - - case XI_TouchBegin: - case XI_TouchEnd: - { - XIDeviceEvent *xev = (XIDeviceEvent *) xi_event; - ClutterEventType evtype; - ClutterModifierType state; - ClutterEventSequence *sequence; - float x, y; - - 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_TouchBegin) - evtype = CLUTTER_TOUCH_BEGIN; - else - evtype = CLUTTER_TOUCH_END; - - translate_coords (stage_x11, xev->event_x, xev->event_y, &x, &y); - state = translate_state (&xev->buttons, &xev->mods, &xev->group); - /* "NULL" sequences are special cased in clutter */ - sequence = GINT_TO_POINTER (MAX (1, xev->detail + 1)); - - if (xi_event->evtype == XI_TouchBegin) - { - state |= CLUTTER_BUTTON1_MASK; - - meta_stage_x11_set_user_time (stage_x11, xev->time); - meta_seat_x11_update_touchpoint (seat, - sequence, - xev->root_x, - xev->root_y); - - if (xev->flags & XITouchEmulatingPointer) - seat->pointer_emulating_sequence = sequence; - else if (seat->pointer_emulating_sequence == sequence) - seat->pointer_emulating_sequence = NULL; - } - else if (xi_event->evtype == XI_TouchEnd) - { - meta_seat_x11_remove_touchpoint (seat, sequence); - } - - event = clutter_event_touch_new (evtype, - (xev->flags & XITouchEmulatingPointer) ? - CLUTTER_EVENT_FLAG_POINTER_EMULATED : - CLUTTER_EVENT_NONE, - ms2us (xev->time), - source_device, - sequence, - state, - GRAPHENE_POINT_INIT (x, y)); - - g_debug ("touch %s: win:0x%x device:%d '%s' (seq:%d, x:%.2f, y:%.2f)", - evtype == CLUTTER_TOUCH_BEGIN ? "begin" : "end", - (unsigned int) stage_x11->xwin, - meta_input_device_x11_get_device_id (device), - clutter_input_device_get_device_name (device), - GPOINTER_TO_UINT (sequence), - x, y); - } - break; - - case XI_TouchUpdate: - { - XIDeviceEvent *xev = (XIDeviceEvent *) xi_event; - ClutterEventSequence *sequence; - ClutterModifierType state; - float x, y; - - 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)); - - /* "NULL" sequences are special cased in clutter */ - sequence = GINT_TO_POINTER (MAX (1, xev->detail + 1)); - translate_coords (stage_x11, xev->event_x, xev->event_y, &x, &y); - state = translate_state (&xev->buttons, &xev->mods, &xev->group); - state |= CLUTTER_BUTTON1_MASK; - - meta_seat_x11_update_touchpoint (seat, - sequence, - xev->root_x, - xev->root_y); - - event = clutter_event_touch_new (CLUTTER_TOUCH_UPDATE, - (xev->flags & XITouchEmulatingPointer) ? - CLUTTER_EVENT_FLAG_POINTER_EMULATED : - CLUTTER_EVENT_NONE, - ms2us (xev->time), - source_device, - sequence, - state, - GRAPHENE_POINT_INIT (x, y)); - - g_debug ("touch update: win:0x%x device:%d '%s' (seq:%d, x:%.2f, y:%.2f)", - (unsigned int) stage_x11->xwin, - meta_input_device_x11_get_device_id (device), - clutter_input_device_get_device_name (device), - GPOINTER_TO_UINT (sequence), - x, y); - } - break; - - case XI_Enter: - case XI_Leave: - { - XIEnterEvent *xev = (XIEnterEvent *) xi_event; - float x, y; - - 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)); - - translate_coords (stage_x11, xev->event_x, xev->event_y, &x, &y); - - event = clutter_event_crossing_new ((xi_event->evtype == XI_Enter) ? - CLUTTER_ENTER : CLUTTER_LEAVE, - CLUTTER_EVENT_NONE, - ms2us (xev->time), - device, - NULL, - GRAPHENE_POINT_INIT (x, y), - CLUTTER_ACTOR (stage), NULL); - - if (xev->deviceid == seat->pointer_id) - seat->has_pointer_focus = (xi_event->evtype == XI_Enter); - - meta_input_device_x11_reset_scroll_info (source_device); - } - break; - - case XI_FocusIn: - case XI_FocusOut: - break; - case XI_PropertyEvent: - translate_property_event (seat, xi_event); - break; - } - - return event; -} - -void -meta_seat_x11_select_stage_events (MetaSeatX11 *seat, - ClutterStage *stage) -{ - Display *xdisplay = xdisplay_from_seat (seat); - 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 (xdisplay, stage_x11->xwin, &xi_event_mask, 1); - - g_free (mask); -} - -ClutterInputDevice * -meta_seat_x11_get_core_pointer (MetaSeatX11 *seat_x11) -{ - return seat_x11->core_pointer; -} - -ClutterEventSequence * -meta_seat_x11_get_pointer_emulating_sequence (MetaSeatX11 *seat_x11) -{ - return seat_x11->pointer_emulating_sequence; -} diff --git a/src/backends/x11/meta-seat-x11.h b/src/backends/x11/meta-seat-x11.h deleted file mode 100644 index ff8114532be..00000000000 --- a/src/backends/x11/meta-seat-x11.h +++ /dev/null @@ -1,47 +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 . - * - * Author: Carlos Garnacho - */ - -#pragma once - -#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 (MetaBackend *backend, - int opcode, - int logical_pointer, - int logical_keyboard); - -MetaBackend * meta_seat_x11_get_backend (MetaSeatX11 *seat_x11); - -ClutterEvent * meta_seat_x11_translate_event (MetaSeatX11 *seat, - XEvent *xevent); -void meta_seat_x11_select_stage_events (MetaSeatX11 *seat, - ClutterStage *stage); -void meta_seat_x11_notify_devices (MetaSeatX11 *seat_x11, - ClutterStage *stage); - -ClutterInputDevice * meta_seat_x11_get_core_pointer (MetaSeatX11 *seat_x11); - -ClutterEventSequence * meta_seat_x11_get_pointer_emulating_sequence (MetaSeatX11 *seat_x11); - -G_END_DECLS diff --git a/src/backends/x11/meta-sprite-x11.c b/src/backends/x11/meta-sprite-x11.c deleted file mode 100644 index 65be8369f50..00000000000 --- a/src/backends/x11/meta-sprite-x11.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2024 Red Hat - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * Author: Carlos Garnacho - */ - -#include "config.h" - -#include "backends/x11/meta-sprite-x11.h" - -G_DEFINE_TYPE (MetaSpriteX11, meta_sprite_x11, META_TYPE_SPRITE) - -static void -meta_sprite_x11_init (MetaSpriteX11 *sprite_x11) -{ -} - -static void -meta_sprite_x11_class_init (MetaSpriteX11Class *klass) -{ -} diff --git a/src/backends/x11/meta-sprite-x11.h b/src/backends/x11/meta-sprite-x11.h deleted file mode 100644 index ce43192d7d6..00000000000 --- a/src/backends/x11/meta-sprite-x11.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2024 Red Hat - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * Author: Carlos Garnacho - */ - -#pragma once - -#include "backends/meta-sprite.h" - -#define META_TYPE_SPRITE_X11 meta_sprite_x11_get_type () -G_DECLARE_DERIVABLE_TYPE (MetaSpriteX11, - meta_sprite_x11, - META, SPRITE_X11, - MetaSprite) - -struct _MetaSpriteX11Class -{ - MetaSpriteClass parent_class; -}; diff --git a/src/backends/x11/meta-stage-x11.c b/src/backends/x11/meta-stage-x11.c deleted file mode 100644 index c9b206bd33f..00000000000 --- a/src/backends/x11/meta-stage-x11.c +++ /dev/null @@ -1,804 +0,0 @@ -/* - * Authored By Matthew Allum - * Copyright (C) 2006-2007 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - */ - -#include "config.h" - -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#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" - -#define STAGE_X11_IS_MAPPED(s) ((((MetaStageX11 *) (s))->wm_state & STAGE_X11_WITHDRAWN) == 0) - -static MetaStageImpl *meta_x11_get_stage_window_from_window (Window win); - -static GHashTable *clutter_stages_by_xid = NULL; - -G_DEFINE_TYPE (MetaStageX11, meta_stage_x11, META_TYPE_STAGE_IMPL) - -#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 MetaClutterBackendX11 * -clutter_backend_x11_from_stage (MetaStageX11 *stage_x11) -{ - MetaBackend *backend = - meta_stage_impl_get_backend (META_STAGE_IMPL (stage_x11)); - - return META_CLUTTER_BACKEND_X11 (meta_backend_get_clutter_backend (backend)); -} - -static Display * -xdisplay_from_stage (MetaStageX11 *stage_x11) -{ - MetaBackend *backend = - meta_stage_impl_get_backend (META_STAGE_IMPL (stage_x11)); - - return meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); -} - -static void -meta_stage_x11_fix_window_size (MetaStageX11 *stage_x11, - int new_width, - int new_height) -{ - g_return_if_fail (new_width > 0); - g_return_if_fail (new_height > 0); - - if (stage_x11->xwin != None) - { - Display *xdisplay = xdisplay_from_stage (stage_x11); - XSizeHints *size_hints; - - size_hints = XAllocSizeHints(); - - 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) -{ - MetaClutterBackendX11 *clutter_backend_x11 = - clutter_backend_x11_from_stage (stage_x11); - Display *xdisplay = xdisplay_from_stage (stage_x11); - Atom protocols[2]; - int n = 0; - - protocols[n++] = clutter_backend_x11->atom_WM_DELETE_WINDOW; - protocols[n++] = clutter_backend_x11->atom_NET_WM_PING; - - XSetWMProtocols (xdisplay, stage_x11->xwin, protocols, n); -} - -static void -meta_stage_x11_get_geometry (ClutterStageWindow *stage_window, - MtkRectangle *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 = xdisplay_from_stage (stage_x11); - - /* 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); - MetaBackend *backend = meta_stage_impl_get_backend (stage_impl); - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); - MetaClutterBackendX11 *clutter_backend_x11 = - clutter_backend_x11_from_stage (stage_x11); - Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11); - 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, - clutter_backend_x11->atom_NET_WM_PID, XA_CARDINAL, 32, - PropModeReplace, - (guchar *) &pid, 1); -} - -static inline void -set_wm_title (MetaStageX11 *stage_x11) -{ - MetaClutterBackendX11 *clutter_backend_x11 = - clutter_backend_x11_from_stage (stage_x11); - Display *xdisplay = xdisplay_from_stage (stage_x11); - const char *title = g_get_prgname (); - - if (stage_x11->xwin == None || title == NULL) - return; - - XChangeProperty (xdisplay, - stage_x11->xwin, - clutter_backend_x11->atom_NET_WM_NAME, - clutter_backend_x11->atom_UTF8_STRING, - 8, - PropModeReplace, - (unsigned char *) title, - (int) strlen (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_CLASS (meta_stage_x11_parent_class)-> - 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 HAVE_GLX - 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 HAVE_EGL - 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); - MetaBackend *backend = meta_stage_impl_get_backend (stage_impl); - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - MetaSeatX11 *seat_x11 = - META_SEAT_X11 (meta_backend_get_default_seat (backend)); - Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11); - float width, height; - GError *error = NULL; - - clutter_actor_get_size (CLUTTER_ACTOR (stage_impl->wrapper), &width, &height); - - stage_x11->onscreen = create_onscreen (clutter_backend->cogl_context, - (int) width, (int) height); - - if (META_IS_BACKEND_X11_CM (backend)) - { - MetaRenderer *renderer = meta_backend_get_renderer (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 = (int) width; - stage_x11->xwin_height = (int) 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_CLASS (meta_stage_x11_parent_class)->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 inline void -update_wm_hints (MetaStageX11 *stage_x11) -{ - Display *xdisplay = xdisplay_from_stage (stage_x11); - 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 = xdisplay_from_stage (stage_x11); - - 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 = xdisplay_from_stage (stage_x11); - - 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) -{ - MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_window); - MetaBackend *backend = meta_stage_impl_get_backend (stage_impl); - MetaRenderer *renderer = meta_backend_get_renderer (backend); - - return meta_renderer_get_views (renderer); -} - -static void -meta_stage_x11_redraw_view (ClutterStageWindow *stage_window, - ClutterStageView *view, - ClutterFrame *frame) -{ - CLUTTER_STAGE_WINDOW_CLASS (meta_stage_x11_parent_class)->redraw_view (stage_window, view, frame); - clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED); -} - -static void -meta_stage_x11_class_init (MetaStageX11Class *klass) -{ - ClutterStageWindowClass *window_class = CLUTTER_STAGE_WINDOW_CLASS (klass); - - window_class->show = meta_stage_x11_show; - window_class->hide = meta_stage_x11_hide; - window_class->resize = meta_stage_x11_resize; - window_class->get_geometry = meta_stage_x11_get_geometry; - window_class->realize = meta_stage_x11_realize; - window_class->unrealize = meta_stage_x11_unrealize; - window_class->can_clip_redraws = meta_stage_x11_can_clip_redraws; - window_class->get_views = meta_stage_x11_get_views; - window_class->redraw_view = meta_stage_x11_redraw_view; -} - -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; -} - -static inline void -set_user_time (MetaStageX11 *stage_x11, - long timestamp) -{ - MetaClutterBackendX11 *clutter_backend_x11 = - clutter_backend_x11_from_stage (stage_x11); - - if (timestamp != CLUTTER_CURRENT_TIME) - { - Display *xdisplay = xdisplay_from_stage (stage_x11); - - XChangeProperty (xdisplay, - stage_x11->xwin, - clutter_backend_x11->atom_NET_WM_USER_TIME, - XA_CARDINAL, 32, - PropModeReplace, - (unsigned char *) ×tamp, 1); - } -} - -static gboolean -handle_wm_protocols_event (MetaStageX11 *stage_x11, - XEvent *xevent) -{ - MetaClutterBackendX11 *clutter_backend_x11 = - clutter_backend_x11_from_stage (stage_x11); - Atom atom = (Atom) xevent->xclient.data.l[0]; - - if (atom == clutter_backend_x11->atom_WM_DELETE_WINDOW && - xevent->xany.window == stage_x11->xwin) - { - set_user_time (stage_x11, xevent->xclient.data.l[1]); - - return TRUE; - } - else if (atom == clutter_backend_x11->atom_NET_WM_PING && - xevent->xany.window == stage_x11->xwin) - { - MetaBackend *backend = - meta_stage_impl_get_backend (META_STAGE_IMPL (stage_x11)); - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); - Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11); - Window root_xwindow = meta_backend_x11_get_root_xwindow (backend_x11); - XClientMessageEvent xclient = xevent->xclient; - - xclient.window = root_xwindow; - 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 void -clipped_redraws_cool_off_cb (void *data) -{ - MetaStageX11 *stage_x11 = data; - - stage_x11->clipped_redraws_cool_off = 0; -} - -void -meta_stage_x11_handle_event (MetaStageX11 *stage_x11, - XEvent *xevent) -{ - MetaClutterBackendX11 *clutter_backend_x11 = - clutter_backend_x11_from_stage (stage_x11); - MetaBackend *backend; - MetaStageImpl *stage_impl; - ClutterStage *stage; - - stage_impl = meta_x11_get_stage_window_from_window (xevent->xany.window); - if (stage_impl == NULL) - return; - - backend = meta_stage_impl_get_backend (stage_impl); - stage = stage_impl->wrapper; - - 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 (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 = - g_timeout_add_once (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 (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: - clutter_stage_set_active (stage_impl->wrapper, TRUE); - break; - - case FocusOut: - clutter_stage_set_active (stage_impl->wrapper, FALSE); - break; - - case Expose: - { - XExposeEvent *expose = (XExposeEvent *) xevent; - MtkRectangle 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_if_fail (META_IS_STAGE_X11_NESTED (stage_x11)); - meta_context_terminate (meta_backend_get_context (backend)); - 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 (stage_x11, xevent)) - { - g_return_if_fail (META_IS_STAGE_X11_NESTED (stage_x11)); - meta_context_terminate (meta_backend_get_context (backend)); - } - } - - break; - - default: - break; - } -} - -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) -{ - set_user_time (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 eb28a912d42..00000000000 --- a/src/backends/x11/meta-stage-x11.h +++ /dev/null @@ -1,88 +0,0 @@ -/* Clutter. - * An OpenGL based 'interactive canvas' library. - * Authored By Matthew Allum - * Copyright (C) 2006-2007 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#pragma once - -#include -#include - -#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; - - CoglOnscreen *onscreen; - Window xwin; - gint xwin_width; - gint xwin_height; /* FIXME target_width / height */ - - CoglFrameClosure *frame_closure; - - 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); - -void meta_stage_x11_handle_event (MetaStageX11 *stage_x11, - XEvent *xevent); - -ClutterStage *meta_x11_get_stage_from_window (Window win); - -Window meta_x11_get_stage_window (ClutterStage *stage); - - -G_END_DECLS 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 ac14cb857c7..00000000000 --- a/src/backends/x11/meta-virtual-input-device-x11.c +++ /dev/null @@ -1,277 +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 . - * - * Author: Jonas Ă…dahl - */ - -#include "config.h" - -#include "backends/x11/meta-virtual-input-device-x11.h" - -#include - -#include - -#include "backends/x11/meta-backend-x11.h" -#include "backends/x11/meta-clutter-backend-x11.h" -#include "backends/x11/meta-keymap-x11.h" -#include "backends/x11/meta-seat-x11.h" -#include "clutter/clutter.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 Display * -xdisplay_from_virtual_input_device (ClutterVirtualInputDevice *virtual_device) -{ - ClutterSeat *seat = clutter_virtual_input_device_get_seat (virtual_device); - MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); - MetaBackend *backend = meta_seat_x11_get_backend (seat_x11); - - return meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); -} - -static void -meta_virtual_input_device_x11_notify_relative_motion (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double dx, - double dy) -{ - Display *xdisplay = xdisplay_from_virtual_input_device (virtual_device); - - XTestFakeRelativeMotionEvent (xdisplay, (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) -{ - ClutterSeat *seat = clutter_virtual_input_device_get_seat (virtual_device); - MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); - MetaBackend *backend = meta_seat_x11_get_backend (seat_x11); - Display *xdisplay; - Screen *xscreen; - - xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); - xscreen = meta_backend_x11_get_xscreen (META_BACKEND_X11 (backend)); - - XTestFakeMotionEvent (xdisplay, XScreenNumberOfScreen (xscreen), - (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) -{ - Display *xdisplay = xdisplay_from_virtual_input_device (virtual_device); - - XTestFakeButtonEvent (xdisplay, - 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 = xdisplay_from_virtual_input_device (virtual_device); - 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 = (int) floor ((fabs (virtual_device_x11->accum_scroll_dx) + - DBL_EPSILON) / - DISCRETE_SCROLL_STEP); - n_yscrolls = (int) 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) -{ - Display *xdisplay = xdisplay_from_virtual_input_device (virtual_device); - - XTestFakeKeyEvent (xdisplay, - 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) -{ - ClutterSeat *seat = clutter_virtual_input_device_get_seat (virtual_device); - MetaKeymapX11 *keymap = META_KEYMAP_X11 (clutter_seat_get_keymap (seat)); - Display *xdisplay = xdisplay_from_virtual_input_device (virtual_device); - 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_lock_modifiers (keymap, level, TRUE); - - XTestFakeKeyEvent (xdisplay, - (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_lock_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 54ea9355e01..00000000000 --- a/src/backends/x11/meta-virtual-input-device-x11.h +++ /dev/null @@ -1,28 +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 . - * - * Author: Jonas Ă…dahl - */ - -#pragma once - -#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) 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 6e13d249924..00000000000 --- a/src/backends/x11/meta-xkb-a11y-x11.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright © 2001 Ximian, Inc. - * Copyright (C) 2007 William Jon McCann - * 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 . - * - */ - -#include "config.h" - -#include "backends/x11/meta-xkb-a11y-x11.h" - -#include -#include - -#include "backends/x11/meta-backend-x11.h" -#include "backends/x11/meta-clutter-backend-x11.h" -#include "backends/x11/meta-seat-x11.h" -#include "core/display-private.h" -#include "mtk/mtk-x11.h" - -#define DEFAULT_XKB_SET_CONTROLS_MASK XkbSlowKeysMask | \ - XkbBounceKeysMask | \ - XkbStickyKeysMask | \ - XkbMouseKeysMask | \ - XkbMouseKeysAccelMask | \ - XkbAccessXKeysMask | \ - XkbAccessXTimeoutMask | \ - XkbAccessXFeedbackMask | \ - XkbControlsEnabledMask - -static Display * -xdisplay_from_seat (ClutterSeat *seat) -{ - MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); - MetaBackend *backend = meta_seat_x11_get_backend (META_SEAT_X11 (seat_x11)); - - return meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); -} - -static XkbDescRec * -get_xkb_desc_rec (Display *xdisplay) -{ - XkbDescRec *desc; - Status status = Success; - - mtk_x11_error_trap_push (xdisplay); - desc = XkbGetMap (xdisplay, XkbAllMapComponentsMask, XkbUseCoreKbd); - if (desc != NULL) - { - desc->ctrls = NULL; - status = XkbGetControls (xdisplay, XkbAllControlsMask, desc); - } - mtk_x11_error_trap_pop (xdisplay); - - 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) -{ - mtk_x11_error_trap_push (xdisplay); - XkbSetControls (xdisplay, DEFAULT_XKB_SET_CONTROLS_MASK, desc); - XSync (xdisplay, FALSE); - mtk_x11_error_trap_pop (xdisplay); -} - -void -meta_seat_x11_check_xkb_a11y_settings_changed (ClutterSeat *seat) -{ - MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); - MetaBackend *backend = meta_seat_x11_get_backend (META_SEAT_X11 (seat_x11)); - Display *xdisplay = xdisplay_from_seat (seat); - 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 (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 gboolean -is_xkb_available (Display *xdisplay) -{ - int opcode, error_base, event_base, major, minor; - - if (!XkbQueryExtension (xdisplay, - &opcode, - &event_base, - &error_base, - &major, - &minor)) - return FALSE; - - if (!XkbUseExtension (xdisplay, &major, &minor)) - return FALSE; - - 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 = xdisplay_from_seat (seat); - 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 = xdisplay_from_seat (seat); - guint event_mask; - - if (!is_xkb_available (xdisplay)) - return FALSE; - - event_mask = XkbControlsNotifyMask | XkbAccessXNotifyMask; - - XkbSelectEvents (xdisplay, XkbUseCoreKbd, event_mask, event_mask); - - 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 6c25763fc6e..00000000000 --- a/src/backends/x11/meta-xkb-a11y-x11.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * Copyright © 2001 Ximian, Inc. - * Copyright (C) 2007 William Jon McCann - * 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 . - * - */ - -#pragma once - -#include - -#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); - -void meta_seat_x11_check_xkb_a11y_settings_changed (ClutterSeat *seat); 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 24377a90beb..00000000000 --- a/src/backends/x11/nested/meta-backend-x11-nested.c +++ /dev/null @@ -1,301 +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 . - */ - -#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/meta-stage-private.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" - -#ifdef HAVE_WAYLAND -#include "wayland/meta-wayland.h" -#endif - -struct _MetaBackendX11Nested -{ - MetaBackendX11 parent; - - MetaGpu *gpu; - MetaCursorRenderer *cursor_renderer; - MetaInputSettings *input_settings; -}; - -G_DEFINE_FINAL_TYPE (MetaBackendX11Nested, - meta_backend_x11_nested, - META_TYPE_BACKEND_X11) - -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, - ClutterSprite *sprite) -{ - MetaBackendX11Nested *backend_x11_nested = META_BACKEND_X11_NESTED (backend); - - if (!backend_x11_nested->cursor_renderer) - { - backend_x11_nested->cursor_renderer = - g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED, - "backend", backend, - "sprite", sprite, - NULL); - } - - return backend_x11_nested->cursor_renderer; -} - -static MetaInputSettings * -meta_backend_x11_nested_get_input_settings (MetaBackend *backend) -{ - MetaBackendX11Nested *backend_x11_nested = META_BACKEND_X11_NESTED (backend); - - if (!backend_x11_nested->input_settings) - { - backend_x11_nested->input_settings = - g_object_new (META_TYPE_INPUT_SETTINGS_DUMMY, - "backend", backend, - NULL); - } - - return backend_x11_nested->input_settings; -} - -static void -meta_backend_x11_nested_update_stage (MetaBackend *backend) -{ - ClutterActor *stage = meta_backend_get_stage (backend); - - meta_stage_rebuild_views (META_STAGE (stage)); -} - -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_set_keymap_async (MetaBackend *backend, - const char *layouts, - const char *variants, - const char *options, - const char *model, - GTask *task) -{ - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -static void -meta_backend_x11_nested_set_keymap_layout_group_async (MetaBackend *backend, - xkb_layout_index_t idx, - GTask *task) -{ - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -static gboolean -meta_backend_x11_nested_is_lid_closed (MetaBackend *backend) -{ - return FALSE; -} - -static void -meta_backend_x11_nested_set_pointer_constraint (MetaBackend *backend, - MetaPointerConstraint *constraint) -{ - g_debug ("Ignored pointer constraint in nested backend"); -} - -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) - { - MetaBackend *backend = META_BACKEND (x11); - MetaContext *context = meta_backend_get_context (backend); - MetaWaylandCompositor *compositor = - meta_context_get_wayland_compositor (context); - 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 -init_gpus (MetaBackendX11Nested *backend_x11_nested) -{ - backend_x11_nested->gpu = g_object_new (META_TYPE_GPU_DUMMY, - "backend", backend_x11_nested, - NULL); - meta_backend_add_gpu (META_BACKEND (backend_x11_nested), - backend_x11_nested->gpu); -} - -static MetaBackendCapabilities -meta_backend_x11_nested_get_capabilities (MetaBackend *backend) -{ - return META_BACKEND_CAPABILITY_NONE; -} - -static gboolean -meta_backend_x11_nested_init_basic (MetaBackend *backend, - GError **error) -{ - MetaBackendX11Nested *backend_x11_nested = META_BACKEND_X11_NESTED (backend); - MetaBackendClass *parent_backend_class = - META_BACKEND_CLASS (meta_backend_x11_nested_parent_class); - - if (!parent_backend_class->init_basic (backend, error)) - return FALSE; - - init_gpus (backend_x11_nested); - - return TRUE; -} - -static void -meta_backend_x11_nested_dispose (GObject *object) -{ - MetaBackendX11Nested *backend_x11_nested = META_BACKEND_X11_NESTED (object); - - g_clear_object (&backend_x11_nested->input_settings); - g_clear_object (&backend_x11_nested->cursor_renderer); - - 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->dispose = meta_backend_x11_nested_dispose; - - backend_class->init_basic = meta_backend_x11_nested_init_basic; - backend_class->get_capabilities = meta_backend_x11_nested_get_capabilities; - 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_stage = meta_backend_x11_nested_update_stage; - backend_class->select_stage_events = meta_backend_x11_nested_select_stage_events; - backend_class->set_keymap_async = meta_backend_x11_nested_set_keymap_async; - backend_class->set_keymap_layout_group_async = meta_backend_x11_nested_set_keymap_layout_group_async; - backend_class->is_lid_closed = meta_backend_x11_nested_is_lid_closed; - backend_class->set_pointer_constraint = meta_backend_x11_nested_set_pointer_constraint; - - 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; -} 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 f923e35fec8..00000000000 --- a/src/backends/x11/nested/meta-backend-x11-nested.h +++ /dev/null @@ -1,29 +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 . - */ - -#pragma once - -#include - -#include "backends/x11/meta-backend-x11.h" -#include "core/util-private.h" - -#define META_TYPE_BACKEND_X11_NESTED (meta_backend_x11_nested_get_type ()) -G_DECLARE_FINAL_TYPE (MetaBackendX11Nested, - meta_backend_x11_nested, - META, BACKEND_X11_NESTED, - MetaBackendX11) 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 a39330bf0fb..00000000000 --- a/src/backends/x11/nested/meta-cursor-renderer-x11-nested.c +++ /dev/null @@ -1,102 +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, see . - * - * Written by: - * Jonas Ă…dahl - */ - -#include "config.h" - -#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h" - -#include "backends/x11/meta-backend-x11.h" -#include "third_party/xcursor/xcursor.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 TRUE; -} - -static Cursor -create_empty_cursor (Display *xdisplay) -{ - XcursorImage *image; - XcursorPixel *pixels; - Cursor xcursor; - - image = xcursor_image_create (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_constructed (GObject *object) -{ - MetaCursorRendererX11Nested *x11_nested = - META_CURSOR_RENDERER_X11_NESTED (object); - MetaCursorRenderer *cursor_renderer = META_CURSOR_RENDERER (x11_nested); - MetaBackend *backend = meta_cursor_renderer_get_backend (cursor_renderer); - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); - Window xwindow = meta_backend_x11_get_xwindow (backend_x11); - Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11); - - Cursor empty_xcursor = create_empty_cursor (xdisplay); - XDefineCursor (xdisplay, xwindow, empty_xcursor); - XFreeCursor (xdisplay, empty_xcursor); - - G_OBJECT_CLASS (meta_cursor_renderer_x11_nested_parent_class)->constructed (object); -} - -static void -meta_cursor_renderer_x11_nested_class_init (MetaCursorRendererX11NestedClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_CLASS (klass); - - object_class->constructed = meta_cursor_renderer_x11_nested_constructed; - - renderer_class->update_cursor = meta_cursor_renderer_x11_nested_update_cursor; -} - -static void -meta_cursor_renderer_x11_nested_init (MetaCursorRendererX11Nested *x11_nested) -{ -} 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 cad7c99d80c..00000000000 --- a/src/backends/x11/nested/meta-cursor-renderer-x11-nested.h +++ /dev/null @@ -1,33 +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, see . - * - * Written by: - * Jonas Ă…dahl - */ - -#pragma once - -#include - -#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); 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 1e08122707c..00000000000 --- a/src/backends/x11/nested/meta-renderer-x11-nested.c +++ /dev/null @@ -1,131 +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 . - * - */ - -#include "config.h" - -#include "backends/x11/nested/meta-renderer-x11-nested.h" - -#include - -#include "backends/meta-backend-private.h" -#include "backends/meta-color-manager.h" -#include "backends/meta-logical-monitor-private.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 CoglOffscreen * -create_offscreen (CoglContext *cogl_context, - int width, - int height) -{ - CoglTexture *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 (texture_2d); - - if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (offscreen), &error)) - meta_fatal ("Couldn't allocate framebuffer: %s", error->message); - - return offscreen; -} - -static MetaRendererView * -meta_renderer_x11_nested_create_view (MetaRenderer *renderer, - MetaLogicalMonitor *logical_monitor, - MetaMonitor *monitor, - MetaOutput *output, - MetaCrtc *crtc, - GError **error) -{ - MetaBackend *backend = meta_renderer_get_backend (renderer); - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); - MetaColorManager *color_manager = meta_backend_get_color_manager (backend); - MetaColorDevice *color_device = - meta_color_manager_get_color_device (color_manager, monitor); - float view_scale; - const MetaCrtcConfig *crtc_config; - int width, height; - CoglOffscreen *fake_onscreen; - MtkRectangle view_layout; - const MetaCrtcModeInfo *mode_info; - MetaRendererView *view; - - if (meta_backend_is_stage_views_scaled (backend)) - view_scale = logical_monitor->scale; - else - view_scale = 1.0; - - crtc_config = meta_crtc_get_config (crtc); - width = (int) roundf (crtc_config->layout.size.width * view_scale); - height = (int) roundf (crtc_config->layout.size.height * view_scale); - - fake_onscreen = create_offscreen (cogl_context, width, height); - - mtk_rectangle_from_graphene_rect (&crtc_config->layout, - MTK_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), - "backend", backend, - "color-device", color_device, - "stage", meta_backend_get_stage (backend), - "layout", &view_layout, - "crtc", crtc, - "refresh-rate", mode_info->refresh_rate, - "framebuffer", COGL_FRAMEBUFFER (fake_onscreen), - "transform", MTK_MONITOR_TRANSFORM_NORMAL, - "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 e2f912b7453..00000000000 --- a/src/backends/x11/nested/meta-renderer-x11-nested.h +++ /dev/null @@ -1,28 +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 . - * - */ - -#pragma once - -#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) diff --git a/src/backends/x11/nested/meta-sprite-x11-nested.c b/src/backends/x11/nested/meta-sprite-x11-nested.c deleted file mode 100644 index c261e33087d..00000000000 --- a/src/backends/x11/nested/meta-sprite-x11-nested.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2024 Red Hat - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * Author: Carlos Garnacho - */ - -#include "config.h" - -#include "backends/x11/nested/meta-sprite-x11-nested.h" - -typedef struct _MetaSpriteX11Nested MetaSpriteX11Nested; - -struct _MetaSpriteX11Nested -{ - MetaSpriteX11 parent_instance; -}; - -G_DEFINE_TYPE (MetaSpriteX11Nested, meta_sprite_x11_nested, META_TYPE_SPRITE_X11) - -static void -meta_sprite_x11_nested_init (MetaSpriteX11Nested *sprite_x11_nested) -{ -} - -static void -meta_sprite_x11_nested_update_from_event (ClutterFocus *focus, - const ClutterEvent *event) -{ - ClutterSprite *sprite = CLUTTER_SPRITE (focus); - MetaBackend *backend = meta_sprite_get_backend (META_SPRITE (focus)); - MetaCursorRenderer *cursor_renderer; - - cursor_renderer = - meta_backend_get_cursor_renderer_for_sprite (backend, sprite); - if (cursor_renderer) - meta_cursor_renderer_update_position (cursor_renderer); -} - -static void -meta_sprite_x11_nested_class_init (MetaSpriteX11NestedClass *klass) -{ - ClutterFocusClass *focus_class = CLUTTER_FOCUS_CLASS (klass); - - focus_class->update_from_event = meta_sprite_x11_nested_update_from_event; -} diff --git a/src/backends/x11/nested/meta-sprite-x11-nested.h b/src/backends/x11/nested/meta-sprite-x11-nested.h deleted file mode 100644 index 60c24bf22ae..00000000000 --- a/src/backends/x11/nested/meta-sprite-x11-nested.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2024 Red Hat - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * Author: Carlos Garnacho - */ - -#pragma once - -#include "backends/x11/meta-sprite-x11.h" - -#define META_TYPE_SPRITE_X11_NESTED meta_sprite_x11_nested_get_type () -G_DECLARE_FINAL_TYPE (MetaSpriteX11Nested, - meta_sprite_x11_nested, - META, SPRITE_X11_NESTED, - MetaSpriteX11) 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 f0da5989929..00000000000 --- a/src/backends/x11/nested/meta-stage-x11-nested.c +++ /dev/null @@ -1,216 +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 . - * - * Written by: - * Jonas Ă…dahl - */ - -#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-private.h" -#include "backends/meta-monitor-private.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" - -struct _MetaStageX11Nested -{ - MetaStageX11 parent; - - CoglPipeline *pipeline; -}; - -G_DEFINE_FINAL_TYPE (MetaStageX11Nested, meta_stage_x11_nested, META_TYPE_STAGE_X11) - -typedef struct _MetaStageX11View -{ - CoglTexture *texture; - MetaStageView *view; -} MetaStageX11NestedView; - -static void -meta_stage_x11_nested_resize (ClutterStageWindow *stage_window, - gint width, - gint height) -{ - CLUTTER_STAGE_WINDOW_CLASS (meta_stage_x11_nested_parent_class)-> - 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) -{ - MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_window); - MetaBackend *backend = meta_stage_impl_get_backend (stage_impl); - 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); - MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_window); - MetaBackend *backend = meta_stage_impl_get_backend (stage_impl); - 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, frame->frame_count); - cogl_onscreen_egl_maybe_create_timestamp_query (stage_x11->onscreen, - frame_info); - 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_object (&stage_nested->pipeline); - - CLUTTER_STAGE_WINDOW_CLASS (meta_stage_x11_nested_parent_class)-> - unrealize (stage_window); -} - -static void -meta_stage_x11_nested_init (MetaStageX11Nested *stage_x11_nested) -{ -} - -static void -meta_stage_x11_nested_class_init (MetaStageX11NestedClass *klass) -{ - ClutterStageWindowClass *window_class = CLUTTER_STAGE_WINDOW_CLASS (klass); - - window_class->resize = meta_stage_x11_nested_resize; - window_class->can_clip_redraws = meta_stage_x11_nested_can_clip_redraws; - window_class->unrealize = meta_stage_x11_nested_unrealize; - window_class->get_views = meta_stage_x11_nested_get_views; - window_class->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 d890eb936da..00000000000 --- a/src/backends/x11/nested/meta-stage-x11-nested.h +++ /dev/null @@ -1,30 +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 . - * - * Written by: - * Jonas Ă…dahl - */ - -#pragma once - -#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) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 146a52653e6..7b1264b9b31 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -78,9 +78,6 @@ #ifdef HAVE_X11_CLIENT #include -#include "backends/x11/meta-backend-x11.h" -#include "backends/x11/meta-event-x11.h" -#include "backends/x11/meta-stage-x11.h" #include "compositor/meta-window-actor-x11.h" @@ -983,9 +980,6 @@ meta_compositor_real_after_paint (MetaCompositor *compositor, status = cogl_context_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"); @@ -993,14 +987,7 @@ meta_compositor_real_after_paint (MetaCompositor *compositor, 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, meta_display_get_context (priv->display)); + case COGL_GRAPHICS_RESET_STATUS_NO_ERROR: break; } diff --git a/src/compositor/meta-compositor-x11.c b/src/compositor/meta-compositor-x11.c deleted file mode 100644 index d1076d464ed..00000000000 --- a/src/compositor/meta-compositor-x11.c +++ /dev/null @@ -1,1068 +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 . - * - */ - -#include "config.h" - -#include "compositor/meta-compositor-x11.h" - -#include -#include - -#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-compositor-view.h" -#include "compositor/meta-sync-ring.h" -#include "compositor/meta-window-actor-x11.h" -#include "core/display-private.h" -#include "core/window-private.h" -#include "mtk/mtk-x11.h" -#include "x11/meta-x11-display-private.h" -#include "x11/window-x11.h" - -#define IS_GESTURE_EVENT(et) ((et) == CLUTTER_TOUCH_BEGIN || \ - (et) == CLUTTER_TOUCH_UPDATE || \ - (et) == CLUTTER_TOUCH_END || \ - (et) == CLUTTER_TOUCH_CANCEL) - -struct _MetaCompositorX11 -{ - MetaCompositor parent; - - Window output; - - gulong before_update_handler_id; - gulong after_update_handler_id; - gulong focus_window_handler_id; - - gboolean frame_has_updated_xsurfaces; - gboolean have_x11_sync_object; - gboolean have_root_window_key_grab; - - MetaWindow *unredirected_window; - MetaWindow *focus_window; - - gboolean xserver_uses_monotonic_clock; - int64_t xserver_time_query_time_us; - int64_t xserver_time_offset_us; -}; - -typedef struct -{ - MetaCompositorX11 *compositor_x11; - Window xwindow; - gboolean grab; -} KeyGrabData; - -G_DEFINE_TYPE (MetaCompositorX11, meta_compositor_x11, META_TYPE_COMPOSITOR) - -static void meta_compositor_x11_grab_root_window_keys (MetaCompositorX11 *compositor_x11); - -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); -} - -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); - MetaContext *context = meta_display_get_context (display); - MetaBackend *backend = meta_context_get_backend (context); - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); - MetaX11Display *x11_display = display->x11_display; - Display *xdisplay = meta_x11_display_get_xdisplay (x11_display); - int composite_version; - 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); - - 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_set_stage_input_region (display->x11_display, NULL, 0); - - /* - * Make sure there isn't any left-over output shape on the overlay window by - * setting the whole screen to be an output region. - * - * Note: there doesn't seem to be any real chance of that because the X - * server will destroy the overlay window when the last client using it - * exits. - */ - XFixesSetWindowShapeRegion (xdisplay, compositor_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 (cogl_context, xdisplay); - - meta_x11_display_redirect_windows (x11_display, display); - - meta_compositor_x11_grab_root_window_keys (compositor_x11); - - return TRUE; -} - -static void -meta_compositor_x11_unmanage (MetaCompositor *compositor) -{ - MetaDisplay *display = meta_compositor_get_display (compositor); - MetaContext *context = meta_display_get_context (display); - MetaBackend *backend = meta_context_get_backend (context); - MetaX11Display *x11_display = display->x11_display; - Display *xdisplay = x11_display->xdisplay; - Window xroot = x11_display->xroot; - Window backend_xwindow; - MetaCompositorClass *parent_class; - - backend_xwindow = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend)); - XReparentWindow (xdisplay, backend_xwindow, xroot, 0, 0); - - /* - * 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); - - parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class); - parent_class->unmanage (compositor); -} - -/* - * 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; - MtkRectangle 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 -maybe_do_sync (MetaCompositor *compositor) -{ - MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); - - if (compositor_x11->frame_has_updated_xsurfaces) - { - MetaDisplay *display = meta_compositor_get_display (compositor); - MetaBackend *backend = meta_compositor_get_backend (compositor); - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); - - /* - * 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 (cogl_context); - else - XSync (display->x11_display->xdisplay, False); - } -} - -static void -on_before_update (ClutterStage *stage, - ClutterStageView *stage_view, - ClutterFrame *frame, - MetaCompositor *compositor) -{ - maybe_do_sync (compositor); -} - -static void -on_after_update (ClutterStage *stage, - ClutterStageView *stage_view, - ClutterFrame *frame, - MetaCompositor *compositor) -{ - MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); - - if (compositor_x11->frame_has_updated_xsurfaces) - { - MetaBackend *backend = meta_compositor_get_backend (compositor); - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); - - if (compositor_x11->have_x11_sync_object) - compositor_x11->have_x11_sync_object = meta_sync_ring_after_frame (cogl_context); - - compositor_x11->frame_has_updated_xsurfaces = FALSE; - } -} - -static void -meta_change_button_grab (MetaCompositorX11 *compositor_x11, - MetaWindow *window, - gboolean grab, - MetaPassiveGrabMode grab_mode, - int button, - int modmask) -{ - MetaBackend *backend = - meta_compositor_get_backend (META_COMPOSITOR (compositor_x11)); - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); - Window xwindow; - - xwindow = meta_window_x11_get_toplevel_xwindow (window); - - if (grab) - { - meta_backend_x11_passive_button_grab (backend_x11, - xwindow, - button, - grab_mode, - modmask); - } - else - { - meta_backend_x11_passive_button_ungrab (backend_x11, - xwindow, - button, - modmask); - } -} - -static void -meta_change_buttons_grab (MetaCompositorX11 *compositor_x11, - MetaWindow *window, - gboolean grab, - MetaPassiveGrabMode grab_mode, - int modmask) -{ -#define MAX_BUTTON 3 - int i; - - /* Grab Alt + button1 for moving window. - * Grab Alt + button2 for resizing window. - * Grab Alt + button3 for popping up window menu. - */ - for (i = 1; i <= MAX_BUTTON; i++) - { - meta_change_button_grab (compositor_x11, window, grab, - grab_mode, i, modmask); - } - - /* Grab Alt + Shift + button1 for snap-moving window. */ - meta_change_button_grab (compositor_x11, window, - grab, grab_mode, - 1, modmask | CLUTTER_SHIFT_MASK); - -#undef MAX_BUTTON -} - -static void -meta_compositor_x11_grab_window_buttons (MetaCompositorX11 *compositor_x11, - MetaWindow *window) -{ - MetaCompositor *compositor = META_COMPOSITOR (compositor_x11); - MetaDisplay *display = meta_compositor_get_display (compositor); - int modmask; - - meta_topic (META_DEBUG_X11, "Grabbing window buttons for %s", window->desc); - - modmask = meta_display_get_compositor_modifiers (display); - - if (modmask != 0) - { - meta_change_buttons_grab (compositor_x11, window, TRUE, - META_GRAB_MODE_ASYNC, modmask); - } -} - -static void -meta_compositor_x11_ungrab_window_buttons (MetaCompositorX11 *compositor_x11, - MetaWindow *window) -{ - MetaCompositor *compositor = META_COMPOSITOR (compositor_x11); - MetaDisplay *display = meta_compositor_get_display (compositor); - int modmask; - - meta_topic (META_DEBUG_X11, "Ungrabbing window buttons for %s", window->desc); - - modmask = meta_display_get_compositor_modifiers (display); - - if (modmask != 0) - { - meta_change_buttons_grab (compositor_x11, window, FALSE, - META_GRAB_MODE_ASYNC, modmask); - } -} - -static void -meta_compositor_x11_grab_focus_window_button (MetaCompositorX11 *compositor_x11, - MetaWindow *window) -{ - /* Grab button 1 for activating unfocused windows */ - meta_topic (META_DEBUG_X11, "Grabbing unfocused window buttons for %s", - window->desc); - - meta_change_buttons_grab (compositor_x11, window, TRUE, - META_GRAB_MODE_SYNC, 0); -} - -static void -meta_compositor_x11_ungrab_focus_window_button (MetaCompositorX11 *compositor_x11, - MetaWindow *window) -{ - meta_topic (META_DEBUG_X11, "Ungrabbing unfocused window buttons for %s", - window->desc); - - meta_change_buttons_grab (compositor_x11, window, FALSE, - META_GRAB_MODE_ASYNC, 0); -} - -static void -meta_compositor_x11_change_keygrab (MetaCompositorX11 *compositor_x11, - Window xwindow, - gboolean grab, - MetaResolvedKeyCombo *resolved_combo) -{ - MetaBackend *backend = - meta_compositor_get_backend (META_COMPOSITOR (compositor_x11)); - MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); - int i; - - 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) - { - meta_backend_x11_passive_key_grab (backend_x11, xwindow, - keycode, - META_GRAB_MODE_SYNC, - resolved_combo->mask); - } - else - { - meta_backend_x11_passive_key_ungrab (backend_x11, xwindow, - keycode, - resolved_combo->mask); - } - } -} - -static void -passive_key_grab_foreach (MetaDisplay *display, - MetaKeyBindingFlags flags, - MetaResolvedKeyCombo *resolved_combo, - gpointer user_data) -{ - MetaX11Display *x11_display = display->x11_display; - Window xroot = x11_display->xroot; - KeyGrabData *data = user_data; - - /* Ignore the key bindings marked as META_KEY_BINDING_NO_AUTO_GRAB. */ - if ((flags & META_KEY_BINDING_NO_AUTO_GRAB) != 0 && - data->grab) - return; - - if ((flags & META_KEY_BINDING_PER_WINDOW) != 0 && - data->xwindow == xroot) - return; - - meta_compositor_x11_change_keygrab (data->compositor_x11, - data->xwindow, - data->grab, - resolved_combo); -} - -static void -meta_compositor_x11_grab_window_keys (MetaCompositorX11 *compositor_x11, - Window xwindow) -{ - MetaCompositor *compositor = META_COMPOSITOR (compositor_x11); - MetaDisplay *display = meta_compositor_get_display (compositor); - KeyGrabData data = { compositor_x11, xwindow, TRUE }; - - meta_display_keybinding_foreach (display, - passive_key_grab_foreach, - &data); -} - -static void -meta_compositor_x11_ungrab_window_keys (MetaCompositorX11 *compositor_x11, - Window xwindow) -{ - MetaCompositor *compositor = META_COMPOSITOR (compositor_x11); - MetaDisplay *display = meta_compositor_get_display (compositor); - KeyGrabData data = { compositor_x11, xwindow, FALSE }; - - meta_display_keybinding_foreach (display, - passive_key_grab_foreach, - &data); -} - -static void -meta_compositor_x11_grab_root_window_keys (MetaCompositorX11 *compositor_x11) -{ - MetaCompositor *compositor = META_COMPOSITOR (compositor_x11); - MetaDisplay *display = meta_compositor_get_display (compositor); - MetaX11Display *x11_display = display->x11_display; - Window xroot = x11_display->xroot; - KeyGrabData data = { compositor_x11, xroot, TRUE }; - - if (compositor_x11->have_root_window_key_grab) - return; - - meta_display_keybinding_foreach (display, - passive_key_grab_foreach, - &data); - compositor_x11->have_root_window_key_grab = TRUE; -} - -static void -meta_compositor_x11_ungrab_root_window_keys (MetaCompositorX11 *compositor_x11) -{ - MetaCompositor *compositor = META_COMPOSITOR (compositor_x11); - MetaDisplay *display = meta_compositor_get_display (compositor); - MetaX11Display *x11_display = display->x11_display; - Window xroot = x11_display->xroot; - KeyGrabData data = { compositor_x11, xroot, FALSE }; - - if (!compositor_x11->have_root_window_key_grab) - return; - - meta_display_keybinding_foreach (display, - passive_key_grab_foreach, - &data); - compositor_x11->have_root_window_key_grab = FALSE; -} - -static gboolean -should_have_passive_grab (MetaWindow *window) -{ - return window->type != META_WINDOW_DOCK && !window->override_redirect; -} - -static void -on_focus_window_change (MetaDisplay *display, - GParamSpec *pspec, - MetaCompositor *compositor) -{ - MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); - MetaWindow *focus, *old_focus; - gboolean needs_grab_change; - - old_focus = compositor_x11->focus_window; - focus = meta_display_get_focus_window (display); - - if (focus && !should_have_passive_grab (focus)) - focus = NULL; - - if (focus == old_focus) - return; - - needs_grab_change = - (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK || - !meta_prefs_get_raise_on_click()); - - if (old_focus && needs_grab_change) - { - /* Restore passive grabs applying to out of focus windows */ - meta_compositor_x11_ungrab_window_buttons (compositor_x11, old_focus); - meta_compositor_x11_grab_focus_window_button (compositor_x11, old_focus); - } - - if (focus && needs_grab_change) - { - /* 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 - */ - meta_compositor_x11_ungrab_focus_window_button (compositor_x11, focus); - meta_compositor_x11_grab_window_buttons (compositor_x11, focus); - } - - compositor_x11->focus_window = focus; -} - -static void -on_window_type_changed (MetaWindow *window, - GParamSpec *pspec, - MetaCompositorX11 *compositor_x11) -{ - Window xwindow; - - xwindow = meta_window_x11_get_toplevel_xwindow (window); - - if (should_have_passive_grab (window)) - meta_compositor_x11_grab_window_keys (compositor_x11, xwindow); - else - meta_compositor_x11_ungrab_window_keys (compositor_x11, xwindow); -} - -static void -on_window_decorated_changed (MetaWindow *window, - GParamSpec *pspec, - MetaCompositorX11 *compositor_x11) -{ - Window old_effective_toplevel = None, xwindow; - - /* We must clean up the passive grab on the prior effective toplevel */ - if (window->decorated) - { - old_effective_toplevel = meta_window_x11_get_xwindow (window); - } - else - { - MetaFrame *frame; - - frame = meta_window_x11_get_frame (window); - if (frame) - old_effective_toplevel = meta_frame_get_xwindow (frame); - } - - if (old_effective_toplevel != None) - { - meta_compositor_x11_ungrab_window_keys (compositor_x11, - old_effective_toplevel); - } - - xwindow = meta_window_x11_get_toplevel_xwindow (window); - meta_compositor_x11_grab_window_keys (compositor_x11, xwindow); -} - -static void -meta_compositor_x11_before_paint (MetaCompositor *compositor, - MetaCompositorView *compositor_view, - ClutterFrame *frame) -{ - 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, compositor_view, frame); - - /* We must sync after MetaCompositor's before_paint because that's the final - * time XDamageSubtract may happen before painting (when it calls - * meta_window_actor_x11_before_paint -> handle_updates -> - * meta_surface_actor_x11_handle_updates). If a client was to redraw between - * the last damage event and XDamageSubtract, and the bounding box of the - * region didn't grow, then we will not receive a new damage report for it - * (because XDamageReportBoundingBox). Then if we haven't synchronized again - * and the same region doesn't change on subsequent frames, we have lost some - * part of the update from the client. So to ensure the correct pixels get - * composited we must sync at least once between XDamageSubtract and - * compositing, which is here. More related documentation can be found in - * maybe_do_sync. - */ - - maybe_do_sync (compositor); -} - -static void -meta_compositor_x11_add_window (MetaCompositor *compositor, - MetaWindow *window) -{ - MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); - MetaCompositorClass *parent_class; - Window xwindow; - - if (should_have_passive_grab (window)) - { - xwindow = meta_window_x11_get_toplevel_xwindow (window); - - meta_compositor_x11_grab_focus_window_button (compositor_x11, window); - meta_compositor_x11_grab_window_keys (compositor_x11, xwindow); - - g_signal_connect_object (window, "notify::window-type", - G_CALLBACK (on_window_type_changed), - compositor, - G_CONNECT_DEFAULT); - g_signal_connect_object (window, "notify::decorated", - G_CALLBACK (on_window_decorated_changed), - compositor, - G_CONNECT_DEFAULT); - } - - parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class); - parent_class->add_window (compositor, window); -} - -static void -meta_compositor_x11_remove_window (MetaCompositor *compositor, - MetaWindow *window) -{ - MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); - MetaCompositorClass *parent_class; - Window xwindow; - - if (compositor_x11->unredirected_window == window) - set_unredirected_window (compositor_x11, NULL); - - if (window == compositor_x11->focus_window) - { - meta_compositor_x11_ungrab_window_buttons (compositor_x11, window); - compositor_x11->focus_window = NULL; - } - else if (should_have_passive_grab (window)) - { - meta_compositor_x11_ungrab_focus_window_button (compositor_x11, window); - } - - xwindow = meta_window_x11_get_toplevel_xwindow (window); - meta_compositor_x11_ungrab_window_keys (compositor_x11, xwindow); - - g_signal_handlers_disconnect_by_func (window, on_window_type_changed, - compositor); - g_signal_handlers_disconnect_by_func (window, on_window_decorated_changed, - compositor); - - 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 MetaCompositorView * -meta_compositor_x11_create_view (MetaCompositor *compositor, - ClutterStageView *stage_view) -{ - return meta_compositor_view_new (stage_view); -} - -static gboolean -meta_compositor_x11_handle_event (MetaCompositor *compositor, - const ClutterEvent *event, - MetaWindow *event_window, - MetaEventMode mode_hint) -{ - MetaBackend *backend = meta_compositor_get_backend (compositor); - ClutterEventType event_type = clutter_event_type (event); - - if (event_type == CLUTTER_BUTTON_PRESS || - event_type == CLUTTER_KEY_PRESS) - { - meta_backend_x11_allow_events (META_BACKEND_X11 (backend), - event, mode_hint); - } - - if (event_window && !IS_GESTURE_EVENT (clutter_event_type (event))) - return CLUTTER_EVENT_STOP; - - return CLUTTER_EVENT_PROPAGATE; -} - -static void -meta_compositor_x11_notify_mapping_change (MetaCompositor *compositor, - MetaMappingType type, - MetaMappingState state) -{ - MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); - MetaDisplay *display = meta_compositor_get_display (compositor); - g_autoptr (GSList) windows = NULL; - GSList *l; - /* Ungrab before change, grab again after it */ - gboolean grab = state == META_MAPPING_STATE_POST_CHANGE; - - switch (type) - { - case META_MAPPING_TYPE_BUTTON: - windows = meta_display_list_windows (display, META_LIST_DEFAULT); - - for (l = windows; l; l = l->next) - { - MetaWindow *window = l->data; - void (*func) (MetaCompositorX11*, MetaWindow*); - - if (window == compositor_x11->focus_window) - { - func = grab ? - meta_compositor_x11_grab_window_buttons : - meta_compositor_x11_ungrab_window_buttons; - } - else - { - func = grab ? - meta_compositor_x11_grab_focus_window_button : - meta_compositor_x11_ungrab_focus_window_button; - } - - func (compositor_x11, window); - } - - break; - case META_MAPPING_TYPE_KEY: - windows = meta_display_list_windows (display, META_LIST_DEFAULT); - - if (grab) - meta_compositor_x11_grab_root_window_keys (compositor_x11); - else - meta_compositor_x11_ungrab_root_window_keys (compositor_x11); - - for (l = windows; l; l = l->next) - { - MetaWindow *window = l->data; - Window xwindow = meta_window_x11_get_toplevel_xwindow (window); - - if (grab) - meta_compositor_x11_grab_window_keys (compositor_x11, xwindow); - else - meta_compositor_x11_ungrab_window_keys (compositor_x11, xwindow); - } - break; - } -} - -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); - MetaDisplay *display = meta_compositor_get_display (compositor); - - compositor_x11->before_update_handler_id = - g_signal_connect (stage, "before-update", - G_CALLBACK (on_before_update), compositor); - compositor_x11->after_update_handler_id = - g_signal_connect (stage, "after-update", - G_CALLBACK (on_after_update), compositor); - - compositor_x11->focus_window_handler_id = - g_signal_connect (display, "notify::focus-window", - G_CALLBACK (on_focus_window_change), 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); - MetaDisplay *display = meta_compositor_get_display (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_clear_signal_handler (&compositor_x11->focus_window_handler_id, display); - - meta_compositor_x11_ungrab_root_window_keys (compositor_x11); - - 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->add_window = meta_compositor_x11_add_window; - 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->create_view = meta_compositor_x11_create_view; - compositor_class->handle_event = meta_compositor_x11_handle_event; - compositor_class->notify_mapping_change = - meta_compositor_x11_notify_mapping_change; -} diff --git a/src/compositor/meta-compositor-x11.h b/src/compositor/meta-compositor-x11.h deleted file mode 100644 index 223f40b8ef9..00000000000 --- a/src/compositor/meta-compositor-x11.h +++ /dev/null @@ -1,34 +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 . - * - */ - -#pragma once - -#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); diff --git a/src/compositor/meta-dnd.c b/src/compositor/meta-dnd.c index 2425dac0c43..819b62d8bed 100644 --- a/src/compositor/meta-dnd.c +++ b/src/compositor/meta-dnd.c @@ -26,12 +26,6 @@ #include "core/display-private.h" #include "backends/meta-dnd-private.h" -#ifdef HAVE_X11 -#include "backends/x11/meta-backend-x11.h" -#include "backends/x11/meta-stage-x11.h" -#include "x11/meta-x11-display-private.h" -#endif - struct _MetaDndClass { GObjectClass parent_class; @@ -119,39 +113,6 @@ meta_dnd_new (MetaBackend *backend) return dnd; } -#ifdef HAVE_X11 -void -meta_dnd_init_xdnd (MetaX11Display *x11_display) -{ - MetaDisplay *display = meta_x11_display_get_display (x11_display); - MetaContext *context = meta_display_get_context (display); - MetaBackend *backend = meta_context_get_backend (context); - 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", False), XA_ATOM, - 32, PropModeReplace, - (const unsigned char *) &xdnd_version, 1); - - XChangeProperty (xdisplay, overlay_xwindow, - XInternAtom (xdisplay, "XdndProxy", False), 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", False), XA_WINDOW, - 32, PropModeReplace, (const unsigned char *) &xwindow, 1); -} -#endif - static void meta_dnd_notify_dnd_enter (MetaDnd *dnd) { @@ -172,76 +133,6 @@ 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 - */ -#ifdef HAVE_X11 -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; -} -#endif - #ifdef HAVE_WAYLAND void meta_dnd_wayland_on_motion_event (MetaDnd *dnd, diff --git a/src/compositor/meta-plugin-manager.c b/src/compositor/meta-plugin-manager.c index 22ce62abd21..64924032fe1 100644 --- a/src/compositor/meta-plugin-manager.c +++ b/src/compositor/meta-plugin-manager.c @@ -343,17 +343,6 @@ meta_plugin_manager_filter_keybinding (MetaPluginManager *plugin_mgr, return FALSE; } -#ifdef HAVE_X11 -gboolean -meta_plugin_manager_xevent_filter (MetaPluginManager *plugin_mgr, - XEvent *xev) -{ - MetaPlugin *plugin = plugin_mgr->plugin; - - return _meta_plugin_xevent_filter (plugin, xev); -} -#endif - void meta_plugin_manager_confirm_display_change (MetaPluginManager *plugin_mgr) { diff --git a/src/compositor/meta-plugin-manager.h b/src/compositor/meta-plugin-manager.h index fc14270fb1d..7d482209207 100644 --- a/src/compositor/meta-plugin-manager.h +++ b/src/compositor/meta-plugin-manager.h @@ -71,13 +71,6 @@ gboolean meta_plugin_manager_switch_workspace (MetaPluginManager *mgr, gboolean meta_plugin_manager_filter_keybinding (MetaPluginManager *mgr, MetaKeyBinding *binding); -#ifdef HAVE_X11 -gboolean meta_plugin_manager_xevent_filter (MetaPluginManager *mgr, - XEvent *xev); -gboolean _meta_plugin_xevent_filter (MetaPlugin *plugin, - XEvent *xev); -#endif - void meta_plugin_manager_confirm_display_change (MetaPluginManager *mgr); gboolean meta_plugin_manager_show_tile_preview (MetaPluginManager *mgr, diff --git a/src/compositor/meta-plugin.c b/src/compositor/meta-plugin.c index ef38b2e3ebf..cb89358c0b7 100644 --- a/src/compositor/meta-plugin.c +++ b/src/compositor/meta-plugin.c @@ -30,15 +30,7 @@ #include "meta/meta-plugin.h" #include -#ifdef HAVE_X11 -#include -#include -#include -#endif - -#ifdef HAVE_X11 -#include "backends/x11/meta-clutter-backend-x11.h" -#endif + #include "backends/meta-monitor-manager-private.h" #include "compositor/compositor-private.h" #include "compositor/meta-window-actor-private.h" @@ -64,20 +56,6 @@ meta_plugin_init (MetaPlugin *self) { } -#ifdef HAVE_X11 -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; -} -#endif - void meta_plugin_switch_workspace_completed (MetaPlugin *plugin) { diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c deleted file mode 100644 index 65393d583d1..00000000000 --- a/src/compositor/meta-surface-actor-x11.c +++ /dev/null @@ -1,441 +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 . - * - * Written by: - * Owen Taylor - * Jasper St. Pierre - */ - -#include "config.h" - -#include "compositor/meta-surface-actor-x11.h" - -#include - -#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 "mtk/mtk-x11.h" -#include "x11/meta-x11-display-private.h" -#include "x11/window-x11.h" - -struct _MetaSurfaceActorX11 -{ - MetaSurfaceActor parent; - - MetaWindow *window; - - MetaDisplay *display; - - MetaMultiTexture *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); - - mtk_x11_error_trap_push (xdisplay); - XDamageDestroy (xdisplay, self->damage); - self->damage = None; - mtk_x11_error_trap_pop (xdisplay); -} - -static void -detach_pixmap (MetaSurfaceActorX11 *self) -{ - MetaDisplay *display = self->display; - MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); - MetaContext *context = meta_display_get_context (display); - MetaBackend *backend = meta_context_get_backend (context); - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); - 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_context_flush (cogl_context); - - mtk_x11_error_trap_push (xdisplay); - XFreePixmap (xdisplay, self->pixmap); - self->pixmap = None; - mtk_x11_error_trap_pop (xdisplay); - - g_clear_object (&self->texture); -} - -static void -set_pixmap (MetaSurfaceActorX11 *self, - Pixmap pixmap) -{ - ClutterContext *clutter_context = - clutter_actor_get_context (CLUTTER_ACTOR (self)); - ClutterBackend *backend = clutter_context_get_backend (clutter_context); - CoglContext *ctx = clutter_backend_get_cogl_context (backend); - MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); - GError *error = NULL; - CoglTexture *cogl_texture; - - g_assert (self->pixmap == None); - self->pixmap = pixmap; - - 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 (cogl_texture)))) - g_warning ("NOTE: Not using GLX TFP!"); - - self->texture = meta_multi_texture_new_simple (cogl_texture); - meta_shaped_texture_set_texture (stex, self->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); - - mtk_x11_error_trap_push (xdisplay); - new_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow); - - if (mtk_x11_error_trap_pop_with_return (xdisplay) != 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_topic (META_DEBUG_RENDER, - "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, - const MtkRectangle *area) -{ - MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); - CoglTexturePixmapX11 *pixmap; - - self->received_damage = TRUE; - - if (meta_window_is_fullscreen (self->window) && !self->unredirected && !self->does_full_damage) - { - MtkRectangle window_rect; - meta_window_get_frame_rect (self->window, &window_rect); - - if (area->x == 0 && - area->y == 0 && - window_rect.width == area->width && - window_rect.height == area->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; - - /* We don't support multi-plane or YUV based formats in X */ - if (!meta_multi_texture_is_simple (self->texture)) - return; - - pixmap = COGL_TEXTURE_PIXMAP_X11 (meta_multi_texture_get_plane (self->texture, 0)); - cogl_texture_pixmap_x11_update_area (pixmap, area); - meta_surface_actor_update_area (actor, area); -} - -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) - { - mtk_x11_error_trap_push (xdisplay); - XDamageSubtract (xdisplay, self->damage, None, None); - mtk_x11_error_trap_pop (xdisplay); - - 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 (!(meta_window_is_fullscreen (self->window) && 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); - - mtk_x11_error_trap_push (xdisplay); - - 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)); - } - - mtk_x11_error_trap_pop (xdisplay); -} - -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) -{ - MetaX11Display *x11_display = meta_display_get_x11_display (self->display); - - mtk_x11_error_trap_push (x11_display->xdisplay); - detach_pixmap (self); - free_damage (self); - mtk_x11_error_trap_pop (x11_display->xdisplay); -} - -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) -{ - MetaX11Display *x11_display = meta_display_get_x11_display (self->display); - Display *xdisplay = meta_x11_display_get_xdisplay (x11_display); - Window xwindow = meta_window_x11_get_toplevel_xwindow (self->window); - - mtk_x11_error_trap_push (xdisplay); - self->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox); - mtk_x11_error_trap_pop (xdisplay); -} - -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); - clutter_actor_set_accessible_name (CLUTTER_ACTOR (self), "X11 surface"); - 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 e74f665cab1..00000000000 --- a/src/compositor/meta-surface-actor-x11.h +++ /dev/null @@ -1,57 +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 . - * - * Written by: - * Owen Taylor - * Jasper St. Pierre - */ - -#pragma once - -#include - -#include - -#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 diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c deleted file mode 100644 index 763d611973f..00000000000 --- a/src/compositor/meta-sync-ring.c +++ /dev/null @@ -1,595 +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 - */ - -#include "config.h" - -#include "compositor/meta-sync-ring.h" - -#include -#include -#include -#include - -#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 (CoglContext *ctx, - const char *name, - void **func) -{ - *func = cogl_renderer_get_proc_address (ctx->display->renderer, name); - if (!*func) - { - meta_topic (META_DEBUG_RENDER, - "MetaSyncRing: failed to resolve required GL symbol \"%s\"", name); - return FALSE; - } - return TRUE; -} - -static gboolean -check_gl_extensions (CoglContext *cogl_context) -{ - CoglDisplay *cogl_display; - CoglRenderer *cogl_renderer; - - cogl_display = cogl_context_get_display (cogl_context); - cogl_renderer = cogl_display_get_renderer (cogl_display); - - switch (cogl_renderer_get_driver_id (cogl_renderer)) - { - case COGL_DRIVER_ID_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; - } - default: - break; - } - - return FALSE; -} - -static gboolean -load_required_symbols (CoglContext *ctx) -{ - 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 (ctx, "glGetString", (void **) &meta_gl_get_string)) - goto out; - if (!load_gl_symbol (ctx, "glGetIntegerv", (void **) &meta_gl_get_integerv)) - goto out; - if (!load_gl_symbol (ctx, "glGetStringi", (void **) &meta_gl_get_stringi)) - goto out; - - if (!check_gl_extensions (ctx)) - { - meta_topic (META_DEBUG_RENDER, - "MetaSyncRing: couldn't find required GL extensions"); - goto out; - } - - if (!load_gl_symbol (ctx, "glDeleteSync", (void **) &meta_gl_delete_sync)) - goto out; - if (!load_gl_symbol (ctx, "glClientWaitSync", (void **) &meta_gl_client_wait_sync)) - goto out; - if (!load_gl_symbol (ctx, "glWaitSync", (void **) &meta_gl_wait_sync)) - goto out; - if (!load_gl_symbol (ctx, "glImportSyncEXT", (void **) &meta_gl_import_sync)) - goto out; - if (!load_gl_symbol (ctx, "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 (CoglContext *ctx, - 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 (ctx)) - 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 (CoglContext *ctx, - Display *xdisplay) -{ - MetaSyncRing *ring = meta_sync_ring_get (); - - if (!ring) - return FALSE; - - meta_sync_ring_destroy (); - - ring->reboots += 1; - - if (!meta_sync_ring_get ()) - { - g_warning ("MetaSyncRing: Too many reboots -- disabling"); - return FALSE; - } - - return meta_sync_ring_init (ctx, xdisplay); -} - -gboolean -meta_sync_ring_after_frame (CoglContext *ctx) -{ - 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) - { - g_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) - { - g_warning ("MetaSyncRing: Timed out waiting for sync object."); - return meta_sync_ring_reboot (ctx, 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 (CoglContext *ctx) -{ - MetaSyncRing *ring = meta_sync_ring_get (); - MetaSync *sync; - - if (!ring) - return FALSE; - - g_return_val_if_fail (ring->xdisplay != NULL, FALSE); - - sync = ring->current_sync; - - if (sync->state == META_SYNC_STATE_WAITING) - { - meta_gl_delete_sync (sync->gpu_fence); - sync->gpu_fence = 0; - sync->state = META_SYNC_STATE_READY; - } - else if (sync->state != META_SYNC_STATE_READY) - { - g_warning ("MetaSyncRing: Sync object is not ready -- were events handled properly?"); - if (!meta_sync_ring_reboot (ctx, ring->xdisplay)) - return FALSE; - } - - meta_sync_insert (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 6b82a349b06..00000000000 --- a/src/compositor/meta-sync-ring.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include -#include - -#include "cogl/cogl.h" - -gboolean meta_sync_ring_init (CoglContext *ctx, - Display *dpy); -void meta_sync_ring_destroy (void); -gboolean meta_sync_ring_after_frame (CoglContext *ctx); -gboolean meta_sync_ring_insert_wait (CoglContext *ctx); -void meta_sync_ring_handle_event (XEvent *event); diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c index e598e3c855f..c31e25e46bb 100644 --- a/src/compositor/meta-window-actor-x11.c +++ b/src/compositor/meta-window-actor-x11.c @@ -28,7 +28,6 @@ #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 "core/window-private.h" #include "meta/compositor.h" #include "meta/meta-enum-types.h" @@ -428,50 +427,6 @@ has_shadow (MetaWindowActorX11 *actor_x11) return TRUE; } -#ifdef HAVE_X11 -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); -} -#endif /* HAVE_X11 */ - static const char * get_shadow_class (MetaWindowActorX11 *actor_x11) { @@ -1018,12 +973,6 @@ is_actor_maybe_transparent (MetaWindowActorX11 *actor_x11) if (!surface) return TRUE; -#ifdef HAVE_X11 - if (META_IS_SURFACE_ACTOR_X11 (surface) && - meta_surface_actor_x11_is_unredirected (META_SURFACE_ACTOR_X11 (surface))) - return FALSE; -#endif - stex = meta_surface_actor_get_texture (surface); if (!meta_shaped_texture_has_alpha (stex)) return FALSE; @@ -1151,12 +1100,6 @@ handle_updates (MetaWindowActorX11 *actor_x11) meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); MetaWindow *window; -#ifdef HAVE_X11 - if (META_IS_SURFACE_ACTOR_X11 (surface) && - meta_surface_actor_x11_is_unredirected (META_SURFACE_ACTOR_X11 (surface))) - return; -#endif - window = meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); if (meta_window_actor_is_frozen (META_WINDOW_ACTOR (actor_x11))) { @@ -1173,19 +1116,6 @@ handle_updates (MetaWindowActorX11 *actor_x11) return; } -#ifdef HAVE_X11 - 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; -#endif /* HAVE_X11 */ - update_frame_bounds (actor_x11); check_needs_reshape (actor_x11); check_needs_shadow (actor_x11); diff --git a/src/compositor/meta-window-actor-x11.h b/src/compositor/meta-window-actor-x11.h index ec57e564df1..39220447252 100644 --- a/src/compositor/meta-window-actor-x11.h +++ b/src/compositor/meta-window-actor-x11.h @@ -33,13 +33,6 @@ G_DECLARE_FINAL_TYPE (MetaWindowActorX11, void meta_window_actor_x11_process_x11_damage (MetaWindowActorX11 *actor_x11, XDamageNotifyEvent *event); -#ifdef HAVE_X11 -gboolean meta_window_actor_x11_should_unredirect (MetaWindowActorX11 *actor_x11); - -void meta_window_actor_x11_set_unredirected (MetaWindowActorX11 *actor_x11, - gboolean unredirected); -#endif - void meta_window_actor_x11_update_shape (MetaWindowActorX11 *actor_x11); void meta_window_actor_x11_process_damage (MetaWindowActorX11 *actor_x11, diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index f3f7db7210e..7aadf119860 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -32,9 +32,6 @@ #include "core/window-private.h" #include "meta/window.h" -#ifdef HAVE_X11_CLIENT -#include "compositor/meta-surface-actor-x11.h" -#endif #ifdef HAVE_WAYLAND #include "compositor/meta-surface-actor-wayland.h" @@ -593,13 +590,6 @@ init_surface_actor (MetaWindowActor *self) MetaWindow *window = priv->window; MetaSurfaceActor *surface_actor = NULL; -#ifdef HAVE_X11 - if (!meta_is_wayland_compositor ()) - { - surface_actor = meta_surface_actor_x11_new (window); - } - else -#endif #ifdef HAVE_WAYLAND { MetaWaylandSurface *surface = meta_window_get_wayland_surface (window); @@ -1049,13 +1039,6 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self, meta_window_get_buffer_rect (priv->window, &actor_rect); - /* When running as a Wayland compositor we catch size changes when new - * buffers are attached */ -#ifdef HAVE_X11 - if (META_IS_SURFACE_ACTOR_X11 (priv->surface)) - meta_surface_actor_x11_set_size (META_SURFACE_ACTOR_X11 (priv->surface), - actor_rect.width, actor_rect.height); -#endif /* 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 diff --git a/src/core/display.c b/src/core/display.c index 2e4a3bf6cf2..c10b33d9118 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -61,12 +61,6 @@ #include "meta/prefs.h" #ifdef HAVE_X11_CLIENT -#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/meta-compositor-x11.h" #include "meta/meta-x11-group.h" #include "x11/meta-startup-notification-x11.h" #include "x11/meta-x11-display-private.h" @@ -664,16 +658,8 @@ create_compositor (MetaDisplay *display) if (META_IS_BACKEND_NATIVE (backend)) return META_COMPOSITOR (meta_compositor_native_new (display, backend)); #endif -#if defined(HAVE_XWAYLAND) && defined(HAVE_X11) - if (META_IS_BACKEND_X11_NESTED (backend)) - return META_COMPOSITOR (meta_compositor_server_new (display, backend)); -#endif #endif/* HAVE_WAYLAND */ -#ifdef HAVE_X11 - return META_COMPOSITOR (meta_compositor_x11_new (display, backend)); -#else g_assert_not_reached (); -#endif } static void @@ -801,29 +787,6 @@ disable_input_capture (MetaInputCapture *input_capture, priv->enable_input_capture = FALSE; } -#ifdef HAVE_X11 -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); - - return TRUE; -} -#endif - #ifdef HAVE_XWAYLAND gboolean meta_display_init_x11_finish (MetaDisplay *display, @@ -945,7 +908,7 @@ meta_display_new (MetaContext *context, ClutterActor *stage = meta_backend_get_stage (backend); MetaDisplay *display; MetaDisplayPrivate *priv; - guint32 timestamp; + guint32 timestamp = 0; MetaMonitorManager *monitor_manager; MetaSettings *settings; MetaInputCapture *input_capture; @@ -1045,21 +1008,6 @@ meta_display_new (MetaContext *context, } else #endif /* HAVE_WAYLAND */ -#ifdef HAVE_X11 - { - if (!meta_display_init_x11_display (display, error)) - { - g_object_unref (display); - return NULL; - } - - timestamp = display->x11_display->timestamp; - } -#else - { - g_assert_not_reached (); - } -#endif display->last_focus_time = timestamp; display->last_user_time = timestamp; diff --git a/src/core/meta-context-main.c b/src/core/meta-context-main.c index abda8f6fbfe..d538ce96331 100644 --- a/src/core/meta-context-main.c +++ b/src/core/meta-context-main.c @@ -35,10 +35,6 @@ #include "core/meta-session-manager.h" #include "meta/meta-backend.h" -#ifdef HAVE_X11 -#include "backends/x11/cm/meta-backend-x11-cm.h" -#endif - #ifdef HAVE_NATIVE_BACKEND #include "backends/native/meta-backend-native.h" #include "backends/native/meta-backend-native-types.h" @@ -48,10 +44,6 @@ #include "core/meta-mdk.h" #endif -#if defined (HAVE_X11) && defined (HAVE_WAYLAND) -#include "backends/x11/nested/meta-backend-x11-nested.h" -#endif - #ifdef HAVE_WAYLAND #include "wayland/meta-wayland.h" #endif @@ -59,14 +51,10 @@ typedef struct _MetaContextMainOptions { struct { - char *display_name; gboolean replace; - gboolean sync; - gboolean force; } x11; #ifdef HAVE_WAYLAND gboolean wayland; - gboolean nested; gboolean no_x11; char *wayland_display; #endif @@ -89,8 +77,6 @@ struct _MetaContextMain MetaSessionManager *session_manager; - MetaCompositorType compositor_type; - #ifdef HAVE_NATIVE_BACKEND GList *persistent_virtual_monitors; #endif @@ -106,40 +92,11 @@ 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) + if (context_main->options.headless && context_main->options.devkit) { 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 || context_main->options.devkit)) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, - "Can't run in X11 mode headlessly"); + "Can't run in both MDK and headless mode"); return FALSE; } @@ -155,123 +112,6 @@ check_configuration (MetaContextMain *context_main, 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 ("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 || - context_main->options.devkit || -#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, @@ -288,11 +128,6 @@ meta_context_main_configure (MetaContext *context, 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); @@ -314,44 +149,23 @@ meta_context_main_configure (MetaContext *context, 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); +#ifdef HAVE_LOGIND g_autofree char *unit = NULL; #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; + if (context_main->options.no_x11) + return META_X11_DISPLAY_POLICY_DISABLED; + #ifdef HAVE_LOGIND - else if (sd_pid_get_user_unit (0, &unit) < 0) - return META_X11_DISPLAY_POLICY_MANDATORY; + if (sd_pid_get_user_unit (0, &unit) < 0) + return META_X11_DISPLAY_POLICY_MANDATORY; + else #endif - else - return META_X11_DISPLAY_POLICY_ON_DEMAND; -#else /* HAVE_WAYLAND */ - g_assert_not_reached (); -#endif /* HAVE_WAYLAND */ - } - - g_assert_not_reached (); + return META_X11_DISPLAY_POLICY_ON_DEMAND; } static gboolean @@ -453,38 +267,6 @@ meta_context_main_setup (MetaContext *context, return TRUE; } -#ifdef HAVE_X11 -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); -} -#endif - -#if defined (HAVE_X11) && defined (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); -} -#endif - #ifdef HAVE_WAYLAND #ifdef HAVE_NATIVE_BACKEND static MetaBackend * @@ -517,32 +299,18 @@ meta_context_main_create_backend (MetaContext *context, #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: -#ifdef HAVE_X11 - return create_x11_cm_backend (context, error); -#endif - case META_COMPOSITOR_TYPE_WAYLAND: #ifdef HAVE_WAYLAND -#ifdef HAVE_X11 - if (context_main->options.nested) - return create_nested_backend (context, error); -#endif #ifdef HAVE_NATIVE_BACKEND - if (context_main->options.headless || - context_main->options.devkit) - return create_headless_backend (context, error); + if (context_main->options.headless || + context_main->options.devkit) + return create_headless_backend (context, error); - return create_native_backend (context, error); + return create_native_backend (context, error); #endif /* HAVE_NATIVE_BACKEND */ #else /* HAVE_WAYLAND */ - g_assert_not_reached (); + g_assert_not_reached (); #endif /* HAVE_WAYLAND */ - } g_assert_not_reached (); } @@ -560,16 +328,6 @@ meta_context_main_notify_ready (MetaContext *context) g_critical ("Could not create session manager: %s", error->message); } -#ifdef HAVE_X11 -static gboolean -meta_context_main_is_x11_sync (MetaContext *context) -{ - MetaContextMain *context_main = META_CONTEXT_MAIN (context); - - return context_main->options.x11.sync || g_getenv ("MUTTER_SYNC"); -} -#endif - static MetaSessionManager * meta_context_main_get_session_manager (MetaContext *context) { @@ -623,26 +381,6 @@ meta_context_main_add_option_entries (MetaContextMain *context_main) { MetaContext *context = META_CONTEXT (context_main); GOptionEntry options[] = { -#ifdef HAVE_X11 - { - "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" - }, - { - "sync", 0, 0, G_OPTION_ARG_NONE, - &context_main->options.x11.sync, - N_("Make X calls synchronous"), - NULL - }, -#endif #ifdef HAVE_WAYLAND { "wayland", 0, 0, G_OPTION_ARG_NONE, @@ -650,14 +388,6 @@ meta_context_main_add_option_entries (MetaContextMain *context_main) N_("Run as a wayland compositor"), NULL }, -#ifdef HAVE_X11 - { - "nested", 0, 0, G_OPTION_ARG_NONE, - &context_main->options.nested, - N_("Run as a nested compositor"), - NULL - }, -#endif #ifdef HAVE_XWAYLAND { "no-x11", 0, 0, G_OPTION_ARG_NONE, @@ -702,13 +432,6 @@ meta_context_main_add_option_entries (MetaContextMain *context_main) &context_main->options.unsafe_mode, "Run in unsafe mode" }, -#ifdef HAVE_X11 - { - "x11", 0, 0, G_OPTION_ARG_NONE, - &context_main->options.x11.force, - N_("Run with X11 backend") - }, -#endif { "profile", 0, 0, G_OPTION_ARG_FILENAME, &context_main->options.trace_file, @@ -783,21 +506,16 @@ meta_context_main_class_init (MetaContextMainClass *klass) 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; -#ifdef HAVE_X11 - context_class->is_x11_sync = meta_context_main_is_x11_sync; -#endif context_class->get_session_manager = meta_context_main_get_session_manager; } static void meta_context_main_init (MetaContextMain *context_main) { - context_main->compositor_type = -1; } diff --git a/src/core/meta-context-private.h b/src/core/meta-context-private.h index e6c24a82584..67bc0a8339f 100644 --- a/src/core/meta-context-private.h +++ b/src/core/meta-context-private.h @@ -40,8 +40,6 @@ struct _MetaContextClass char ***argv, GError **error); - MetaCompositorType (* get_compositor_type) (MetaContext *context); - MetaX11DisplayPolicy (* get_x11_display_policy) (MetaContext *context); gboolean (* is_replacing) (MetaContext *context); @@ -54,9 +52,6 @@ struct _MetaContextClass void (* notify_ready) (MetaContext *context); -#ifdef HAVE_X11 - gboolean (* is_x11_sync) (MetaContext *context); -#endif MetaSessionManager * (* get_session_manager) (MetaContext *context); }; @@ -79,11 +74,6 @@ MetaServiceChannel * meta_context_get_service_channel (MetaContext *context); MetaX11DisplayPolicy meta_context_get_x11_display_policy (MetaContext *context); -#ifdef HAVE_X11 -META_EXPORT_TEST -gboolean meta_context_is_x11_sync (MetaContext *context); -#endif - #ifdef HAVE_PROFILER MetaProfiler * meta_context_get_profiler (MetaContext *context); diff --git a/src/core/meta-context.c b/src/core/meta-context.c index b5c51009a60..6d9561c8bbd 100644 --- a/src/core/meta-context.c +++ b/src/core/meta-context.c @@ -286,9 +286,7 @@ meta_context_get_display (MetaContext *context) * meta_context_get_wayland_compositor: * @context: The #MetaContext * - * Get the #MetaWaylandCompositor associated with the MetaContext. The might be - * none currently associated if the context hasn't been started or if the - * requested compositor type is not %META_COMPOSITOR_TYPE_WAYLAND. + * Get the #MetaWaylandCompositor associated with the MetaContext. * * Returns: (transfer none) (nullable): the #MetaWaylandCompositor */ @@ -309,14 +307,6 @@ meta_context_get_service_channel (MetaContext *context) } #endif -MetaCompositorType -meta_context_get_compositor_type (MetaContext *context) -{ - g_return_val_if_fail (META_IS_CONTEXT (context), META_COMPOSITOR_TYPE_WAYLAND); - - return META_CONTEXT_GET_CLASS (context)->get_compositor_type (context); -} - gboolean meta_context_is_replacing (MetaContext *context) { @@ -331,14 +321,6 @@ meta_context_get_x11_display_policy (MetaContext *context) return META_CONTEXT_GET_CLASS (context)->get_x11_display_policy (context); } -#ifdef HAVE_X11 -gboolean -meta_context_is_x11_sync (MetaContext *context) -{ - return META_CONTEXT_GET_CLASS (context)->is_x11_sync (context); -} -#endif - #ifdef HAVE_PROFILER MetaProfiler * meta_context_get_profiler (MetaContext *context) @@ -403,7 +385,6 @@ meta_context_configure (MetaContext *context, GError **error) { MetaContextPrivate *priv = meta_context_get_instance_private (context); - MetaCompositorType compositor_type; g_return_val_if_fail (META_IS_CONTEXT (context), FALSE); @@ -419,36 +400,13 @@ meta_context_configure (MetaContext *context, priv->profiler = meta_profiler_new (priv->trace_file); #endif - 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; - } + meta_set_is_wayland_compositor (TRUE); 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) { @@ -477,7 +435,6 @@ meta_context_setup (MetaContext *context, GError **error) { MetaContextPrivate *priv = meta_context_get_instance_private (context); - MetaCompositorType compositor_type; g_return_val_if_fail (META_IS_CONTEXT (context), FALSE); @@ -493,10 +450,8 @@ meta_context_setup (MetaContext *context, 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)); + g_message ("Running %s (using mutter %s) as a Wayland display server", + priv->name, VERSION); if (priv->plugin_name) meta_plugin_manager_load (priv->plugin_name); @@ -529,9 +484,7 @@ meta_context_start (MetaContext *context, 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); + priv->wayland_compositor = meta_wayland_compositor_new (context); #endif plugin_options = g_steal_pointer (&priv->plugin_options), diff --git a/src/core/meta-service-channel.c b/src/core/meta-service-channel.c index 37f08a7c6bc..74a9904e268 100644 --- a/src/core/meta-service-channel.c +++ b/src/core/meta-service-channel.c @@ -219,16 +219,6 @@ handle_open_wayland_service_connection (MetaDBusServiceChannel *object, const char *sender; g_autoptr (MetaServiceChannelData) data = NULL; - if (meta_context_get_compositor_type (service_channel->context) != - META_COMPOSITOR_TYPE_WAYLAND) - { - g_dbus_method_invocation_return_error (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_NOT_SUPPORTED, - "Not a Wayland compositor"); - return G_DBUS_METHOD_INVOCATION_HANDLED; - } - if (!verify_service_client_type (service_client_type)) { g_dbus_method_invocation_return_error (invocation, @@ -327,22 +317,11 @@ handle_open_wayland_connection (MetaDBusServiceChannel *object, GUnixFDList *in_fd_list, GVariant *arg_options) { -#ifdef HAVE_WAYLAND MetaServiceChannel *service_channel = META_SERVICE_CHANNEL (object); GDBusConnection *connection; const char *sender; g_autoptr (MetaServiceChannelData) data = NULL; - if (meta_context_get_compositor_type (service_channel->context) != - META_COMPOSITOR_TYPE_WAYLAND) - { - g_dbus_method_invocation_return_error (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_NOT_SUPPORTED, - "Not a Wayland compositor"); - return G_DBUS_METHOD_INVOCATION_HANDLED; - } - connection = g_dbus_method_invocation_get_connection (invocation); sender = g_dbus_method_invocation_get_sender (invocation); @@ -358,13 +337,6 @@ handle_open_wayland_connection (MetaDBusServiceChannel *object, g_steal_pointer (&data)); return G_DBUS_METHOD_INVOCATION_HANDLED; -#else /* HAVE_WAYLAND */ - g_dbus_method_invocation_return_error (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_NOT_SUPPORTED, - "Wayland not supported"); - return G_DBUS_METHOD_INVOCATION_HANDLED; -#endif /* HAVE_WAYLAND */ } static void diff --git a/src/core/mutter.c b/src/core/mutter.c index 3772ecca4e7..dee4726a850 100644 --- a/src/core/mutter.c +++ b/src/core/mutter.c @@ -170,8 +170,7 @@ main (int argc, char **argv) g_child_watch_add (command_pid, command_exited_cb, context); } - if (meta_context_get_compositor_type (context) == META_COMPOSITOR_TYPE_WAYLAND) - meta_context_raise_rlimit_nofile (context, NULL); + meta_context_raise_rlimit_nofile (context, NULL); if (!meta_context_run_main_loop (context, &error)) { diff --git a/src/helpers/meson.build b/src/helpers/meson.build index eadc52b2f64..cc21ede2013 100644 --- a/src/helpers/meson.build +++ b/src/helpers/meson.build @@ -18,23 +18,3 @@ executable('mutter-backlight-helper', install_dir: libexecdir, install: true, ) - -# restart helper -if have_x11 - executable('mutter-restart-helper', - sources: [ - files('meta-restart-helper.c'), - ], - include_directories: top_includepath, - c_args: [ - mutter_c_args, - '-DG_LOG_DOMAIN="mutter-restart-helper"', - ], - dependencies: [ - x11_dep, - xcomposite_dep, - ], - install_dir: libexecdir, - install: true, - ) -endif \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index 508c3416da9..64ae9e6111d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -112,16 +112,6 @@ if have_x11_client ] endif -if have_x11 - mutter_pkg_private_deps += [ - fribidi_dep, - xcb_randr_dep, - xkbfile_dep, - xkbcommon_x11_dep, - xtst_dep, - ] -endif - if have_wayland mutter_pkg_deps += [ wayland_server_dep, @@ -401,77 +391,6 @@ mutter_sources = [ 'core/workspace-private.h', ] -if have_x11 - mutter_sources += [ - '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-backlight-x11.c', - 'backends/x11/meta-backlight-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-color-manager-x11.c', - 'backends/x11/meta-color-manager-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-sprite-x11.c', - 'backends/x11/meta-sprite-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-sprite-x11-nested.c', - 'backends/x11/nested/meta-sprite-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/meta-compositor-x11.c', - 'compositor/meta-compositor-x11.h', - 'compositor/meta-surface-actor-x11.c', - 'compositor/meta-surface-actor-x11.h', - 'compositor/meta-sync-ring.c', - 'compositor/meta-sync-ring.h', - ] -endif - if have_x11_client mutter_sources += [ 'compositor/meta-window-actor-x11.c', @@ -1149,101 +1068,100 @@ wayland_protocol_server_headers = [] wayland_protocol_client_headers = [] wayland_protocol_sources = [] -if have_wayland - # Format: - # - protocol name - # - protocol type ('stable', 'staging', 'unstable', 'private', 'eglstreams') - # * 'stable', 'staging' and 'unstable' are from wayland-protocols - # * 'private' are shipped in this repo - # * 'eglstreams' are from wayland-eglstream-protocols - # - protocol version (optional for 'stable', 'staging' and 'unstable') - wayland_protocols = [ - ['color-management', 'staging', 1, ], - ['color-representation', 'staging', 1, ], - ['commit-timing', 'staging', 1, ], - ['cursor-shape', 'staging', 1, ], - ['drm-lease', 'staging', 1, ], - ['fractional-scale', 'staging', 1, ], - ['fifo', 'staging', 1, ], - ['gtk-shell', 'private', ], - ['idle-inhibit', 'unstable', 1, ], - ['keyboard-shortcuts-inhibit', 'unstable', 1, ], - ['linux-dmabuf', 'stable', 1, ], - ['linux-drm-syncobj', 'staging', 1, ], - ['pointer-constraints', 'unstable', 1, ], - ['pointer-gestures', 'unstable', 1, ], - ['pointer-warp', 'staging', 1, ], - ['presentation-time', 'stable', ], - ['primary-selection', 'unstable', 1, ], - ['relative-pointer', 'unstable', 1, ], - ['session-management-v1', 'private', ], - ['single-pixel-buffer', 'staging', 1, ], - ['tablet', 'stable', 2, ], - ['text-input', 'unstable', 3, ], - ['viewporter', 'stable', ], - ['xdg-activation', 'staging', 1, ], - ['xdg-dialog', 'staging', 1, ], - ['xdg-foreign', 'unstable', 1, ], - ['xdg-foreign', 'unstable', 2, ], - ['xdg-output', 'unstable', 1, ], - ['xdg-shell', 'stable', ], - ['xdg-system-bell', 'staging', 1, ], - ['xdg-toplevel-drag', 'staging', 1, ], - ['xdg-toplevel-tag', 'staging', 1, ], +# Format: +# - protocol name +# - protocol type ('stable', 'staging', 'unstable', 'private', 'eglstreams') +# * 'stable', 'staging' and 'unstable' are from wayland-protocols +# * 'private' are shipped in this repo +# * 'eglstreams' are from wayland-eglstream-protocols +# - protocol version (optional for 'stable', 'staging' and 'unstable') +wayland_protocols = [ + ['color-management', 'staging', 1, ], + ['color-representation', 'staging', 1, ], + ['commit-timing', 'staging', 1, ], + ['cursor-shape', 'staging', 1, ], + ['drm-lease', 'staging', 1, ], + ['fractional-scale', 'staging', 1, ], + ['fifo', 'staging', 1, ], + ['gtk-shell', 'private', ], + ['idle-inhibit', 'unstable', 1, ], + ['keyboard-shortcuts-inhibit', 'unstable', 1, ], + ['linux-dmabuf', 'stable', 1, ], + ['linux-drm-syncobj', 'staging', 1, ], + ['pointer-constraints', 'unstable', 1, ], + ['pointer-gestures', 'unstable', 1, ], + ['pointer-warp', 'staging', 1, ], + ['presentation-time', 'stable', ], + ['primary-selection', 'unstable', 1, ], + ['relative-pointer', 'unstable', 1, ], + ['session-management-v1', 'private', ], + ['single-pixel-buffer', 'staging', 1, ], + ['tablet', 'stable', 2, ], + ['text-input', 'unstable', 3, ], + ['viewporter', 'stable', ], + ['xdg-activation', 'staging', 1, ], + ['xdg-dialog', 'staging', 1, ], + ['xdg-foreign', 'unstable', 1, ], + ['xdg-foreign', 'unstable', 2, ], + ['xdg-output', 'unstable', 1, ], + ['xdg-shell', 'stable', ], + ['xdg-system-bell', 'staging', 1, ], + ['xdg-toplevel-drag', 'staging', 1, ], + ['xdg-toplevel-tag', 'staging', 1, ], +] + +if have_xwayland + wayland_protocols += [ + ['mutter-x11-interop', 'private', ], ['xwayland-keyboard-grab', 'unstable', 1, ], ] - if have_xwayland - wayland_protocols += [ - ['mutter-x11-interop', 'private', ], - ] - endif - if have_wayland_eglstream - wayland_protocols += [ - ['wayland-eglstream-controller', 'eglstreams', ], - ] - wayland_eglstream_protocols_dir = wayland_eglstream_protocols_dep.get_variable('pkgdatadir') - endif +endif +if have_wayland_eglstream + wayland_protocols += [ + ['wayland-eglstream-controller', 'eglstreams', ], + ] + wayland_eglstream_protocols_dir = wayland_eglstream_protocols_dep.get_variable('pkgdatadir') +endif - protocol_xmls = files() +protocol_xmls = files() - foreach p: wayland_protocols - protocol_name = p.get(0) - protocol_type = p.get(1) +foreach p: wayland_protocols + protocol_name = p.get(0) + protocol_type = p.get(1) - if protocol_type == 'private' - protocol_xmls += files( - 'wayland/protocol/@0@.xml'.format(protocol_name) - ) - elif protocol_type == 'eglstreams' - protocol_xmls += files( - '@0@/@1@.xml'.format(wayland_eglstream_protocols_dir, protocol_name) - ) + if protocol_type == 'private' + protocol_xmls += files( + 'wayland/protocol/@0@.xml'.format(protocol_name) + ) + elif protocol_type == 'eglstreams' + protocol_xmls += files( + '@0@/@1@.xml'.format(wayland_eglstream_protocols_dir, protocol_name) + ) + else + if p.length() > 2 + protocol_xmls += wl_mod.find_protocol( + protocol_name, + state: protocol_type, + version: p.get(2)) else - if p.length() > 2 - protocol_xmls += wl_mod.find_protocol( - protocol_name, - state: protocol_type, - version: p.get(2)) - else - protocol_xmls += wl_mod.find_protocol( - protocol_name, - state: protocol_type) - endif + protocol_xmls += wl_mod.find_protocol( + protocol_name, + state: protocol_type) endif - endforeach + endif +endforeach - foreach xml: protocol_xmls - generated = wl_mod.scan_xml(xml, - client: true, - server: true) +foreach xml: protocol_xmls + generated = wl_mod.scan_xml(xml, + client: true, + server: true) - wayland_protocol_sources += generated[0] - wayland_protocol_client_headers += generated[1] - wayland_protocol_server_headers += generated[2] - endforeach + wayland_protocol_sources += generated[0] + wayland_protocol_client_headers += generated[1] + wayland_protocol_server_headers += generated[2] +endforeach - message('Generated code for @0@ wayland protocols'.format(wayland_protocol_sources.length())) -endif +message('Generated code for @0@ wayland protocols'.format(wayland_protocol_sources.length())) mutter_built_sources += wayland_protocol_server_headers mutter_built_sources += wayland_protocol_sources @@ -1363,7 +1281,6 @@ pkg.generate(libmutter, 'apiversion=' + libmutter_api_version, 'girdir=${libdir}/mutter-' + libmutter_api_version, 'typelibdir=${libdir}/mutter-' + libmutter_api_version, - 'have_x11=@0@'.format(have_x11), 'have_x11_client=@0@'.format(have_x11_client), 'have_wayland=@0@'.format(have_wayland), 'have_fonts=@0@'.format(have_fonts), diff --git a/src/meta/meta-context.h b/src/meta/meta-context.h index ed35834df8d..046cee2f773 100644 --- a/src/meta/meta-context.h +++ b/src/meta/meta-context.h @@ -82,9 +82,6 @@ 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); diff --git a/src/meta/meta-enums.h b/src/meta/meta-enums.h index e0a2fc50eac..f3bb9e0ca47 100644 --- a/src/meta/meta-enums.h +++ b/src/meta/meta-enums.h @@ -18,12 +18,6 @@ #pragma once -typedef enum _MetaCompositorType -{ - META_COMPOSITOR_TYPE_WAYLAND, - META_COMPOSITOR_TYPE_X11, -} MetaCompositorType; - /** * MetaGrabOp: * @META_GRAB_OP_NONE: None diff --git a/src/meta/meta-x11-display.h b/src/meta/meta-x11-display.h index cf53f365603..23d1eb4bc45 100644 --- a/src/meta/meta-x11-display.h +++ b/src/meta/meta-x11-display.h @@ -43,11 +43,6 @@ Display *meta_x11_display_get_xdisplay (MetaX11Display *x11_display); META_EXPORT Window meta_x11_display_get_xroot (MetaX11Display *x11_display); -META_EXPORT -void meta_x11_display_set_stage_input_region (MetaX11Display *x11_display, - XRectangle *rects, - int n_rects); - META_EXPORT unsigned int meta_x11_display_add_event_func (MetaX11Display *x11_display, MetaX11DisplayEventFunc event_func, diff --git a/src/tests/clutter/interactive/test-main.c b/src/tests/clutter/interactive/test-main.c index 29fc82a6a55..06e6be1125b 100644 --- a/src/tests/clutter/interactive/test-main.c +++ b/src/tests/clutter/interactive/test-main.c @@ -5,7 +5,6 @@ #include #include -#include "backends/x11/nested/meta-backend-x11-nested.h" #include "meta-test/meta-context-test.h" #include "tests/clutter-test-utils.h" @@ -224,4 +223,3 @@ out: return ret; } - diff --git a/src/tests/cogl/conform/meson.build b/src/tests/cogl/conform/meson.build index 7d327fa29fb..84a18eb55a7 100644 --- a/src/tests/cogl/conform/meson.build +++ b/src/tests/cogl/conform/meson.build @@ -46,7 +46,6 @@ cogl_tests = [ # "test-npot-texture", # "test-readpixels", # "test-texture-mipmaps", -# "test-texture-pixmap-x11", # "test-viewport", #] diff --git a/src/tests/cogl/conform/test-texture-pixmap-x11.c b/src/tests/cogl/conform/test-texture-pixmap-x11.c deleted file mode 100644 index 5e50a59b2d4..00000000000 --- a/src/tests/cogl/conform/test-texture-pixmap-x11.c +++ /dev/null @@ -1,248 +0,0 @@ -#include - -#include "test-conform-common.h" - -static const CoglColor stage_color = { 0x00, 0x00, 0x00, 0xff }; - -#ifdef HAVE_X11 - -#include -#include - -#define PIXMAP_WIDTH 512 -#define PIXMAP_HEIGHT 256 -#define GRID_SQUARE_SIZE 16 - -/* Coordinates of a square that we'll update */ -#define PIXMAP_CHANGE_X 1 -#define PIXMAP_CHANGE_Y 1 - -typedef struct _TestState -{ - ClutterActor *stage; - CoglTexture *tfp; - Pixmap pixmap; - unsigned int frame_count; - Display *display; -} TestState; - -static Pixmap -create_pixmap (TestState *state) -{ - Pixmap pixmap; - XGCValues gc_values = { 0, }; - GC black_gc, white_gc; - int screen = DefaultScreen (state->display); - int x, y; - - pixmap = XCreatePixmap (state->display, - DefaultRootWindow (state->display), - PIXMAP_WIDTH, PIXMAP_HEIGHT, - DefaultDepth (state->display, screen)); - - gc_values.foreground = BlackPixel (state->display, screen); - black_gc = XCreateGC (state->display, pixmap, GCForeground, &gc_values); - gc_values.foreground = WhitePixel (state->display, screen); - white_gc = XCreateGC (state->display, pixmap, GCForeground, &gc_values); - - /* Draw a grid of alternative black and white rectangles to the - pixmap */ - for (y = 0; y < PIXMAP_HEIGHT / GRID_SQUARE_SIZE; y++) - for (x = 0; x < PIXMAP_WIDTH / GRID_SQUARE_SIZE; x++) - XFillRectangle (state->display, pixmap, - ((x ^ y) & 1) ? black_gc : white_gc, - x * GRID_SQUARE_SIZE, - y * GRID_SQUARE_SIZE, - GRID_SQUARE_SIZE, - GRID_SQUARE_SIZE); - - XFreeGC (state->display, black_gc); - XFreeGC (state->display, white_gc); - - return pixmap; -} - -static void -update_pixmap (TestState *state) -{ - XGCValues gc_values = { 0, }; - GC black_gc; - int screen = DefaultScreen (state->display); - - gc_values.foreground = BlackPixel (state->display, screen); - black_gc = XCreateGC (state->display, state->pixmap, - GCForeground, &gc_values); - - /* Fill in one the rectangles with black */ - XFillRectangle (state->display, state->pixmap, - black_gc, - PIXMAP_CHANGE_X * GRID_SQUARE_SIZE, - PIXMAP_CHANGE_Y * GRID_SQUARE_SIZE, - GRID_SQUARE_SIZE, GRID_SQUARE_SIZE); - - XFreeGC (state->display, black_gc); -} - -static gboolean -check_paint (TestState *state, int x, int y, int scale) -{ - uint8_t *data, *p, update_value = 0; - - p = data = g_malloc (PIXMAP_WIDTH * PIXMAP_HEIGHT * 4); - - cogl_read_pixels (x, y, PIXMAP_WIDTH / scale, PIXMAP_HEIGHT / scale, - COGL_READ_PIXELS_COLOR_BUFFER, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - data); - - for (y = 0; y < PIXMAP_HEIGHT / scale; y++) - for (x = 0; x < PIXMAP_WIDTH / scale; x++) - { - int grid_x = x * scale / GRID_SQUARE_SIZE; - int grid_y = y * scale / GRID_SQUARE_SIZE; - - /* If this is the updatable square then we'll let it be either - color but we'll return which one it was */ - if (grid_x == PIXMAP_CHANGE_X && grid_y == PIXMAP_CHANGE_Y) - { - if (x % (GRID_SQUARE_SIZE / scale) == 0 && - y % (GRID_SQUARE_SIZE / scale) == 0) - update_value = *p; - else - g_assert_cmpint (p[0], ==, update_value); - - g_assert_true (p[1] == update_value); - g_assert_true (p[2] == update_value); - p += 4; - } - else - { - uint8_t value = ((grid_x ^ grid_y) & 1) ? 0x00 : 0xff; - g_assert_cmpint (*(p++), ==, value); - g_assert_cmpint (*(p++), ==, value); - g_assert_cmpint (*(p++), ==, value); - p++; - } - } - - g_free (data); - - return update_value == 0x00; -} - -/* We skip these frames first */ -#define FRAME_COUNT_BASE 5 -/* First paint the tfp with no mipmaps */ -#define FRAME_COUNT_NORMAL 6 -/* Then use mipmaps */ -#define FRAME_COUNT_MIPMAP 7 -/* After this frame will start waiting for the pixmap to change */ -#define FRAME_COUNT_UPDATED 8 - -static void -on_after_paint (ClutterActor *actor, - ClutterStageView *view, - ClutterFrame *frame, - TestState *state) -{ - CoglPipeline *pipeline; - - pipeline = cogl_pipeline_new (); - cogl_pipeline_set_layer (pipeline, 0, state->tfp); - if (state->frame_count == FRAME_COUNT_MIPMAP) - { - const CoglPipelineFilter min_filter = - COGL_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST; - cogl_pipeline_set_layer_filters (pipeline, 0, - min_filter, - COGL_PIPELINE_FILTER_NEAREST); - } - else - cogl_pipeline_set_layer_filters (pipeline, 0, - COGL_PIPELINE_FILTER_NEAREST, - COGL_PIPELINE_FILTER_NEAREST); - cogl_set_source (pipeline); - - cogl_rectangle (0, 0, PIXMAP_WIDTH, PIXMAP_HEIGHT); - - cogl_rectangle (0, PIXMAP_HEIGHT, - PIXMAP_WIDTH / 4, PIXMAP_HEIGHT * 5 / 4); - - if (state->frame_count >= 5) - { - gboolean big_updated, small_updated; - - big_updated = check_paint (state, 0, 0, 1); - small_updated = check_paint (state, 0, PIXMAP_HEIGHT, 4); - - g_assert_true (big_updated == small_updated); - - if (state->frame_count < FRAME_COUNT_UPDATED) - g_assert_true (big_updated == FALSE); - else if (state->frame_count == FRAME_COUNT_UPDATED) - /* Change the pixmap and keep drawing until it updates */ - update_pixmap (state); - else if (big_updated) - /* If we successfully got the update then the test is over */ - clutter_test_quit (); - } - - state->frame_count++; -} - -static gboolean -queue_redraw (void *stage) -{ - clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); - - return TRUE; -} - -#endif /* HAVE_X11 */ - -void -test_texture_pixmap_x11 (TestUtilsGTestFixture *fixture, - void *data) -{ -#ifdef HAVE_X11 - - TestState state; - unsigned int idle_handler; - unsigned long paint_handler; - - state.frame_count = 0; - state.stage = clutter_stage_get_default (); - - state.display = clutter_x11_get_default_display (); - - state.pixmap = create_pixmap (&state); - state.tfp = cogl_texture_pixmap_x11_new (state.pixmap, TRUE); - - clutter_actor_set_background_color (CLUTTER_ACTOR (state.stage), &stage_color); - - paint_handler = g_signal_connect (CLUTTER_STAGE (state.stage), "after-paint", - G_CALLBACK (on_after_paint), &state); - - idle_handler = g_idle_add (queue_redraw, state.stage); - - clutter_actor_show (state.stage); - - clutter_test_main (); - - g_clear_signal_handler (&paint_handler, state.stage); - - g_clear_handle_id (&idle_handler, g_source_remove); - - XFreePixmap (state.display, state.pixmap); - - if (cogl_test_verbose ()) - g_print ("OK\n"); - -#else /* HAVE_X11 */ - - if (cogl_test_verbose ()) - g_print ("Skipping\n"); - -#endif /* HAVE_X11 */ -} - diff --git a/src/tests/meson.build b/src/tests/meson.build index 8c3773033f3..1adf8a2234c 100644 --- a/src/tests/meson.build +++ b/src/tests/meson.build @@ -1260,40 +1260,6 @@ if have_kvm_tests or have_tty_tests endif endif -if have_x11_tests - xvfb_args = [ - '-a', - '-s', - '+iglx -noreset', - ] - - zenity = find_program('zenity', required: true) - - foreach mode: ['', 'sync'] - x11_env = test_env - x11_env.set('ZENITY', zenity.full_path()) - if mode == 'sync' - x11_env.set('MUTTER_SYNC', '1') - endif - test('x11' + (mode != '' ? '-' + mode : ''), xvfb, - args: [ - xvfb_args, - find_program('x11-test.sh').full_path(), - mutter.full_path(), - ], - depends: [ - mutter, - default_plugin, - x11_frames, - ], - env: x11_env, - suite: ['core', 'mutter/x11'], - is_parallel: false, - timeout: 60, - ) - endforeach -endif - tools_test_env = test_env tools_test_env.set('G_DEBUG', 'fatal-warnings') diff --git a/src/tests/meta-context-test.c b/src/tests/meta-context-test.c index 418a114e8f7..9acbb6cc879 100644 --- a/src/tests/meta-context-test.c +++ b/src/tests/meta-context-test.c @@ -141,12 +141,6 @@ meta_context_test_configure (MetaContext *context, 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) { @@ -277,14 +271,6 @@ meta_context_test_get_session_manager (MetaContext *context) return priv->session_manager; } -#ifdef HAVE_X11 -static gboolean -meta_context_test_is_x11_sync (MetaContext *context) -{ - return !!g_getenv ("MUTTER_SYNC"); -} -#endif - static gboolean run_tests_idle (gpointer user_data) { @@ -438,16 +424,13 @@ meta_context_test_class_init (MetaContextTestClass *klass) object_class->finalize = meta_context_test_finalize; 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; -#ifdef HAVE_X11 - context_class->is_x11_sync = meta_context_test_is_x11_sync; -#endif + context_class->get_session_manager = meta_context_test_get_session_manager; signals[BEFORE_TESTS] = diff --git a/src/tests/x11-test.sh b/src/tests/x11-test.sh deleted file mode 100755 index faf90251f8e..00000000000 --- a/src/tests/x11-test.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash - -set -ex - -MUTTER="$1" - -if [ -z "$MUTTER" ]; then - echo Usage: $0 PATH-TO-MUTTER > /dev/stderr - exit 1 -fi - -export GDK_BACKEND=x11 -export G_DEBUG=fatal-warnings -export MUTTER_DEBUG=${MUTTER_DEBUG:-x11} - -echo \# Launching mutter > /dev/stderr -$MUTTER --x11 --mutter-plugin="$MUTTER_TEST_PLUGIN_PATH" & -MUTTER1_PID=$! -gdbus wait --session org.gnome.Mutter.IdleMonitor -echo \# Launched with pid $MUTTER1_PID - -sleep 2 - -echo Launching a couple of X11 clients > /dev/stderr -${ZENITY:-zenity} --warning & -ZENITY1_PID=$! -sleep 2 -${ZENITY:-zenity} --info & -ZENITY2_PID=$! -sleep 4 - -echo \# Replacing existing mutter with a new instance > /dev/stderr -$MUTTER --x11 --replace --mutter-plugin="$MUTTER_TEST_PLUGIN_PATH" & -MUTTER2_PID=$! -echo \# Launched with pid $MUTTER2_PID -wait $MUTTER1_PID - -echo \# Waiting for the second mutter to finish loading -gdbus wait --session org.gnome.Mutter.IdleMonitor - -sleep 2 - -echo \# Terminating clients > /dev/stderr -kill $ZENITY1_PID -sleep 1 -kill $ZENITY2_PID -sleep 1 - -echo \# Terminating mutter > /dev/stderr -kill $MUTTER2_PID -wait $MUTTER2_PID diff --git a/src/third_party/xcursor/xcursor.h b/src/third_party/xcursor/xcursor.h index 5494ae36649..13b242873ac 100644 --- a/src/third_party/xcursor/xcursor.h +++ b/src/third_party/xcursor/xcursor.h @@ -26,7 +26,7 @@ */ #pragma once -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND #include #else typedef unsigned int XcursorPixel; diff --git a/src/x11/events.c b/src/x11/events.c index 8b25b724a7b..857c6f2f7ff 100644 --- a/src/x11/events.c +++ b/src/x11/events.c @@ -27,12 +27,10 @@ #include #include #include +#include #include #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" @@ -1867,10 +1865,6 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display, { MetaDisplay *display = x11_display->display; MetaContext *context = meta_display_get_context (display); -#ifdef HAVE_X11 - MetaCursorTracker *cursor_tracker; - MetaBackend *backend = meta_context_get_backend (context); -#endif gboolean bypass_compositor G_GNUC_UNUSED = FALSE; XIEvent *input_event; #ifdef HAVE_XWAYLAND @@ -1915,11 +1909,6 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display, display->current_time = event_get_time (x11_display, event); -#ifdef HAVE_X11 - if (META_IS_BACKEND_X11 (backend)) - meta_backend_x11_reset_cached_logical_monitor (META_BACKEND_X11 (backend)); -#endif - if (x11_display->focused_by_us && event->xany.serial > x11_display->focus_serial && display->focus_window && @@ -1935,24 +1924,6 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display, x11_display->is_server_focus = FALSE; } -#ifdef HAVE_X11 - 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_compositor = TRUE; - goto out; - } - } - } -#endif - input_event = get_input_event (x11_display, event); if (handle_input_xevent (x11_display, input_event, event->xany.serial)) @@ -1970,24 +1941,6 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display, } out: -#ifdef HAVE_X11 - if (!bypass_compositor && META_IS_COMPOSITOR_X11 (display->compositor)) - { - MetaCompositorX11 *compositor_x11 = - META_COMPOSITOR_X11 (display->compositor); - MetaWindow *window; - Window modified; - - modified = event_get_modified_window (x11_display, event); - - 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); - } -#endif /* HAVE_X11 */ display->current_time = META_CURRENT_TIME; diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index a20434fd698..9076d06ec34 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include "backends/meta-backend-private.h" @@ -50,8 +51,6 @@ #include "backends/meta-cursor-sprite-xcursor.h" #include "backends/meta-logical-monitor-private.h" #include "backends/meta-settings-private.h" -#include "backends/x11/meta-backend-x11.h" -#include "backends/x11/meta-stage-x11.h" #include "core/meta-workspace-manager-private.h" #include "core/util-private.h" #include "core/workspace-private.h" @@ -141,24 +140,14 @@ stage_to_protocol (MetaX11Display *x11_display, MetaContext *context = meta_display_get_context (display); int scale = 1; - switch (meta_context_get_compositor_type (context)) - { - case META_COMPOSITOR_TYPE_WAYLAND: - { #ifdef HAVE_XWAYLAND - MetaWaylandCompositor *wayland_compositor = - meta_context_get_wayland_compositor (context); - MetaXWaylandManager *xwayland_manager = - &wayland_compositor->xwayland_manager; + MetaWaylandCompositor *wayland_compositor = + meta_context_get_wayland_compositor (context); + MetaXWaylandManager *xwayland_manager = + &wayland_compositor->xwayland_manager; - scale = meta_xwayland_get_effective_scale (xwayland_manager); + scale = meta_xwayland_get_effective_scale (xwayland_manager); #endif - break; - } - - case META_COMPOSITOR_TYPE_X11: - break; - } if (protocol_x) *protocol_x = stage_x * scale; @@ -219,28 +208,15 @@ update_ui_scaling_factor (MetaX11Display *x11_display) MetaContext *context = meta_backend_get_context (backend); int ui_scaling_factor = 1; - switch (meta_context_get_compositor_type (context)) - { - case META_COMPOSITOR_TYPE_WAYLAND: - { + #ifdef HAVE_XWAYLAND - MetaWaylandCompositor *wayland_compositor = - meta_context_get_wayland_compositor (context); - MetaXWaylandManager *xwayland_manager = - &wayland_compositor->xwayland_manager; + MetaWaylandCompositor *wayland_compositor = + meta_context_get_wayland_compositor (context); + MetaXWaylandManager *xwayland_manager = + &wayland_compositor->xwayland_manager; - ui_scaling_factor = meta_xwayland_get_x11_ui_scaling_factor (xwayland_manager); + ui_scaling_factor = meta_xwayland_get_x11_ui_scaling_factor (xwayland_manager); #endif - break; - } - case META_COMPOSITOR_TYPE_X11: - { - MetaSettings *settings = meta_backend_get_settings (backend); - - ui_scaling_factor = meta_settings_get_ui_scaling_factor (settings); - break; - } - } meta_dbus_x11_set_ui_scaling_factor (priv->dbus_api, ui_scaling_factor); } @@ -1267,50 +1243,6 @@ on_frames_client_died (GObject *source, } } -#ifdef HAVE_X11 -static gboolean -stage_is_focused (MetaX11Display *x11_display) -{ - MetaDisplay *display = x11_display->display; - ClutterStage *stage = CLUTTER_STAGE (meta_compositor_get_stage (display->compositor)); - Window xwindow = meta_x11_get_stage_window (stage); - - return x11_display->focus_xwindow == xwindow; -} - -static gboolean -stage_has_focus_actor (MetaX11Display *x11_display) -{ - MetaDisplay *display = x11_display->display; - ClutterStage *stage = CLUTTER_STAGE (meta_compositor_get_stage (display->compositor)); - ClutterActor *key_focus; - - key_focus = clutter_stage_get_key_focus (stage); - - return key_focus != NULL; -} - -static void -on_stage_key_focus_changed (MetaX11Display *x11_display) -{ - MetaDisplay *display = x11_display->display; - uint32_t timestamp; - gboolean has_actor_focus, has_stage_focus; - - has_actor_focus = stage_has_focus_actor (x11_display); - has_stage_focus = stage_is_focused (x11_display); - if (has_actor_focus == has_stage_focus) - return; - - timestamp = meta_display_get_current_time_roundtrip (display); - - if (has_actor_focus) - meta_display_unset_input_focus (display, timestamp); - else - meta_display_focus_default_window (display, timestamp); -} -#endif - static void focus_window_cb (MetaX11Display *x11_display, MetaWindow *window, @@ -1432,10 +1364,6 @@ meta_x11_display_new (MetaDisplay *display, if (!xdisplay) return NULL; -#ifdef HAVE_X11 - XSynchronize (xdisplay, meta_context_is_x11_sync (context)); -#endif - #ifdef HAVE_XWAYLAND if (meta_is_wayland_compositor ()) { @@ -1532,20 +1460,6 @@ meta_x11_display_new (MetaDisplay *display, x11_display, G_CONNECT_SWAPPED); -#ifdef HAVE_X11 - if (!meta_is_wayland_compositor ()) - { - ClutterStage *stage = - CLUTTER_STAGE (meta_backend_get_stage (backend)); - - g_signal_connect_object (stage, - "notify::key-focus", - G_CALLBACK (on_stage_key_focus_changed), - x11_display, - G_CONNECT_SWAPPED); - } -#endif - x11_display->xids = g_hash_table_new (meta_unsigned_long_hash, meta_unsigned_long_equal); x11_display->alarms = g_hash_table_new (meta_unsigned_long_hash, @@ -1681,11 +1595,6 @@ meta_x11_display_new (MetaDisplay *display, meta_x11_startup_notification_init (x11_display); meta_x11_selection_init (x11_display); -#ifdef HAVE_X11 - if (!meta_is_wayland_compositor ()) - meta_dnd_init_xdnd (x11_display); -#endif - sprintf (buf, "WM_S%d", number); wm_sn_atom = XInternAtom (xdisplay, buf, False); @@ -1941,30 +1850,18 @@ update_cursor_theme (MetaX11Display *x11_display) { MetaBackend *backend = backend_from_x11_display (x11_display); MetaContext *context = meta_backend_get_context (backend); - MetaSettings *settings = meta_backend_get_settings (backend); int scale = 1; int size; const char *theme; - switch (meta_context_get_compositor_type (context)) - { - case META_COMPOSITOR_TYPE_WAYLAND: - { #ifdef HAVE_XWAYLAND - MetaWaylandCompositor *wayland_compositor = - meta_context_get_wayland_compositor (context); - MetaXWaylandManager *xwayland_manager = - &wayland_compositor->xwayland_manager; + MetaWaylandCompositor *wayland_compositor = + meta_context_get_wayland_compositor (context); + MetaXWaylandManager *xwayland_manager = + &wayland_compositor->xwayland_manager; - scale = meta_xwayland_get_x11_ui_scaling_factor (xwayland_manager); + scale = meta_xwayland_get_x11_ui_scaling_factor (xwayland_manager); #endif - break; - } - - case META_COMPOSITOR_TYPE_X11: - scale = meta_settings_get_ui_scaling_factor (settings); - break; - } size = meta_prefs_get_cursor_size () * scale; @@ -1972,17 +1869,6 @@ update_cursor_theme (MetaX11Display *x11_display) set_cursor_theme (x11_display->xdisplay, theme, size); schedule_reload_x11_cursor (x11_display); - -#ifdef HAVE_X11 - 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, theme, size); - meta_backend_x11_reload_cursor (backend_x11); - } -#endif } MetaWindow * @@ -2104,28 +1990,6 @@ create_guard_window (MetaX11Display *x11_display) /* https://bugzilla.gnome.org/show_bug.cgi?id=710346 */ XStoreName (x11_display->xdisplay, guard_window, "mutter guard window"); -#ifdef HAVE_X11 - if (!meta_is_wayland_compositor ()) - { - MetaBackendX11 *backend = - META_BACKEND_X11 (backend_from_x11_display (x11_display)); - 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); - } -#endif - meta_stack_tracker_record_add (x11_display->display->stack_tracker, guard_window, create_serial); @@ -2324,10 +2188,6 @@ meta_x11_display_set_input_focus (MetaX11Display *x11_display, Window xwindow = x11_display->no_focus_window; gulong serial; MetaFrame *frame; -#ifdef HAVE_X11 - MetaDisplay *display = x11_display->display; - ClutterStage *stage = CLUTTER_STAGE (meta_compositor_get_stage (display->compositor)); -#endif if (window && META_IS_WINDOW_X11 (window)) { @@ -2343,16 +2203,6 @@ meta_x11_display_set_input_focus (MetaX11Display *x11_display, else xwindow = meta_window_x11_get_xwindow (window); } -#ifdef HAVE_X11 - else if (!meta_is_wayland_compositor () && - stage_has_focus_actor (x11_display)) - { - /* If we expect keyboard focus (e.g. there is a focused actor, keep - * focus on the stage window, otherwise focus the no focus window. - */ - xwindow = meta_x11_get_stage_window (stage); - } -#endif meta_topic (META_DEBUG_FOCUS, "Setting X11 input focus for window %s to 0x%lx", window ? window->desc : "none", xwindow); @@ -2371,11 +2221,6 @@ meta_x11_display_set_input_focus (MetaX11Display *x11_display, meta_x11_display_update_focus_window (x11_display, xwindow, serial, !x11_display->is_server_focus); - -#ifdef HAVE_X11 - if (window && !meta_is_wayland_compositor ()) - clutter_stage_set_key_focus (stage, NULL); -#endif } static MetaX11DisplayLogicalMonitorData * @@ -2658,36 +2503,6 @@ prefs_changed_callback (MetaPreference pref, } } -/** - * meta_x11_display_set_stage_input_region: (skip) - */ -void -meta_x11_display_set_stage_input_region (MetaX11Display *x11_display, - XRectangle *rects, - int n_rects) -{ -#ifdef HAVE_X11 - Display *xdisplay = x11_display->xdisplay; - MetaBackend *backend = backend_from_x11_display (x11_display); - ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); - Window stage_xwindow; - - g_return_if_fail (!meta_is_wayland_compositor ()); - - if (x11_display->stage_input_region) - XFixesDestroyRegion (xdisplay, x11_display->stage_input_region); - - x11_display->stage_input_region = XFixesCreateRegion (xdisplay, rects, n_rects); - - stage_xwindow = meta_x11_get_stage_window (stage); - XFixesSetWindowShapeRegion (xdisplay, stage_xwindow, - ShapeInput, 0, 0, x11_display->stage_input_region); - XFixesSetWindowShapeRegion (xdisplay, - x11_display->composite_overlay_window, - ShapeInput, 0, 0, x11_display->stage_input_region); -#endif -} - /** * meta_x11_display_add_event_func: (skip): **/ diff --git a/src/x11/meta-x11-frame.c b/src/x11/meta-x11-frame.c index f9d61cd518d..43bb0d5df16 100644 --- a/src/x11/meta-x11-frame.c +++ b/src/x11/meta-x11-frame.c @@ -23,7 +23,6 @@ #include "config.h" -#include "backends/x11/meta-backend-x11.h" #include "compositor/compositor-private.h" #include "core/bell.h" #include "mtk/mtk-x11.h" diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index e3d406bdffb..4309d74c81e 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -31,10 +31,10 @@ #include #include #include +#include #include #include "backends/meta-logical-monitor-private.h" -#include "backends/x11/meta-backend-x11.h" #include "compositor/compositor-private.h" #include "compositor/meta-window-actor-private.h" #include "core/boxes-private.h" @@ -3863,12 +3863,6 @@ is_our_xwindow (MetaX11Display *x11_display, Window xwindow, XWindowAttributes *attrs) { -#ifdef HAVE_X11 - MetaDisplay *display; - MetaContext *context; - MetaBackend *backend; -#endif - if (xwindow == x11_display->no_focus_window) return TRUE; @@ -3884,16 +3878,6 @@ is_our_xwindow (MetaX11Display *x11_display, if (xwindow == x11_display->composite_overlay_window) return TRUE; -#ifdef HAVE_X11 - display = meta_x11_display_get_display (x11_display); - context = meta_display_get_context (display); - backend = meta_context_get_backend (context); - - if (META_IS_BACKEND_X11 (backend) && - xwindow == meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend))) - return TRUE; -#endif - /* Any windows created via meta_create_offscreen_window */ if (attrs->override_redirect && attrs->x == -100 && @@ -4069,28 +4053,14 @@ meta_window_x11_new (MetaDisplay *display, goto error; } -#ifdef HAVE_XWAYLAND - if (meta_is_wayland_compositor ()) - { - window = g_initable_new (META_TYPE_WINDOW_XWAYLAND, - NULL, NULL, - "display", display, - "effect", effect, - "attributes", &attrs, - "xwindow", xwindow, - NULL); - } - else -#endif - { - window = g_initable_new (META_TYPE_WINDOW_X11, - NULL, NULL, - "display", display, - "effect", effect, - "attributes", &attrs, - "xwindow", xwindow, - NULL); - } + window = g_initable_new (META_TYPE_WINDOW_XWAYLAND, + NULL, NULL, + "display", display, + "effect", effect, + "attributes", &attrs, + "xwindow", xwindow, + NULL); + if (existing_wm_state == IconicState) { /* WM_STATE said minimized */ -- GitLab From 99fd5567fd974c3d8e0b950079bb2b0f268e3a2d Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Tue, 4 Nov 2025 13:31:15 +0100 Subject: [PATCH 2/8] Drop restarting capability Part-of: --- doc/man/mutter.1 | 7 +- src/backends/meta-a11y-manager.c | 8 +- src/backends/meta-idle-manager.c | 5 +- src/backends/meta-monitor-manager.c | 6 +- src/core/display-private.h | 6 - src/core/display.c | 83 ----------- src/core/meta-context-main.c | 12 -- src/core/meta-context-private.h | 2 - src/core/meta-context.c | 8 - src/core/restart.c | 218 ---------------------------- src/helpers/meta-restart-helper.c | 85 ----------- src/meson.build | 1 - src/meta/main.h | 7 - src/meta/meta-context.h | 3 - src/tests/meta-context-test.c | 7 - src/x11/meta-x11-display.c | 59 +------- 16 files changed, 12 insertions(+), 505 deletions(-) delete mode 100644 src/core/restart.c delete mode 100644 src/helpers/meta-restart-helper.c diff --git a/doc/man/mutter.1 b/doc/man/mutter.1 index 6d9122cdee4..7ee48e94911 100644 --- a/doc/man/mutter.1 +++ b/doc/man/mutter.1 @@ -19,13 +19,13 @@ MUTTER \- Clutter based compositing GTK2 Window Manager .SH SYNOPSIS .B mutter -[\-\-display=\fIDISPLAY\fP] [\-\-replace] [\-\-sm\-client\-id=\fIID\fP] [\-\-sm\-disable] [\-\-sm\-save\-file=\fIFILENAME\fP] [\-\-version] [\-\-help] [[\-\-] command [argument...]] +[\-\-display=\fIDISPLAY\fP] [\-\-sm\-client\-id=\fIID\fP] [\-\-sm\-disable] [\-\-sm\-save\-file=\fIFILENAME\fP] [\-\-version] [\-\-help] [[\-\-] command [argument...]] .SH DESCRIPTION This manual page documents briefly .B mutter\fP. .PP .\" TeX users may be more comfortable with the \fB\fP and -.\" \fI\fP escape sequences to invode bold face and italics, +.\" \fI\fP escape sequences to invode bold face and italics, .\" respectively. \fBmutter\fP is a minimal X window manager aimed at nontechnical users and is designed to integrate well with the GNOME desktop. \fBmutter\fP lacks some features that may be expected by traditional UNIX or other technical users; these users may want to investigate other available window managers for use with GNOME or standalone. .SH OPTIONS @@ -33,9 +33,6 @@ This manual page documents briefly .B \-\-display=DISPLAY Connect to X display \fIDISPLAY\fP. .TP -.B \-\-replace -a window manager which is running is replaced by \fBmutter\fP. Users are encouraged to change the GNOME window manager by running the new WM with the --replace or -replace option, and subsequently saving the session. -.TP .B \-\-sm\-client\-id=ID Specify a session management \fIID\fP. .TP diff --git a/src/backends/meta-a11y-manager.c b/src/backends/meta-a11y-manager.c index d8f02fc9291..c56ce5a4120 100644 --- a/src/backends/meta-a11y-manager.c +++ b/src/backends/meta-a11y-manager.c @@ -394,10 +394,6 @@ static void meta_a11y_manager_constructed (GObject *object) { MetaA11yManager *a11y_manager = META_A11Y_MANAGER (object); - MetaContext *context; - - g_assert (a11y_manager->backend); - context = meta_backend_get_context (a11y_manager->backend); a11y_manager->grabbed_keypresses = g_hash_table_new (NULL, NULL); a11y_manager->all_grabbed_modifiers = g_hash_table_new (NULL, NULL); @@ -406,9 +402,7 @@ meta_a11y_manager_constructed (GObject *object) g_bus_own_name (G_BUS_TYPE_SESSION, "org.freedesktop.a11y.Manager", G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | - (meta_context_is_replacing (context) ? - G_BUS_NAME_OWNER_FLAGS_REPLACE : - G_BUS_NAME_OWNER_FLAGS_NONE), + G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired, on_name_acquired, on_name_lost, diff --git a/src/backends/meta-idle-manager.c b/src/backends/meta-idle-manager.c index 93d1754445a..b3c3e4cf22d 100644 --- a/src/backends/meta-idle-manager.c +++ b/src/backends/meta-idle-manager.c @@ -275,7 +275,6 @@ meta_idle_manager_reset_idle_time (MetaIdleManager *idle_manager) MetaIdleManager * meta_idle_manager_new (MetaBackend *backend) { - MetaContext *context = meta_backend_get_context (backend); MetaIdleManager *idle_manager; idle_manager = g_new0 (MetaIdleManager, 1); @@ -285,9 +284,7 @@ meta_idle_manager_new (MetaBackend *backend) 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), + G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired, on_name_acquired, on_name_lost, diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 827df6ee52c..b919fc85213 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -3647,15 +3647,11 @@ on_name_lost (GDBusConnection *connection, 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), + G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired, on_name_acquired, on_name_lost, diff --git a/src/core/display-private.h b/src/core/display-private.h index 640aa84be21..019f50daab3 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -261,18 +261,12 @@ void meta_display_remove_pending_pings_for_window (MetaDisplay *display, 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, MtkRectangle *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); diff --git a/src/core/display.c b/src/core/display.c index c10b33d9118..42941b2dd7b 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -157,8 +157,6 @@ enum WINDOW_MARKED_URGENT, GRAB_OP_BEGIN, GRAB_OP_END, - SHOW_RESTART_MESSAGE, - RESTART, SHOW_RESIZE_POPUP, GL_VIDEO_MEMORY_PURGED, SHOW_PAD_OSD, @@ -408,62 +406,6 @@ meta_display_class_init (MetaDisplayClass *klass) 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 signal will be emitted to indicate that the compositor - * should show a message during restart. - * - * This is emitted when [func@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 - - * [signal@Meta.Display::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 signal is emitted to indicate that compositor - * should reexec the process. - * - * This is emitted when [func@Meta.restart] is called, - * either by Mutter internally or by the embedding compositor. - * - * See also [signal@Meta.Display::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), @@ -2514,31 +2456,6 @@ 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, diff --git a/src/core/meta-context-main.c b/src/core/meta-context-main.c index d538ce96331..2441fea7f21 100644 --- a/src/core/meta-context-main.c +++ b/src/core/meta-context-main.c @@ -50,9 +50,6 @@ typedef struct _MetaContextMainOptions { - struct { - gboolean replace; - } x11; #ifdef HAVE_WAYLAND gboolean wayland; gboolean no_x11; @@ -168,14 +165,6 @@ meta_context_main_get_x11_display_policy (MetaContext *context) return META_X11_DISPLAY_POLICY_ON_DEMAND; } -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, @@ -508,7 +497,6 @@ meta_context_main_class_init (MetaContextMainClass *klass) context_class->configure = meta_context_main_configure; 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; diff --git a/src/core/meta-context-private.h b/src/core/meta-context-private.h index 67bc0a8339f..f83c70f0a9d 100644 --- a/src/core/meta-context-private.h +++ b/src/core/meta-context-private.h @@ -42,8 +42,6 @@ struct _MetaContextClass MetaX11DisplayPolicy (* get_x11_display_policy) (MetaContext *context); - gboolean (* is_replacing) (MetaContext *context); - gboolean (* setup) (MetaContext *context, GError **error); diff --git a/src/core/meta-context.c b/src/core/meta-context.c index 6d9561c8bbd..e6554e88c24 100644 --- a/src/core/meta-context.c +++ b/src/core/meta-context.c @@ -307,14 +307,6 @@ meta_context_get_service_channel (MetaContext *context) } #endif -gboolean -meta_context_is_replacing (MetaContext *context) -{ - g_return_val_if_fail (META_IS_CONTEXT (context), FALSE); - - return META_CONTEXT_GET_CLASS (context)->is_replacing (context); -} - MetaX11DisplayPolicy meta_context_get_x11_display_policy (MetaContext *context) { diff --git a/src/core/restart.c b/src/core/restart.c deleted file mode 100644 index 3d7871a65c2..00000000000 --- a/src/core/restart.c +++ /dev/null @@ -1,218 +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 . - */ - -/* - * restart: - * - * 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 - -#include "clutter/clutter.h" -#include "core/display-private.h" -#include "core/util-private.h" -#include "meta/main.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 (MetaContext *context) -{ - if (restart_helper_started && restart_message_shown) - { - MetaDisplay *display = meta_context_get_display (context); - - 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) -{ - MetaContext *context = 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) - { - g_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 (context); -} - -static gboolean -restart_message_painted (gpointer user_data) -{ - MetaContext *context = user_data; - - restart_message_shown = TRUE; - restart_check_ready (context); - - return FALSE; -} - -static void -child_setup (gpointer user_data) -{ - MetaDisplay *display = user_data; - MetaContext *context = meta_display_get_context (display); - - meta_context_restore_rlimit_nofile (context, NULL); -} - -/** - * meta_restart: - * @message: (allow-none): message to display to the user, or %NULL - * @context: a #MetaContext - * - * 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 - * - * - [signal@Meta.Display::show-restart-message], to display the - * message passed here on the Clutter stage - * - [signal@Meta.Display::restart] to actually reexec the compositor. - */ -void -meta_restart (const char *message, - MetaContext *context) -{ - MetaDisplay *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 - }; - - g_return_if_fail (META_IS_CONTEXT (context)); - - display = meta_context_get_display (context); - - if (message && meta_display_show_restart_message (display, message)) - { - /* Wait until the stage was painted */ - clutter_threads_add_repaint_func (CLUTTER_REPAINT_FLAGS_POST_PAINT, - restart_message_painted, - context, NULL); - } - else - { - /* Can't show the message, show the message as soon as the - * restart helper starts - */ - restart_message_painted (context); - } - - /* 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, - child_setup, display, - NULL, /* child_pid */ - NULL, /* standard_input */ - &helper_out_fd, - NULL, /* standard_error */ - &error)) - { - g_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, - context); - - 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 (context); - - return; -} - -/** - * meta_is_restart: - * - * Returns %TRUE if this instance of Mutter comes from Mutter - * restarting itself (for example to enable/disable stereo.) - * - * See [func@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/helpers/meta-restart-helper.c b/src/helpers/meta-restart-helper.c deleted file mode 100644 index 9aa30597d34..00000000000 --- a/src/helpers/meta-restart-helper.c +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * restart-helper - * - * 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 . - */ - -#include "config.h" - -#include -#include -#include -#include - -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/meson.build b/src/meson.build index 64ae9e6111d..75035e68265 100644 --- a/src/meson.build +++ b/src/meson.build @@ -376,7 +376,6 @@ mutter_sources = [ 'core/place.h', 'core/prefs-private.h', 'core/prefs.c', - 'core/restart.c', 'core/stack.c', 'core/stack.h', 'core/stack-tracker.c', diff --git a/src/meta/main.h b/src/meta/main.h index bea75c66188..ff7f5dd9f69 100644 --- a/src/meta/main.h +++ b/src/meta/main.h @@ -26,13 +26,6 @@ #include "meta/common.h" #include "meta/meta-context.h" -META_EXPORT -void meta_restart (const char *message, - MetaContext *context); - -META_EXPORT -gboolean meta_is_restart (void); - /** * MetaExitCode: * @META_EXIT_SUCCESS: Success diff --git a/src/meta/meta-context.h b/src/meta/meta-context.h index 046cee2f773..6e61fe8cf3a 100644 --- a/src/meta/meta-context.h +++ b/src/meta/meta-context.h @@ -82,9 +82,6 @@ META_EXPORT void meta_context_terminate_with_error (MetaContext *context, GError *error); -META_EXPORT -gboolean meta_context_is_replacing (MetaContext *context); - META_EXPORT MetaBackend * meta_context_get_backend (MetaContext *context); diff --git a/src/tests/meta-context-test.c b/src/tests/meta-context-test.c index 9acbb6cc879..5bd572d6bc1 100644 --- a/src/tests/meta-context-test.c +++ b/src/tests/meta-context-test.c @@ -154,12 +154,6 @@ meta_context_test_get_x11_display_policy (MetaContext *context) 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) @@ -426,7 +420,6 @@ meta_context_test_class_init (MetaContextTestClass *klass) context_class->configure = meta_context_test_configure; 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; diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index 9076d06ec34..fd493a9a01f 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -796,33 +796,16 @@ static Window take_manager_selection (MetaX11Display *x11_display, Window xroot, Atom manager_atom, - int timestamp, - gboolean should_replace) + int timestamp) { 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 */ - mtk_x11_error_trap_push (x11_display->xdisplay); - attrs.event_mask = StructureNotifyMask; - XChangeWindowAttributes (x11_display->xdisplay, current_owner, CWEventMask, &attrs); - if (mtk_x11_error_trap_pop_with_return (x11_display->xdisplay) != Success) - current_owner = None; /* don't wait for it to die later on */ - } - else - { - g_warning (_("Display “%s” already has a window manager; " - "try using the --replace option to replace " - "the current window manager."), - x11_display->name); - return None; - } + g_warning (_("Display “%s” already has a window manager"), + x11_display->name); + return None; } /* We need SelectionClear and SelectionRequest events on the new owner, @@ -1343,14 +1326,10 @@ meta_x11_display_new (MetaDisplay *display, Window xroot; int i, number; Window new_wm_sn_owner; - gboolean replace_current_wm; Atom wm_sn_atom; Atom wm_cm_atom; char buf[128]; guint32 timestamp; - Atom atom_restart_helper; - Window restart_helper_window = None; - gboolean is_restart = FALSE; /* A list of all atom names, so that we can intern them in one go. */ const char *atom_names[] = { @@ -1374,9 +1353,6 @@ meta_x11_display_new (MetaDisplay *display, } #endif - replace_current_wm = - meta_context_is_replacing (meta_backend_get_context (backend)); - number = DefaultScreen (xdisplay); xroot = RootWindow (xdisplay, number); @@ -1398,14 +1374,6 @@ meta_x11_display_new (MetaDisplay *display, 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) - { - is_restart = TRUE; - meta_set_is_restart (TRUE); - } - x11_display = g_object_new (META_TYPE_X11_DISPLAY, NULL); x11_display->display = display; @@ -1510,11 +1478,6 @@ meta_x11_display_new (MetaDisplay *display, 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 (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, @@ -1601,8 +1564,7 @@ meta_x11_display_new (MetaDisplay *display, new_wm_sn_owner = take_manager_selection (x11_display, xroot, wm_sn_atom, - timestamp, - replace_current_wm); + timestamp); if (new_wm_sn_owner == None) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, @@ -1620,8 +1582,7 @@ meta_x11_display_new (MetaDisplay *display, wm_cm_atom = XInternAtom (x11_display->xdisplay, buf, False); x11_display->wm_cm_selection_window = - take_manager_selection (x11_display, xroot, wm_cm_atom, timestamp, - replace_current_wm); + take_manager_selection (x11_display, xroot, wm_cm_atom, timestamp); if (x11_display->wm_cm_selection_window == None) { @@ -2571,17 +2532,11 @@ void meta_x11_display_redirect_windows (MetaX11Display *x11_display, MetaDisplay *display) { - MetaContext *context = meta_display_get_context (display); 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; + guint max_retries = 1; n_retries = 0; -- GitLab From 52974792dec42448fc2ff48d8f8b5811be7c5447 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Tue, 24 Jun 2025 14:41:44 +0200 Subject: [PATCH 3/8] Merge have_x11_client with have_xwayland By keeping only have_xwayland as that is the only possible option with the dropped X11 backend. Part-of: --- .gitlab-ci.yml | 1 - cogl/meson.build | 7 +- config.h.meson | 6 - data/meson.build | 7 +- meson.build | 68 +-- meson.options | 6 - mtk/meson.build | 2 +- mtk/mtk/meson.build | 2 +- src/backends/meta-backend.c | 4 +- src/backends/meta-dnd-private.h | 2 - .../native/meta-cursor-renderer-native.c | 7 - src/compositor/compositor.c | 13 +- src/compositor/meta-compositor-native.c | 2 - src/compositor/meta-compositor-view-native.c | 11 +- src/compositor/meta-compositor-view-native.h | 2 - src/compositor/meta-dnd.c | 11 +- src/compositor/meta-window-actor.c | 16 +- src/compositor/meta-window-drag.c | 6 +- src/core/constraints.c | 22 +- src/core/display-private.h | 6 +- src/core/display.c | 158 +++---- src/core/events.c | 40 +- src/core/meta-context-main.c | 21 +- src/core/meta-context-private.h | 2 - src/core/meta-context.c | 19 +- src/core/meta-launch-context.c | 4 +- src/core/meta-service-channel.c | 8 - src/core/meta-service-channel.h | 4 - src/core/place.c | 4 +- src/core/stack-tracker.c | 32 +- src/core/stack-tracker.h | 4 +- src/core/stack.c | 4 +- src/core/window-private.h | 4 - src/core/window.c | 91 ++-- src/meson.build | 406 +++++++++--------- src/meta/meson.build | 13 +- src/wayland/meta-wayland-data-device.c | 4 +- 37 files changed, 379 insertions(+), 640 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3f61c1039ea..3bd7eee32c7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -492,7 +492,6 @@ build-wayland-only@x86_64: --werror --wrap-mode nofallback -Dbuildtype=debugoptimized - -Dwayland=true -Dxwayland=false -Dtests=disabled -Dintrospection=false diff --git a/cogl/meson.build b/cogl/meson.build index 9cec31ddcff..e7f2f9ab54d 100644 --- a/cogl/meson.build +++ b/cogl/meson.build @@ -9,6 +9,7 @@ cogl_pkg_deps = [ gio_dep, gobject_dep, graphene_dep, + wayland_server_dep, ] cogl_pkg_private_deps = [ @@ -22,12 +23,6 @@ if have_profiler ] endif -if have_wayland - cogl_pkg_deps += [ - wayland_server_dep, - ] -endif - if have_egl cogl_pkg_deps += [ egl_dep, diff --git a/config.h.meson b/config.h.meson index c9d1003643a..4d72f9ea985 100644 --- a/config.h.meson +++ b/config.h.meson @@ -52,15 +52,9 @@ /* Define if you want to enable the native (KMS) backend based on systemd */ #mesondefine HAVE_NATIVE_BACKEND -/* Define if you want to enable Wayland support */ -#mesondefine HAVE_WAYLAND - /* Define if you want to enable XWayland support */ #mesondefine HAVE_XWAYLAND -/* Define if either XWayland or X11 backend are enabled */ -#mesondefine HAVE_X11_CLIENT - /* Defined if screen cast and remote desktop support is enabled */ #mesondefine HAVE_REMOTE_DESKTOP diff --git a/data/meson.build b/data/meson.build index 71b81530976..2a70387f828 100644 --- a/data/meson.build +++ b/data/meson.build @@ -26,14 +26,9 @@ keybinding_xml_files = [ '50-mutter-navigation.xml', '50-mutter-system.xml', '50-mutter-windows.xml', + '50-mutter-wayland.xml', ] -if have_wayland - keybinding_xml_files += [ - '50-mutter-wayland.xml', - ] -endif - install_data(keybinding_xml_files, install_dir: gnome_keybindings_keysdir, ) diff --git a/meson.build b/meson.build index 76f16065bb5..12563fc5bec 100644 --- a/meson.build +++ b/meson.build @@ -139,18 +139,9 @@ libeis_dep = dependency('libeis-1.0', version: libei_req) libei_dep = dependency('libei-1.0', version: libei_req) gvdb_dep = dependency('gvdb') libdisplay_info_dep = dependency('libdisplay-info', version: libdisplay_info_req) +libdrm_dep = dependency('libdrm', version: libdrm_req) -have_wayland = get_option('wayland') have_xwayland = get_option('xwayland') -have_x11_client = have_xwayland - -if have_xwayland and not have_wayland - error('XWayland support requires Wayland support enabled') -endif - -if not have_wayland - error('A Wayland backend must be enabled') -endif have_fonts = get_option('fonts') @@ -164,7 +155,7 @@ if have_fonts fribidi_dep = dependency('fribidi', version: fribidi_req) endif -if have_x11_client +if have_xwayland if not gtk4_dep.found() error('X11 client support requires gtk4 @0@'.format(gtk4_req)) endif @@ -219,23 +210,21 @@ if not have_gl and not have_gles2 error('Neither GLES2 or OpenGL was enabled') endif -if have_wayland - if meson.version().version_compare('>= 1.8.0') - wl_mod = import('wayland') - else - wl_mod = import('unstable-wayland') - endif +if meson.version().version_compare('>= 1.8.0') + wl_mod = import('wayland') +else + wl_mod = import('unstable-wayland') +endif - wayland_server_dep = dependency('wayland-server', version: wayland_server_req) - wayland_client_dep = dependency('wayland-client', version: wayland_server_req) - wayland_cursor_dep = dependency('wayland-cursor') - wayland_protocols_dep = dependency('wayland-protocols', - version: wayland_protocols_req) - wayland_egl_dep = dependency('wayland-egl') +wayland_server_dep = dependency('wayland-server', version: wayland_server_req) +wayland_client_dep = dependency('wayland-client', version: wayland_server_req) +wayland_cursor_dep = dependency('wayland-cursor') +wayland_protocols_dep = dependency('wayland-protocols', + version: wayland_protocols_req) +wayland_egl_dep = dependency('wayland-egl') - if not have_egl - error('Wayland support requires EGL to be enabled') - endif +if not have_egl + error('Wayland support requires EGL to be enabled') endif have_logind = get_option('logind') @@ -289,14 +278,9 @@ if have_native_backend endif endif -if have_wayland or have_native_backend - libdrm_dep = dependency('libdrm', version: libdrm_req) - have_drm_plane_size_hint = cc.has_type('struct drm_plane_size_hint', - dependencies: libdrm_dep, - prefix: '#include ') -else - have_drm_plane_size_hint = false -endif +have_drm_plane_size_hint = cc.has_type('struct drm_plane_size_hint', + dependencies: libdrm_dep, + prefix: '#include ') have_egl_device = get_option('egl_device') @@ -305,9 +289,6 @@ if have_wayland_eglstream wayland_eglstream_protocols_dep = dependency('wayland-eglstream-protocols') dl_dep = cc.find_library('dl', required: true) - if not have_wayland - error('Wayland EGLStream support requires Wayland to be enabled') - endif endif @@ -320,7 +301,7 @@ else have_libwacom_get_num_rings = false endif -have_startup_notification = get_option('startup_notification') and have_x11_client +have_startup_notification = get_option('startup_notification') and have_xwayland if have_startup_notification libstartup_notification_dep = dependency('libstartup-notification-1.0', version: libstartup_notification_req) @@ -399,10 +380,8 @@ if have_tests have_mutter_tests = get_option('mutter_tests') if have_mutter_tests - if not have_wayland - error('Tests require Wayland to be enabled') - endif - if not have_x11_client + + if not have_xwayland error('Tests requires an X11 client') endif if not dbusmock_dep.found() @@ -571,9 +550,7 @@ cdata.set_quoted('PACKAGE_VERSION', meson.project_version()) cdata.set('HAVE_EGL', have_egl) cdata.set('HAVE_GL', have_gl) cdata.set('HAVE_GLES2', have_gles2) -cdata.set('HAVE_WAYLAND', have_wayland) cdata.set('HAVE_XWAYLAND', have_xwayland) -cdata.set('HAVE_X11_CLIENT', have_x11_client) cdata.set('HAVE_LOGIND', have_logind) cdata.set('HAVE_NATIVE_BACKEND', have_native_backend) cdata.set('HAVE_REMOTE_DESKTOP', have_remote_desktop) @@ -597,7 +574,7 @@ cdata.set('HAVE_XKBCOMMON_KANA_COMPOSE_LEDS', cdata.set('HAVE_EIS_EVENT_REF', libeis_dep.version().version_compare('>= 1.5.0')) -if have_x11_client +if have_xwayland xkb_base = xkeyboard_config_dep.get_variable('xkb_base') cdata.set_quoted('XKB_BASE', xkb_base) endif @@ -762,7 +739,6 @@ summary('OpenGL', have_gl, section: 'Rendering APIs') summary('GLES2', have_gles2, section: 'Rendering APIs') summary('EGL', have_egl, section: 'Rendering APIs') -summary('Wayland', have_wayland, section: 'Options') summary('Wayland EGLStream', have_wayland_eglstream, section: 'Options') summary('XWayland', have_xwayland, section: 'Options') summary('Native Backend', have_native_backend, section: 'Options') diff --git a/meson.options b/meson.options index a30a0b9d03a..4824a8c750f 100644 --- a/meson.options +++ b/meson.options @@ -28,12 +28,6 @@ option('egl', description: 'Enable EGL support' ) -option('wayland', - type: 'boolean', - value: true, - description: 'Enable Wayland support' -) - option('xwayland', type: 'boolean', value: true, diff --git a/mtk/meson.build b/mtk/meson.build index 4b270095292..d0becbc864b 100644 --- a/mtk/meson.build +++ b/mtk/meson.build @@ -21,7 +21,7 @@ mtk_pkg_deps = [ pixman_dep, ] -if have_x11_client +if have_xwayland mtk_pkg_deps += x11_dep endif diff --git a/mtk/mtk/meson.build b/mtk/mtk/meson.build index bd189687aa0..d74c45a10ae 100644 --- a/mtk/mtk/meson.build +++ b/mtk/mtk/meson.build @@ -24,7 +24,7 @@ mtk_sources = [ 'mtk-utils.c', ] -if have_x11_client +if have_xwayland mtk_sources += 'mtk-x11-errors.c' mtk_headers += [ 'mtk-x11-errors.h', diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index 9fb66519b83..7ef79d5cb11 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -78,6 +78,7 @@ #include "meta/meta-context.h" #include "meta/meta-enum-types.h" #include "meta/util.h" +#include "wayland/meta-wayland.h" #ifdef HAVE_REMOTE_DESKTOP #include "backends/meta-dbus-session-watcher.h" @@ -90,9 +91,6 @@ #include "backends/native/meta-backend-native.h" #endif -#ifdef HAVE_WAYLAND -#include "wayland/meta-wayland.h" -#endif #ifdef HAVE_LOGIND #include "backends/meta-launcher.h" diff --git a/src/backends/meta-dnd-private.h b/src/backends/meta-dnd-private.h index bb1cdbdb0d7..6eb2f680613 100644 --- a/src/backends/meta-dnd-private.h +++ b/src/backends/meta-dnd-private.h @@ -23,11 +23,9 @@ #include "backends/meta-backend-private.h" -#ifdef HAVE_WAYLAND void meta_dnd_wayland_handle_begin_modal (MetaCompositor *compositor); void meta_dnd_wayland_handle_end_modal (MetaCompositor *compositor); void meta_dnd_wayland_on_motion_event (MetaDnd *dnd, const ClutterEvent *event); -#endif diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c index 949f922d76b..71b8b4127d4 100644 --- a/src/backends/native/meta-cursor-renderer-native.c +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -56,11 +56,8 @@ #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 static GQuark quark_cursor_sprite = 0; @@ -1042,7 +1039,6 @@ load_scaled_and_transformed_cursor_sprite (MetaCursorRendererNative *native, return retval; } -#ifdef HAVE_WAYLAND static gboolean realize_cursor_sprite_from_wl_buffer_for_crtc (MetaCursorRenderer *renderer, MetaCrtcKms *crtc_kms, @@ -1190,7 +1186,6 @@ realize_cursor_sprite_from_wl_buffer_for_crtc (MetaCursorRenderer *renderer return TRUE; } } -#endif /* HAVE_WAYLAND */ static gboolean realize_cursor_sprite_from_xcursor_for_crtc (MetaCursorRenderer *renderer, @@ -1241,7 +1236,6 @@ realize_cursor_sprite_for_crtc (MetaCursorRenderer *renderer, target_color_state, sprite_xcursor); } -#ifdef HAVE_WAYLAND else if (META_IS_CURSOR_SPRITE_WAYLAND (cursor_sprite)) { MetaCursorSpriteWayland *sprite_wayland = @@ -1252,7 +1246,6 @@ realize_cursor_sprite_for_crtc (MetaCursorRenderer *renderer, target_color_state, sprite_wayland); } -#endif else { return FALSE; diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 7b1264b9b31..2ed1efa5dc1 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -59,6 +59,7 @@ #include "compositor/meta-cullable.h" #include "compositor/meta-later-private.h" #include "compositor/meta-window-actor-private.h" +#include "compositor/meta-window-actor-wayland.h" #include "compositor/meta-window-group-private.h" #include "core/util-private.h" #include "core/window-private.h" @@ -69,13 +70,9 @@ #include "meta/meta-context.h" #include "meta/prefs.h" #include "meta/window.h" - -#ifdef HAVE_WAYLAND -#include "compositor/meta-window-actor-wayland.h" #include "wayland/meta-wayland-private.h" -#endif -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND #include @@ -343,19 +340,17 @@ meta_compositor_real_add_window (MetaCompositor *compositor, switch (window->client_type) { -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND case META_WINDOW_CLIENT_TYPE_X11: window_actor_type = META_TYPE_WINDOW_ACTOR_X11; accessible_name = "X11 window"; break; #endif -#ifdef HAVE_WAYLAND case META_WINDOW_CLIENT_TYPE_WAYLAND: window_actor_type = META_TYPE_WINDOW_ACTOR_WAYLAND; accessible_name = "Wayland window"; break; -#endif default: g_return_if_reached (); @@ -443,7 +438,7 @@ meta_compositor_window_shape_changed (MetaCompositor *compositor, if (!window_actor) return; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND meta_window_actor_x11_update_shape (META_WINDOW_ACTOR_X11 (window_actor)); #endif } diff --git a/src/compositor/meta-compositor-native.c b/src/compositor/meta-compositor-native.c index 06841bbd35a..4b4f1e74b42 100644 --- a/src/compositor/meta-compositor-native.c +++ b/src/compositor/meta-compositor-native.c @@ -39,10 +39,8 @@ meta_compositor_native_before_paint (MetaCompositor *compositor, META_COMPOSITOR_VIEW_NATIVE (compositor_view); MetaCompositorClass *parent_class; -#ifdef HAVE_WAYLAND meta_compositor_view_native_maybe_assign_scanout (compositor_view_native, compositor); -#endif meta_compositor_view_native_maybe_update_frame_sync_surface (compositor_view_native, compositor); diff --git a/src/compositor/meta-compositor-view-native.c b/src/compositor/meta-compositor-view-native.c index e683b090518..86b17dd20d3 100644 --- a/src/compositor/meta-compositor-view-native.c +++ b/src/compositor/meta-compositor-view-native.c @@ -31,12 +31,9 @@ #include "clutter/clutter.h" #include "compositor/compositor-private.h" #include "compositor/meta-window-actor-private.h" -#include "core/window-private.h" - -#ifdef HAVE_WAYLAND #include "compositor/meta-surface-actor-wayland.h" +#include "core/window-private.h" #include "wayland/meta-wayland-surface-private.h" -#endif /* HAVE_WAYLAND */ static void update_frame_sync_surface (MetaCompositorViewNative *view_native, MetaSurfaceActor *surface_actor); @@ -45,9 +42,7 @@ struct _MetaCompositorViewNative { MetaCompositorView parent; -#ifdef HAVE_WAYLAND MetaWaylandSurface *scanout_candidate; -#endif /* HAVE_WAYLAND */ MetaSurfaceActor *frame_sync_surface; @@ -117,7 +112,6 @@ on_frame_sync_surface_destroyed (MetaSurfaceActor *surface_actor, update_frame_sync_surface (view_native, NULL); } -#ifdef HAVE_WAYLAND static void update_scanout_candidate (MetaCompositorViewNative *view_native, MetaWaylandSurface *surface, @@ -397,7 +391,6 @@ meta_compositor_view_native_maybe_assign_scanout (MetaCompositorViewNative *view update_scanout_candidate (view_native, surface, crtc); } -#endif /* HAVE_WAYLAND */ static MetaSurfaceActor * find_frame_sync_candidate (MetaCompositorView *compositor_view, @@ -599,11 +592,9 @@ meta_compositor_view_native_dispose (GObject *object) static void meta_compositor_view_native_finalize (GObject *object) { -#ifdef HAVE_WAYLAND MetaCompositorViewNative *view_native = META_COMPOSITOR_VIEW_NATIVE (object); g_clear_weak_pointer (&view_native->scanout_candidate); -#endif /* HAVE_WAYLAND */ G_OBJECT_CLASS (meta_compositor_view_native_parent_class)->finalize (object); } diff --git a/src/compositor/meta-compositor-view-native.h b/src/compositor/meta-compositor-view-native.h index 52a2bef272d..bc71f6b5174 100644 --- a/src/compositor/meta-compositor-view-native.h +++ b/src/compositor/meta-compositor-view-native.h @@ -32,10 +32,8 @@ G_DECLARE_FINAL_TYPE (MetaCompositorViewNative, meta_compositor_view_native, MetaCompositorViewNative *meta_compositor_view_native_new (ClutterStageView *stage_view); -#ifdef HAVE_WAYLAND void meta_compositor_view_native_maybe_assign_scanout (MetaCompositorViewNative *view_native, MetaCompositor *compositor); -#endif /* HAVE_WAYLAND */ void meta_compositor_view_native_maybe_update_frame_sync_surface (MetaCompositorViewNative *view_native, MetaCompositor *compositor); diff --git a/src/compositor/meta-dnd.c b/src/compositor/meta-dnd.c index 819b62d8bed..52f75367eeb 100644 --- a/src/compositor/meta-dnd.c +++ b/src/compositor/meta-dnd.c @@ -25,26 +25,21 @@ #include "compositor/compositor-private.h" #include "core/display-private.h" #include "backends/meta-dnd-private.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-data-device.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 { MetaBackend *backend; -#ifdef HAVE_WAYLAND gboolean dnd_during_modal; -#endif }; struct _MetaDnd @@ -133,7 +128,6 @@ meta_dnd_notify_dnd_leave (MetaDnd *dnd) g_signal_emit (dnd, signals[LEAVE], 0); } -#ifdef HAVE_WAYLAND void meta_dnd_wayland_on_motion_event (MetaDnd *dnd, const ClutterEvent *event) @@ -183,4 +177,3 @@ meta_dnd_wayland_handle_end_modal (MetaCompositor *compositor) meta_dnd_notify_dnd_leave (dnd); } -#endif diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 7aadf119860..3ff09fbeabc 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -28,15 +28,11 @@ #include "compositor/meta-shaped-texture-private.h" #include "compositor/meta-surface-actor.h" #include "compositor/meta-window-actor-private.h" +#include "compositor/meta-surface-actor-wayland.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-private.h" -#endif typedef enum { @@ -588,14 +584,8 @@ init_surface_actor (MetaWindowActor *self) MetaWindowActorPrivate *priv = meta_window_actor_get_instance_private (self); MetaWindow *window = priv->window; - MetaSurfaceActor *surface_actor = NULL; - -#ifdef HAVE_WAYLAND - { - MetaWaylandSurface *surface = meta_window_get_wayland_surface (window); - surface_actor = surface ? meta_wayland_surface_get_actor (surface) : NULL; - } -#endif + MetaWaylandSurface *surface = meta_window_get_wayland_surface (window); + MetaSurfaceActor *surface_actor = surface ? meta_wayland_surface_get_actor (surface) : NULL; if (surface_actor) meta_window_actor_assign_surface_actor (self, surface_actor); diff --git a/src/compositor/meta-window-drag.c b/src/compositor/meta-window-drag.c index ed8c8d32603..9034726f750 100644 --- a/src/compositor/meta-window-drag.c +++ b/src/compositor/meta-window-drag.c @@ -27,7 +27,7 @@ #include "core/window-private.h" #include "meta/meta-enum-types.h" -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND #include "x11/meta-x11-frame.h" #include "x11/window-x11.h" #endif @@ -1461,7 +1461,7 @@ update_move (MetaWindowDrag *window_drag, window->saved_rect.x = work_area.x; window->saved_rect.y = work_area.y; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XXWAYLAND if (META_IS_WINDOW_X11 (window)) { MetaFrame *frame; @@ -1689,7 +1689,7 @@ update_resize (MetaWindowDrag *window_drag, * resize the window when the window responds, or when we time * the response out. */ -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11 && meta_window_x11_is_awaiting_sync_response (window)) return; diff --git a/src/core/constraints.c b/src/core/constraints.c index fe4f6b3de37..b67b53f2efa 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -39,7 +39,7 @@ #include "core/workspace-private.h" #include "meta/prefs.h" -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND #include "x11/meta-x11-frame.h" #include "x11/window-x11-private.h" #endif @@ -375,7 +375,7 @@ setup_constraint_info (MetaBackend *backend, info->rel_y = 0; info->flags = flags; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) { if (info->current.width < 1) @@ -725,7 +725,7 @@ update_onscreen_requirements (MetaWindow *window, /* Update whether we want future constraint runs to require the * titlebar to be visible. */ -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11 && window->decorated) { MtkRectangle frame_rect; @@ -1417,7 +1417,7 @@ constrain_fullscreen (MetaWindow *window, monitor = info->entire_monitor; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) { MtkRectangle min_size, max_size; @@ -1429,7 +1429,7 @@ constrain_fullscreen (MetaWindow *window, if (too_big || too_small) return TRUE; } -#endif /* HAVE_X11_CLIENT */ +#endif /* HAVE_XWAYLAND */ /* Determine whether constraint is already satisfied; exit if it is */ constraint_already_satisfied = @@ -1539,11 +1539,9 @@ constrain_size_limits (MetaWindow *window, if (info->action_type == ACTION_MOVE) return TRUE; -#ifdef HAVE_WAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND && meta_window_is_fullscreen (window)) return TRUE; -#endif if (mtk_rectangle_is_empty (&info->current)) return TRUE; @@ -1804,7 +1802,7 @@ constrain_to_single_monitor (MetaWindow *window, if (priority > PRIORITY_ENTIRELY_VISIBLE_ON_SINGLE_MONITOR) return TRUE; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) client_driven_interactive_move = meta_window_x11_get_frame (window) == NULL; #endif @@ -1873,7 +1871,7 @@ constrain_titlebar_visible (MetaWindow *window, int horiz_amount_offscreen, vert_amount_offscreen; int horiz_amount_onscreen, vert_amount_onscreen; MetaWindowDrag *window_drag; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND MetaFrameBorders borders; #endif @@ -1937,7 +1935,7 @@ constrain_titlebar_visible (MetaWindow *window, /* Allow the titlebar to touch the bottom panel; If there is no titlebar, * require vert_amount to remain on the screen. */ -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11 && meta_window_x11_get_frame_borders (window, &borders)) { @@ -1982,7 +1980,7 @@ constrain_partially_onscreen (MetaWindow *window, int top_amount, bottom_amount; int horiz_amount_offscreen, vert_amount_offscreen; int horiz_amount_onscreen, vert_amount_onscreen; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND MetaFrameBorders borders; #endif @@ -2019,7 +2017,7 @@ constrain_partially_onscreen (MetaWindow *window, /* Allow the titlebar to touch the bottom panel; If there is no titlebar, * require vert_amount to remain on the screen. */ -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11 && meta_window_x11_get_frame_borders (window, &borders)) { diff --git a/src/core/display-private.h b/src/core/display-private.h index 019f50daab3..74578d85b7b 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -40,7 +40,7 @@ #include "meta/common.h" #include "meta/meta-selection.h" #include "meta/prefs.h" -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND #include "meta/meta-x11-types.h" #endif @@ -63,7 +63,7 @@ typedef void (* MetaDisplayWindowFunc) (MetaWindow *window, /* To avoid ifdefing MetaX11Display usage when built without X11 support */ -#ifndef HAVE_X11_CLIENT +#ifndef HAVE_XWAYLAND typedef struct _MetaX11Display MetaX11Display; #endif @@ -185,7 +185,7 @@ MetaDisplay * meta_display_new (MetaContext *context, GVariant *plugin_options, GError **error); -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND void meta_display_manage_all_xwindows (MetaDisplay *display); #endif diff --git a/src/core/display.c b/src/core/display.c index 42941b2dd7b..cb3ae667d4f 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -42,6 +42,8 @@ #include "backends/meta-input-mapper-private.h" #include "backends/meta-stage-private.h" #include "compositor/compositor-private.h" +#include "compositor/meta-compositor-native.h" +#include "compositor/meta-compositor-server.h" #include "cogl/cogl.h" #include "core/bell.h" #include "core/boxes-private.h" @@ -60,17 +62,6 @@ #include "meta/meta-sound-player.h" #include "meta/prefs.h" -#ifdef HAVE_X11_CLIENT -#include "meta/meta-x11-group.h" -#include "x11/meta-startup-notification-x11.h" -#include "x11/meta-x11-display-private.h" -#include "x11/window-x11.h" -#include "x11/xprops.h" -#endif - -#ifdef HAVE_WAYLAND -#include "compositor/meta-compositor-native.h" -#include "compositor/meta-compositor-server.h" #include "wayland/meta-wayland.h" #include "wayland/meta-wayland-input-device.h" #include "wayland/meta-wayland-private.h" @@ -78,9 +69,14 @@ #include "wayland/meta-wayland-tablet-pad.h" #include "wayland/meta-wayland-tablet-manager.h" #include "wayland/meta-wayland-touch.h" -#endif + #ifdef HAVE_XWAYLAND +#include "meta/meta-x11-group.h" +#include "x11/meta-startup-notification-x11.h" +#include "x11/meta-x11-display-private.h" +#include "x11/window-x11.h" +#include "x11/xprops.h" #include "wayland/meta-xwayland-private.h" #endif @@ -224,7 +220,6 @@ backend_from_display (MetaDisplay *display) return meta_context_get_backend (context); } -#ifdef HAVE_WAYLAND static MetaWaylandCompositor * wayland_compositor_from_display (MetaDisplay *display) { @@ -232,7 +227,6 @@ wayland_compositor_from_display (MetaDisplay *display) return meta_context_get_wayland_compositor (context); } -#endif static void meta_display_get_property(GObject *object, @@ -595,12 +589,10 @@ create_compositor (MetaDisplay *display) { MetaBackend *backend = backend_from_display (display); -#ifdef HAVE_WAYLAND #ifdef HAVE_NATIVE_BACKEND if (META_IS_BACKEND_NATIVE (backend)) return META_COMPOSITOR (meta_compositor_native_new (display, backend)); #endif -#endif/* HAVE_WAYLAND */ g_assert_not_reached (); } @@ -614,15 +606,10 @@ meta_display_init (MetaDisplay *display) void meta_display_cancel_touch (MetaDisplay *display) { -#ifdef HAVE_WAYLAND MetaWaylandCompositor *compositor; - if (!meta_is_wayland_compositor ()) - return; - compositor = wayland_compositor_from_display (display); meta_wayland_touch_cancel (compositor->seat->touch); -#endif } static void @@ -826,7 +813,7 @@ on_mandatory_x11_initialized (MetaDisplay *display, } #endif /* HAVE_XWAYLAND */ -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND void meta_display_shutdown_x11 (MetaDisplay *display) { @@ -868,7 +855,7 @@ meta_display_new (MetaContext *context, display->autoraise_window = NULL; display->focus_window = NULL; display->workspace_manager = NULL; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND display->x11_display = NULL; #endif @@ -927,29 +914,25 @@ meta_display_new (MetaContext *context, display->selection = meta_selection_new (display); meta_clipboard_manager_init (display); -#ifdef HAVE_WAYLAND - if (meta_is_wayland_compositor ()) - { + #ifdef HAVE_XWAYLAND - MetaWaylandCompositor *wayland_compositor = - wayland_compositor_from_display (display); - MetaX11DisplayPolicy x11_display_policy; + MetaWaylandCompositor *wayland_compositor = + wayland_compositor_from_display (display); + MetaX11DisplayPolicy x11_display_policy; - meta_xwayland_init_display (&wayland_compositor->xwayland_manager, - display); + meta_xwayland_init_display (&wayland_compositor->xwayland_manager, + display); - 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_mandatory_x11_initialized, - NULL); - } -#endif /* HAVE_XWAYLAND */ - timestamp = meta_display_get_current_time_roundtrip (display); + 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_mandatory_x11_initialized, + NULL); } - else -#endif /* HAVE_WAYLAND */ +#endif /* HAVE_XWAYLAND */ + timestamp = meta_display_get_current_time_roundtrip (display); + display->last_focus_time = timestamp; display->last_user_time = timestamp; @@ -960,7 +943,7 @@ meta_display_new (MetaContext *context, return NULL; } -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (display->x11_display) { g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0); @@ -1021,7 +1004,7 @@ meta_display_list_windows (MetaDisplay *display, winlist = NULL; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (display->x11_display) { g_hash_table_iter_init (&iter, display->x11_display->xids); @@ -1138,7 +1121,7 @@ meta_display_close (MetaDisplay *display, meta_stack_tracker_free); g_clear_pointer (&display->compositor, meta_compositor_destroy); -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND meta_display_shutdown_x11 (display); #endif g_clear_object (&display->stack); @@ -1304,7 +1287,7 @@ meta_display_get_current_time_roundtrip (MetaDisplay *display) /* Xwayland uses monotonic clock, so lets use it here as well */ return (guint32) (g_get_monotonic_time () / 1000); else -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND return meta_x11_display_get_current_time_roundtrip (display->x11_display); #else g_assert_not_reached (); @@ -1525,7 +1508,7 @@ MetaWindow* meta_display_lookup_stack_id (MetaDisplay *display, guint64 stack_id) { -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (META_STACK_ID_IS_X11 (stack_id)) { if (!display->x11_display) @@ -1803,7 +1786,7 @@ in_tab_chain (MetaWindow *window, gboolean in_normal_tab_chain; gboolean in_dock_tab_chain; gboolean in_group_tab_chain = FALSE; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND MetaGroup *focus_group = NULL; MetaGroup *window_group = NULL; @@ -2163,7 +2146,7 @@ meta_resize_gravity_from_grab_op (MetaGrabOp op) return gravity; } -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND void meta_display_manage_all_xwindows (MetaDisplay *display) { @@ -2551,6 +2534,9 @@ meta_display_get_pad_button_label (MetaDisplay *display, ClutterInputDevice *pad, int button) { + MetaWaylandCompositor *compositor; + MetaWaylandTabletSeat *tablet_seat; + MetaWaylandTabletPad *tablet_pad = NULL; char *label; /* First, lookup the action, as imposed by settings */ @@ -2559,30 +2545,21 @@ meta_display_get_pad_button_label (MetaDisplay *display, 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 = wayland_compositor_from_display (display); - 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_button_label (tablet_pad, - button); - } + /* Second, lookup the actions set by the clients */ + compositor = wayland_compositor_from_display (display); + 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 (label) - return label; + if (tablet_pad) + { + label = meta_wayland_tablet_pad_get_button_label (tablet_pad, + button); } -#endif + + if (label) + return label; return NULL; } @@ -2594,6 +2571,9 @@ meta_display_get_pad_feature_label (MetaDisplay *display, MetaPadDirection direction, int feature_number) { + MetaWaylandCompositor *compositor; + MetaWaylandTabletSeat *tablet_seat; + MetaWaylandTabletPad *tablet_pad = NULL; char *label; /* First, lookup the action, as imposed by settings */ @@ -2604,31 +2584,23 @@ meta_display_get_pad_feature_label (MetaDisplay *display, 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 = wayland_compositor_from_display (display); - 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); + /* Second, lookup the actions set by the clients */ - if (tablet_pad) - { - label = meta_wayland_tablet_pad_get_feature_label (tablet_pad, - feature, - feature_number); - } + compositor = wayland_compositor_from_display (display); + 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 (label) - return label; + if (tablet_pad) + { + label = meta_wayland_tablet_pad_get_feature_label (tablet_pad, + feature, + feature_number); } -#endif + + if (label) + return label; return NULL; } diff --git a/src/core/events.c b/src/core/events.c index 43c37e09914..897493f0891 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -33,15 +33,12 @@ #include "core/display-private.h" #include "core/window-private.h" #include "meta/meta-backend.h" +#include "wayland/meta-wayland-private.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_KEY_EVENT(et) ((et) == CLUTTER_KEY_PRESS || \ (et) == CLUTTER_KEY_RELEASE) @@ -176,19 +173,12 @@ meta_display_handle_event (MetaDisplay *display, gboolean a11y_grabbed; MetaTabletActionMapper *mapper; MetaEventMode mode_hint; -#ifdef HAVE_WAYLAND MetaWaylandCompositor *wayland_compositor; MetaWaylandTextInput *wayland_text_input = NULL; -#endif -#ifdef HAVE_WAYLAND wayland_compositor = meta_context_get_wayland_compositor (context); - if (wayland_compositor) - { - wayland_text_input = - meta_wayland_compositor_get_text_input (wayland_compositor); - } -#endif + wayland_text_input = + meta_wayland_compositor_get_text_input (wayland_compositor); COGL_TRACE_BEGIN_SCOPED (MetaDisplayHandleEvent, "Meta::Display::handle_event()"); @@ -235,15 +225,12 @@ meta_display_handle_event (MetaDisplay *display, } } -#ifdef HAVE_WAYLAND if (wayland_text_input && !meta_compositor_get_current_window_drag (compositor) && meta_wayland_text_input_update (wayland_text_input, event)) return CLUTTER_EVENT_STOP; - if (wayland_compositor) - meta_wayland_compositor_update (wayland_compositor, event); -#endif + meta_wayland_compositor_update (wayland_compositor, event); if (event_type == CLUTTER_PAD_BUTTON_PRESS || event_type == CLUTTER_PAD_BUTTON_RELEASE || @@ -397,20 +384,15 @@ meta_display_handle_event (MetaDisplay *display, mode_hint = META_EVENT_MODE_KEEP_FROZEN; } -#ifdef HAVE_WAYLAND - if (wayland_compositor) - { - uint32_t time_ms; + uint32_t time_ms; - time_ms = clutter_event_get_time (event); - if (window && event_type == CLUTTER_MOTION && - time_ms != CLUTTER_CURRENT_TIME) - meta_window_check_alive_on_event (window, time_ms); + time_ms = clutter_event_get_time (event); + if (window && event_type == CLUTTER_MOTION && + time_ms != CLUTTER_CURRENT_TIME) + meta_window_check_alive_on_event (window, time_ms); - if (meta_wayland_compositor_handle_event (wayland_compositor, event)) - return CLUTTER_EVENT_STOP; - } -#endif + if (meta_wayland_compositor_handle_event (wayland_compositor, event)) + return CLUTTER_EVENT_STOP; return meta_compositor_handle_event (compositor, event, window, mode_hint); } diff --git a/src/core/meta-context-main.c b/src/core/meta-context-main.c index 2441fea7f21..737e316e8d2 100644 --- a/src/core/meta-context-main.c +++ b/src/core/meta-context-main.c @@ -25,15 +25,14 @@ #include #include -#ifdef HAVE_WAYLAND #include -#endif #include "backends/meta-monitor-private.h" #include "backends/meta-monitor-manager-private.h" #include "backends/meta-virtual-monitor.h" #include "core/meta-session-manager.h" #include "meta/meta-backend.h" +#include "wayland/meta-wayland.h" #ifdef HAVE_NATIVE_BACKEND #include "backends/native/meta-backend-native.h" @@ -44,17 +43,11 @@ #include "core/meta-mdk.h" #endif -#ifdef HAVE_WAYLAND -#include "wayland/meta-wayland.h" -#endif - typedef struct _MetaContextMainOptions { -#ifdef HAVE_WAYLAND gboolean wayland; gboolean no_x11; char *wayland_display; -#endif #ifdef HAVE_NATIVE_BACKEND gboolean display_server; gboolean headless; @@ -125,10 +118,8 @@ meta_context_main_configure (MetaContext *context, if (!check_configuration (context_main, error)) return FALSE; -#ifdef HAVE_WAYLAND if (context_main->options.wayland_display) meta_wayland_override_display_name (context_main->options.wayland_display); -#endif #ifdef HAVE_PROFILER meta_context_set_trace_file (context, context_main->options.trace_file); @@ -256,7 +247,6 @@ meta_context_main_setup (MetaContext *context, return TRUE; } -#ifdef HAVE_WAYLAND #ifdef HAVE_NATIVE_BACKEND static MetaBackend * create_headless_backend (MetaContext *context, @@ -279,17 +269,13 @@ create_native_backend (MetaContext *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 -#ifdef HAVE_WAYLAND #ifdef HAVE_NATIVE_BACKEND if (context_main->options.headless || context_main->options.devkit) @@ -297,9 +283,6 @@ meta_context_main_create_backend (MetaContext *context, return create_native_backend (context, error); #endif /* HAVE_NATIVE_BACKEND */ -#else /* HAVE_WAYLAND */ - g_assert_not_reached (); -#endif /* HAVE_WAYLAND */ g_assert_not_reached (); } @@ -370,7 +353,6 @@ meta_context_main_add_option_entries (MetaContextMain *context_main) { MetaContext *context = META_CONTEXT (context_main); GOptionEntry options[] = { -#ifdef HAVE_WAYLAND { "wayland", 0, 0, G_OPTION_ARG_NONE, &context_main->options.wayland, @@ -391,7 +373,6 @@ meta_context_main_add_option_entries (MetaContextMain *context_main) N_("Specify Wayland display name to use"), NULL }, -#endif #ifdef HAVE_NATIVE_BACKEND { "display-server", 0, 0, G_OPTION_ARG_NONE, diff --git a/src/core/meta-context-private.h b/src/core/meta-context-private.h index f83c70f0a9d..cd058534c40 100644 --- a/src/core/meta-context-private.h +++ b/src/core/meta-context-private.h @@ -65,10 +65,8 @@ void meta_context_set_unsafe_mode (MetaContext *context, gboolean meta_context_get_unsafe_mode (MetaContext *context); -#ifdef HAVE_WAYLAND META_EXPORT_TEST MetaServiceChannel * meta_context_get_service_channel (MetaContext *context); -#endif MetaX11DisplayPolicy meta_context_get_x11_display_policy (MetaContext *context); diff --git a/src/core/meta-context.c b/src/core/meta-context.c index e6554e88c24..c6ce70067c3 100644 --- a/src/core/meta-context.c +++ b/src/core/meta-context.c @@ -30,15 +30,12 @@ #include "core/prefs-private.h" #include "core/util-private.h" #include "meta/meta-enums.h" +#include "wayland/meta-wayland.h" #ifdef HAVE_PROFILER #include "core/meta-profiler.h" #endif -#ifdef HAVE_WAYLAND -#include "wayland/meta-wayland.h" -#endif - enum { PROP_0, @@ -89,9 +86,7 @@ typedef struct _MetaContextPrivate MetaBackend *backend; MetaDisplay *display; -#ifdef HAVE_WAYLAND MetaWaylandCompositor *wayland_compositor; -#endif GMainLoop *main_loop; GError *termination_error; @@ -104,9 +99,7 @@ typedef struct _MetaContextPrivate MetaProfiler *profiler; #endif -#ifdef HAVE_WAYLAND MetaServiceChannel *service_channel; -#endif MetaDebugControl *debug_control; } MetaContextPrivate; @@ -281,7 +274,6 @@ meta_context_get_display (MetaContext *context) return priv->display; } -#ifdef HAVE_WAYLAND /** * meta_context_get_wayland_compositor: * @context: The #MetaContext @@ -305,7 +297,6 @@ meta_context_get_service_channel (MetaContext *context) return priv->service_channel; } -#endif MetaX11DisplayPolicy meta_context_get_x11_display_policy (MetaContext *context) @@ -475,9 +466,7 @@ meta_context_start (MetaContext *context, meta_prefs_init (); -#ifdef HAVE_WAYLAND priv->wayland_compositor = meta_wayland_compositor_new (context); -#endif plugin_options = g_steal_pointer (&priv->plugin_options), priv->display = meta_display_new (context, plugin_options, error); @@ -487,9 +476,7 @@ meta_context_start (MetaContext *context, return FALSE; } -#ifdef HAVE_WAYLAND priv->service_channel = meta_service_channel_new (context); -#endif priv->main_loop = g_main_loop_new (NULL, FALSE); @@ -811,20 +798,16 @@ meta_context_dispose (GObject *object) g_signal_emit (context, signals[PREPARE_SHUTDOWN], 0); -#ifdef HAVE_WAYLAND g_clear_object (&priv->service_channel); 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); diff --git a/src/core/meta-launch-context.c b/src/core/meta-launch-context.c index 998febef118..348cdab0f42 100644 --- a/src/core/meta-launch-context.c +++ b/src/core/meta-launch-context.c @@ -24,7 +24,7 @@ #include "core/display-private.h" #include "meta/meta-launch-context.h" -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND #include "x11/meta-startup-notification-x11.h" #endif @@ -138,7 +138,7 @@ meta_launch_context_get_startup_notify_id (GAppLaunchContext *launch_context, if (context->workspace) workspace_idx = meta_workspace_index (context->workspace); -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (display->x11_display) { /* If there is a X11 display, we prefer going entirely through diff --git a/src/core/meta-service-channel.c b/src/core/meta-service-channel.c index 74a9904e268..ea1ace5b77f 100644 --- a/src/core/meta-service-channel.c +++ b/src/core/meta-service-channel.c @@ -213,7 +213,6 @@ handle_open_wayland_service_connection (MetaDBusServiceChannel *object, GUnixFDList *in_fd_list, uint32_t service_client_type) { -#ifdef HAVE_WAYLAND MetaServiceChannel *service_channel = META_SERVICE_CHANNEL (object); GDBusConnection *connection; const char *sender; @@ -243,13 +242,6 @@ handle_open_wayland_service_connection (MetaDBusServiceChannel *object, g_steal_pointer (&data)); return G_DBUS_METHOD_INVOCATION_HANDLED; -#else /* HAVE_WAYLAND */ - g_dbus_method_invocation_return_error (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_NOT_SUPPORTED, - "Wayland not supported"); - return G_DBUS_METHOD_INVOCATION_HANDLED; -#endif /* HAVE_WAYLAND */ } static void diff --git a/src/core/meta-service-channel.h b/src/core/meta-service-channel.h index cb51b78a3b4..6ae1ad4de99 100644 --- a/src/core/meta-service-channel.h +++ b/src/core/meta-service-channel.h @@ -17,8 +17,6 @@ #pragma once -#ifdef HAVE_WAYLAND - #include "meta/meta-context.h" #include "core/util-private.h" @@ -44,5 +42,3 @@ MetaServiceChannel * meta_service_channel_new (MetaContext *context); META_EXPORT_TEST MetaWaylandClient * meta_service_channel_get_service_client (MetaServiceChannel *service_channel, MetaServiceClientType service_client_type); - -#endif /* HAVE_WAYLAND */ diff --git a/src/core/place.c b/src/core/place.c index d3f0b1cf75d..43ffd2fd0eb 100644 --- a/src/core/place.c +++ b/src/core/place.c @@ -37,7 +37,7 @@ #include "meta/prefs.h" #include "meta/workspace.h" -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND #include "x11/window-x11-private.h" #endif @@ -486,7 +486,7 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, if (flags & META_PLACE_FLAG_DENIED_FOCUS_AND_NOT_TRANSIENT && window->type == META_WINDOW_MODAL_DIALOG && -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND meta_window_x11_same_application (window, focus_window) && #endif window_overlaps_focus_window (window, *x, *y)) diff --git a/src/core/stack-tracker.c b/src/core/stack-tracker.c index afe4173fef0..c7380afbe08 100644 --- a/src/core/stack-tracker.c +++ b/src/core/stack-tracker.c @@ -45,7 +45,7 @@ #include "core/window-private.h" #include "meta/util.h" -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND #include "mtk/mtk-x11.h" #include "x11/meta-x11-display-private.h" #include "x11/meta-x11-frame.h" @@ -511,7 +511,7 @@ copy_stack (GArray *stack) return copy; } -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND static void query_xserver_stack (MetaDisplay *display, MetaStackTracker *tracker) @@ -573,7 +573,7 @@ drop_x11_windows (MetaDisplay *display, l = next; } } -#endif /* HAVE_X11_CLIENT */ +#endif /* HAVE_XWAYLAND */ static void on_stack_changed (MetaStack *stack, @@ -583,7 +583,7 @@ on_stack_changed (MetaStack *stack, GList *l; GArray *hidden_stack_ids; GList *sorted; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND MetaFrame *frame; #endif @@ -609,7 +609,7 @@ on_stack_changed (MetaStack *stack, meta_topic (META_DEBUG_STACK, " %u:%d - %s ", w->layer, w->stack_position, w->desc); -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (w->client_type == META_WINDOW_CLIENT_TYPE_X11) { frame = meta_window_x11_get_frame (w); @@ -632,7 +632,7 @@ on_stack_changed (MetaStack *stack, g_array_append_val (all_root_children_stacked, stack_id); } -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (tracker->display->x11_display) { uint64_t guard_window_id; @@ -673,7 +673,7 @@ meta_stack_tracker_new (MetaStack *stack) tracker->verified_stack = g_array_new (FALSE, FALSE, sizeof (guint64)); tracker->unverified_predictions = g_queue_new (); -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND g_signal_connect (tracker->display, "x11-display-setup", G_CALLBACK (query_xserver_stack), @@ -712,7 +712,7 @@ meta_stack_tracker_free (MetaStackTracker *tracker) g_queue_free (tracker->unverified_predictions); tracker->unverified_predictions = NULL; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND g_signal_handlers_disconnect_by_func (tracker->display, (gpointer)query_xserver_stack, tracker); @@ -821,7 +821,7 @@ meta_stack_tracker_record_lower_below (MetaStackTracker *tracker, stack_tracker_apply_prediction (tracker, op); } -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND static void stack_tracker_event_received (MetaStackTracker *tracker, MetaStackOp *op) @@ -962,13 +962,13 @@ meta_stack_tracker_configure_event (MetaStackTracker *tracker, stack_tracker_event_received (tracker, &op); } -#endif /* HAVE_X11_CLIENT */ +#endif /* HAVE_XWAYLAND */ static gboolean meta_stack_tracker_is_guard_window (MetaStackTracker *tracker, uint64_t stack_id) { -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND MetaX11Display *x11_display = tracker->display->x11_display; if (!x11_display) @@ -1045,7 +1045,7 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker) GList *meta_windows; int n_windows; int i; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND MetaFrame *frame; #endif @@ -1067,7 +1067,7 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker) { guint64 window = windows[i]; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (META_STACK_ID_IS_X11 (window)) { MetaX11Display *x11_display = tracker->display->x11_display; @@ -1150,7 +1150,7 @@ meta_stack_tracker_queue_sync_stack (MetaStackTracker *tracker) * otherwise it searches downwards looking for the nearest X window. * * If no X based sibling could be found return NULL. */ -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND static Window find_x11_sibling_downwards (MetaStackTracker *tracker, guint64 sibling) @@ -1216,7 +1216,7 @@ meta_stack_tracker_lower_below (MetaStackTracker *tracker, guint64 sibling) { gulong serial = 0; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND MetaX11Display *x11_display = tracker->display->x11_display; if (META_STACK_ID_IS_X11 (window)) @@ -1253,7 +1253,7 @@ meta_stack_tracker_raise_above (MetaStackTracker *tracker, guint64 sibling) { gulong serial = 0; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND MetaX11Display *x11_display = tracker->display->x11_display; if (META_STACK_ID_IS_X11 (window)) diff --git a/src/core/stack-tracker.h b/src/core/stack-tracker.h index 667d5d7e67b..3fbf751c1b1 100644 --- a/src/core/stack-tracker.h +++ b/src/core/stack-tracker.h @@ -33,7 +33,7 @@ #pragma once -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND #include #endif @@ -71,7 +71,7 @@ void meta_stack_tracker_restack_at_bottom (MetaStackTracker *tracker, /* These functions are used to update the stack when we get events * reflecting changes to the stacking order */ -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND void meta_stack_tracker_create_event (MetaStackTracker *tracker, XCreateWindowEvent *event); void meta_stack_tracker_destroy_event (MetaStackTracker *tracker, diff --git a/src/core/stack.c b/src/core/stack.c index e071ee6ec87..eea538e9053 100644 --- a/src/core/stack.c +++ b/src/core/stack.c @@ -38,7 +38,7 @@ #include "meta/prefs.h" #include "meta/workspace.h" -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND #include "meta/meta-x11-group.h" #include "x11/meta-x11-display-private.h" #include "x11/window-x11.h" @@ -489,7 +489,7 @@ create_constraints (Constraint **constraints, continue; } -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (WINDOW_TRANSIENT_FOR_WHOLE_GROUP (w)) { GSList *group_windows; diff --git a/src/core/window-private.h b/src/core/window-private.h index 08c0faec9bb..9b7f048aaa2 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -608,9 +608,7 @@ struct _MetaWindowClass MetaStackLayer (*calculate_layer) (MetaWindow *window); -#ifdef HAVE_WAYLAND MetaWaylandSurface * (*get_wayland_surface) (MetaWindow *window); -#endif gboolean (*set_transient_for) (MetaWindow *window, MetaWindow *parent); @@ -693,10 +691,8 @@ gboolean meta_window_can_ping (MetaWindow *window); MetaStackLayer meta_window_calculate_layer (MetaWindow *window); -#ifdef HAVE_WAYLAND META_EXPORT_TEST MetaWaylandSurface * meta_window_get_wayland_surface (MetaWindow *window); -#endif void meta_window_current_workspace_changed (MetaWindow *window); diff --git a/src/core/window.c b/src/core/window.c index d6c1dc4e083..b736fe89f0c 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -82,8 +82,11 @@ #include "meta/meta-enum-types.h" #include "meta/prefs.h" #include "meta/meta-window-config.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-surface-private.h" +#include "wayland/meta-window-wayland.h" -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND #include "mtk/mtk-x11.h" #include "x11/meta-x11-display-private.h" #include "x11/meta-x11-frame.h" @@ -92,19 +95,7 @@ #include "x11/window-x11-private.h" #include "x11/window-x11.h" #include "x11/xprops.h" -#endif - -#ifdef HAVE_WAYLAND -#include "wayland/meta-wayland-private.h" -#include "wayland/meta-wayland-surface-private.h" -#include "wayland/meta-window-wayland.h" -#endif - -#ifdef HAVE_X11_CLIENT #include "x11/window-x11-private.h" -#endif - -#ifdef HAVE_XWAYLAND #include "wayland/meta-window-xwayland.h" #endif @@ -913,16 +904,14 @@ meta_window_should_attach_to_parent (MetaWindow *window) static gboolean client_window_should_be_mapped (MetaWindow *window) { -#ifdef HAVE_WAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) { MetaWaylandSurface *surface = meta_window_get_wayland_surface (window); if (!meta_wayland_surface_get_buffer (surface)) return FALSE; } -#endif -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11 && window->decorated && !meta_window_x11_is_ssd (window)) return FALSE; @@ -1042,7 +1031,7 @@ meta_window_update_desc (MetaWindow *window) { g_clear_pointer (&window->desc, g_free); -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) { window->desc = g_strdup_printf ("0x%lx (%s)", @@ -1553,7 +1542,7 @@ meta_window_unmanage (MetaWindow *window, if (meta_prefs_get_workspaces_only_on_primary ()) meta_window_on_all_workspaces_changed (window); -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (meta_window_is_fullscreen (window)) { MetaGroup *group = NULL; @@ -1576,7 +1565,7 @@ meta_window_unmanage (MetaWindow *window, /* safe to do this early as group.c won't re-add to the * group if window->unmanaging */ -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) meta_window_x11_shutdown_group (window); #endif @@ -1681,7 +1670,7 @@ meta_window_unmanage (MetaWindow *window, static void set_wm_state (MetaWindow *window) { -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) meta_window_x11_set_wm_state (window); #endif @@ -1690,7 +1679,7 @@ set_wm_state (MetaWindow *window) static void set_net_wm_state (MetaWindow *window) { -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) meta_window_x11_set_net_wm_state (window); #endif @@ -1699,7 +1688,7 @@ set_net_wm_state (MetaWindow *window) static void set_allowed_actions_hint (MetaWindow *window) { -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) meta_window_x11_set_allowed_actions_hint (window); #endif @@ -1802,14 +1791,9 @@ meta_window_showing_on_its_workspace (MetaWindow *window) static gboolean window_has_buffer (MetaWindow *window) { -#ifdef HAVE_WAYLAND - if (meta_is_wayland_compositor ()) - { - MetaWaylandSurface *surface = meta_window_get_wayland_surface (window); - if (!surface || !meta_wayland_surface_get_buffer (surface)) - return FALSE; - } -#endif + MetaWaylandSurface *surface = meta_window_get_wayland_surface (window); + if (!surface || !meta_wayland_surface_get_buffer (surface)) + return FALSE; return TRUE; } @@ -1835,13 +1819,11 @@ meta_window_is_showable (MetaWindow *window) if (should_show_be_postponed (window)) return FALSE; -#ifdef HAVE_WAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND && !window_has_buffer (window)) return FALSE; -#endif -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11 && window->decorated && !meta_window_x11_is_ssd (window)) return FALSE; @@ -3382,23 +3364,6 @@ unmaximize_window_before_freeing (MetaWindow *window) meta_window_config_set_rect (window->config, 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 } void @@ -4691,7 +4656,7 @@ meta_window_client_rect_to_frame_rect (MetaWindow *window, MtkRectangle *client_rect, MtkRectangle *frame_rect) { -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND MetaFrameBorders borders; #endif @@ -4704,7 +4669,7 @@ meta_window_client_rect_to_frame_rect (MetaWindow *window, * constraints.c:get_size_limits() and not something that we provide * in other locations or document. */ -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11 && meta_window_x11_get_frame_borders (window, &borders)) { @@ -4743,7 +4708,7 @@ meta_window_frame_rect_to_client_rect (MetaWindow *window, MtkRectangle *frame_rect, MtkRectangle *client_rect) { -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND MetaFrameBorders borders; #endif @@ -4752,7 +4717,7 @@ meta_window_frame_rect_to_client_rect (MetaWindow *window, *client_rect = *frame_rect; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11 && meta_window_x11_get_frame_borders (window, &borders)) { @@ -4804,7 +4769,7 @@ meta_window_get_client_area_rect (MetaWindow *window, MtkRectangle *rect) { MetaFrameBorders borders = { 0, }; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) meta_window_x11_get_frame_borders (window, &borders); #endif @@ -4827,7 +4792,7 @@ meta_window_get_client_area_rect (MetaWindow *window, const char* meta_window_get_startup_id (MetaWindow *window) { -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->startup_id == NULL && window->client_type == META_WINDOW_CLIENT_TYPE_X11) { MetaGroup *group; @@ -4883,13 +4848,11 @@ get_modal_transient (MetaWindow *window) static gboolean meta_window_transient_can_focus (MetaWindow *window) { -#ifdef HAVE_WAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) { MetaWaylandSurface *surface = meta_window_get_wayland_surface (window); return meta_wayland_surface_get_buffer (surface) != NULL; } -#endif return TRUE; } @@ -5757,7 +5720,7 @@ meta_window_type_changed (MetaWindow *window) if (!window->override_redirect) set_net_wm_state (window); -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) { /* Update frame */ @@ -5804,7 +5767,7 @@ meta_window_set_type (MetaWindow *window, void meta_window_frame_size_changed (MetaWindow *window) { -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND MetaFrame *frame; if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) @@ -6378,7 +6341,7 @@ meta_window_get_default_layer (MetaWindow *window) void meta_window_update_layer (MetaWindow *window) { -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND MetaGroup *group = NULL; if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) @@ -7621,7 +7584,7 @@ meta_window_has_pointer (MetaWindow *window) { if (meta_is_wayland_compositor ()) return window_has_pointer_wayland (window); -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND else return meta_window_x11_has_pointer (window); #else @@ -7942,7 +7905,6 @@ meta_window_calculate_layer (MetaWindow *window) return META_WINDOW_GET_CLASS (window)->calculate_layer (window); } -#ifdef HAVE_WAYLAND MetaWaylandSurface * meta_window_get_wayland_surface (MetaWindow *window) { @@ -7951,7 +7913,6 @@ meta_window_get_wayland_surface (MetaWindow *window) return klass->get_wayland_surface (window); } -#endif /** * meta_window_get_id: @@ -8522,7 +8483,7 @@ meta_window_get_client_content_rect (MetaWindow *window, { meta_window_get_frame_rect (window, rect); -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_X11 && meta_window_x11_is_ssd (window)) meta_window_frame_rect_to_client_rect (window, rect, rect); diff --git a/src/meson.build b/src/meson.build index 75035e68265..4f3f15e53e0 100644 --- a/src/meson.build +++ b/src/meson.build @@ -17,6 +17,7 @@ mutter_pkg_deps = [ gio_unix_dep, glib_dep, gsettings_desktop_schemas_dep, + wayland_server_dep, ] mutter_pkg_private_deps = [ @@ -28,6 +29,7 @@ mutter_pkg_private_deps = [ glycin_dep, libeis_dep, libdisplay_info_dep, + libdrm_dep, ] if have_gnome_desktop @@ -92,7 +94,7 @@ if have_introspection ] endif -if have_x11_client +if have_xwayland mutter_pkg_deps += [ xfixes_dep, xi_dep, @@ -112,12 +114,6 @@ if have_x11_client ] endif -if have_wayland - mutter_pkg_deps += [ - wayland_server_dep, - ] -endif - if have_logind mutter_pkg_private_deps += [ logind_dep, @@ -132,11 +128,6 @@ if have_native_backend ] endif -if have_wayland or have_native_backend - mutter_pkg_private_deps += [ - libdrm_dep, - ] -endif if have_wayland_eglstream mutter_lib_deps += [ @@ -277,6 +268,12 @@ mutter_sources = [ 'backends/meta-viewport-info.h', 'backends/meta-virtual-monitor.c', 'backends/meta-virtual-monitor.h', + 'common/meta-cogl-drm-formats.c', + 'common/meta-cogl-drm-formats.h', + 'common/meta-drm-format-helpers.c', + 'common/meta-drm-format-helpers.h', + 'common/meta-drm-timeline.c', + 'common/meta-drm-timeline.h', 'compositor/clutter-utils.c', 'compositor/clutter-utils.h', 'compositor/cogl-utils.c', @@ -390,7 +387,7 @@ mutter_sources = [ 'core/workspace-private.h', ] -if have_x11_client +if have_xwayland mutter_sources += [ 'compositor/meta-window-actor-x11.c', 'compositor/meta-window-actor-x11.h', @@ -432,6 +429,19 @@ if have_x11_client 'x11/window-x11-private.h', 'x11/xprops.c', 'x11/xprops.h', + 'wayland/meta-wayland-x11-interop.c', + 'wayland/meta-wayland-x11-interop.h', + 'wayland/meta-window-xwayland.c', + 'wayland/meta-window-xwayland.h', + 'wayland/meta-xwayland-dnd-private.h', + 'wayland/meta-xwayland-dnd.c', + 'wayland/meta-xwayland-grab-keyboard.c', + 'wayland/meta-xwayland-grab-keyboard.h', + 'wayland/meta-xwayland-private.h', + 'wayland/meta-xwayland-surface.c', + 'wayland/meta-xwayland-surface.h', + 'wayland/meta-xwayland.c', + 'wayland/meta-xwayland.h', ] endif @@ -500,194 +510,174 @@ if have_remote_desktop ] 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', + 'core/meta-service-channel.c', + 'core/meta-service-channel.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-client-private.h', + 'wayland/meta-wayland-color-management.c', + 'wayland/meta-wayland-color-management.h', + 'wayland/meta-wayland-color-representation.c', + 'wayland/meta-wayland-color-representation.h', + 'wayland/meta-wayland-commit-timing.c', + 'wayland/meta-wayland-cursor-shape.c', + 'wayland/meta-wayland-cursor-shape.h', + 'wayland/meta-wayland-fifo.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-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-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-dma-buf.c', + 'wayland/meta-wayland-dma-buf.h', + 'wayland/meta-wayland-dnd-surface.c', + 'wayland/meta-wayland-dnd-surface.h', + 'wayland/meta-wayland-filter-manager.c', + 'wayland/meta-wayland-filter-manager.h', + 'wayland/meta-wayland-fixes.c', + 'wayland/meta-wayland-fixes.h', + 'wayland/meta-wayland-fractional-scale.c', + 'wayland/meta-wayland-fractional-scale.h', + 'wayland/meta-wayland-gtk-shell.c', + 'wayland/meta-wayland-gtk-shell.h', + 'wayland/meta-wayland.h', + 'wayland/meta-wayland-idle-inhibit.c', + 'wayland/meta-wayland-idle-inhibit.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.c', + 'wayland/meta-wayland-input.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-foreign.c', + 'wayland/meta-wayland-legacy-xdg-foreign.h', + 'wayland/meta-wayland-linux-drm-syncobj.c', + 'wayland/meta-wayland-linux-drm-syncobj.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-hold.c', + 'wayland/meta-wayland-pointer-gesture-hold.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-pointer-warp.c', + 'wayland/meta-wayland-pointer-warp.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-single-pixel-buffer.c', + 'wayland/meta-wayland-single-pixel-buffer.h', + 'wayland/meta-wayland-subsurface.c', + 'wayland/meta-wayland-subsurface.h', + 'wayland/meta-wayland-surface.c', + 'wayland/meta-wayland-surface-private.h', + 'wayland/meta-wayland-system-bell.c', + 'wayland/meta-wayland-system-bell.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-dial.c', + 'wayland/meta-wayland-tablet-pad-dial.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-toplevel-drag.c', + 'wayland/meta-wayland-toplevel-drag.h', + 'wayland/meta-wayland-touch.c', + 'wayland/meta-wayland-touch.h', + 'wayland/meta-wayland-transaction.c', + 'wayland/meta-wayland-transaction.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-xdg-foreign.c', + 'wayland/meta-wayland-xdg-foreign.h', + 'wayland/meta-wayland-xdg-foreign-private.h', + 'wayland/meta-wayland-xdg-session-manager.c', + 'wayland/meta-wayland-xdg-session-manager.h', + 'wayland/meta-wayland-xdg-session-state.c', + 'wayland/meta-wayland-xdg-session-state.h', + 'wayland/meta-wayland-xdg-session.c', + 'wayland/meta-wayland-xdg-session.h', + 'wayland/meta-wayland-xdg-shell.c', + 'wayland/meta-wayland-xdg-shell.h', + 'wayland/meta-wayland-xdg-dialog.c', + 'wayland/meta-wayland-xdg-dialog.h', + 'wayland/meta-wayland-xdg-toplevel-tag.c', + 'wayland/meta-wayland-xdg-toplevel-tag.h', + 'wayland/meta-window-wayland.c', + 'wayland/meta-window-wayland.h', +] + +if have_native_backend 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', - 'core/meta-service-channel.c', - 'core/meta-service-channel.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-client-private.h', - 'wayland/meta-wayland-color-management.c', - 'wayland/meta-wayland-color-management.h', - 'wayland/meta-wayland-color-representation.c', - 'wayland/meta-wayland-color-representation.h', - 'wayland/meta-wayland-commit-timing.c', - 'wayland/meta-wayland-cursor-shape.c', - 'wayland/meta-wayland-cursor-shape.h', - 'wayland/meta-wayland-fifo.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-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-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-dma-buf.c', - 'wayland/meta-wayland-dma-buf.h', - 'wayland/meta-wayland-dnd-surface.c', - 'wayland/meta-wayland-dnd-surface.h', - 'wayland/meta-wayland-filter-manager.c', - 'wayland/meta-wayland-filter-manager.h', - 'wayland/meta-wayland-fixes.c', - 'wayland/meta-wayland-fixes.h', - 'wayland/meta-wayland-fractional-scale.c', - 'wayland/meta-wayland-fractional-scale.h', - 'wayland/meta-wayland-gtk-shell.c', - 'wayland/meta-wayland-gtk-shell.h', - 'wayland/meta-wayland.h', - 'wayland/meta-wayland-idle-inhibit.c', - 'wayland/meta-wayland-idle-inhibit.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.c', - 'wayland/meta-wayland-input.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-foreign.c', - 'wayland/meta-wayland-legacy-xdg-foreign.h', - 'wayland/meta-wayland-linux-drm-syncobj.c', - 'wayland/meta-wayland-linux-drm-syncobj.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-hold.c', - 'wayland/meta-wayland-pointer-gesture-hold.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-warp.c', - 'wayland/meta-wayland-pointer-warp.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-single-pixel-buffer.c', - 'wayland/meta-wayland-single-pixel-buffer.h', - 'wayland/meta-wayland-subsurface.c', - 'wayland/meta-wayland-subsurface.h', - 'wayland/meta-wayland-surface.c', - 'wayland/meta-wayland-surface-private.h', - 'wayland/meta-wayland-system-bell.c', - 'wayland/meta-wayland-system-bell.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-dial.c', - 'wayland/meta-wayland-tablet-pad-dial.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-toplevel-drag.c', - 'wayland/meta-wayland-toplevel-drag.h', - 'wayland/meta-wayland-touch.c', - 'wayland/meta-wayland-touch.h', - 'wayland/meta-wayland-transaction.c', - 'wayland/meta-wayland-transaction.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-xdg-foreign.c', - 'wayland/meta-wayland-xdg-foreign.h', - 'wayland/meta-wayland-xdg-foreign-private.h', - 'wayland/meta-wayland-xdg-session-manager.c', - 'wayland/meta-wayland-xdg-session-manager.h', - 'wayland/meta-wayland-xdg-session-state.c', - 'wayland/meta-wayland-xdg-session-state.h', - 'wayland/meta-wayland-xdg-session.c', - 'wayland/meta-wayland-xdg-session.h', - 'wayland/meta-wayland-xdg-shell.c', - 'wayland/meta-wayland-xdg-shell.h', - 'wayland/meta-wayland-xdg-dialog.c', - 'wayland/meta-wayland-xdg-dialog.h', - 'wayland/meta-wayland-xdg-toplevel-tag.c', - 'wayland/meta-wayland-xdg-toplevel-tag.h', - 'wayland/meta-window-wayland.c', - 'wayland/meta-window-wayland.h', + 'wayland/meta-wayland-drm-lease.c', + 'wayland/meta-wayland-drm-lease.h', ] - - if have_xwayland - mutter_sources += [ - 'wayland/meta-wayland-x11-interop.c', - 'wayland/meta-wayland-x11-interop.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 += [ - 'wayland/meta-wayland-drm-lease.c', - 'wayland/meta-wayland-drm-lease.h', - ] - endif endif if have_native_backend @@ -841,17 +831,6 @@ if have_devkit ] endif -if have_wayland or have_native_backend - mutter_sources += [ - 'common/meta-cogl-drm-formats.c', - 'common/meta-cogl-drm-formats.h', - 'common/meta-drm-format-helpers.c', - 'common/meta-drm-format-helpers.h', - 'common/meta-drm-timeline.c', - 'common/meta-drm-timeline.h', - ] -endif - if have_wayland_eglstream mutter_sources += [ 'wayland/meta-wayland-egl-stream.c', @@ -1243,7 +1222,7 @@ if have_introspection libmutter_clutter_gir[0], libmutter_mtk_gir[0], ] - if have_x11_client + if have_xwayland libmutter_gir_includes += [ 'xlib-2.0', 'xfixes-4.0', @@ -1280,15 +1259,14 @@ pkg.generate(libmutter, 'apiversion=' + libmutter_api_version, 'girdir=${libdir}/mutter-' + libmutter_api_version, 'typelibdir=${libdir}/mutter-' + libmutter_api_version, - 'have_x11_client=@0@'.format(have_x11_client), - 'have_wayland=@0@'.format(have_wayland), + 'have_xwayland=@0@'.format(have_xwayland), 'have_fonts=@0@'.format(have_fonts), ], install_dir: pcdir, ) subdir('compositor/plugins') -if have_x11_client +if have_xwayland subdir('frames') endif diff --git a/src/meta/meson.build b/src/meta/meson.build index bc42b56174c..81950998da5 100644 --- a/src/meta/meson.build +++ b/src/meta/meson.build @@ -41,6 +41,9 @@ mutter_public_headers = [ 'meta-sound-player.h', 'meta-stage.h', 'meta-startup-notification.h', + 'meta-wayland-client.h', + 'meta-wayland-compositor.h', + 'meta-wayland-surface.h', 'meta-window-actor.h', 'meta-window-config.h', 'meta-window-group.h', @@ -52,15 +55,7 @@ mutter_public_headers = [ 'workspace.h', ] -if have_wayland - mutter_public_headers += [ - 'meta-wayland-client.h', - 'meta-wayland-compositor.h', - 'meta-wayland-surface.h', - ] -endif - -if have_x11_client +if have_xwayland mutter_public_headers += [ 'meta-x11-display.h', 'meta-x11-types.h', diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c index b17093f8b98..76c0dd63f82 100644 --- a/src/wayland/meta-wayland-data-device.c +++ b/src/wayland/meta-wayland-data-device.c @@ -50,7 +50,7 @@ #include "wayland/meta-wayland-toplevel-drag.h" #include "wayland/meta-wayland-types.h" -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND #include "wayland/meta-xwayland-dnd-private.h" #endif @@ -233,7 +233,7 @@ meta_wayland_drag_grab_set_cursor (MetaWaylandDragGrab *drag_grab, g_autoptr (MetaCursorSprite) cursor_sprite = NULL; MetaCursorRenderer *cursor_renderer; -#ifdef HAVE_X11_CLIENT +#ifdef HAVE_XWAYLAND /* X11 DnD lets the drag source client drive pointer cursor updates */ if (META_IS_WAYLAND_DATA_SOURCE_XWAYLAND (drag_grab->drag_data_source)) return; -- GitLab From b4348951ec9f0ea8d043c7bb9536a90c8d3904cf Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Wed, 5 Nov 2025 11:44:23 +0100 Subject: [PATCH 4/8] Drop is_wayland_compositor checks As we will always be running as one. Part-of: --- src/backends/meta-backend.c | 10 +-- src/backends/meta-cursor-sprite-xcursor.c | 24 ++---- src/backends/meta-stage.c | 9 +-- src/compositor/meta-surface-actor-wayland.c | 2 - src/compositor/meta-window-actor-x11.c | 2 - src/compositor/plugins/default.c | 3 +- src/core/display-private.h | 3 - src/core/display.c | 10 +-- src/core/events.c | 3 +- src/core/meta-context.c | 2 - src/core/meta-gesture-tracker.c | 23 ++---- src/core/util-private.h | 2 - src/core/util.c | 13 ---- src/core/window.c | 2 +- src/meta/util.h | 3 - src/tests/meta-test-utils.c | 1 - src/tests/xwayland-tests.c | 1 - src/wayland/meta-wayland-client.c | 7 +- src/x11/events.c | 45 +---------- src/x11/meta-x11-display.c | 45 +---------- src/x11/window-x11.c | 84 +-------------------- 21 files changed, 34 insertions(+), 260 deletions(-) diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index 7ef79d5cb11..5aac2863060 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -431,12 +431,7 @@ determine_hotplug_pointer_visibility (ClutterSeat *seat) if (device_type == CLUTTER_TABLET_DEVICE || device_type == CLUTTER_PEN_DEVICE || device_type == CLUTTER_ERASER_DEVICE) - { - if (meta_is_wayland_compositor ()) - has_tablet = TRUE; - else - has_pointer = TRUE; - } + has_tablet = TRUE; } return has_pointer && !has_touchscreen && !has_tablet; @@ -1151,8 +1146,7 @@ update_pointer_visibility_from_event (MetaBackend *backend, case CLUTTER_PEN_DEVICE: case CLUTTER_ERASER_DEVICE: case CLUTTER_CURSOR_DEVICE: - if (meta_is_wayland_compositor () && - time_ms > priv->last_pointer_motion + HIDDEN_POINTER_TIMEOUT) + if (time_ms > priv->last_pointer_motion + HIDDEN_POINTER_TIMEOUT) set_cursor_visible (backend, FALSE); break; case CLUTTER_KEYBOARD_DEVICE: diff --git a/src/backends/meta-cursor-sprite-xcursor.c b/src/backends/meta-cursor-sprite-xcursor.c index 85bd49da4f1..b1b877d2a10 100644 --- a/src/backends/meta-cursor-sprite-xcursor.c +++ b/src/backends/meta-cursor-sprite-xcursor.c @@ -382,20 +382,13 @@ load_from_current_xcursor_image (MetaCursorSpriteXcursor *sprite_xcursor) g_error_free (error); } - if (meta_is_wayland_compositor ()) - { - hotspot_x = ((int) roundf ((float) xc_image->xhot / - sprite_xcursor->theme_scale) * - sprite_xcursor->theme_scale); - hotspot_y = ((int) roundf ((float) xc_image->yhot / - sprite_xcursor->theme_scale) * - sprite_xcursor->theme_scale); - } - else - { - hotspot_x = xc_image->xhot; - hotspot_y = xc_image->yhot; - } + hotspot_x = ((int) roundf ((float) xc_image->xhot / + sprite_xcursor->theme_scale) * + sprite_xcursor->theme_scale); + hotspot_y = ((int) roundf ((float) xc_image->yhot / + sprite_xcursor->theme_scale) * + sprite_xcursor->theme_scale); + meta_cursor_sprite_set_texture (sprite, texture, hotspot_x, hotspot_y); @@ -543,9 +536,6 @@ meta_cursor_sprite_xcursor_prepare_at (MetaCursorSprite *sprite, MetaBackend *backend = meta_cursor_tracker_get_backend (cursor_tracker); - if (!meta_is_wayland_compositor ()) - return; - if (meta_backend_is_stage_views_scaled (backend)) { if (best_scale != 0.0f) diff --git a/src/backends/meta-stage.c b/src/backends/meta-stage.c index 34add204ba9..1ff5aae911a 100644 --- a/src/backends/meta-stage.c +++ b/src/backends/meta-stage.c @@ -364,12 +364,9 @@ meta_stage_init (MetaStage *stage) for (i = 0; i < META_N_WATCH_MODES; i++) stage->watchers[i] = g_ptr_array_new_with_free_func (g_free); - if (meta_is_wayland_compositor ()) - { - g_signal_connect (stage, - "notify::key-focus", - G_CALLBACK (key_focus_actor_changed), NULL); - } + g_signal_connect (stage, + "notify::key-focus", + G_CALLBACK (key_focus_actor_changed), NULL); } ClutterActor * diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c index dbde5d59bd4..a6acaf9a7dd 100644 --- a/src/compositor/meta-surface-actor-wayland.c +++ b/src/compositor/meta-surface-actor-wayland.c @@ -317,8 +317,6 @@ meta_surface_actor_wayland_new (MetaWaylandSurface *surface) "accessible-name", "Wayland surface", NULL); - g_assert (meta_is_wayland_compositor ()); - self->surface = surface; g_object_weak_ref (G_OBJECT (self->surface), on_surface_disposed, diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c index c31e25e46bb..b5e43c541ba 100644 --- a/src/compositor/meta-window-actor-x11.c +++ b/src/compositor/meta-window-actor-x11.c @@ -289,8 +289,6 @@ meta_window_actor_x11_assign_surface_actor (MetaWindowActor *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)); diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c index f5e06845884..4939c81e336 100644 --- a/src/compositor/plugins/default.c +++ b/src/compositor/plugins/default.c @@ -453,8 +453,7 @@ start (MetaPlugin *plugin) G_CALLBACK (prepare_shutdown), self); - if (meta_is_wayland_compositor ()) - init_keymap (self, backend); + init_keymap (self, backend); clutter_actor_show (meta_backend_get_stage (backend)); } diff --git a/src/core/display-private.h b/src/core/display-private.h index 74578d85b7b..b5def18e244 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -329,6 +329,3 @@ void meta_display_handle_window_enter (MetaDisplay *display, uint32_t timestamp_ms, int root_x, int root_y); - -void meta_display_handle_window_leave (MetaDisplay *display, - MetaWindow *window); diff --git a/src/core/display.c b/src/core/display.c index cb3ae667d4f..b5bab526e1a 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1283,7 +1283,7 @@ meta_display_get_current_time (MetaDisplay *display) guint32 meta_display_get_current_time_roundtrip (MetaDisplay *display) { - if (meta_is_wayland_compositor ()) + if (!display->x11_display) /* Xwayland uses monotonic clock, so lets use it here as well */ return (guint32) (g_get_monotonic_time () / 1000); else @@ -3687,11 +3687,3 @@ meta_display_handle_window_enter (MetaDisplay *display, if (window && window->type == META_WINDOW_DOCK) meta_window_raise (window); } - -void -meta_display_handle_window_leave (MetaDisplay *display, - MetaWindow *window) -{ - if (window && window->type == META_WINDOW_DOCK && !window->has_focus) - meta_window_lower (window); -} diff --git a/src/core/events.c b/src/core/events.c index 897493f0891..52203494960 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -343,8 +343,7 @@ meta_display_handle_event (MetaDisplay *display, return CLUTTER_EVENT_PROPAGATE; } - if (meta_is_wayland_compositor () && - event_type == CLUTTER_SCROLL && + if (event_type == CLUTTER_SCROLL && meta_prefs_get_mouse_button_mods () > 0) { ClutterModifierType grab_mods; diff --git a/src/core/meta-context.c b/src/core/meta-context.c index c6ce70067c3..73f61e78d11 100644 --- a/src/core/meta-context.c +++ b/src/core/meta-context.c @@ -383,8 +383,6 @@ meta_context_configure (MetaContext *context, priv->profiler = meta_profiler_new (priv->trace_file); #endif - meta_set_is_wayland_compositor (TRUE); - priv->state = META_CONTEXT_STATE_CONFIGURED; return TRUE; diff --git a/src/core/meta-gesture-tracker.c b/src/core/meta-gesture-tracker.c index 5919005e91b..5f426fa8f0b 100644 --- a/src/core/meta-gesture-tracker.c +++ b/src/core/meta-gesture-tracker.c @@ -220,23 +220,12 @@ static gboolean state_is_applicable (MetaSequenceState prev_state, MetaSequenceState state) { - - if (meta_is_wayland_compositor ()) - { - /* Never reject sequences on Wayland, on Wayland we deliver touch events - * to clients right away and can cancel them later when accepting a - * sequence. - */ - if (state == META_SEQUENCE_REJECTED) - return FALSE; - } - else - { - /* Sequences must be accepted/denied before PENDING_END */ - if (prev_state == META_SEQUENCE_NONE && - state == META_SEQUENCE_PENDING_END) - return FALSE; - } + /* Never reject sequences on Wayland, on Wayland we deliver touch events + * to clients right away and can cancel them later when accepting a + * sequence. + */ + if (state == META_SEQUENCE_REJECTED) + return FALSE; /* PENDING_END state is final */ if (prev_state == META_SEQUENCE_PENDING_END) diff --git a/src/core/util-private.h b/src/core/util-private.h index bf1dac6f05f..5ab888053f9 100644 --- a/src/core/util-private.h +++ b/src/core/util-private.h @@ -34,8 +34,6 @@ void meta_set_verbose (gboolean setting); -void meta_set_is_wayland_compositor (gboolean setting); - char * meta_generate_random_id (GRand *rand, int length); diff --git a/src/core/util.c b/src/core/util.c index 85f956e9e47..066cde2d4df 100644 --- a/src/core/util.c +++ b/src/core/util.c @@ -83,7 +83,6 @@ typedef struct _MetaReadBytesContext } MetaReadBytesContext; static gint verbose_topics = 0; -static gboolean is_wayland_compositor = FALSE; static int debug_paint_flags = 0; static GLogLevelFlags mutter_log_level = G_LOG_LEVEL_MESSAGE; @@ -226,18 +225,6 @@ meta_init_debug_utils (void) mutter_log_level = G_LOG_LEVEL_DEBUG; } -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) diff --git a/src/core/window.c b/src/core/window.c index b736fe89f0c..c900f6f3f4f 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -7582,7 +7582,7 @@ window_has_pointer_wayland (MetaWindow *window) gboolean meta_window_has_pointer (MetaWindow *window) { - if (meta_is_wayland_compositor ()) + if (meta_window_get_client_type (window) == META_WINDOW_CLIENT_TYPE_WAYLAND) return window_has_pointer_wayland (window); #ifdef HAVE_XWAYLAND else diff --git a/src/meta/util.h b/src/meta/util.h index cf570633954..b1601d3fc80 100644 --- a/src/meta/util.h +++ b/src/meta/util.h @@ -32,9 +32,6 @@ META_EXPORT gboolean meta_is_verbose (void); -META_EXPORT -gboolean meta_is_wayland_compositor (void); - META_EXPORT void meta_bug (const char *format, ...) G_GNUC_PRINTF (1, 2); diff --git a/src/tests/meta-test-utils.c b/src/tests/meta-test-utils.c index 6d1d16e5734..c47862b0c46 100644 --- a/src/tests/meta-test-utils.c +++ b/src/tests/meta-test-utils.c @@ -656,7 +656,6 @@ meta_test_client_new (MetaContext *context, launcher = g_subprocess_launcher_new ((G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE)); - g_assert_true (meta_is_wayland_compositor ()); compositor = meta_context_get_wayland_compositor (context); wayland_display_name = meta_wayland_get_wayland_display_name (compositor); #ifdef HAVE_XWAYLAND diff --git a/src/tests/xwayland-tests.c b/src/tests/xwayland-tests.c index fa5e36779b7..5f050e22345 100644 --- a/src/tests/xwayland-tests.c +++ b/src/tests/xwayland-tests.c @@ -272,7 +272,6 @@ meta_test_xwayland_compositor_selection (void) g_assert_null (meta_display_get_x11_display (display)); - g_assert_true (meta_is_wayland_compositor ()); compositor = meta_context_get_wayland_compositor (test_context); x11_display_name = meta_wayland_get_public_xwayland_display_name (compositor); g_assert_nonnull (x11_display_name); diff --git a/src/wayland/meta-wayland-client.c b/src/wayland/meta-wayland-client.c index 59b53550cf7..b433742f16c 100644 --- a/src/wayland/meta-wayland-client.c +++ b/src/wayland/meta-wayland-client.c @@ -20,7 +20,7 @@ /** * MetaWaylandClient: - * + * * A class that allows to launch a trusted client and detect if an specific * Wayland window belongs to it. */ @@ -167,8 +167,6 @@ meta_wayland_client_new_create (MetaContext *context, int client_fd[2]; MetaWaylandClient *client; - g_return_val_if_fail (meta_is_wayland_compositor (), NULL); - if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, client_fd) < 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, @@ -232,7 +230,6 @@ meta_wayland_client_new_subprocess (MetaContext *context, argv[0][0] != '\0', NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); - g_return_val_if_fail (meta_is_wayland_compositor (), NULL); if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, client_fd) < 0) { @@ -358,7 +355,7 @@ meta_wayland_client_owns_window (MetaWaylandClient *client, MetaWindowWayland *wl_window; MetaWaylandClient *window_client; - g_return_val_if_fail (meta_is_wayland_compositor (), FALSE); + g_return_val_if_fail (client->subprocess.subprocess != NULL, FALSE); if (!META_IS_WINDOW_WAYLAND (window)) return FALSE; diff --git a/src/x11/events.c b/src/x11/events.c index 857c6f2f7ff..bd51be46e58 100644 --- a/src/x11/events.c +++ b/src/x11/events.c @@ -932,9 +932,6 @@ handle_input_xevent (MetaX11Display *x11_display, MetaWindow *window; MetaDisplay *display = x11_display->display; MetaWorkspaceManager *workspace_manager = display->workspace_manager; - MetaContext *context = meta_display_get_context (display); - MetaBackend *backend = meta_context_get_backend (context); - ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); if (input_event == NULL) return FALSE; @@ -957,38 +954,6 @@ handle_input_xevent (MetaX11Display *x11_display, switch (input_event->evtype) { - case XI_Enter: - if (clutter_stage_get_grab_actor (stage) != NULL) - break; - - /* Check if we've entered a window; do this even if window->has_focus to - * avoid races. - */ - if (window && - enter_event->mode != XINotifyGrab && - enter_event->mode != XINotifyUngrab && - enter_event->detail != XINotifyInferior && - !meta_is_wayland_compositor () && - enter_event->sourceid != enter_event->deviceid) - { - meta_display_handle_window_enter (display, - window, - enter_event->time, - (int) enter_event->root_x, - (int) enter_event->root_y); - } - break; - case XI_Leave: - if (clutter_stage_get_grab_actor (stage) != NULL) - break; - - if (window != NULL && - enter_event->mode != XINotifyGrab && - enter_event->mode != XINotifyUngrab) - { - meta_display_handle_window_leave (display, window); - } - break; case XI_FocusIn: case XI_FocusOut: if (handle_window_focus_event (x11_display, window, enter_event, serial) && @@ -1652,10 +1617,9 @@ handle_other_xevent (MetaX11Display *x11_display, 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); + g_object_set (G_OBJECT (window), + "xwayland-may-grab-keyboard", (event->xclient.data.l[0] != 0), + NULL); } else #endif @@ -1892,8 +1856,7 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display, #ifdef HAVE_XWAYLAND wayland_compositor = meta_context_get_wayland_compositor (context); - if (meta_is_wayland_compositor () && - meta_xwayland_manager_handle_xevent (&wayland_compositor->xwayland_manager, + if (meta_xwayland_manager_handle_xevent (&wayland_compositor->xwayland_manager, event)) { bypass_compositor = TRUE; diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index fd493a9a01f..5829918e36c 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -381,32 +381,7 @@ static void on_x11_display_opened (MetaX11Display *x11_display, MetaDisplay *display) { - Window old_active_xwindow = None; - - if (!meta_is_wayland_compositor ()) - { - meta_prop_get_window (display->x11_display, - display->x11_display->xroot, - display->x11_display->atom__NET_ACTIVE_WINDOW, - &old_active_xwindow); - } - meta_display_manage_all_xwindows (display); - - if (old_active_xwindow != None) - { - MetaWindow *old_active_window; - - old_active_window = meta_x11_display_lookup_x_window (x11_display, - old_active_xwindow); - if (old_active_window) - { - uint32_t timestamp; - - timestamp = display->x11_display->timestamp; - meta_window_focus (old_active_window, timestamp); - } - } } static void @@ -841,10 +816,6 @@ take_manager_selection (MetaX11Display *x11_display, { XEvent event; -#ifdef HAVE_XWAYLAND - g_return_val_if_fail (!meta_is_wayland_compositor (), new_owner); -#endif - /* We sort of block infinitely here which is probably lame. */ meta_topic (META_DEBUG_X11, "Waiting for old window manager to exit"); @@ -1344,13 +1315,10 @@ meta_x11_display_new (MetaDisplay *display, return NULL; #ifdef HAVE_XWAYLAND - if (meta_is_wayland_compositor ()) - { - MetaWaylandCompositor *compositor = - meta_context_get_wayland_compositor (context); + MetaWaylandCompositor *compositor = + meta_context_get_wayland_compositor (context); - meta_xwayland_setup_xdisplay (&compositor->xwayland_manager, xdisplay); - } + meta_xwayland_setup_xdisplay (&compositor->xwayland_manager, xdisplay); #endif number = DefaultScreen (xdisplay); @@ -1473,11 +1441,6 @@ meta_x11_display_new (MetaDisplay *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); - /* Handle creating a no_focus_window for this screen */ x11_display->no_focus_window = meta_x11_display_create_offscreen_window (x11_display, @@ -2070,7 +2033,7 @@ meta_x11_display_update_active_window_hint (MetaX11Display *x11_display) if (focus_window) data[0] = meta_window_x11_get_xwindow (focus_window); #ifdef HAVE_XWAYLAND - else if (x11_display->focus_xwindow && meta_is_wayland_compositor ()) + else if (x11_display->focus_xwindow) /* On Wayland, when a Wayland window is focused, indicate that an * actual window is focused rather than None, as None is otherwise * also used during transient focus changes. diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 4309d74c81e..de36f444538 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -3095,27 +3095,6 @@ meta_window_x11_property_notify (MetaWindow *window, #define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 #define _NET_WM_MOVERESIZE_CANCEL 11 -static int -query_pressed_buttons (MetaWindow *window) -{ - MetaContext *context = meta_display_get_context (window->display); - MetaBackend *backend = meta_context_get_backend (context); - MetaCursorTracker *tracker = meta_backend_get_cursor_tracker (backend); - 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) @@ -3555,25 +3534,10 @@ meta_window_x11_client_message (MetaWindow *window, (op != META_GRAB_OP_MOVING && op != META_GRAB_OP_KEYBOARD_MOVING)))) { - MetaContext *context = meta_display_get_context (display); - MetaBackend *backend = meta_context_get_backend (context); - ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); ClutterSprite *sprite = NULL; - int button_mask; -#ifdef HAVE_XWAYLAND - if (meta_is_wayland_compositor ()) - { - if (!guess_nearest_device (window, x_root, y_root, button, &sprite)) - return FALSE; - } - else -#endif - { - sprite = clutter_backend_get_pointer_sprite (clutter_backend, - stage); - } + if (!guess_nearest_device (window, x_root, y_root, button, &sprite)) + return FALSE; g_assert (sprite); meta_topic (META_DEBUG_WINDOW_OPS, @@ -3582,50 +3546,6 @@ meta_window_x11_client_message (MetaWindow *window, sprite, timestamp, &GRAPHENE_POINT_INIT (x_root, y_root)); - - window_drag = - meta_compositor_get_current_window_drag (window->display->compositor); - -#ifdef HAVE_XWAYLAND - if (!meta_is_wayland_compositor ()) -#endif - { - 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_drag) - meta_window_drag_end (window_drag); - } - 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 (window_drag && (button_mask & (1 << button)) == 0) - meta_window_drag_end (window_drag); - } - } } return TRUE; -- GitLab From 2ae09598d48716a402149b8d968d58915e4b49cc Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Tue, 24 Jun 2025 21:30:17 +0200 Subject: [PATCH 5/8] cogl: Remove no longer useful DriverConstraints Can be re-added later once there is work to add a Vulkan driver for example but for now, it just extra work for once we start migrating to GObjects. Part-of: --- cogl/cogl/cogl-texture-2d.c | 4 ---- cogl/cogl/driver/gl/cogl-texture-2d-gl.c | 4 ---- cogl/cogl/winsys/cogl-winsys-egl.c | 2 -- cogl/cogl/winsys/cogl-winsys-private.h | 26 ------------------------ 4 files changed, 36 deletions(-) diff --git a/cogl/cogl/cogl-texture-2d.c b/cogl/cogl/cogl-texture-2d.c index f06255d185d..3e62c5da546 100644 --- a/cogl/cogl/cogl-texture-2d.c +++ b/cogl/cogl/cogl-texture-2d.c @@ -473,10 +473,6 @@ cogl_texture_2d_new_from_egl_image (CoglContext *ctx, CoglTextureLoader *loader; CoglTexture *tex; - g_return_val_if_fail (_cogl_context_get_winsys (ctx)->constraints & - COGL_RENDERER_CONSTRAINT_USES_EGL, - NULL); - g_return_val_if_fail (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE), diff --git a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c index da86b1c4b5b..90c017ca0ef 100644 --- a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c +++ b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c @@ -83,10 +83,6 @@ cogl_texture_2d_new_from_egl_image_external (CoglContext *ctx, CoglTexture2D *tex_2d; CoglPixelFormat internal_format = COGL_PIXEL_FORMAT_ANY; - g_return_val_if_fail (_cogl_context_get_winsys (ctx)->constraints & - COGL_RENDERER_CONSTRAINT_USES_EGL, - NULL); - g_return_val_if_fail (cogl_context_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL), NULL); diff --git a/cogl/cogl/winsys/cogl-winsys-egl.c b/cogl/cogl/winsys/cogl-winsys-egl.c index 5daeacf5a82..4b34f4ef5e2 100644 --- a/cogl/cogl/winsys/cogl-winsys-egl.c +++ b/cogl/cogl/winsys/cogl-winsys-egl.c @@ -562,8 +562,6 @@ _cogl_winsys_update_sync (CoglContext *context) static CoglWinsysVtable _cogl_winsys_vtable = { - .constraints = COGL_RENDERER_CONSTRAINT_USES_EGL, - /* This winsys is only used as a base for the EGL-platform winsys's so it does not have an ID or a name */ diff --git a/cogl/cogl/winsys/cogl-winsys-private.h b/cogl/cogl/winsys/cogl-winsys-private.h index d14592c5d07..98702e29678 100644 --- a/cogl/cogl/winsys/cogl-winsys-private.h +++ b/cogl/cogl/winsys/cogl-winsys-private.h @@ -47,36 +47,10 @@ typedef enum /*< prefix=COGL_WINSYS_ERROR >*/ COGL_WINSYS_ERROR_MAKE_CURRENT, } CoglWinsysError; -/** - * CoglRendererConstraint: - * @COGL_RENDERER_CONSTRAINT_USES_X11: Require the renderer to be X11 based - * @COGL_RENDERER_CONSTRAINT_USES_XLIB: Require the renderer to be X11 - * based and use Xlib - * @COGL_RENDERER_CONSTRAINT_USES_EGL: Require the renderer to be EGL based - * - * These constraint flags are hard-coded features of the different renderer - * backends. Sometimes a platform may support multiple rendering options which - * Cogl will usually choose from automatically. Some of these features are - * important to higher level applications and frameworks though, such as - * whether a renderer is X11 based because an application might only support - * X11 based input handling. An application might also need to ensure EGL is - * used internally too if they depend on access to an EGLDisplay for some - * purpose. - * - * Applications should ideally minimize how many of these constraints - * they depend on to ensure maximum portability. - */ -typedef enum -{ - COGL_RENDERER_CONSTRAINT_USES_X11 = (1 << 0), - COGL_RENDERER_CONSTRAINT_USES_XLIB = (1 << 1), - COGL_RENDERER_CONSTRAINT_USES_EGL = (1 << 2), -} CoglRendererConstraint; typedef struct _CoglWinsysVtable { CoglWinsysID id; - CoglRendererConstraint constraints; const char *name; -- GitLab From 4bdb279ebd0e118b13589190c70fa177b08e7ccb Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Fri, 27 Jun 2025 13:24:07 +0200 Subject: [PATCH 6/8] x11: Remove no longer useful HAVE_XWAYLAND As src/x11 is only build for xwayland nowadays. Part-of: --- src/x11/events.c | 9 --------- src/x11/meta-x11-display.c | 37 ++++++++----------------------------- src/x11/window-x11.c | 8 +------- 3 files changed, 9 insertions(+), 45 deletions(-) diff --git a/src/x11/events.c b/src/x11/events.c index bd51be46e58..88ae8bc81bb 100644 --- a/src/x11/events.c +++ b/src/x11/events.c @@ -51,12 +51,9 @@ #include "x11/window-x11.h" #include "x11/window-x11-private.h" #include "x11/xprops.h" - -#ifdef HAVE_XWAYLAND #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, @@ -1608,7 +1605,6 @@ handle_other_xevent (MetaX11Display *x11_display, case ClientMessage: if (window) { -#ifdef HAVE_XWAYLAND if (event->xclient.message_type == x11_display->atom_WL_SURFACE_ID) { guint32 surface_id = event->xclient.data.l[0]; @@ -1622,7 +1618,6 @@ handle_other_xevent (MetaX11Display *x11_display, NULL); } else -#endif meta_window_x11_client_message (window, event); } else @@ -1831,9 +1826,7 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display, MetaContext *context = meta_display_get_context (display); gboolean bypass_compositor G_GNUC_UNUSED = FALSE; XIEvent *input_event; -#ifdef HAVE_XWAYLAND MetaWaylandCompositor *wayland_compositor; -#endif COGL_TRACE_BEGIN_SCOPED (MetaX11DisplayHandleXevent, "Meta::X11Display::handle_xevent()"); @@ -1853,7 +1846,6 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display, goto out; } -#ifdef HAVE_XWAYLAND wayland_compositor = meta_context_get_wayland_compositor (context); if (meta_xwayland_manager_handle_xevent (&wayland_compositor->xwayland_manager, @@ -1862,7 +1854,6 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display, bypass_compositor = TRUE; goto out; } -#endif if (process_selection_event (x11_display, event)) { diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index 5829918e36c..6113e0d7a7f 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -64,10 +64,7 @@ #include "x11/window-props.h" #include "x11/window-x11.h" #include "x11/xprops.h" - -#ifdef HAVE_XWAYLAND #include "wayland/meta-xwayland-private.h" -#endif #include "meta-dbus-x11.h" @@ -140,14 +137,12 @@ stage_to_protocol (MetaX11Display *x11_display, MetaContext *context = meta_display_get_context (display); int scale = 1; -#ifdef HAVE_XWAYLAND MetaWaylandCompositor *wayland_compositor = meta_context_get_wayland_compositor (context); MetaXWaylandManager *xwayland_manager = &wayland_compositor->xwayland_manager; scale = meta_xwayland_get_effective_scale (xwayland_manager); -#endif if (protocol_x) *protocol_x = stage_x * scale; @@ -206,17 +201,12 @@ update_ui_scaling_factor (MetaX11Display *x11_display) meta_x11_display_get_instance_private (x11_display); MetaBackend *backend = backend_from_x11_display (x11_display); MetaContext *context = meta_backend_get_context (backend); - int ui_scaling_factor = 1; - - -#ifdef HAVE_XWAYLAND MetaWaylandCompositor *wayland_compositor = meta_context_get_wayland_compositor (context); MetaXWaylandManager *xwayland_manager = &wayland_compositor->xwayland_manager; - - ui_scaling_factor = meta_xwayland_get_x11_ui_scaling_factor (xwayland_manager); -#endif + int ui_scaling_factor = + meta_xwayland_get_x11_ui_scaling_factor (xwayland_manager); meta_dbus_x11_set_ui_scaling_factor (priv->dbus_api, ui_scaling_factor); } @@ -1122,7 +1112,6 @@ set_work_area_hint (MetaDisplay *display, static const char * get_display_name (MetaDisplay *display) { -#ifdef HAVE_XWAYLAND MetaContext *context = meta_display_get_context (display); MetaWaylandCompositor *compositor = meta_context_get_wayland_compositor (context); @@ -1130,7 +1119,6 @@ get_display_name (MetaDisplay *display) if (compositor) return meta_wayland_get_private_xwayland_display_name (compositor); else -#endif return g_getenv ("DISPLAY"); } @@ -1291,6 +1279,8 @@ meta_x11_display_new (MetaDisplay *display, MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend); MetaSettings *settings = meta_backend_get_settings (backend); + MetaWaylandCompositor *compositor = + meta_context_get_wayland_compositor (context); g_autoptr (MetaX11Display) x11_display = NULL; Display *xdisplay; Screen *xscreen; @@ -1314,12 +1304,7 @@ meta_x11_display_new (MetaDisplay *display, if (!xdisplay) return NULL; -#ifdef HAVE_XWAYLAND - MetaWaylandCompositor *compositor = - meta_context_get_wayland_compositor (context); - meta_xwayland_setup_xdisplay (&compositor->xwayland_manager, xdisplay); -#endif number = DefaultScreen (xdisplay); @@ -1774,18 +1759,14 @@ update_cursor_theme (MetaX11Display *x11_display) { MetaBackend *backend = backend_from_x11_display (x11_display); MetaContext *context = meta_backend_get_context (backend); - int scale = 1; - int size; - const char *theme; - -#ifdef HAVE_XWAYLAND MetaWaylandCompositor *wayland_compositor = meta_context_get_wayland_compositor (context); MetaXWaylandManager *xwayland_manager = &wayland_compositor->xwayland_manager; - - scale = meta_xwayland_get_x11_ui_scaling_factor (xwayland_manager); -#endif + int scale = + meta_xwayland_get_x11_ui_scaling_factor (xwayland_manager); + int size; + const char *theme; size = meta_prefs_get_cursor_size () * scale; @@ -2032,14 +2013,12 @@ meta_x11_display_update_active_window_hint (MetaX11Display *x11_display) if (focus_window) data[0] = meta_window_x11_get_xwindow (focus_window); -#ifdef HAVE_XWAYLAND else if (x11_display->focus_xwindow) /* On Wayland, when a Wayland window is focused, indicate that an * actual window is focused rather than None, as None is otherwise * also used during transient focus changes. */ data[0] = x11_display->no_focus_window; -#endif else data[0] = None; diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index de36f444538..eb5ba269e47 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -47,17 +47,13 @@ #include "meta/meta-later.h" #include "meta/prefs.h" #include "mtk/mtk-x11.h" - -#ifdef HAVE_XWAYLAND -#include "wayland/meta-window-xwayland.h" -#endif - #include "x11/meta-sync-counter.h" #include "x11/meta-x11-display-private.h" #include "x11/meta-x11-frame.h" #include "x11/meta-x11-group-private.h" #include "x11/window-props.h" #include "x11/xprops.h" +#include "wayland/meta-window-xwayland.h" #define TAKE_FOCUS_FALLBACK_DELAY_MS 150 @@ -3119,7 +3115,6 @@ handle_net_restack_window (MetaDisplay *display, } } -#ifdef HAVE_XWAYLAND typedef struct { ClutterSprite *sprite; graphene_point_t device_point; @@ -3194,7 +3189,6 @@ guess_nearest_device (MetaWindow *window, return data.sprite != NULL; } -#endif /* HAVE_XWAYLAND */ gboolean meta_window_x11_client_message (MetaWindow *window, -- GitLab From c85f31b598e44f1f9e459355e56fad4871fce3c1 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Tue, 4 Nov 2025 10:18:54 +0100 Subject: [PATCH 7/8] cogl: Remove no longer useful WinsysID As the only winsys we have is a custom one anyways. Part-of: --- cogl/cogl/cogl-context.h | 2 -- cogl/cogl/cogl-renderer.c | 8 ----- cogl/cogl/cogl-renderer.h | 35 ---------------------- cogl/cogl/winsys/cogl-winsys-private.h | 2 -- src/backends/native/meta-renderer-native.c | 1 - 5 files changed, 48 deletions(-) diff --git a/cogl/cogl/cogl-context.h b/cogl/cogl/cogl-context.h index 4bce391c409..1eeb04b476f 100644 --- a/cogl/cogl/cogl-context.h +++ b/cogl/cogl/cogl-context.h @@ -388,8 +388,6 @@ cogl_context_get_rectangle_indices (CoglContext *context, * handle that was setup internally. The result is undefined if Cogl * is not using EGL. * - * Note: The current window system backend can be checked using - * cogl_renderer_get_winsys_id(). * * Return value: The internally setup EGLDisplay handle. */ diff --git a/cogl/cogl/cogl-renderer.c b/cogl/cogl/cogl-renderer.c index a468fd2d42d..0d14eb18e57 100644 --- a/cogl/cogl/cogl-renderer.c +++ b/cogl/cogl/cogl-renderer.c @@ -403,14 +403,6 @@ cogl_renderer_connect (CoglRenderer *renderer, GError **error) return TRUE; } -CoglWinsysID -cogl_renderer_get_winsys_id (CoglRenderer *renderer) -{ - g_return_val_if_fail (renderer->connected, 0); - - return renderer->winsys_vtable->id; -} - void * cogl_renderer_get_proc_address (CoglRenderer *renderer, const char *name) diff --git a/cogl/cogl/cogl-renderer.h b/cogl/cogl/cogl-renderer.h index b52562a7f67..51c9bc4e4f9 100644 --- a/cogl/cogl/cogl-renderer.h +++ b/cogl/cogl/cogl-renderer.h @@ -125,41 +125,6 @@ cogl_renderer_new (void); /* optional configuration APIs */ -/** - * CoglWinsysID: - * @COGL_WINSYS_ID_ANY: Implies no preference for which backend is used - * @COGL_WINSYS_ID_STUB: Use the no-op stub backend - * @COGL_WINSYS_ID_GLX: Use the GLX window system binding API - * @COGL_WINSYS_ID_EGL_XLIB: Use EGL with the X window system via XLib - * - * Identifies specific window system backends that Cogl supports. - * - * These can be used to query what backend Cogl is using or to try and - * explicitly select a backend to use. - */ -typedef enum -{ - COGL_WINSYS_ID_ANY, - COGL_WINSYS_ID_STUB, - COGL_WINSYS_ID_GLX, - COGL_WINSYS_ID_EGL_XLIB, - COGL_WINSYS_ID_CUSTOM, -} CoglWinsysID; - -/** - * cogl_renderer_get_winsys_id: - * @renderer: A #CoglRenderer - * - * Queries which window system backend Cogl has chosen to use. - * - * This may only be called on a connected #CoglRenderer. - * - * Returns: The #CoglWinsysID corresponding to the chosen window - * system backend. - */ -COGL_EXPORT CoglWinsysID -cogl_renderer_get_winsys_id (CoglRenderer *renderer); - /* Final connection API */ /** diff --git a/cogl/cogl/winsys/cogl-winsys-private.h b/cogl/cogl/winsys/cogl-winsys-private.h index 98702e29678..c082858f0f5 100644 --- a/cogl/cogl/winsys/cogl-winsys-private.h +++ b/cogl/cogl/winsys/cogl-winsys-private.h @@ -50,8 +50,6 @@ typedef enum /*< prefix=COGL_WINSYS_ERROR >*/ typedef struct _CoglWinsysVtable { - CoglWinsysID id; - const char *name; /* Required functions */ diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 60b8d005c13..eabe20901f0 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -1334,7 +1334,6 @@ get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer) vtable = *_cogl_winsys_egl_get_vtable (); - vtable.id = COGL_WINSYS_ID_CUSTOM; vtable.name = "EGL_KMS"; vtable.renderer_connect = meta_renderer_native_connect; -- GitLab From 3ce48d0153df09e289106c74333d31ca18875039 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Tue, 4 Nov 2025 10:23:47 +0100 Subject: [PATCH 8/8] cogl: Drop X11 specific docs Part-of: --- cogl/cogl/cogl-display.h | 4 ++-- cogl/cogl/cogl-meta-texture.h | 9 ++++----- cogl/cogl/cogl-onscreen.h | 5 ----- cogl/cogl/cogl-renderer.h | 9 ++------- 4 files changed, 8 insertions(+), 19 deletions(-) diff --git a/cogl/cogl/cogl-display.h b/cogl/cogl/cogl-display.h index 3a2d36542ba..a414fff04eb 100644 --- a/cogl/cogl/cogl-display.h +++ b/cogl/cogl/cogl-display.h @@ -57,8 +57,8 @@ G_BEGIN_DECLS * * Another aspect is that display options may constrain or affect how * onscreen framebuffers should later be configured. The original - * rationale for the display object in fact was to let us handle GLX - * and EGLs requirements that framebuffers must be "compatible" with + * rationale for the display object in fact was to let us handle EGLs + * EGLs requirements that framebuffers must be "compatible" with * the config associated with the current context meaning we have to * force the user to describe how they would like to create their * onscreen windows before we can choose a suitable fbconfig and diff --git a/cogl/cogl/cogl-meta-texture.h b/cogl/cogl/cogl-meta-texture.h index c8a28e07d24..66ba24cbea9 100644 --- a/cogl/cogl/cogl-meta-texture.h +++ b/cogl/cogl/cogl-meta-texture.h @@ -44,9 +44,8 @@ G_BEGIN_DECLS * low-level textures like #CoglTexture2D. * * Cogl helps to make it easy to deal with high level textures such - * as `CoglAtlasTexture`s, `CoglSubTexture`s, - * #CoglTexturePixmapX11 textures and #CoglTexture2DSliced textures - * consistently. + * as `CoglAtlasTexture`s, `CoglSubTexture`s and #CoglTexture2DSliced + * textures consistently. * * A #CoglTexture is a texture that might internally be * represented by one or more low-level `CoglTexture`s @@ -140,8 +139,8 @@ typedef void (*CoglTextureForeachCallback) (CoglTexture *sub_texture, * not directly understood by a GPU and so this API must be used to * manually resolve the underlying textures for drawing. * - * All high level textures (#CoglAtlasTexture, #CoglSubTexture, - * #CoglTexturePixmapX11, and #CoglTexture2DSliced) can be handled + * All high level textures (#CoglAtlasTexture, #CoglSubTexture and + * #CoglTexture2DSliced) can be handled * consistently using this interface which greately simplifies * implementing primitives that support all texture types. * diff --git a/cogl/cogl/cogl-onscreen.h b/cogl/cogl/cogl-onscreen.h index d6cd6b2e0f8..95de5818441 100644 --- a/cogl/cogl/cogl-onscreen.h +++ b/cogl/cogl/cogl-onscreen.h @@ -129,11 +129,6 @@ cogl_onscreen_swap_buffers (CoglOnscreen *onscreen, * * The queried value remains valid until the next buffer swap. * - * One caveat is that under X11 the buffer age does not reflect - * changes to buffer contents caused by the window systems. X11 - * applications must track Expose events to determine what buffer - * regions need to additionally be repaired each frame. - * * The recommended way to take advantage of this buffer age api is to * build up a circular buffer of length 3 for tracking damage regions * over the last 3 frames and when starting a new frame look at the diff --git a/cogl/cogl/cogl-renderer.h b/cogl/cogl/cogl-renderer.h index 51c9bc4e4f9..6f3ce08f2e7 100644 --- a/cogl/cogl/cogl-renderer.h +++ b/cogl/cogl/cogl-renderer.h @@ -52,8 +52,7 @@ typedef enum _CoglDrmModifierFilter * Choosing a means to render * * A #CoglRenderer represents a means to render. It encapsulates the - * selection of an underlying driver, such as OpenGL or OpenGL-ES and - * a selection of a window system binding API such as GLX or EGL. + * selection of an underlying driver, such as OpenGL or OpenGL-ES. * * A #CoglRenderer has two states, "unconnected" and "connected". When * a renderer is first instantiated using cogl_renderer_new() it is @@ -99,11 +98,7 @@ G_DECLARE_FINAL_TYPE (CoglRenderer, * Instantiates a new (unconnected) #CoglRenderer object. A * #CoglRenderer represents a means to render. It encapsulates the * selection of an underlying driver, such as OpenGL or OpenGL-ES and - * a selection of a window system binding API such as GLX or EGL. - * - * There are also some platform specific configuration apis such - * as cogl_xlib_renderer_set_foreign_display() that may also be - * used while the renderer is unconnected. + * a selection of a window system binding API such as EGL. * * Once the renderer has been configured, then it may (optionally) be * explicitly connected using cogl_renderer_connect() which allows -- GitLab