# HG changeset patch # User Guido Berhoerster # Date 1367015591 -7200 # Node ID 9a16bf50dabac120cc1b01fdd26b4dc80c890ed3 Initial revision diff -r 000000000000 -r 9a16bf50daba Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Sat Apr 27 00:33:11 2013 +0200 @@ -0,0 +1,128 @@ +# +# Copyright (C) 2013 Guido Berhoerster +# +# 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. +# + +PACKAGE = xinhibit-applet +APP_NAME = org.guido-berhoerster.xinhibit-applet +VERSION = 1 +DISTNAME := $(PACKAGE)-$(VERSION) + +INSTALL := install +INSTALL.exec := $(INSTALL) -D -m 0755 +INSTALL.data := $(INSTALL) -D -m 0644 +PAX := pax +GZIP := gzip +SED := sed +MSGFMT := msgfmt +INTLTOOL_UPDATE := intltool-update +INTLTOOL_MERGE := intltool-merge + +DESTDIR ?= +prefix ?= /usr/local +bindir ?= $(prefix)/bin +datadir ?= $(prefix)/share +mandir ?= $(datadir)/man +localedir ?= $(datadir)/locale +sysconfdir ?= /etc +xdgautostartdir ?= $(sysconfdir)/xdg/autostart + +HAVE_LIBXTST ?= 1 + +ifeq ($(HAVE_LIBXTST),1) + CPPFLAGS_LIBXTST := -DHAVE_LIBXTST + LDLIBS_LIBXTST := -lX11 -lXext -lXtst +endif + +OBJS = main.o xia-icon.o xia-inhibitor.o xia-debug.o +AUTOSTART_FILE = data/$(PACKAGE).desktop +MOFILES := $(patsubst %.po,%.mo,$(wildcard po/*.po)) +POTFILE = po/$(PACKAGE).pot +POSRCS := $(shell sed -e 's/\#.*//' -e '/^[ \t]*$$/d' \ + -e 's/^\[[^]]*\]//' po/POTFILES.in | paste -s -d ' ') +CPPFLAGS := $(CPPFLAGS_LIBXTST) \ + $(shell pkg-config --cflags glib-2.0 gtk+-2.0 unique-1.0) \ + -DPACKAGE="\"$(PACKAGE)\"" \ + -DAPP_NAME=\"$(APP_NAME)\" \ + -DVERSION=\"$(VERSION)\" \ + -DLOCALEDIR="\"$(localedir)\"" +LDLIBS := $(LDLIBS_LIBXTST) \ + $(shell pkg-config --libs glib-2.0 gtk+-2.0 unique-1.0) + +.DEFAULT_TARGET = all + +.PHONY: all clean clobber dist install + +all: $(PACKAGE) $(MOFILES) $(AUTOSTART_FILE) + +$(PACKAGE): $(OBJS) + $(LINK.o) $^ $(LDLIBS) -o $@ + +$(POTFILE): po/POTFILES.in $(POSRCS) + cd po/ && $(INTLTOOL_UPDATE) --pot --gettext-package="$(PACKAGE)" + +pot: $(POTFILE) + +update-po: $(POTFILE) + cd po/ && for lang in $(patsubst po/%.mo,%,$(MOFILES)); do \ + $(INTLTOOL_UPDATE) --dist --gettext-package="$(PACKAGE)" \ + $${lang}; \ + done + +%.o: %.c + $(COMPILE.c) -MD -o $@ $< + @cp $*.d $*.P; \ + $(SED) -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' -e '/^$$/ d' \ + -e 's/$$/ :/' < $*.d >> $*.P; \ + rm -f $*.d + +%.desktop: %.desktop.in $(MOFILES) + $(INTLTOOL_MERGE) --desktop-style --utf8 po $< $@ + +%.mo: %.po + $(MSGFMT) -o $@ $< + +install: + $(INSTALL.exec) $(PACKAGE) "$(DESTDIR)$(bindir)/$(PACKAGE)" + for lang in $(patsubst po/%.mo,%,$(MOFILES)); do \ + $(INSTALL.data) po/$${lang}.mo \ + "$(DESTDIR)$(localedir)/$${lang}/LC_MESSAGES/$(PACKAGE).mo"; \ + done + cd data/icons && for icon in */*/*.png scalable/*/*.svg; do \ + $(INSTALL.data) $$icon \ + "$(DESTDIR)$(datadir)/icons/hicolor/$${icon}"; \ + done + $(INSTALL.data) $(AUTOSTART_FILE) \ + "$(DESTDIR)$(xdgautostartdir)/$(notdir $(AUTOSTART_FILE))" + $(INSTALL.data) data/$(PACKAGE).1 \ + "$(DESTDIR)$(mandir)/man1/$(PACKAGE).1" + +clean: + rm -f $(PACKAGE) $(OBJS) $(POTFILE) $(MOFILES) $(AUTOSTART_FILE) + +clobber: clean + rm -f *.P + +dist: clobber + $(PAX) -w -x ustar -s ',.*/\..*,,' -s ',./[^/]*\.tar\.gz,,' \ + -s ',\./,$(DISTNAME)/,' . | $(GZIP) > $(DISTNAME).tar.gz + +-include $(patsubst %.o,%.P,$(OBJS)) diff -r 000000000000 -r 9a16bf50daba README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Sat Apr 27 00:33:11 2013 +0200 @@ -0,0 +1,23 @@ +Except otherwise noted, all files are Copyright (C) 2013 Guido Berhoerster and +distributed under the following license terms: + +Copyright (C) 2013 Guido Berhoerster + +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. diff -r 000000000000 -r 9a16bf50daba data/icons/16x16/apps/xinhibit-applet.png Binary file data/icons/16x16/apps/xinhibit-applet.png has changed diff -r 000000000000 -r 9a16bf50daba data/icons/16x16/status/xinhibit-applet-inhibited.png Binary file data/icons/16x16/status/xinhibit-applet-inhibited.png has changed diff -r 000000000000 -r 9a16bf50daba data/icons/16x16/status/xinhibit-applet-uninhibited.png Binary file data/icons/16x16/status/xinhibit-applet-uninhibited.png has changed diff -r 000000000000 -r 9a16bf50daba data/icons/22x22/apps/xinhibit-applet.png Binary file data/icons/22x22/apps/xinhibit-applet.png has changed diff -r 000000000000 -r 9a16bf50daba data/icons/22x22/status/xinhibit-applet-inhibited.png Binary file data/icons/22x22/status/xinhibit-applet-inhibited.png has changed diff -r 000000000000 -r 9a16bf50daba data/icons/22x22/status/xinhibit-applet-uninhibited.png Binary file data/icons/22x22/status/xinhibit-applet-uninhibited.png has changed diff -r 000000000000 -r 9a16bf50daba data/icons/24x24/apps/xinhibit-applet.png Binary file data/icons/24x24/apps/xinhibit-applet.png has changed diff -r 000000000000 -r 9a16bf50daba data/icons/24x24/status/xinhibit-applet-inhibited.png Binary file data/icons/24x24/status/xinhibit-applet-inhibited.png has changed diff -r 000000000000 -r 9a16bf50daba data/icons/24x24/status/xinhibit-applet-uninhibited.png Binary file data/icons/24x24/status/xinhibit-applet-uninhibited.png has changed diff -r 000000000000 -r 9a16bf50daba data/icons/48x48/apps/xinhibit-applet.png Binary file data/icons/48x48/apps/xinhibit-applet.png has changed diff -r 000000000000 -r 9a16bf50daba data/icons/48x48/status/xinhibit-applet-inhibited.png Binary file data/icons/48x48/status/xinhibit-applet-inhibited.png has changed diff -r 000000000000 -r 9a16bf50daba data/icons/48x48/status/xinhibit-applet-uninhibited.png Binary file data/icons/48x48/status/xinhibit-applet-uninhibited.png has changed diff -r 000000000000 -r 9a16bf50daba data/icons/scalable/apps/xinhibit-applet.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/icons/scalable/apps/xinhibit-applet.svg Sat Apr 27 00:33:11 2013 +0200 @@ -0,0 +1,240 @@ + + + + + xinhibit-applet + + + + + + image/svg+xml + + xinhibit-applet + 2013-04-22 + + + + Guido Berhoerster + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r 9a16bf50daba data/icons/scalable/status/xinhibit-applet-inhibited.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/icons/scalable/status/xinhibit-applet-inhibited.svg Sat Apr 27 00:33:11 2013 +0200 @@ -0,0 +1,240 @@ + + + + + xinhibit-applet-inhibited + + + + + + image/svg+xml + + xinhibit-applet-inhibited + 2013-04-22 + + + + Guido Berhoerster + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r 9a16bf50daba data/icons/scalable/status/xinhibit-applet-uninhibited.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/icons/scalable/status/xinhibit-applet-uninhibited.svg Sat Apr 27 00:33:11 2013 +0200 @@ -0,0 +1,194 @@ + + + + + xinhibit-applet-uninhibited + + + + + + image/svg+xml + + xinhibit-applet-uninhibited + 2013-04-22 + + + + Guido Berhoerster + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r 9a16bf50daba data/xinhibit-applet.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/xinhibit-applet.1 Sat Apr 27 00:33:11 2013 +0200 @@ -0,0 +1,49 @@ +.\" +.\" Copyright (C) 2013 Guido Berhoerster +.\" +.\" 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. +.\" +.TH XINHIBIT\-APPLET 1 "22 Apr 2013" +.SH NAME +xinhibit\-applet \- inhibit automatic power management +.SH SYNOPSIS +\fBxinhibit\-applet\fR +[\fB\-dhv?\fR] +.SH DESCRIPTION +\fBxinhibit\-applet\fR provides an icon in the tray area of the panel which +allows to inhibit automatic power management of power managers and screensavers. +.SH OPTIONS +The following options are supported: +.TP +.BR \-d ", " \-\-debug +Enable debugging output. +.TP +.BR \-h ", " \-? ", " \-\-help +Print a summary of all command line options and exit. +.TP +.BR \-v ", " \-\-version +Print the version number and exit. +.SH EXIT STATUS +.TP +.B 0 +The program has exited normally. +.TP +.B >0 +An Error has occurred. diff -r 000000000000 -r 9a16bf50daba data/xinhibit-applet.desktop.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/xinhibit-applet.desktop.in Sat Apr 27 00:33:11 2013 +0200 @@ -0,0 +1,9 @@ +[Desktop Entry] +_Name=XInhibit Applet +_GenericName=Applet for Inhibiting Automatic Power Management +_Comment=Inhibit automatic power management +Icon=xinhibit-applet +Exec=xinhibit-applet +Terminal=false +Type=Application +Categories=Utility;GTK;TrayIcon; diff -r 000000000000 -r 9a16bf50daba main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.c Sat Apr 27 00:33:11 2013 +0200 @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2013 Guido Berhoerster + * + * 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 +#include +#include +#include +#include +#include "xia-debug.h" +#include "xia-icon.h" + +int +main(int argc, char **argv) +{ + XiaIcon *icon; + UniqueApp *app = NULL; + int exitval = 0; + gboolean debug_mode = FALSE; + gboolean version = FALSE; + GOptionContext *context; + GError *error = NULL; + const GOptionEntry options[] = { + { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug_mode, + N_("Enable debugging output"), NULL }, + { "version", 'v', 0, G_OPTION_ARG_NONE, &version, + N_("Print the version number and exit"), NULL }, + { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, 0 } + }; + + setlocale(LC_ALL, ""); + + bindtextdomain(PACKAGE, LOCALEDIR); + bind_textdomain_codeset(PACKAGE, "UTF-8"); + textdomain(PACKAGE); + + gtk_init(&argc, &argv); + + g_set_application_name(_("XInhibit Applet")); + gtk_window_set_default_icon_name("xinhibit-applet"); + + context = g_option_context_new(_("- inhibit automatic power " + "management")); + g_option_context_add_main_entries(context, options, PACKAGE); + g_option_context_parse(context, &argc, &argv, &error); + g_option_context_free(context); + if (error) { + g_printerr("Error parsing command line options: %s\n", + error->message); + g_error_free(error); + exitval = 1; + goto out; + } + + xia_debug_init(debug_mode); + + if (version) { + g_print("%s %s\n", PACKAGE, VERSION); + goto out; + } + + app = unique_app_new(APP_NAME, NULL); + if (unique_app_is_running(app)) { + g_printerr("Another instance of " PACKAGE " is already " + "running, exiting\n"); + exitval = 1; + goto out; + } + + icon = xia_icon_new(); + + gtk_main(); + + g_object_unref(icon); +out: + if (app != NULL) + g_object_unref(app); + + exit(exitval); +} diff -r 000000000000 -r 9a16bf50daba po/POTFILES.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/po/POTFILES.in Sat Apr 27 00:33:11 2013 +0200 @@ -0,0 +1,4 @@ +main.c +xia-icon.c +xia-inhibitor.c +data/xinhibit-applet.desktop.in diff -r 000000000000 -r 9a16bf50daba xia-debug.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xia-debug.c Sat Apr 27 00:33:11 2013 +0200 @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2013 Guido Berhoerster + * + * 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 +#include +#include + +#include "xia-debug.h" + +static void +dummy_log_handler(const gchar *log_domain, GLogLevelFlags log_level, + const gchar *message, gpointer data) +{ + /* Swallow all messages */ +} + +void +xia_debug_init(gboolean debug_mode) +{ + /* + * glib >= 2.32 only shows debug messages if G_MESSAGES_DEBUG contains + * the log domain or "all", earlier glib version always show debugging + * output + */ +#if GLIB_CHECK_VERSION(2, 32, 0) + const gchar *debug_env; + gchar *debug_env_new; + + if (debug_mode) { + debug_env = g_getenv("G_MESSAGES_DEBUG"); + + if (debug_env == NULL) { + g_setenv("G_MESSAGES_DEBUG", G_LOG_DOMAIN, TRUE); + } else if (strstr(debug_env, G_LOG_DOMAIN) == NULL) { + debug_env_new = g_strdup_printf("%s %s", debug_env, + G_LOG_DOMAIN); + g_setenv("G_MESSAGES_DEBUG", debug_env_new, TRUE); + g_free(debug_env_new); + } + } +#else + if (!debug_mode) { + g_log_set_handler(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, + dummy_log_handler, NULL); + } +#endif /* GLIB_CHECK_VERSION (2,32,0) */ +} diff -r 000000000000 -r 9a16bf50daba xia-debug.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xia-debug.h Sat Apr 27 00:33:11 2013 +0200 @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2013 Guido Berhoerster + * + * 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. + */ + +#ifndef __XIA_DEBUG_H +#define __XIA_DEBUG_H + +G_BEGIN_DECLS + +void xia_debug_init(gboolean debug_mode); + +G_END_DECLS + +#endif /* __XIA_DEBUG_H */ diff -r 000000000000 -r 9a16bf50daba xia-icon.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xia-icon.c Sat Apr 27 00:33:11 2013 +0200 @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2013 Guido Berhoerster + * + * 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 +#include "xia-debug.h" +#include "xia-inhibitor.h" +#include "xia-icon.h" + +G_DEFINE_TYPE(XiaIcon, xia_icon, G_TYPE_OBJECT) + +#define XIA_ICON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + XIA_TYPE_ICON, XiaIconPrivate)) + +struct _XiaIconPrivate +{ + XiaInhibitor *inhibitor; + + GtkStatusIcon *status_icon; + GtkWidget *status_icon_popup_menu; + GtkWidget *check_menu_item_inhibited; +}; + +static void icon_update(XiaIcon *self); +static GtkWidget* icon_popup_menu_create(XiaIcon *self); +static void icon_popup_menu_popup(GtkStatusIcon *status_icon, guint button, + guint activate_time, gpointer user_data); +static void icon_activate(GtkStatusIcon *status_icon, gpointer user_data); + +static void +xia_icon_finalize(GObject *gobject) +{ + XiaIcon *self = XIA_ICON(gobject); + + gtk_widget_destroy(self->priv->status_icon_popup_menu); + g_object_unref(self->priv->status_icon_popup_menu); + g_object_unref(self->priv->status_icon); + g_object_unref(self->priv->inhibitor); + + G_OBJECT_CLASS(xia_icon_parent_class)->finalize(gobject); +} + +static void +xia_icon_class_init(XiaIconClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = xia_icon_finalize; + + g_type_class_add_private(klass, sizeof (XiaIconPrivate)); +} + +static void +xia_icon_init(XiaIcon *self) +{ + self->priv = XIA_ICON_GET_PRIVATE(self); + + self->priv->inhibitor = xia_inhibitor_new(); + + self->priv->status_icon = gtk_status_icon_new(); + gtk_status_icon_set_title(self->priv->status_icon, + _("Inhibit automatic power management")); + + self->priv->status_icon_popup_menu = icon_popup_menu_create(self); + g_object_ref(self->priv->status_icon_popup_menu); + g_object_ref_sink(GTK_OBJECT(self->priv->status_icon_popup_menu)); + + g_signal_connect(G_OBJECT(self->priv->status_icon), "activate", + G_CALLBACK(icon_activate), self); + g_signal_connect(G_OBJECT(self->priv->status_icon), "popup-menu", + G_CALLBACK(icon_popup_menu_popup), self); + + icon_update(self); +} + +static void +about_dialog_show(GtkMenuItem *item, gpointer user_data) +{ + const gchar *copyright = "Copyright \302\251 2013 Guido Berhoerster\n"; + const gchar *comments = _("Allows users to inhibit automatic power " + "management\n\nTo Ai\n"); + const gchar *logo_icon_name = "xinhibit-applet"; + const gchar *authors[2] = { + "Guido Berhoerster ", + NULL + }; + const gchar *license = + "Copyright \302\251 2013 Guido Berhoerster\n\n" + "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:\n\n" + "The above copyright notice and this permission notice shall be " + "included in all copies or substantial portions of the Software." + "\n\n" + "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."; + const gchar *translators = _("translators"); + + if (strcmp(translators, "translators") == 0) { + translators = NULL; + } + + gtk_show_about_dialog(NULL, "version", VERSION, "copyright", copyright, + "logo-icon-name", logo_icon_name, "comments", comments, "authors", + authors, "translator-credits", translators, "license", license, + "wrap-license", TRUE, NULL); +} + +static void +icon_update(XiaIcon *self) +{ + gboolean inhibited; + + inhibited = xia_inhibitor_get_inhibited(self->priv->inhibitor); + + g_debug("Updating icon, inhibit: %s", (inhibited) ? "on" : "off"); + + gtk_status_icon_set_tooltip_text(self->priv->status_icon, (inhibited) ? + _("Enable Automatic Power Management") : + _("Inhibit Automatic Power Management")); + gtk_status_icon_set_from_icon_name(self->priv->status_icon, + (inhibited) ? "xinhibit-applet-inhibited" : + "xinhibit-applet-uninhibited"); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM( + self->priv->check_menu_item_inhibited), inhibited); +} + +static void +icon_activate(GtkStatusIcon *status_icon, gpointer user_data) +{ + XiaIcon *self = XIA_ICON(user_data); + gboolean inhibited = xia_inhibitor_get_inhibited(self->priv->inhibitor); + + g_debug("Icon activated, inhibit: %s", (!inhibited) ? "on" : "off"); + + xia_inhibitor_set_inhibited(self->priv->inhibitor, !inhibited); + icon_update(self); +} + +static void +check_menu_item_inhibit_activate(GtkCheckMenuItem *menu_item, + gpointer user_data) +{ + XiaIcon *self = XIA_ICON(user_data); + gboolean inhibited = gtk_check_menu_item_get_active(menu_item); + + g_debug("Inhibit menu item activated, inhibit: %s", (inhibited) ? "on" : + "off"); + + if (xia_inhibitor_get_inhibited(self->priv->inhibitor) != inhibited) { + xia_inhibitor_set_inhibited(self->priv->inhibitor, inhibited); + icon_update(self); + } +} + +static GtkWidget* +icon_popup_menu_create(XiaIcon *self) +{ + GtkWidget *popup_menu = gtk_menu_new(); + GtkWidget *item; + GtkWidget *image; + + self->priv->check_menu_item_inhibited = \ + gtk_check_menu_item_new_with_mnemonic(_("_Inhibit Automatic Power " + "Management")); + gtk_menu_shell_append(GTK_MENU_SHELL(popup_menu), + self->priv->check_menu_item_inhibited); + g_signal_connect(G_OBJECT(self->priv->check_menu_item_inhibited), + "activate", G_CALLBACK(check_menu_item_inhibit_activate), self); + + item = gtk_image_menu_item_new_with_mnemonic(_("_About")); + image = gtk_image_new_from_icon_name(GTK_STOCK_ABOUT, + GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image); + gtk_menu_shell_append(GTK_MENU_SHELL(popup_menu), item); + g_signal_connect(G_OBJECT(item), "activate", + G_CALLBACK(about_dialog_show), self); + + gtk_widget_show_all(GTK_WIDGET(popup_menu)); + + return (popup_menu); +} + +static void +icon_popup_menu_popup(GtkStatusIcon *status_icon, guint button, + guint activate_time, gpointer user_data) +{ + XiaIcon *self = XIA_ICON(user_data); + + gtk_menu_popup(GTK_MENU(self->priv->status_icon_popup_menu), NULL, NULL, + NULL, NULL, button, activate_time); +} + +XiaIcon * +xia_icon_new(void) +{ + return (g_object_new(XIA_TYPE_ICON, NULL)); +} diff -r 000000000000 -r 9a16bf50daba xia-icon.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xia-icon.h Sat Apr 27 00:33:11 2013 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2013 Guido Berhoerster + * + * 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. + */ + +#ifndef __XIA_ICON_H +#define __XIA_ICON_H + +#include +#include + +G_BEGIN_DECLS + +#define XIA_TYPE_ICON (xia_icon_get_type()) +#define XIA_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + XIA_TYPE_ICON, XiaIcon)) +#define XIA_IS_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \ + XIA_TYPE_ICON)) +#define XIA_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \ + XIA_TYPE_ICON, XiaIconClass)) +#define XIA_IS_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \ + XIA_TYPE_ICON)) +#define XIA_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \ + XIA_TYPE_ICON, XiaIconClass)) + +typedef struct _XiaIcon XiaIcon; +typedef struct _XiaIconClass XiaIconClass; +typedef struct _XiaIconPrivate XiaIconPrivate; + +struct _XiaIcon +{ + GObject parent_instance; + XiaIconPrivate *priv; +}; + +struct _XiaIconClass +{ + GObjectClass parent_class; +}; + +XiaIcon *xia_icon_new(void); + +G_END_DECLS + +#endif /* __XIA_ICON_H */ diff -r 000000000000 -r 9a16bf50daba xia-inhibitor.c --- /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 + * + * 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 +#include +#include +#ifdef HAVE_LIBXTST +#include +#endif /* HAVE_LIBXTST */ +#include +#include +#include +#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)); +} diff -r 000000000000 -r 9a16bf50daba xia-inhibitor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xia-inhibitor.h Sat Apr 27 00:33:11 2013 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2013 Guido Berhoerster + * + * 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. + */ + +#ifndef __XIA_INHIBITOR_H +#define __XIA_INHIBITOR_H + +#include + +G_BEGIN_DECLS + +#define XIA_TYPE_INHIBITOR (xia_inhibitor_get_type()) +#define XIA_INHIBITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + XIA_TYPE_INHIBITOR, XiaInhibitor)) +#define XIA_IS_INHIBITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \ + XIA_TYPE_INHIBITOR)) +#define XIA_INHIBITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \ + XIA_TYPE_INHIBITOR, XiaInhibitorClass)) +#define XIA_IS_INHIBITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \ + XIA_TYPE_INHIBITOR)) +#define XIA_INHIBITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \ + XIA_TYPE_INHIBITOR, XiaInhibitorClass)) + +typedef struct _XiaInhibitor XiaInhibitor; +typedef struct _XiaInhibitorClass XiaInhibitorClass; +typedef struct _XiaInhibitorPrivate XiaInhibitorPrivate; + +struct _XiaInhibitor +{ + GObject parent_instance; + + XiaInhibitorPrivate *priv; +}; + +struct _XiaInhibitorClass +{ + GObjectClass parent_class; +}; + +XiaInhibitor *xia_inhibitor_new(void); +void xia_inhibitor_set_inhibited(XiaInhibitor *self, gboolean inhibited); +gboolean xia_inhibitor_get_inhibited(XiaInhibitor *self); + +G_END_DECLS + +#endif /* __XIA_INHIBITOR_H */