[gnome-settings-daemon] rfkill: Add property to Rfkill helper to inhibit kernel handling
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon] rfkill: Add property to Rfkill helper to inhibit kernel handling
- Date: Thu, 4 May 2017 14:54:19 +0000 (UTC)
commit 3810072d2b3776c1183303adc8cd9f50732841a2
Author: Benjamin Berg <bberg redhat com>
Date: Tue Apr 18 11:56:09 2017 +0200
rfkill: Add property to Rfkill helper to inhibit kernel handling
The kernel will handle input events by default which is causing race
conditions and can for example make it impossible to disable airplane
mode again. Add API to allow disabling the kernel handler.
https://bugzilla.gnome.org/show_bug.cgi?id=760517
plugins/rfkill/rfkill-glib.c | 114 ++++++++++++++++++++++++++++++++++++++++++
plugins/rfkill/rfkill-glib.h | 4 ++
2 files changed, 118 insertions(+), 0 deletions(-)
---
diff --git a/plugins/rfkill/rfkill-glib.c b/plugins/rfkill/rfkill-glib.c
index 3ba4f89..a0e423b 100644
--- a/plugins/rfkill/rfkill-glib.c
+++ b/plugins/rfkill/rfkill-glib.c
@@ -31,6 +31,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
+#include <sys/ioctl.h>
#include <glib.h>
#include <gio/gio.h>
@@ -43,6 +44,10 @@ enum {
LAST_SIGNAL
};
+enum {
+ PROP_RFKILL_INPUT_INHIBITED = 1
+};
+
static int signals[LAST_SIGNAL] = { 0 };
struct _CcRfkillGlib {
@@ -52,6 +57,9 @@ struct _CcRfkillGlib {
GIOChannel *channel;
guint watch_id;
+ /* rfkill-input inhibitor */
+ int noinput_fd;
+
/* Pending Bluetooth enablement.
* If (@change_all_timeout_id != 0), then (task != NULL). The converse
* does not necessarily hold. */
@@ -356,6 +364,7 @@ event_cb (GIOChannel *source,
static void
cc_rfkill_glib_init (CcRfkillGlib *rfkill)
{
+ rfkill->noinput_fd = -1;
}
gboolean
@@ -435,6 +444,96 @@ cc_rfkill_glib_open (CcRfkillGlib *rfkill,
return TRUE;
}
+#define RFKILL_INPUT_INHIBITED(rfkill) (rfkill->noinput_fd >= 0)
+
+gboolean
+cc_rfkill_glib_get_rfkill_input_inhibited (CcRfkillGlib *rfkill)
+{
+ g_return_val_if_fail (CC_RFKILL_IS_GLIB (rfkill), FALSE);
+
+ return RFKILL_INPUT_INHIBITED(rfkill);
+}
+
+void
+cc_rfkill_glib_set_rfkill_input_inhibited (CcRfkillGlib *rfkill,
+ gboolean inhibit)
+{
+ g_return_if_fail (CC_RFKILL_IS_GLIB (rfkill));
+
+ /* Nothing to do if the states already match. */
+ if (RFKILL_INPUT_INHIBITED(rfkill) == inhibit)
+ return;
+
+ if (!inhibit && RFKILL_INPUT_INHIBITED(rfkill)) {
+ close (rfkill->noinput_fd);
+ rfkill->noinput_fd = -1;
+
+ g_debug ("Closed rfkill noinput FD.");
+ }
+
+ if (inhibit && !RFKILL_INPUT_INHIBITED(rfkill)) {
+ int fd, res;
+ /* Open write only as we don't want to do any IO to it ever. */
+ fd = open ("/dev/rfkill", O_WRONLY);
+ if (fd < 0) {
+ if (errno == EACCES)
+ g_warning ("Could not open RFKILL control device, please verify your
installation");
+ else
+ g_debug ("Could not open RFKILL control device: %s", g_strerror (errno));
+ return;
+ }
+
+ res = ioctl (fd, RFKILL_IOCTL_NOINPUT, (long) 0);
+ if (res != 0) {
+ g_warning ("Could not disable kernel handling of RFKILL related keys: %s", g_strerror
(errno));
+ close (fd);
+ return;
+ }
+
+ g_debug ("Opened rfkill-input inhibitor.");
+
+ rfkill->noinput_fd = fd;
+ }
+
+ g_object_notify (G_OBJECT (rfkill), "kernel-noinput");
+}
+
+static void
+cc_rfkill_glib_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ CcRfkillGlib *rfkill = CC_RFKILL_GLIB (object);
+
+ switch (prop_id) {
+ case PROP_RFKILL_INPUT_INHIBITED:
+ cc_rfkill_glib_set_rfkill_input_inhibited (rfkill, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+cc_rfkill_glib_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ CcRfkillGlib *rfkill = CC_RFKILL_GLIB (object);
+
+ switch (prop_id) {
+ case PROP_RFKILL_INPUT_INHIBITED:
+ g_value_set_boolean (value, RFKILL_INPUT_INHIBITED(rfkill));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
static void
cc_rfkill_glib_finalize (GObject *object)
{
@@ -451,6 +550,11 @@ cc_rfkill_glib_finalize (GObject *object)
}
g_clear_object (&rfkill->stream);
+ if (RFKILL_INPUT_INHIBITED(rfkill)) {
+ close (rfkill->noinput_fd);
+ rfkill->noinput_fd = -1;
+ }
+
G_OBJECT_CLASS(cc_rfkill_glib_parent_class)->finalize(object);
}
@@ -459,8 +563,18 @@ cc_rfkill_glib_class_init(CcRfkillGlibClass *klass)
{
GObjectClass *object_class = (GObjectClass *) klass;
+ object_class->set_property = cc_rfkill_glib_set_property;
+ object_class->get_property = cc_rfkill_glib_get_property;
object_class->finalize = cc_rfkill_glib_finalize;
+ g_object_class_install_property (object_class,
+ PROP_RFKILL_INPUT_INHIBITED,
+ g_param_spec_boolean ("rfkill-input-inhibited",
+ "Rfkill input inhibited",
+ "Whether to prevent the kernel from handling
RFKILL related key events.",
+ FALSE,
+ G_PARAM_READWRITE));
+
signals[CHANGED] =
g_signal_new ("changed",
G_TYPE_FROM_CLASS (klass),
diff --git a/plugins/rfkill/rfkill-glib.h b/plugins/rfkill/rfkill-glib.h
index 9468407..0655eb4 100644
--- a/plugins/rfkill/rfkill-glib.h
+++ b/plugins/rfkill/rfkill-glib.h
@@ -37,6 +37,10 @@ CcRfkillGlib *cc_rfkill_glib_new (void);
gboolean cc_rfkill_glib_open (CcRfkillGlib *rfkill,
GError **error);
+gboolean cc_rfkill_glib_get_rfkill_input_inhibited (CcRfkillGlib *rfkill);
+void cc_rfkill_glib_set_rfkill_input_inhibited (CcRfkillGlib *rfkill,
+ gboolean noinput);
+
void cc_rfkill_glib_send_change_all_event (CcRfkillGlib *rfkill,
guint rfkill_type,
gboolean enable,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]