diff --git a/src/backends/meta-fd-source.c b/src/backends/meta-fd-source.c new file mode 100644 index 000000000..2c0fb09b7 --- /dev/null +++ b/src/backends/meta-fd-source.c @@ -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; +} diff --git a/src/backends/meta-fd-source.h b/src/backends/meta-fd-source.h new file mode 100644 index 000000000..b005170c3 --- /dev/null +++ b/src/backends/meta-fd-source.h @@ -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 + +GSource * meta_create_fd_source (int fd, + const char *name, + GSourceFunc prepare, + GSourceFunc dispatch, + gpointer user_data, + GDestroyNotify notify); + +#endif /* META_FD_SOURCE_H */ diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 3a9176369..6766caba5 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -34,6 +34,7 @@ #include #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); diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h index 53a2ed76a..bfda20a39 100644 --- a/src/backends/native/meta-seat-impl.h +++ b/src/backends/native/meta-seat-impl.h @@ -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; diff --git a/src/meson.build b/src/meson.build index ba35c9279..863c78255 100644 --- a/src/meson.build +++ b/src/meson.build @@ -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',