mirror of
https://github.com/brl/mutter.git
synced 2024-12-25 20:32:16 +00:00
backends/native: Add basic KMS abstraction building blocks
The intention with KMS abstraction is to hide away accessing the drm functions behind an API that allows us to have different kind of KMS implementations, including legacy non-atomic and atomic. The intention is also that the code interacting with the drm device should be able to be run in a different thread than the main thread. This means that we need to make sure that all drm*() API usage must only occur from within tasks that eventually can be run in the dedicated thread. The idea here is that MetaKms provides a outward facing API other places of mutter can use (e.g. MetaGpuKms and friends), while MetaKmsImpl is an internal implementation that only gets interacted with via "tasks" posted via the MetaKms object. These tasks will in the future potentially be run on the dedicated KMS thread. Initially, we don't create any new threads. Likewise, MetaKmsDevice is a outward facing representation of a KMS device, while MetaKmsImplDevice is the corresponding implementation, which only runs from within the MetaKmsImpl tasks. This commit only moves opening and closing the device to this new API, while leaking the fd outside of the impl enclosure, effectively making the isolation for drm*() calls pointless. This, however, is necessary to allow gradual porting of drm interaction, and eventually the file descriptor in MetaGpuKms will be removed. For now, it's harmless, since everything still run in the main thread. https://gitlab.gnome.org/GNOME/mutter/issues/548 https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
This commit is contained in:
parent
f3fd7cf92b
commit
fef5753a19
@ -51,6 +51,8 @@
|
||||
#include "backends/native/meta-clutter-backend-native.h"
|
||||
#include "backends/native/meta-cursor-renderer-native.h"
|
||||
#include "backends/native/meta-input-settings-native.h"
|
||||
#include "backends/native/meta-kms.h"
|
||||
#include "backends/native/meta-kms-device.h"
|
||||
#include "backends/native/meta-launcher.h"
|
||||
#include "backends/native/meta-monitor-manager-kms.h"
|
||||
#include "backends/native/meta-renderer-native.h"
|
||||
@ -65,6 +67,7 @@ struct _MetaBackendNative
|
||||
|
||||
MetaLauncher *launcher;
|
||||
MetaUdev *udev;
|
||||
MetaKms *kms;
|
||||
MetaBarrierManagerNative *barrier_manager;
|
||||
|
||||
guint udev_device_added_handler_id;
|
||||
@ -91,6 +94,7 @@ meta_backend_native_finalize (GObject *object)
|
||||
disconnect_udev_device_added_handler (native);
|
||||
|
||||
g_clear_object (&native->udev);
|
||||
g_clear_object (&native->kms);
|
||||
meta_launcher_free (native->launcher);
|
||||
|
||||
G_OBJECT_CLASS (meta_backend_native_parent_class)->finalize (object);
|
||||
@ -523,17 +527,24 @@ create_gpu_from_udev_device (MetaBackendNative *native,
|
||||
GUdevDevice *device,
|
||||
GError **error)
|
||||
{
|
||||
MetaGpuKmsFlag flags = META_GPU_KMS_FLAG_NONE;
|
||||
MetaKmsDeviceFlag flags = META_KMS_DEVICE_FLAG_NONE;
|
||||
const char *device_path;
|
||||
MetaKmsDevice *kms_device;
|
||||
|
||||
if (meta_is_udev_device_platform_device (device))
|
||||
flags |= META_GPU_KMS_FLAG_PLATFORM_DEVICE;
|
||||
flags |= META_KMS_DEVICE_FLAG_PLATFORM_DEVICE;
|
||||
|
||||
if (meta_is_udev_device_boot_vga (device))
|
||||
flags |= META_GPU_KMS_FLAG_BOOT_VGA;
|
||||
flags |= META_KMS_DEVICE_FLAG_BOOT_VGA;
|
||||
|
||||
device_path = g_udev_device_get_device_file (device);
|
||||
return meta_gpu_kms_new (native, device_path, flags, error);
|
||||
|
||||
kms_device = meta_kms_create_device (native->kms, device_path, flags,
|
||||
error);
|
||||
if (!kms_device)
|
||||
return NULL;
|
||||
|
||||
return meta_gpu_kms_new (native, kms_device, error);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -661,6 +672,10 @@ meta_backend_native_initable_init (GInitable *initable,
|
||||
native->udev = meta_udev_new (native);
|
||||
native->barrier_manager = meta_barrier_manager_native_new ();
|
||||
|
||||
native->kms = meta_kms_new (META_BACKEND (native), error);
|
||||
if (!native->kms)
|
||||
return FALSE;
|
||||
|
||||
if (!init_gpus (native, error))
|
||||
return FALSE;
|
||||
|
||||
@ -722,6 +737,12 @@ meta_backend_native_get_udev (MetaBackendNative *native)
|
||||
return native->udev;
|
||||
}
|
||||
|
||||
MetaKms *
|
||||
meta_backend_native_get_kms (MetaBackendNative *native)
|
||||
{
|
||||
return native->kms;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_activate_vt (int vt, GError **error)
|
||||
{
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/native/meta-clutter-backend-native.h"
|
||||
#include "backends/native/meta-kms-types.h"
|
||||
#include "backends/native/meta-launcher.h"
|
||||
#include "backends/native/meta-udev.h"
|
||||
|
||||
@ -44,4 +45,6 @@ MetaLauncher * meta_backend_native_get_launcher (MetaBackendNative *native);
|
||||
|
||||
MetaUdev * meta_backend_native_get_udev (MetaBackendNative *native);
|
||||
|
||||
MetaKms * meta_backend_native_get_kms (MetaBackendNative *native);
|
||||
|
||||
#endif /* META_BACKEND_NATIVE_H */
|
||||
|
@ -37,6 +37,8 @@
|
||||
#include "backends/meta-output.h"
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/native/meta-crtc-kms.h"
|
||||
#include "backends/native/meta-kms-device.h"
|
||||
#include "backends/native/meta-kms.h"
|
||||
#include "backends/native/meta-launcher.h"
|
||||
#include "backends/native/meta-output-kms.h"
|
||||
|
||||
@ -61,9 +63,10 @@ struct _MetaGpuKms
|
||||
{
|
||||
MetaGpu parent;
|
||||
|
||||
MetaKmsDevice *kms_device;
|
||||
|
||||
uint32_t id;
|
||||
int fd;
|
||||
char *file_path;
|
||||
GSource *source;
|
||||
|
||||
clockid_t clock_id;
|
||||
@ -72,8 +75,6 @@ struct _MetaGpuKms
|
||||
unsigned int n_connectors;
|
||||
|
||||
gboolean resources_init_failed_before;
|
||||
|
||||
MetaGpuKmsFlag flags;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaGpuKms, meta_gpu_kms, META_TYPE_GPU)
|
||||
@ -397,7 +398,7 @@ meta_gpu_kms_get_id (MetaGpuKms *gpu_kms)
|
||||
const char *
|
||||
meta_gpu_kms_get_file_path (MetaGpuKms *gpu_kms)
|
||||
{
|
||||
return gpu_kms->file_path;
|
||||
return meta_kms_device_get_path (gpu_kms->kms_device);
|
||||
}
|
||||
|
||||
int64_t
|
||||
@ -428,13 +429,19 @@ meta_gpu_kms_set_power_save_mode (MetaGpuKms *gpu_kms,
|
||||
gboolean
|
||||
meta_gpu_kms_is_boot_vga (MetaGpuKms *gpu_kms)
|
||||
{
|
||||
return !!(gpu_kms->flags & META_GPU_KMS_FLAG_BOOT_VGA);
|
||||
MetaKmsDeviceFlag flags;
|
||||
|
||||
flags = meta_kms_device_get_flags (gpu_kms->kms_device);
|
||||
return !!(flags & META_KMS_DEVICE_FLAG_BOOT_VGA);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_gpu_kms_is_platform_device (MetaGpuKms *gpu_kms)
|
||||
{
|
||||
return !!(gpu_kms->flags & META_GPU_KMS_FLAG_PLATFORM_DEVICE);
|
||||
MetaKmsDeviceFlag flags;
|
||||
|
||||
flags = meta_kms_device_get_flags (gpu_kms->kms_device);
|
||||
return !!(flags & META_KMS_DEVICE_FLAG_PLATFORM_DEVICE);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -869,27 +876,22 @@ meta_gpu_kms_can_have_outputs (MetaGpuKms *gpu_kms)
|
||||
|
||||
MetaGpuKms *
|
||||
meta_gpu_kms_new (MetaBackendNative *backend_native,
|
||||
const char *kms_file_path,
|
||||
MetaGpuKmsFlag flags,
|
||||
MetaKmsDevice *kms_device,
|
||||
GError **error)
|
||||
{
|
||||
MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native);
|
||||
GSource *source;
|
||||
MetaKmsSource *kms_source;
|
||||
MetaGpuKms *gpu_kms;
|
||||
int kms_fd;
|
||||
|
||||
kms_fd = meta_launcher_open_restricted (launcher, kms_file_path, error);
|
||||
if (kms_fd == -1)
|
||||
return NULL;
|
||||
kms_fd = meta_kms_device_leak_fd (kms_device);
|
||||
|
||||
gpu_kms = g_object_new (META_TYPE_GPU_KMS,
|
||||
"backend", backend_native,
|
||||
NULL);
|
||||
|
||||
gpu_kms->flags = flags;
|
||||
gpu_kms->kms_device = kms_device;
|
||||
gpu_kms->fd = kms_fd;
|
||||
gpu_kms->file_path = g_strdup (kms_file_path);
|
||||
|
||||
drmSetClientCap (gpu_kms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
||||
|
||||
@ -912,13 +914,6 @@ static void
|
||||
meta_gpu_kms_finalize (GObject *object)
|
||||
{
|
||||
MetaGpuKms *gpu_kms = META_GPU_KMS (object);
|
||||
MetaBackend *backend = meta_gpu_get_backend (META_GPU (gpu_kms));
|
||||
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||
MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native);
|
||||
|
||||
if (gpu_kms->fd != -1)
|
||||
meta_launcher_close_restricted (launcher, gpu_kms->fd);
|
||||
g_clear_pointer (&gpu_kms->file_path, g_free);
|
||||
|
||||
g_source_destroy (gpu_kms->source);
|
||||
|
||||
|
@ -44,16 +44,8 @@ typedef struct _MetaKmsResources
|
||||
|
||||
typedef void (*MetaKmsFlipCallback) (void *user_data);
|
||||
|
||||
typedef enum _MetaGpuKmsFlag
|
||||
{
|
||||
META_GPU_KMS_FLAG_NONE = 0,
|
||||
META_GPU_KMS_FLAG_BOOT_VGA = (1 << 0),
|
||||
META_GPU_KMS_FLAG_PLATFORM_DEVICE = (1 << 1),
|
||||
} MetaGpuKmsFlag;
|
||||
|
||||
MetaGpuKms * meta_gpu_kms_new (MetaBackendNative *backend_native,
|
||||
const char *kms_file_path,
|
||||
MetaGpuKmsFlag flags,
|
||||
MetaKmsDevice *kms_device,
|
||||
GError **error);
|
||||
|
||||
gboolean meta_gpu_kms_apply_crtc_mode (MetaGpuKms *gpu_kms,
|
||||
|
185
src/backends/native/meta-kms-device.c
Normal file
185
src/backends/native/meta-kms-device.c
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/native/meta-kms-device.h"
|
||||
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/native/meta-kms-impl-device.h"
|
||||
#include "backends/native/meta-kms-impl.h"
|
||||
#include "backends/native/meta-kms-private.h"
|
||||
|
||||
struct _MetaKmsDevice
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
MetaKms *kms;
|
||||
|
||||
MetaKmsImplDevice *impl_device;
|
||||
|
||||
MetaKmsDeviceFlag flags;
|
||||
char *path;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaKmsDevice, meta_kms_device, G_TYPE_OBJECT);
|
||||
|
||||
int
|
||||
meta_kms_device_leak_fd (MetaKmsDevice *device)
|
||||
{
|
||||
return meta_kms_impl_device_leak_fd (device->impl_device);
|
||||
}
|
||||
|
||||
const char *
|
||||
meta_kms_device_get_path (MetaKmsDevice *device)
|
||||
{
|
||||
return device->path;
|
||||
}
|
||||
|
||||
MetaKmsDeviceFlag
|
||||
meta_kms_device_get_flags (MetaKmsDevice *device)
|
||||
{
|
||||
return device->flags;
|
||||
}
|
||||
|
||||
typedef struct _CreateImplDeviceData
|
||||
{
|
||||
MetaKmsDevice *device;
|
||||
int fd;
|
||||
|
||||
MetaKmsImplDevice *out_impl_device;
|
||||
} CreateImplDeviceData;
|
||||
|
||||
static gboolean
|
||||
create_impl_device_in_impl (MetaKmsImpl *impl,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
CreateImplDeviceData *data = user_data;
|
||||
MetaKmsImplDevice *impl_device;
|
||||
|
||||
impl_device = meta_kms_impl_device_new (data->device, impl, data->fd);
|
||||
|
||||
data->out_impl_device = impl_device;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
MetaKmsDevice *
|
||||
meta_kms_device_new (MetaKms *kms,
|
||||
const char *path,
|
||||
MetaKmsDeviceFlag flags,
|
||||
GError **error)
|
||||
{
|
||||
MetaBackend *backend = meta_kms_get_backend (kms);
|
||||
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||
MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native);
|
||||
MetaKmsDevice *device;
|
||||
CreateImplDeviceData data;
|
||||
int fd;
|
||||
|
||||
fd = meta_launcher_open_restricted (launcher, path, error);
|
||||
if (fd == -1)
|
||||
return NULL;
|
||||
|
||||
device = g_object_new (META_TYPE_KMS_DEVICE, NULL);
|
||||
|
||||
data = (CreateImplDeviceData) {
|
||||
.device = device,
|
||||
.fd = fd,
|
||||
};
|
||||
if (!meta_kms_run_impl_task_sync (kms, create_impl_device_in_impl, &data,
|
||||
error))
|
||||
{
|
||||
meta_launcher_close_restricted (launcher, fd);
|
||||
g_object_unref (device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device->kms = kms;
|
||||
device->impl_device = data.out_impl_device;
|
||||
device->flags = flags;
|
||||
device->path = g_strdup (path);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
typedef struct _FreeImplDeviceData
|
||||
{
|
||||
MetaKmsImplDevice *impl_device;
|
||||
|
||||
int out_fd;
|
||||
} FreeImplDeviceData;
|
||||
|
||||
static gboolean
|
||||
free_impl_device_in_impl (MetaKmsImpl *impl,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
FreeImplDeviceData *data = user_data;
|
||||
MetaKmsImplDevice *impl_device = data->impl_device;
|
||||
int fd;
|
||||
|
||||
fd = meta_kms_impl_device_close (impl_device);
|
||||
g_object_unref (impl_device);
|
||||
|
||||
data->out_fd = fd;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_device_finalize (GObject *object)
|
||||
{
|
||||
MetaKmsDevice *device = META_KMS_DEVICE (object);
|
||||
MetaBackend *backend = meta_kms_get_backend (device->kms);
|
||||
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||
MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native);
|
||||
FreeImplDeviceData data;
|
||||
GError *error = NULL;
|
||||
|
||||
data = (FreeImplDeviceData) {
|
||||
.impl_device = device->impl_device,
|
||||
};
|
||||
if (!meta_kms_run_impl_task_sync (device->kms, free_impl_device_in_impl, &data,
|
||||
&error))
|
||||
{
|
||||
g_warning ("Failed to close KMS impl device: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_launcher_close_restricted (launcher, data.out_fd);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (meta_kms_device_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_device_init (MetaKmsDevice *device)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_device_class_init (MetaKmsDeviceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_kms_device_finalize;
|
||||
}
|
43
src/backends/native/meta-kms-device.h
Normal file
43
src/backends/native/meta-kms-device.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_KMS_DEVICE_H
|
||||
#define META_KMS_DEVICE_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "backends/native/meta-kms-types.h"
|
||||
|
||||
#define META_TYPE_KMS_DEVICE (meta_kms_device_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaKmsDevice, meta_kms_device,
|
||||
META, KMS_DEVICE,
|
||||
GObject)
|
||||
|
||||
int meta_kms_device_leak_fd (MetaKmsDevice *device);
|
||||
|
||||
const char * meta_kms_device_get_path (MetaKmsDevice *device);
|
||||
|
||||
MetaKmsDeviceFlag meta_kms_device_get_flags (MetaKmsDevice *device);
|
||||
|
||||
MetaKmsDevice * meta_kms_device_new (MetaKms *kms,
|
||||
const char *path,
|
||||
MetaKmsDeviceFlag flags,
|
||||
GError **error);
|
||||
|
||||
#endif /* META_KMS_DEVICE_H */
|
98
src/backends/native/meta-kms-impl-device.c
Normal file
98
src/backends/native/meta-kms-impl-device.c
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/native/meta-kms-impl-device.h"
|
||||
|
||||
#include "backends/native/meta-kms-impl.h"
|
||||
#include "backends/native/meta-kms-private.h"
|
||||
|
||||
struct _MetaKmsImplDevice
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
MetaKmsDevice *device;
|
||||
MetaKmsImpl *impl;
|
||||
|
||||
int fd;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaKmsImplDevice, meta_kms_impl_device, G_TYPE_OBJECT)
|
||||
|
||||
MetaKmsDevice *
|
||||
meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device)
|
||||
{
|
||||
return impl_device->device;
|
||||
}
|
||||
|
||||
MetaKmsImplDevice *
|
||||
meta_kms_impl_device_new (MetaKmsDevice *device,
|
||||
MetaKmsImpl *impl,
|
||||
int fd)
|
||||
{
|
||||
MetaKmsImplDevice *impl_device;
|
||||
|
||||
meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl));
|
||||
|
||||
impl_device = g_object_new (META_TYPE_KMS_IMPL_DEVICE, NULL);
|
||||
impl_device->device = device;
|
||||
impl_device->impl = impl;
|
||||
impl_device->fd = fd;
|
||||
|
||||
return impl_device;
|
||||
}
|
||||
|
||||
int
|
||||
meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device)
|
||||
{
|
||||
meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl_device->impl));
|
||||
|
||||
return impl_device->fd;
|
||||
}
|
||||
|
||||
int
|
||||
meta_kms_impl_device_leak_fd (MetaKmsImplDevice *impl_device)
|
||||
{
|
||||
return impl_device->fd;
|
||||
}
|
||||
|
||||
int
|
||||
meta_kms_impl_device_close (MetaKmsImplDevice *impl_device)
|
||||
{
|
||||
int fd;
|
||||
|
||||
meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl_device->impl));
|
||||
|
||||
fd = impl_device->fd;
|
||||
impl_device->fd = -1;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_device_init (MetaKmsImplDevice *device)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_device_class_init (MetaKmsImplDeviceClass *klass)
|
||||
{
|
||||
}
|
||||
|
46
src/backends/native/meta-kms-impl-device.h
Normal file
46
src/backends/native/meta-kms-impl-device.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_KMS_IMPL_DEVICE_H
|
||||
#define META_KMS_IMPL_DEVICE_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "backends/native/meta-kms-device.h"
|
||||
#include "backends/native/meta-kms-types.h"
|
||||
|
||||
#define META_TYPE_KMS_IMPL_DEVICE (meta_kms_impl_device_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaKmsImplDevice, meta_kms_impl_device,
|
||||
META, KMS_IMPL_DEVICE,
|
||||
GObject)
|
||||
|
||||
MetaKmsDevice * meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device);
|
||||
|
||||
int meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device);
|
||||
|
||||
int meta_kms_impl_device_leak_fd (MetaKmsImplDevice *impl_device);
|
||||
|
||||
int meta_kms_impl_device_close (MetaKmsImplDevice *impl_device);
|
||||
|
||||
MetaKmsImplDevice * meta_kms_impl_device_new (MetaKmsDevice *device,
|
||||
MetaKmsImpl *kms_impl,
|
||||
int fd);
|
||||
|
||||
#endif /* META_KMS_IMPL_DEVICE_H */
|
51
src/backends/native/meta-kms-impl-simple.c
Normal file
51
src/backends/native/meta-kms-impl-simple.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2019 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/native/meta-kms-impl-simple.h"
|
||||
|
||||
#include <gbm.h>
|
||||
|
||||
struct _MetaKmsImplSimple
|
||||
{
|
||||
MetaKmsImpl parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaKmsImplSimple, meta_kms_impl_simple,
|
||||
META_TYPE_KMS_IMPL)
|
||||
|
||||
MetaKmsImplSimple *
|
||||
meta_kms_impl_simple_new (MetaKms *kms,
|
||||
GError **error)
|
||||
{
|
||||
return g_object_new (META_TYPE_KMS_IMPL_SIMPLE,
|
||||
"kms", kms,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_simple_init (MetaKmsImplSimple *impl_simple)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_simple_class_init (MetaKmsImplSimpleClass *klass)
|
||||
{
|
||||
}
|
32
src/backends/native/meta-kms-impl-simple.h
Normal file
32
src/backends/native/meta-kms-impl-simple.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_KMS_IMPL_SIMPLE_H
|
||||
#define META_KMS_IMPL_SIMPLE_H
|
||||
|
||||
#include "backends/native/meta-kms-impl.h"
|
||||
|
||||
#define META_TYPE_KMS_IMPL_SIMPLE meta_kms_impl_simple_get_type ()
|
||||
G_DECLARE_FINAL_TYPE (MetaKmsImplSimple, meta_kms_impl_simple,
|
||||
META, KMS_IMPL_SIMPLE, MetaKmsImpl)
|
||||
|
||||
MetaKmsImplSimple * meta_kms_impl_simple_new (MetaKms *kms,
|
||||
GError **error);
|
||||
|
||||
#endif /* META_KMS_IMPL_SIMPLE_H */
|
110
src/backends/native/meta-kms-impl.c
Normal file
110
src/backends/native/meta-kms-impl.c
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/native/meta-kms-impl.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_KMS,
|
||||
};
|
||||
|
||||
typedef struct _MetaKmsImplPrivate
|
||||
{
|
||||
MetaKms *kms;
|
||||
} MetaKmsImplPrivate;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaKmsImpl, meta_kms_impl, G_TYPE_OBJECT)
|
||||
|
||||
MetaKms *
|
||||
meta_kms_impl_get_kms (MetaKmsImpl *impl)
|
||||
{
|
||||
MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl);
|
||||
|
||||
return priv->kms;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaKmsImpl *impl = META_KMS_IMPL (object);
|
||||
MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_KMS:
|
||||
priv->kms = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaKmsImpl *impl = META_KMS_IMPL (object);
|
||||
MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_KMS:
|
||||
g_value_set_object (value, priv->kms);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_init (MetaKmsImpl *kms_impl)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_class_init (MetaKmsImplClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
object_class->set_property = meta_kms_impl_set_property;
|
||||
object_class->get_property = meta_kms_impl_get_property;
|
||||
|
||||
pspec = g_param_spec_object ("kms",
|
||||
"kms",
|
||||
"MetaKms",
|
||||
META_TYPE_KMS,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_KMS,
|
||||
pspec);
|
||||
}
|
37
src/backends/native/meta-kms-impl.h
Normal file
37
src/backends/native/meta-kms-impl.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_KMS_IMPL_H
|
||||
#define META_KMS_IMPL_H
|
||||
|
||||
#include "backends/native/meta-kms-impl-device.h"
|
||||
#include "backends/native/meta-kms.h"
|
||||
|
||||
#define META_TYPE_KMS_IMPL (meta_kms_impl_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (MetaKmsImpl, meta_kms_impl,
|
||||
META, KMS_IMPL, GObject)
|
||||
|
||||
struct _MetaKmsImplClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
MetaKms * meta_kms_impl_get_kms (MetaKmsImpl *impl);
|
||||
|
||||
#endif /* META_KMS_IMPL_H */
|
43
src/backends/native/meta-kms-private.h
Normal file
43
src/backends/native/meta-kms-private.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_KMS_PRIVATE_H
|
||||
#define META_KMS_PRIVATE_H
|
||||
|
||||
#include "backends/native/meta-kms.h"
|
||||
|
||||
#include "backends/native/meta-kms-types.h"
|
||||
|
||||
typedef gboolean (* MetaKmsImplTaskFunc) (MetaKmsImpl *impl,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
gboolean meta_kms_run_impl_task_sync (MetaKms *kms,
|
||||
MetaKmsImplTaskFunc func,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
gboolean meta_kms_in_impl_task (MetaKms *kms);
|
||||
|
||||
#define meta_assert_in_kms_impl(kms) \
|
||||
g_assert (meta_kms_in_impl_task (kms))
|
||||
#define meta_assert_not_in_kms_impl(kms) \
|
||||
g_assert (!meta_kms_in_impl_task (kms))
|
||||
|
||||
#endif /* META_KMS_PRIVATE_H */
|
36
src/backends/native/meta-kms-types.h
Normal file
36
src/backends/native/meta-kms-types.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_KMS_IMPL_TYPES_H
|
||||
#define META_KMS_IMPL_TYPES_H
|
||||
|
||||
typedef struct _MetaKms MetaKms;
|
||||
typedef struct _MetaKmsDevice MetaKmsDevice;
|
||||
|
||||
typedef struct _MetaKmsImpl MetaKmsImpl;
|
||||
typedef struct _MetaKmsImplDevice MetaKmsImplDevice;
|
||||
|
||||
typedef enum _MetaKmsDeviceFlag
|
||||
{
|
||||
META_KMS_DEVICE_FLAG_NONE = 0,
|
||||
META_KMS_DEVICE_FLAG_BOOT_VGA = 1 << 0,
|
||||
META_KMS_DEVICE_FLAG_PLATFORM_DEVICE = 1 << 1,
|
||||
} MetaKmsDeviceFlag;
|
||||
|
||||
#endif /* META_KMS_IMPL_TYPES_H */
|
124
src/backends/native/meta-kms.c
Normal file
124
src/backends/native/meta-kms.c
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/native/meta-kms-private.h"
|
||||
|
||||
#include "backends/native/meta-kms-impl.h"
|
||||
#include "backends/native/meta-kms-impl-simple.h"
|
||||
|
||||
struct _MetaKms
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
MetaBackend *backend;
|
||||
|
||||
MetaKmsImpl *impl;
|
||||
gboolean in_impl_task;
|
||||
|
||||
GList *devices;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaKms, meta_kms, G_TYPE_OBJECT)
|
||||
|
||||
gboolean
|
||||
meta_kms_run_impl_task_sync (MetaKms *kms,
|
||||
MetaKmsImplTaskFunc func,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret;
|
||||
|
||||
kms->in_impl_task = TRUE;
|
||||
ret = func (kms->impl, user_data, error);
|
||||
kms->in_impl_task = FALSE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_kms_in_impl_task (MetaKms *kms)
|
||||
{
|
||||
return kms->in_impl_task;
|
||||
}
|
||||
|
||||
MetaBackend *
|
||||
meta_kms_get_backend (MetaKms *kms)
|
||||
{
|
||||
return kms->backend;
|
||||
}
|
||||
|
||||
MetaKmsDevice *
|
||||
meta_kms_create_device (MetaKms *kms,
|
||||
const char *path,
|
||||
MetaKmsDeviceFlag flags,
|
||||
GError **error)
|
||||
{
|
||||
MetaKmsDevice *device;
|
||||
|
||||
device = meta_kms_device_new (kms, path, flags, error);
|
||||
if (!device)
|
||||
return NULL;
|
||||
|
||||
kms->devices = g_list_append (kms->devices, device);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
MetaKms *
|
||||
meta_kms_new (MetaBackend *backend,
|
||||
GError **error)
|
||||
{
|
||||
MetaKms *kms;
|
||||
|
||||
kms = g_object_new (META_TYPE_KMS, NULL);
|
||||
kms->backend = backend;
|
||||
kms->impl = META_KMS_IMPL (meta_kms_impl_simple_new (kms, error));
|
||||
if (!kms->impl)
|
||||
{
|
||||
g_object_unref (kms);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return kms;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_finalize (GObject *object)
|
||||
{
|
||||
MetaKms *kms = META_KMS (object);
|
||||
|
||||
g_list_free_full (kms->devices, g_object_unref);
|
||||
|
||||
G_OBJECT_CLASS (meta_kms_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_init (MetaKms *kms)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_class_init (MetaKmsClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_kms_finalize;
|
||||
}
|
41
src/backends/native/meta-kms.h
Normal file
41
src/backends/native/meta-kms.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_KMS_H
|
||||
#define META_KMS_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/native/meta-kms-types.h"
|
||||
|
||||
#define META_TYPE_KMS (meta_kms_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaKms, meta_kms, META, KMS, GObject)
|
||||
|
||||
MetaBackend * meta_kms_get_backend (MetaKms *kms);
|
||||
|
||||
MetaKmsDevice * meta_kms_create_device (MetaKms *kms,
|
||||
const char *path,
|
||||
MetaKmsDeviceFlag flags,
|
||||
GError **error);
|
||||
|
||||
MetaKms * meta_kms_new (MetaBackend *backend,
|
||||
GError **error);
|
||||
|
||||
#endif /* META_KMS_H */
|
@ -595,6 +595,18 @@ if have_native_backend
|
||||
'backends/native/meta-output-kms.c',
|
||||
'backends/native/meta-output-kms.h',
|
||||
'backends/native/meta-renderer-native.c',
|
||||
'backends/native/meta-kms-device.c',
|
||||
'backends/native/meta-kms-device.h',
|
||||
'backends/native/meta-kms-impl-device.c',
|
||||
'backends/native/meta-kms-impl-device.h',
|
||||
'backends/native/meta-kms-impl-simple.c',
|
||||
'backends/native/meta-kms-impl-simple.h',
|
||||
'backends/native/meta-kms-impl.c',
|
||||
'backends/native/meta-kms-impl.h',
|
||||
'backends/native/meta-kms-private.h',
|
||||
'backends/native/meta-kms-types.h',
|
||||
'backends/native/meta-kms.c',
|
||||
'backends/native/meta-kms.h',
|
||||
'backends/native/meta-renderer-native-gles3.c',
|
||||
'backends/native/meta-renderer-native-gles3.h',
|
||||
'backends/native/meta-renderer-native.h',
|
||||
|
Loading…
Reference in New Issue
Block a user