From 78bc1362e852f52507c88ee3c987004d8007fac7 Mon Sep 17 00:00:00 2001 From: Jason Woofenden Date: Sat, 13 Feb 2010 12:06:32 -0500 Subject: [PATCH] read stdin instead of polling a text file --- Makefile | 2 +- README | 50 ++++++++++++++++++++++++++++++++++++---------- now-playing-d.c | 59 ++++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 82 insertions(+), 29 deletions(-) diff --git a/Makefile b/Makefile index d2d6a53..3fb709c 100644 --- 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 --- 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+ diff --git a/now-playing-d.c b/now-playing-d.c index 7b2ec06..9ac043d 100644 --- a/now-playing-d.c +++ b/now-playing-d.c @@ -20,34 +20,52 @@ #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(); } -- 1.7.10.4