All pastes #242419 Raw Edit

Someone

public text v1 · immutable
·published 2006-11-07 07:02 UTC
rendered paste body
#include <gtk/gtk.h> // For gtk related stuff
#include <curl/curl.h> // The engine for retriving http data
#include <string.h> // Generic string manipulation functions (str*)
#include <stdlib.h> // For malloc and some other useful functions
#include <pcre.h> // For the regexp to get the song names from the http data
#include <unistd.h> // for getenv (get environmental variable)
#include <xosd.h>
char *recData = NULL; // The storage of http data

xosd *osd = NULL;
char *font = "-adobe-helvetica-bold-r-normal-*-*-320-*-*-p-*-iso8859-1";

char *curSong = NULL;

typedef struct _config
{
        int channel; // The current channel of interest
        char update; // Whether we pop up a splash telling updates
}config;

typedef struct _channelWin
{
        GtkWidget *window;
        GtkWidget *channelSpin;
        GtkWidget *ok;
}channelWin;


channelWin chWin;
config mainConfig;

// Curl launches this function when data is available
static int writer(char *data, size_t size, size_t nmemb, char *buffer)
{
        strcat(recData,data);
        return size*nmemb; // Return size read
}

void updateShow()
{
        xosd_display (osd, 0, XOSD_string, "Song:");
        xosd_display (osd, 1, XOSD_string, curSong);
        xosd_set_timeout(osd, 3);
}

void findSongNames()
{
        int offset;
        const char *error = malloc(128);
        pcre *reg = pcre_compile("Array\\(([0-9]+),\"(.+?)\",\"(.+?)\"",0,&error,&offset,NULL);
        char currSong[255];
        int ovector[30];
        ovector[2] = 0;
        while(pcre_exec(reg, NULL, recData, strlen(recData), ovector[2],0, ovector, 30)>1)
        {
                char *chan = strdup(recData+ovector[2]);
                chan[ovector[3]-ovector[2]]='\0';
                int chann = atoi(chan);
                if(chann==mainConfig.channel)
                {
                        int i = 4;
                        for(;i<8;i+=2)
                        {
                                int k;
                                for(k=ovector[i];k<ovector[i+1];k++)
                                {
                                        sprintf(currSong,"%s%c",currSong,recData[k]);
                                }
                                if(i!=6)
                                        sprintf(currSong,"%s - ",currSong);
                        }
                        printf("\n");
                }
        }
        if(curSong==NULL)
        {
                curSong = malloc(255);
        }
        if(strcmp(curSong,currSong)!=0)
        {
                strcpy(curSong,currSong);
                updateShow();
        }
}

gboolean updateListing(gpointer user_data)
{
        char url[] = "http://www.siriusbackstage.com:8999/itson/streams.php";
        recData = malloc(10240); // 10 kbytes for html data
        CURL *curl;
        CURLcode res;
        curl = curl_easy_init();
        if(curl)
        {
                curl_easy_setopt(curl, CURLOPT_URL, url);
                curl_easy_setopt(curl, CURLOPT_HEADER, 0);
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
                curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);

                res = curl_easy_perform(curl);

        }
        findSongNames();
        return 1;
}

gboolean closeConfigWindow(GtkWidget *win, gpointer user_data)
{
        gtk_widget_hide(win);
        return 1;
}

static void onMenu(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data)
{
        GtkMenu *pmenu = (GtkMenu*)gtk_menu_new();
        GtkWidget *menuItem = gtk_menu_item_new_with_label("Change Channel");
        gtk_menu_append(GTK_MENU(pmenu), menuItem);
        g_signal_connect_swapped(G_OBJECT(menuItem),"activate",G_CALLBACK(gtk_widget_show_all),chWin.window);
        menuItem = gtk_menu_item_new_with_label("Exit");
        gtk_menu_append(GTK_MENU(pmenu), menuItem);
        g_signal_connect_swapped(G_OBJECT(menuItem),"activate",G_CALLBACK(gtk_exit),0);
        gtk_widget_show_all((GtkWidget*)pmenu);
        gtk_menu_popup(pmenu,NULL,NULL,NULL,NULL,button,activate_time);
}

void saveConfig(GtkWidget *widg, gpointer user_data)
{
        char confFileP[255];
        strcpy(confFileP,getenv("HOME"));
        strcat(confFileP,"/.sirius");
        FILE *confFile = fopen(confFileP,"w");
        fwrite(&mainConfig,1,sizeof(config),confFile);
        fclose(confFile);
        updateListing(NULL);
        gtk_widget_hide(chWin.window);
}

void onSpin(GtkWidget *sbutton, gpointer user_data)
{
        mainConfig.channel = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(sbutton));
}

int main(int argc, char ** argv)
{
        osd = xosd_create(2);
        char confFileP[255];

        xosd_set_font (osd, font); 
        xosd_set_shadow_offset (osd, 2);
        xosd_set_colour (osd, "lawngreen");
   
        xosd_set_pos (osd, XOSD_bottom);
        xosd_set_vertical_offset (osd, 48);
   
        xosd_set_align (osd, XOSD_left);
        xosd_set_horizontal_offset (osd, 48);

        strcpy(confFileP,getenv("HOME"));
        strcat(confFileP,"/.sirius");
        FILE *confFile = fopen(confFileP,"r");
        if(confFile !=NULL)
        {
                fread(&mainConfig,1,sizeof(config),confFile); // Read config
                fclose(confFile);
        }else{
                mainConfig.channel = 1;
                mainConfig.update = 1;
                // Set default config and write it's ass!
                confFile = fopen(confFileP,"w");
                fwrite(&mainConfig,1,sizeof(config),confFile);
                fclose(confFile);
        }
        gtk_init(&argc, &argv);
        chWin.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        chWin.channelSpin = gtk_spin_button_new_with_range(1,198,1);
        GtkWidget *vbox = gtk_vbox_new(0,0);
        GtkWidget *hbox = gtk_hbox_new(0,0);
        GtkWidget *hbox2 = gtk_hbox_new(0,0);
        chWin.ok = gtk_button_new_with_label("Ok");
        gtk_container_add(GTK_CONTAINER(chWin.window),vbox);
        gtk_box_pack_start(GTK_BOX(vbox),hbox,0,0,0);
        gtk_box_pack_start(GTK_BOX(vbox),hbox2,0,0,0);
        gtk_box_pack_start(GTK_BOX(hbox),gtk_label_new("Select a channel:"),0,0,0);
        gtk_box_pack_start(GTK_BOX(hbox),chWin.channelSpin,0,0,0);
        gtk_box_pack_start(GTK_BOX(hbox2),chWin.ok,0,0,0);

        GtkStatusIcon *sysIcon; //Icon that will sit in the system tray
        sysIcon = gtk_status_icon_new_from_file("radio.xpm");
        g_signal_connect(G_OBJECT(sysIcon),"popup-menu",G_CALLBACK(onMenu),NULL);
        g_signal_connect(G_OBJECT(chWin.channelSpin),"value-changed",G_CALLBACK(onSpin),NULL);
        g_signal_connect(G_OBJECT(chWin.window),"delete-event",G_CALLBACK(closeConfigWindow),NULL);
        g_signal_connect(G_OBJECT(chWin.ok),"clicked",G_CALLBACK(saveConfig),NULL);
        g_timeout_add(10000,(GSourceFunc)updateListing,NULL); //Update list ever 2 minutes
        updateListing(NULL);
        gtk_main();
        return 0;
}