mirror of
https://github.com/brl/mutter.git
synced 2024-11-28 11:00:54 -05:00
1959a872b8
This means moving things from the private struct _MetaKmsImplDevice into a instance private struct. No other changes made. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
715 lines
19 KiB
C
715 lines
19 KiB
C
/*
|
|
* Copyright (C) 2019 Red Hat
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
* 02111-1307, USA.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "backends/native/meta-kms-impl-device.h"
|
|
|
|
#include <errno.h>
|
|
#include <xf86drm.h>
|
|
|
|
#include "backends/native/meta-kms-connector-private.h"
|
|
#include "backends/native/meta-kms-connector.h"
|
|
#include "backends/native/meta-kms-crtc-private.h"
|
|
#include "backends/native/meta-kms-crtc.h"
|
|
#include "backends/native/meta-kms-impl.h"
|
|
#include "backends/native/meta-kms-mode-private.h"
|
|
#include "backends/native/meta-kms-page-flip-private.h"
|
|
#include "backends/native/meta-kms-plane-private.h"
|
|
#include "backends/native/meta-kms-plane.h"
|
|
#include "backends/native/meta-kms-private.h"
|
|
#include "backends/native/meta-kms-update.h"
|
|
|
|
#include "meta-default-modes.h"
|
|
|
|
typedef struct _MetaKmsImplDevicePrivate
|
|
{
|
|
MetaKmsDevice *device;
|
|
MetaKmsImpl *impl;
|
|
|
|
int fd;
|
|
GSource *fd_source;
|
|
|
|
char *driver_name;
|
|
char *driver_description;
|
|
|
|
GList *crtcs;
|
|
GList *connectors;
|
|
GList *planes;
|
|
|
|
MetaKmsDeviceCaps caps;
|
|
|
|
GList *fallback_modes;
|
|
} MetaKmsImplDevicePrivate;
|
|
|
|
G_DEFINE_TYPE_WITH_PRIVATE (MetaKmsImplDevice, meta_kms_impl_device,
|
|
G_TYPE_OBJECT)
|
|
|
|
MetaKmsDevice *
|
|
meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
|
|
return priv->device;
|
|
}
|
|
|
|
GList *
|
|
meta_kms_impl_device_copy_connectors (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
|
|
return g_list_copy (priv->connectors);
|
|
}
|
|
|
|
GList *
|
|
meta_kms_impl_device_copy_crtcs (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
|
|
return g_list_copy (priv->crtcs);
|
|
}
|
|
|
|
GList *
|
|
meta_kms_impl_device_copy_planes (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
|
|
return g_list_copy (priv->planes);
|
|
}
|
|
|
|
const MetaKmsDeviceCaps *
|
|
meta_kms_impl_device_get_caps (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
|
|
return &priv->caps;
|
|
}
|
|
|
|
GList *
|
|
meta_kms_impl_device_copy_fallback_modes (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
|
|
return g_list_copy (priv->fallback_modes);
|
|
}
|
|
|
|
const char *
|
|
meta_kms_impl_device_get_driver_name (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
|
|
return priv->driver_name;
|
|
}
|
|
|
|
const char *
|
|
meta_kms_impl_device_get_driver_description (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
|
|
return priv->driver_description;
|
|
}
|
|
|
|
static void
|
|
page_flip_handler (int fd,
|
|
unsigned int sequence,
|
|
unsigned int sec,
|
|
unsigned int usec,
|
|
void *user_data)
|
|
{
|
|
MetaKmsPageFlipData *page_flip_data = user_data;
|
|
MetaKmsImpl *impl;
|
|
|
|
meta_kms_page_flip_data_set_timings_in_impl (page_flip_data,
|
|
sequence, sec, usec);
|
|
|
|
impl = meta_kms_page_flip_data_get_kms_impl (page_flip_data);
|
|
meta_kms_impl_handle_page_flip_callback (impl, page_flip_data);
|
|
}
|
|
|
|
gboolean
|
|
meta_kms_impl_device_dispatch (MetaKmsImplDevice *impl_device,
|
|
GError **error)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
|
|
drmEventContext drm_event_context;
|
|
|
|
meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
|
|
|
|
drm_event_context = (drmEventContext) { 0 };
|
|
drm_event_context.version = 2;
|
|
drm_event_context.page_flip_handler = page_flip_handler;
|
|
|
|
while (TRUE)
|
|
{
|
|
if (drmHandleEvent (priv->fd, &drm_event_context) != 0)
|
|
{
|
|
struct pollfd pfd;
|
|
int ret;
|
|
|
|
if (errno != EAGAIN)
|
|
{
|
|
g_set_error_literal (error, G_IO_ERROR,
|
|
g_io_error_from_errno (errno),
|
|
strerror (errno));
|
|
return FALSE;
|
|
}
|
|
|
|
pfd.fd = priv->fd;
|
|
pfd.events = POLL_IN | POLL_ERR;
|
|
do
|
|
{
|
|
ret = poll (&pfd, 1, -1);
|
|
}
|
|
while (ret == -1 && errno == EINTR);
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gpointer
|
|
kms_event_dispatch_in_impl (MetaKmsImpl *impl,
|
|
gpointer user_data,
|
|
GError **error)
|
|
{
|
|
MetaKmsImplDevice *impl_device = user_data;
|
|
gboolean ret;
|
|
|
|
ret = meta_kms_impl_device_dispatch (impl_device, error);
|
|
return GINT_TO_POINTER (ret);
|
|
}
|
|
|
|
drmModePropertyPtr
|
|
meta_kms_impl_device_find_property (MetaKmsImplDevice *impl_device,
|
|
drmModeObjectProperties *props,
|
|
const char *prop_name,
|
|
int *out_idx)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
unsigned int i;
|
|
|
|
meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
|
|
|
|
for (i = 0; i < props->count_props; i++)
|
|
{
|
|
drmModePropertyPtr prop;
|
|
|
|
prop = drmModeGetProperty (priv->fd, props->props[i]);
|
|
if (!prop)
|
|
continue;
|
|
|
|
if (strcmp (prop->name, prop_name) == 0)
|
|
{
|
|
*out_idx = i;
|
|
return prop;
|
|
}
|
|
|
|
drmModeFreeProperty (prop);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
init_caps (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
int fd = priv->fd;
|
|
uint64_t cursor_width, cursor_height;
|
|
|
|
if (drmGetCap (fd, DRM_CAP_CURSOR_WIDTH, &cursor_width) == 0 &&
|
|
drmGetCap (fd, DRM_CAP_CURSOR_HEIGHT, &cursor_height) == 0)
|
|
{
|
|
priv->caps.has_cursor_size = TRUE;
|
|
priv->caps.cursor_width = cursor_width;
|
|
priv->caps.cursor_height = cursor_height;
|
|
}
|
|
}
|
|
|
|
static void
|
|
init_crtcs (MetaKmsImplDevice *impl_device,
|
|
drmModeRes *drm_resources)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
int idx;
|
|
|
|
for (idx = 0; idx < drm_resources->count_crtcs; idx++)
|
|
{
|
|
drmModeCrtc *drm_crtc;
|
|
MetaKmsCrtc *crtc;
|
|
|
|
drm_crtc = drmModeGetCrtc (priv->fd, drm_resources->crtcs[idx]);
|
|
crtc = meta_kms_crtc_new (impl_device, drm_crtc, idx);
|
|
drmModeFreeCrtc (drm_crtc);
|
|
|
|
priv->crtcs = g_list_prepend (priv->crtcs, crtc);
|
|
}
|
|
priv->crtcs = g_list_reverse (priv->crtcs);
|
|
}
|
|
|
|
static MetaKmsConnector *
|
|
find_existing_connector (MetaKmsImplDevice *impl_device,
|
|
drmModeConnector *drm_connector)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
GList *l;
|
|
|
|
for (l = priv->connectors; l; l = l->next)
|
|
{
|
|
MetaKmsConnector *connector = l->data;
|
|
|
|
if (meta_kms_connector_is_same_as (connector, drm_connector))
|
|
return connector;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
update_connectors (MetaKmsImplDevice *impl_device,
|
|
drmModeRes *drm_resources)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
GList *connectors = NULL;
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < drm_resources->count_connectors; i++)
|
|
{
|
|
drmModeConnector *drm_connector;
|
|
MetaKmsConnector *connector;
|
|
|
|
drm_connector = drmModeGetConnector (priv->fd,
|
|
drm_resources->connectors[i]);
|
|
if (!drm_connector)
|
|
continue;
|
|
|
|
connector = find_existing_connector (impl_device, drm_connector);
|
|
if (connector)
|
|
connector = g_object_ref (connector);
|
|
else
|
|
connector = meta_kms_connector_new (impl_device, drm_connector,
|
|
drm_resources);
|
|
drmModeFreeConnector (drm_connector);
|
|
|
|
connectors = g_list_prepend (connectors, connector);
|
|
}
|
|
|
|
g_list_free_full (priv->connectors, g_object_unref);
|
|
priv->connectors = g_list_reverse (connectors);
|
|
}
|
|
|
|
static MetaKmsPlaneType
|
|
get_plane_type (MetaKmsImplDevice *impl_device,
|
|
drmModeObjectProperties *props)
|
|
{
|
|
drmModePropertyPtr prop;
|
|
int idx;
|
|
|
|
prop = meta_kms_impl_device_find_property (impl_device, props, "type", &idx);
|
|
if (!prop)
|
|
return FALSE;
|
|
drmModeFreeProperty (prop);
|
|
|
|
switch (props->prop_values[idx])
|
|
{
|
|
case DRM_PLANE_TYPE_PRIMARY:
|
|
return META_KMS_PLANE_TYPE_PRIMARY;
|
|
case DRM_PLANE_TYPE_CURSOR:
|
|
return META_KMS_PLANE_TYPE_CURSOR;
|
|
case DRM_PLANE_TYPE_OVERLAY:
|
|
return META_KMS_PLANE_TYPE_OVERLAY;
|
|
default:
|
|
g_warning ("Unhandled plane type %" G_GUINT64_FORMAT,
|
|
props->prop_values[idx]);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
MetaKmsPlane *
|
|
meta_kms_impl_device_add_fake_plane (MetaKmsImplDevice *impl_device,
|
|
MetaKmsPlaneType plane_type,
|
|
MetaKmsCrtc *crtc)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
MetaKmsPlane *plane;
|
|
|
|
plane = meta_kms_plane_new_fake (plane_type, crtc);
|
|
priv->planes = g_list_append (priv->planes, plane);
|
|
|
|
return plane;
|
|
}
|
|
|
|
static MetaKmsProp *
|
|
find_prop (MetaKmsProp *props,
|
|
int n_props,
|
|
const char *name)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < n_props; i++)
|
|
{
|
|
MetaKmsProp *prop = &props[i];
|
|
|
|
g_warn_if_fail (prop->name);
|
|
|
|
if (g_strcmp0 (prop->name, name) == 0)
|
|
return prop;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
meta_kms_impl_device_init_prop_table (MetaKmsImplDevice *impl_device,
|
|
uint32_t *drm_props,
|
|
uint64_t *drm_prop_values,
|
|
int n_drm_props,
|
|
MetaKmsProp *props,
|
|
int n_props,
|
|
gpointer user_data)
|
|
{
|
|
int fd;
|
|
uint32_t i;
|
|
|
|
fd = meta_kms_impl_device_get_fd (impl_device);
|
|
|
|
for (i = 0; i < n_drm_props; i++)
|
|
{
|
|
drmModePropertyRes *drm_prop;
|
|
MetaKmsProp *prop;
|
|
|
|
drm_prop = drmModeGetProperty (fd, drm_props[i]);
|
|
if (!drm_prop)
|
|
continue;
|
|
|
|
prop = find_prop (props, n_props, drm_prop->name);
|
|
if (!prop)
|
|
{
|
|
drmModeFreeProperty (drm_prop);
|
|
continue;
|
|
}
|
|
|
|
if (!(drm_prop->flags & prop->type))
|
|
{
|
|
g_warning ("DRM property '%s' (%u) had unexpected flags (0x%x), "
|
|
"ignoring",
|
|
drm_prop->name, drm_props[i], drm_prop->flags);
|
|
drmModeFreeProperty (drm_prop);
|
|
continue;
|
|
}
|
|
|
|
prop->prop_id = drm_props[i];
|
|
|
|
if (prop->parse)
|
|
{
|
|
prop->parse (impl_device, prop,
|
|
drm_prop, drm_prop_values[i],
|
|
user_data);
|
|
}
|
|
|
|
drmModeFreeProperty (drm_prop);
|
|
}
|
|
}
|
|
|
|
static void
|
|
init_planes (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
int fd = priv->fd;
|
|
drmModePlaneRes *drm_planes;
|
|
unsigned int i;
|
|
|
|
drm_planes = drmModeGetPlaneResources (fd);
|
|
if (!drm_planes)
|
|
return;
|
|
|
|
for (i = 0; i < drm_planes->count_planes; i++)
|
|
{
|
|
drmModePlane *drm_plane;
|
|
drmModeObjectProperties *props;
|
|
|
|
drm_plane = drmModeGetPlane (fd, drm_planes->planes[i]);
|
|
if (!drm_plane)
|
|
continue;
|
|
|
|
props = drmModeObjectGetProperties (fd,
|
|
drm_plane->plane_id,
|
|
DRM_MODE_OBJECT_PLANE);
|
|
if (props)
|
|
{
|
|
MetaKmsPlaneType plane_type;
|
|
|
|
plane_type = get_plane_type (impl_device, props);
|
|
if (plane_type != -1)
|
|
{
|
|
MetaKmsPlane *plane;
|
|
|
|
plane = meta_kms_plane_new (plane_type,
|
|
impl_device,
|
|
drm_plane, props);
|
|
|
|
priv->planes = g_list_prepend (priv->planes, plane);
|
|
}
|
|
}
|
|
|
|
g_clear_pointer (&props, drmModeFreeObjectProperties);
|
|
drmModeFreePlane (drm_plane);
|
|
}
|
|
priv->planes = g_list_reverse (priv->planes);
|
|
}
|
|
|
|
static void
|
|
init_fallback_modes (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
GList *modes = NULL;
|
|
int i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (meta_default_landscape_drm_mode_infos); i++)
|
|
{
|
|
MetaKmsMode *mode;
|
|
|
|
mode = meta_kms_mode_new (impl_device,
|
|
&meta_default_landscape_drm_mode_infos[i],
|
|
META_KMS_MODE_FLAG_FALLBACK_LANDSCAPE);
|
|
modes = g_list_prepend (modes, mode);
|
|
}
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (meta_default_portrait_drm_mode_infos); i++)
|
|
{
|
|
MetaKmsMode *mode;
|
|
|
|
mode = meta_kms_mode_new (impl_device,
|
|
&meta_default_portrait_drm_mode_infos[i],
|
|
META_KMS_MODE_FLAG_FALLBACK_PORTRAIT);
|
|
modes = g_list_prepend (modes, mode);
|
|
}
|
|
|
|
priv->fallback_modes = g_list_reverse (modes);
|
|
}
|
|
|
|
static void
|
|
init_info (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
drmVersion *drm_version;
|
|
|
|
drm_version = drmGetVersion (priv->fd);
|
|
if (!drm_version)
|
|
return;
|
|
|
|
priv->driver_name = g_strndup (drm_version->name,
|
|
drm_version->name_len);
|
|
priv->driver_description = g_strndup (drm_version->desc,
|
|
drm_version->desc_len);
|
|
drmFreeVersion (drm_version);
|
|
}
|
|
|
|
void
|
|
meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
drmModeRes *drm_resources;
|
|
|
|
meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
|
|
|
|
drm_resources = drmModeGetResources (priv->fd);
|
|
if (!drm_resources)
|
|
{
|
|
g_list_free_full (priv->planes, g_object_unref);
|
|
g_list_free_full (priv->crtcs, g_object_unref);
|
|
g_list_free_full (priv->connectors, g_object_unref);
|
|
priv->planes = NULL;
|
|
priv->crtcs = NULL;
|
|
priv->connectors = NULL;
|
|
return;
|
|
}
|
|
|
|
update_connectors (impl_device, drm_resources);
|
|
|
|
g_list_foreach (priv->crtcs, (GFunc) meta_kms_crtc_update_state,
|
|
NULL);
|
|
g_list_foreach (priv->connectors, (GFunc) meta_kms_connector_update_state,
|
|
drm_resources);
|
|
drmModeFreeResources (drm_resources);
|
|
}
|
|
|
|
void
|
|
meta_kms_impl_device_predict_states (MetaKmsImplDevice *impl_device,
|
|
MetaKmsUpdate *update)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
|
|
g_list_foreach (priv->crtcs, (GFunc) meta_kms_crtc_predict_state,
|
|
update);
|
|
g_list_foreach (priv->connectors, (GFunc) meta_kms_connector_predict_state,
|
|
update);
|
|
}
|
|
|
|
MetaKmsImplDevice *
|
|
meta_kms_impl_device_new (MetaKmsDevice *device,
|
|
MetaKmsImpl *impl,
|
|
int fd,
|
|
GError **error)
|
|
{
|
|
MetaKms *kms = meta_kms_impl_get_kms (impl);
|
|
MetaKmsImplDevice *impl_device;
|
|
MetaKmsImplDevicePrivate *priv;
|
|
int ret;
|
|
drmModeRes *drm_resources;
|
|
|
|
meta_assert_in_kms_impl (kms);
|
|
|
|
ret = drmSetClientCap (fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
|
if (ret != 0)
|
|
{
|
|
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
|
|
"Failed to activate universal planes: %s",
|
|
g_strerror (-ret));
|
|
return NULL;
|
|
}
|
|
|
|
drm_resources = drmModeGetResources (fd);
|
|
if (!drm_resources)
|
|
{
|
|
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
|
|
"Failed to activate universal planes: %s",
|
|
g_strerror (errno));
|
|
return NULL;
|
|
}
|
|
|
|
impl_device = g_object_new (META_TYPE_KMS_IMPL_DEVICE, NULL);
|
|
priv = meta_kms_impl_device_get_instance_private (impl_device);
|
|
priv->device = device;
|
|
priv->impl = impl;
|
|
priv->fd = fd;
|
|
|
|
init_caps (impl_device);
|
|
|
|
init_crtcs (impl_device, drm_resources);
|
|
init_planes (impl_device);
|
|
init_info (impl_device);
|
|
|
|
init_fallback_modes (impl_device);
|
|
|
|
update_connectors (impl_device, drm_resources);
|
|
|
|
drmModeFreeResources (drm_resources);
|
|
|
|
priv->fd_source =
|
|
meta_kms_register_fd_in_impl (kms, fd,
|
|
kms_event_dispatch_in_impl,
|
|
impl_device);
|
|
|
|
return impl_device;
|
|
}
|
|
|
|
int
|
|
meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
|
|
meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
|
|
|
|
return priv->fd;
|
|
}
|
|
|
|
int
|
|
meta_kms_impl_device_leak_fd (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
|
|
return priv->fd;
|
|
}
|
|
|
|
int
|
|
meta_kms_impl_device_close (MetaKmsImplDevice *impl_device)
|
|
{
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
int fd;
|
|
|
|
meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
|
|
|
|
g_clear_pointer (&priv->fd_source, g_source_destroy);
|
|
fd = priv->fd;
|
|
priv->fd = -1;
|
|
|
|
return fd;
|
|
}
|
|
|
|
static void
|
|
meta_kms_impl_device_finalize (GObject *object)
|
|
{
|
|
MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (object);
|
|
MetaKmsImplDevicePrivate *priv =
|
|
meta_kms_impl_device_get_instance_private (impl_device);
|
|
|
|
g_list_free_full (priv->planes, g_object_unref);
|
|
g_list_free_full (priv->crtcs, g_object_unref);
|
|
g_list_free_full (priv->connectors, g_object_unref);
|
|
g_list_free_full (priv->fallback_modes,
|
|
(GDestroyNotify) meta_kms_mode_free);
|
|
g_free (priv->driver_name);
|
|
g_free (priv->driver_description);
|
|
|
|
G_OBJECT_CLASS (meta_kms_impl_device_parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
meta_kms_impl_device_init (MetaKmsImplDevice *device)
|
|
{
|
|
}
|
|
|
|
static void
|
|
meta_kms_impl_device_class_init (MetaKmsImplDeviceClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
object_class->finalize = meta_kms_impl_device_finalize;
|
|
}
|
|
|