diff xia-inhibitor.c @ 0:9a16bf50daba

Initial revision
author Guido Berhoerster <guido+xinhibit-applet@berhoerster.name>
date Sat, 27 Apr 2013 00:33:11 +0200
parents
children 957d697d27d3
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xia-inhibitor.c	Sat Apr 27 00:33:11 2013 +0200
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2013 Guido Berhoerster <guido+xinhibit-applet@berhoerster.name>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#include <X11/extensions/Xext.h>
+#ifdef HAVE_LIBXTST
+#include <X11/extensions/XTest.h>
+#endif /* HAVE_LIBXTST */
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkx.h>
+#include "xia-inhibitor.h"
+
+#define	FAKE_EVENT_TIMEOUT	20
+
+G_DEFINE_TYPE(XiaInhibitor, xia_inhibitor, G_TYPE_OBJECT)
+
+#define	XIA_INHIBITOR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+	XIA_TYPE_INHIBITOR, XiaInhibitorPrivate))
+
+struct _XiaInhibitorPrivate
+{
+	XiaInhibitor	*inhibitor;
+	gboolean	inhibited;
+	gboolean	have_xtest;
+	guint		generate_fake_event_id;
+};
+
+enum { PROP_0, PROP_INHIBITED };
+
+static gboolean
+generate_fake_event(gpointer data)
+{
+#ifdef HAVE_LIBXTST
+	XiaInhibitor *self = XIA_INHIBITOR(data);
+	static KeyCode keycode = 0;
+
+	if (!self->priv->have_xtest) {
+		return (TRUE);
+	}
+
+	if (keycode == 0) {
+		keycode = XKeysymToKeycode(gdk_x11_get_default_xdisplay(),
+		    XK_Alt_L);
+		if (keycode == 0) {
+			return (TRUE);
+		}
+	}
+
+	XTestFakeKeyEvent(gdk_x11_get_default_xdisplay(), keycode, True, 0);
+	XTestFakeKeyEvent(gdk_x11_get_default_xdisplay(), keycode, False, 0);
+
+	g_debug("Generated fake key event using XTEST");
+#endif /* HAVE_LIBXTST */
+
+	return (TRUE);
+}
+
+static void
+xia_inhibitor_set_property(GObject *object, guint property_id,
+    const GValue *value, GParamSpec *pspec)
+{
+	XiaInhibitor	*self = XIA_INHIBITOR(object);
+
+	switch (property_id) {
+	case PROP_INHIBITED: {
+		gboolean inhibited = g_value_get_boolean(value);
+		if (self->priv->inhibited == inhibited) {
+			return;
+		}
+
+		if (inhibited) {
+			self->priv->generate_fake_event_id = \
+			    g_timeout_add_seconds(FAKE_EVENT_TIMEOUT,
+			    (GSourceFunc)generate_fake_event, self);
+		} else {
+			g_source_remove(self->priv->generate_fake_event_id);
+			self->priv->generate_fake_event_id = 0;
+		}
+
+		self->priv->inhibited = inhibited;
+
+		g_debug("Automatic power management is %s", (inhibited) ?
+		    "inhibited" : "enabled");
+		break;
+	}
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+		break;
+	}
+}
+
+static void
+xia_inhibitor_get_property(GObject *object, guint property_id, GValue *value,
+    GParamSpec *pspec)
+{
+	XiaInhibitor	*self = XIA_INHIBITOR(object);
+
+	switch (property_id) {
+		case PROP_INHIBITED:
+			g_value_set_boolean(value, self->priv->inhibited);
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id,
+			    pspec);
+			break;
+	}
+}
+
+static void
+xia_inhibitor_finalize(GObject *gobject)
+{
+	XiaInhibitor	*self = XIA_INHIBITOR(gobject);
+
+	if (self->priv->generate_fake_event_id != 0) {
+		g_source_remove(self->priv->generate_fake_event_id);
+		self->priv->generate_fake_event_id = 0;
+	}
+
+	G_OBJECT_CLASS(xia_inhibitor_parent_class)->finalize(gobject);
+}
+
+static void
+xia_inhibitor_class_init(XiaInhibitorClass *klass)
+{
+	GObjectClass	*gobject_class = G_OBJECT_CLASS(klass);
+	GParamSpec	*pspec;
+
+	gobject_class->set_property = xia_inhibitor_set_property;
+	gobject_class->get_property = xia_inhibitor_get_property;
+	gobject_class->finalize = xia_inhibitor_finalize;
+
+	pspec = g_param_spec_boolean("inhibited", "Inhibited",
+	    "Whether automatic power management is inhibited", FALSE,
+	    G_PARAM_READWRITE);
+	g_object_class_install_property(gobject_class, PROP_INHIBITED, pspec);
+
+	g_type_class_add_private(klass, sizeof (XiaInhibitorPrivate));
+}
+
+static void
+xia_inhibitor_init(XiaInhibitor *self)
+{
+#ifdef HAVE_LIBXTST
+	int	event_base;
+	int	error_base;
+	int	xtest_major;
+	int	xtest_minor;
+#endif /* HAVE_LIBXTST */
+
+	self->priv = XIA_INHIBITOR_GET_PRIVATE(self);
+
+	self->priv->inhibited = FALSE;
+	self->priv->generate_fake_event_id = 0;
+
+#ifdef HAVE_LIBXTST
+	self->priv->have_xtest = ((gboolean)XTestQueryExtension(
+	    gdk_x11_get_default_xdisplay(), &event_base, &error_base,
+	    &xtest_major, &xtest_minor));
+#endif /* HAVE_LIBXTST */
+}
+
+void
+xia_inhibitor_set_inhibited(XiaInhibitor *self, gboolean inhibited)
+{
+	g_return_if_fail(XIA_IS_INHIBITOR(self));
+
+	g_object_set(G_OBJECT(self), "inhibited", inhibited, NULL);
+}
+
+gboolean
+xia_inhibitor_get_inhibited(XiaInhibitor *self)
+{
+	gboolean inhibited;
+
+	g_return_val_if_fail(XIA_IS_INHIBITOR(self), FALSE);
+
+	g_object_get(G_OBJECT(self), "inhibited", &inhibited, NULL);
+
+	return (inhibited);
+}
+
+XiaInhibitor *
+xia_inhibitor_new(void)
+{
+	return (g_object_new(XIA_TYPE_INHIBITOR, NULL));
+}