seat/impl: Move out the GSource implementation to a helper object

This will help adding similar sources that work practically the same.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2628>
This commit is contained in:
Jonas Ådahl 2022-04-13 11:40:53 +02:00 committed by Carlos Garnacho
parent 3bd401f33a
commit a170f2a82b
5 changed files with 185 additions and 101 deletions

View File

@ -0,0 +1,110 @@
/*
* Copyright (C) 2010 Intel Corp.
* Copyright (C) 2014 Jonas Ådahl
* Copyright (C) 2016-2022 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
*/
#include "config.h"
#include "backends/meta-fd-source.h"
typedef struct _MetaFdtSource
{
GSource source;
GSourceFunc prepare;
GSourceFunc dispatch;
gpointer user_data;
GPollFD poll_fd;
} MetaFdSource;
static gboolean
meta_fd_source_prepare (GSource *source,
int *timeout_ms)
{
MetaFdSource *fd_source = (MetaFdSource *) source;
*timeout_ms = -1;
return fd_source->prepare (fd_source->user_data);
}
static gboolean
meta_fd_source_check (GSource *source)
{
MetaFdSource *fd_source = (MetaFdSource *) source;
return !!(fd_source->poll_fd.revents & G_IO_IN);
}
static gboolean
meta_fd_source_dispatch (GSource *source,
GSourceFunc callback,
gpointer user_data)
{
MetaFdSource *fd_source = (MetaFdSource *) source;
return fd_source->dispatch (fd_source->user_data);
}
static void
meta_fd_source_finalize (GSource *source)
{
MetaFdSource *fd_source = (MetaFdSource *) source;
close (fd_source->poll_fd.fd);
}
static GSourceFuncs fd_source_funcs = {
.prepare = meta_fd_source_prepare,
.check = meta_fd_source_check,
.dispatch = meta_fd_source_dispatch,
.finalize = meta_fd_source_finalize,
};
GSource *
meta_create_fd_source (int fd,
const char *name,
GSourceFunc prepare,
GSourceFunc dispatch,
gpointer user_data,
GDestroyNotify notify)
{
GSource *source;
MetaFdSource *fd_source;
source = g_source_new (&fd_source_funcs, sizeof (MetaFdSource));
g_source_set_name (source, name);
fd_source = (MetaFdSource *) source;
fd_source->poll_fd.fd = fd;
fd_source->poll_fd.events = G_IO_IN;
fd_source->prepare = prepare;
fd_source->dispatch = dispatch;
fd_source->user_data = user_data;
g_source_set_callback (source, dispatch, user_data, notify);
g_source_set_priority (source, G_PRIORITY_DEFAULT);
g_source_add_poll (source, &fd_source->poll_fd);
g_source_set_can_recurse (source, TRUE);
return source;
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2016-2022 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public 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_FD_SOURCE_H
#define META_FD_SOURCE_H
#include <glib.h>
GSource * meta_create_fd_source (int fd,
const char *name,
GSourceFunc prepare,
GSourceFunc dispatch,
gpointer user_data,
GDestroyNotify notify);
#endif /* META_FD_SOURCE_H */

View File

@ -34,6 +34,7 @@
#include <math.h>
#include "backends/meta-cursor-tracker-private.h"
#include "backends/meta-fd-source.h"
#include "backends/native/meta-backend-native-private.h"
#include "backends/native/meta-barrier-native.h"
#include "backends/native/meta-device-pool.h"
@ -1337,39 +1338,6 @@ meta_seat_impl_notify_touch_event_in_impl (MetaSeatImpl *seat_impl,
queue_event (seat_impl, event);
}
/*
* MetaEventSource for reading input devices
*/
static gboolean
meta_event_prepare (GSource *g_source,
int *timeout_ms)
{
MetaEventSource *source = (MetaEventSource *) g_source;
MetaSeatImpl *seat_impl = source->seat_impl;
*timeout_ms = -1;
switch (libinput_next_event_type (seat_impl->libinput))
{
case LIBINPUT_EVENT_NONE:
return FALSE;
default:
return TRUE;
}
}
static gboolean
meta_event_check (GSource *source)
{
MetaEventSource *event_source = (MetaEventSource *) source;
gboolean retval;
retval = !!(event_source->event_poll_fd.revents & G_IO_IN);
return retval;
}
static void
constrain_to_barriers (MetaSeatImpl *seat_impl,
ClutterInputDevice *device,
@ -1878,68 +1846,6 @@ notify_pad_ring (ClutterInputDevice *input_device,
queue_event (seat_impl, event);
}
static gboolean
meta_event_dispatch (GSource *g_source,
GSourceFunc callback,
gpointer user_data)
{
MetaEventSource *source = (MetaEventSource *) g_source;
MetaSeatImpl *seat_impl;
seat_impl = source->seat_impl;
dispatch_libinput (seat_impl);
return TRUE;
}
static GSourceFuncs event_funcs = {
meta_event_prepare,
meta_event_check,
meta_event_dispatch,
NULL
};
static MetaEventSource *
meta_event_source_new (MetaSeatImpl *seat_impl)
{
GSource *source;
MetaEventSource *event_source;
int fd;
source = g_source_new (&event_funcs, sizeof (MetaEventSource));
g_source_set_name (source, "[mutter] Events");
event_source = (MetaEventSource *) source;
/* setup the source */
event_source->seat_impl = seat_impl;
fd = libinput_get_fd (seat_impl->libinput);
event_source->event_poll_fd.fd = fd;
event_source->event_poll_fd.events = G_IO_IN;
/* and finally configure and attach the GSource */
g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS);
g_source_add_poll (source, &event_source->event_poll_fd);
g_source_set_can_recurse (source, TRUE);
g_source_attach (source, seat_impl->input_context);
return event_source;
}
static void
meta_event_source_free (MetaEventSource *source)
{
GSource *g_source = (GSource *) source;
/* ignore the return value of close, it's not like we can do something
* about it */
close (source->event_poll_fd.fd);
g_source_destroy (g_source);
g_source_unref (g_source);
}
static gboolean
has_touchscreen (MetaSeatImpl *seat_impl)
{
@ -3132,6 +3038,30 @@ meta_seat_impl_set_keyboard_numlock_in_impl (MetaSeatImpl *seat_impl,
seat_impl->xkb);
}
static gboolean
meta_libinput_source_prepare (gpointer user_data)
{
MetaSeatImpl *seat_impl = META_SEAT_IMPL (user_data);
switch (libinput_next_event_type (seat_impl->libinput))
{
case LIBINPUT_EVENT_NONE:
return FALSE;
default:
return TRUE;
}
}
static gboolean
meta_libinput_source_dispatch (gpointer user_data)
{
MetaSeatImpl *seat_impl = META_SEAT_IMPL (user_data);
dispatch_libinput (seat_impl);
return G_SOURCE_CONTINUE;
}
static gboolean
init_libinput (MetaSeatImpl *seat_impl,
GError **error)
@ -3176,10 +3106,19 @@ init_libinput (MetaSeatImpl *seat_impl,
static void
init_libinput_source (MetaSeatImpl *seat_impl)
{
MetaEventSource *source;
int fd;
GSource *source;
source = meta_event_source_new (seat_impl);
seat_impl->event_source = source;
fd = libinput_get_fd (seat_impl->libinput);
source = meta_create_fd_source (fd,
"[mutter] libinput",
meta_libinput_source_prepare,
meta_libinput_source_dispatch,
seat_impl,
NULL);
seat_impl->libinput_source = source;
g_source_attach (source, seat_impl->input_context);
g_source_unref (source);
}
static gpointer
@ -3377,7 +3316,7 @@ destroy_in_impl (GTask *task)
g_clear_pointer (&seat_impl->libinput, libinput_unref);
g_clear_pointer (&seat_impl->tools, g_hash_table_unref);
g_clear_pointer (&seat_impl->touch_states, g_hash_table_destroy);
g_clear_pointer (&seat_impl->event_source, meta_event_source_free);
g_clear_pointer (&seat_impl->libinput_source, g_source_destroy);
numlock_active =
xkb_state_mod_name_is_active (seat_impl->xkb, XKB_MOD_NAME_NUM,
@ -3424,7 +3363,7 @@ meta_seat_impl_finalize (GObject *object)
g_assert (!seat_impl->libinput);
g_assert (!seat_impl->tools);
g_assert (!seat_impl->event_source);
g_assert (!seat_impl->libinput_source);
g_free (seat_impl->seat_id);

View File

@ -68,7 +68,7 @@ struct _MetaSeatImpl
MetaSeatNative *seat_native;
char *seat_id;
MetaSeatNativeFlag flags;
MetaEventSource *event_source;
GSource *libinput_source;
struct libinput *libinput;
GRWLock state_lock;

View File

@ -220,6 +220,8 @@ mutter_sources = [
'backends/meta-dbus-session-watcher.h',
'backends/meta-display-config-shared.h',
'backends/meta-dnd-private.h',
'backends/meta-fd-source.c',
'backends/meta-fd-source.h',
'backends/meta-gpu.c',
'backends/meta-gpu.h',
'backends/meta-idle-monitor.c',