Mercurial > projects > xinhibit-applet
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)); +}