JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
read stdin instead of polling a text file master
authorJason Woofenden <jason@jasonwoof.com>
Sat, 13 Feb 2010 17:06:32 +0000 (12:06 -0500)
committerJason Woofenden <jason@jasonwoof.com>
Sat, 13 Feb 2010 17:17:34 +0000 (12:17 -0500)
Makefile
README
now-playing-d.c

index d2d6a53..3fb709c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 now-playing-d: now-playing-d.c eggtrayicon.c eggtrayicon.h
-       gcc -D"TMP_FILE=\"$(HOME)/tmp/now-playing\"" `pkg-config --cflags --libs gtk+-2.0` eggtrayicon.c now-playing-d.c -o $@
+       gcc `pkg-config --cflags --libs gtk+-2.0` eggtrayicon.c now-playing-d.c -o $@
 
 install: now-playing-d
        cp now-playing-d "$(HOME)/bin/"
diff --git a/README b/README
index 084fda0..6ea8e36 100644 (file)
--- a/README
+++ b/README
@@ -1,15 +1,45 @@
-This is a very simple program which displays one line of text in the
-notification area.
+now-playing-d
 
-It reads a file (~/tmp/now-playing) every second, and displays the contents in
-the notification area. For best results, make sure there's no newlines in the
-file, and that there's not too much text.
+NAME
+       now-playing-d - display text from stdin in the notification area.
 
-You can build it with this command: make
+DESCRIPTION
 
-And install it in your ~/bin with this command: make install
+       now-playind-d reads from stdin. Whenever a full new line is read, this
+       text is displayed in the notification area (replacing any text
+       now-playing-d put there before, if any).
+       
+       Careful not to make the lines too long for your notification area.
 
-This program is licensed under the GNU GPLv3+.
+BUILDING
 
-This download also contains a copy of eggtrayicon by Anders Carlsson, which is
-licensed under the GNU LGPLv2+
+       make
+
+
+INSTALLING
+
+       To install to ~/bin:
+
+       make install
+
+       or just copy now-playing-d wherever you like
+
+
+USAGE
+
+       Here's an example of how to make it so you can "echo" text to it from scripts:
+
+       mkfifo ~/tmp/now-playing
+       while true; do cat ~/tmp/now-playing; done | now-playing-d
+
+       echo 'Hello, world!' > ~/tmp/now-playing
+       sleep 2
+       echo 'another message' > ~/tmp/now-playing
+
+
+LICENSING
+
+       This program is licensed under the GNU GPLv3+.
+
+       This download also contains a copy of eggtrayicon by Anders Carlsson,
+       which is licensed under the GNU LGPLv2+
index 7b2ec06..9ac043d 100644 (file)
 #include "eggtrayicon.h"
 
 
-char buf[1000];
-char* playing[2] = {&buf[0], &buf[500]};
+gchar* playing[2];
 int playing_i = 0;
 
 
 // this gets called regularly by gtk
-static gboolean
-ticker(GtkWidget *widget) {
-       FILE * fd;
-       int len;
+gboolean
+stdin_callback(GIOChannel *channel, GIOCondition cond, gpointer data) {
+       GtkWidget *widget;
+       GIOStatus ret;
+       gsize length;
+       gsize terminator_pos;
+       GError *error = NULL;
+
+       widget = GTK_WIDGET(data);
 
        if (widget->window == NULL) {
                return FALSE;
        }
 
-       fd = fopen(TMP_FILE, "r");
-       if(fd == NULL) {
-               return TRUE;
+       ret = g_io_channel_read_line(
+               channel,
+               &(playing[playing_i]),
+               &length,
+               &terminator_pos,
+               &error);
+
+       if (ret == G_IO_STATUS_ERROR) {
+               g_error ("Error reading: %s\n", error->message);
+               gtk_exit(2);
+       }
+       if (length == 0) {
+               gtk_exit(0);
        }
-       len = fread(playing[playing_i], 1, 499, fd);
-       fclose(fd);
-       playing[playing_i][len] = 0;
 
-       if(strcmp(playing[playing_i], playing[1 - playing_i])) {
+       // remove terminator
+       if(terminator_pos) {
+               playing[playing_i][terminator_pos] = 0;
+       }
+
+
+       if(strcmp(playing[0], playing[1])) {
                gtk_label_set_text(GTK_LABEL(widget), playing[playing_i]);
        }
 
        playing_i = 1 - playing_i;
+       g_free(playing[playing_i]);
 
        // gtk_widget_queue_draw(widget);
        return TRUE;
@@ -58,22 +76,27 @@ int
 main(int argc, char *argv[]) {
        GtkWidget *label;
        EggTrayIcon *egg;
+       GIOChannel *channel;
 
        // initialize GTK
        gtk_set_locale();
        gtk_init(&argc, &argv);
 
+       // initialize globals
+       playing_i = 0;
+       playing[1] = g_strdup("");
+
        // make the widget
-       label = gtk_label_new("initializing...");
+       label = gtk_label_new("");
        egg = egg_tray_icon_new("what's this string do?");
        // nest and display the widget
        gtk_container_add(GTK_CONTAINER(egg), label);
        gtk_widget_show_all(GTK_WIDGET(egg));
 
-       // initialize and start ticker
-       playing[0][0] = 0;
-       playing[1][0] = 0;
-       g_timeout_add(1000, (GSourceFunc) ticker, (gpointer) label);
+       // watch stdin
+       channel = g_io_channel_unix_new(fileno(stdin));
+       g_io_channel_set_encoding(channel, NULL, NULL); // kiss
+       g_io_add_watch(channel, G_IO_IN, stdin_callback, (gpointer)label);
 
        gtk_main();
 }