/* gtkSlash - Slashdot headlines news-ticker * (c) 1998 Troy Engel * * Based on original code from slashes.pl * (c) 1998 Alex Shnitman * * Other cool code from grun * (c) 1998 Southern Gold Development * * This code is distributed under the terms of the GNU * General Public License, etc etc. Use it, don't abuse it. */ /* just what it says - good for layout development * just remember to turn it off :P */ /* #define _LOCAL_TEST_MODE */ #include #ifdef WIN32 #include #define DIR_CHAR "\\" #define DOT_CHAR "_" #else #include #include #include #include #include #include #include #define DIR_CHAR "/" #define DOT_CHAR "." /* these two allow Win people to "hide" a cmdline * app. Provided here just so it works (could be used * for the same thing in 'startApp' on unix?) */ #define SW_SHOWDEFAULT 0 #define SW_HIDE 0 #endif #include "rcfuncs.h" #define MAX_BUFF 1024 #define APP_RC "gtkslashrc" #define MSG_TITLE "Slashdot Headlines" #define MSG_INIT "Initializing..." #define MSG_LOAD "Loading ultramode.txt..." #define MSG_LOAD_ERR "Error loading ultramode.txt!" #define MSG_RETRIEVE "Retrieving latest ultramode.txt..." #define MSG_RETR_ERR "Error retrieving ultramode.txt!" #define MSG_LAUNCH "Launching web browser..." #define MSG_LAUNCH_ERR "Error launching browser!" #define MSG_IDLE "Status: Idle (gtkSlash 0.5.5)" /* read from RC file */ gint refresh_timeout; gchar browser_cmd[MAX_BUFF]; gchar new_browser_cmd[MAX_BUFF]; gchar curl_cmd[MAX_BUFF]; BOOL compact_mode; gint num_fields; BOOL comments_flat; /* some ugly global vars */ GtkWidget *status; /* retrieves a line from a linefeed delimited textfile */ static gchar *app_getLine(FILE *file) { char *tmp, in; int cnt = 0, retIn; if (feof(file)) { return NULL; } else { tmp = g_malloc(sizeof(char) * MAX_BUFF); retIn = fread((void *) &in, sizeof(char), 1, file); if (retIn != 1) { g_free(tmp); return NULL; } while ((in != '\n') && (cnt < MAX_BUFF)) { tmp[cnt] = in; cnt++; retIn = fread((void *) &in, sizeof(char), 1, file); if (retIn != 1) { g_free(tmp); return NULL; } } if (cnt == MAX_BUFF) { g_free(tmp); return NULL; } tmp[cnt] = '\0'; return tmp; } } /* loads ultramode.txt into our clist */ static BOOL app_loadFile(GtkWidget *list, const gchar *fname) { gchar *line; gchar *article[4], *link; FILE *fHnd; gint i; fHnd = fopen(fname, "rb"); if (!fHnd) { return FALSE; } line = app_getLine(fHnd); if (!line) { fclose(fHnd); return FALSE; } /* loop till we find the first record delim */ while (strncmp(line, "%%", 2) != 0) { g_free(line); line = app_getLine(fHnd); } gtk_clist_clear(GTK_CLIST(list)); gtk_clist_freeze(GTK_CLIST(list)); link = NULL; while (line) { gboolean bGotit = FALSE; g_free(line); /* should be %% */ for (i = 0 ; ifocus_row); if (comments_flat) { gchar *tmp; tmp = strrchr(url, '.'); url[tmp - url] = '\0'; strcat(url, "_F.shtml"); } #ifndef WIN32 home = g_get_home_dir(); fname = g_malloc(sizeof(gchar) * (strlen(home) + 16)); strcpy(fname, home); strcat(fname, "/.netscape/lock"); rerr = lstat(fname, &buff); if (rerr == -1) { sprintf(cmd, new_browser_cmd, url); } else { sprintf(cmd, browser_cmd, url); } g_free(fname); #else sprintf(cmd, browser_cmd, url); #endif /* WIN32 */ gtk_label_set(GTK_LABEL(status), MSG_LAUNCH); if (!app_startApp(cmd, FALSE, SW_SHOWDEFAULT)) gtk_label_set(GTK_LABEL(status), MSG_LAUNCH_ERR); gtk_timeout_add(1000*5, app_timer_idle, NULL); } /* sorting */ static void app_click_column(GtkCList *clist, gint column, gpointer data) { if (column == clist->sort_column) { clist->sort_type = (clist->sort_type == GTK_SORT_ASCENDING) ? GTK_SORT_DESCENDING : GTK_SORT_ASCENDING; } else { gtk_clist_set_sort_column (clist, column); } gtk_clist_sort(clist); } static BOOL app_parse_rc() { gchar *home_env, *fname; gint retval; home_env = g_get_home_dir(); /* /home/foobar + /. + myrc + \0 */ fname = g_malloc(sizeof(gchar) * (strlen(home_env)+2+strlen(APP_RC)+1)); strcpy(fname, home_env); strcat(fname, DIR_CHAR); strcat(fname, DOT_CHAR); strcat(fname, APP_RC); retval = RCInit(fname); g_free(fname); /* if no personal file, look for system */ if (!retval) { #ifdef WIN32 gchar tmp[MAX_BUFF]; GetWindowsDirectory(tmp, sizeof(tmp)); /* c:\windows + \ + myrc + \0 */ fname = g_malloc(sizeof(gchar) * (sizeof(tmp) + 1 + sizeof(APP_RC) + 1)); strcpy(fname, tmp); #else /* /etc + / + myrc + \0 */ fname = g_malloc(sizeof(gchar) * (4 + 1 + strlen(APP_RC) + 1)); strcpy(fname, "/etc"); #endif strcat(fname, DIR_CHAR); strcat(fname, APP_RC); retval = RCInit(fname); g_free(fname); } refresh_timeout = RCGetInt("timeout-refresh", 1800); compact_mode = RCGetBool("compact-mode", FALSE); num_fields = RCGetInt("num-fields", 9); RCGetString("browser-cmd", browser_cmd, "", sizeof(browser_cmd)); RCGetString("new-browser-cmd", new_browser_cmd, "", sizeof(new_browser_cmd)); RCGetString("curl-cmd", curl_cmd, "", sizeof(curl_cmd)); comments_flat = RCGetBool("comments-flat", FALSE); RCShutDown(); return retval; } static void app_window() { GtkWidget *window, *vbox, *clist, *scrolled_win, *hbox, *but; gchar *titles[4] = {"Title", "Author", "Topic", "Comments"}; window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), MSG_TITLE); gtk_signal_connect(GTK_OBJECT(window), "destroy", (GtkSignalFunc) app_exit, NULL); gtk_widget_set_usize(GTK_WIDGET(window), 550, 155); gtk_window_set_policy(GTK_WINDOW (window), TRUE, TRUE, TRUE); vbox = gtk_vbox_new(FALSE, 5); gtk_container_border_width (GTK_CONTAINER(vbox), 5); gtk_container_add(GTK_CONTAINER(window), vbox); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start(GTK_BOX(vbox), scrolled_win, TRUE, TRUE, 0); clist = gtk_clist_new_with_titles(4, titles); gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_BROWSE); gtk_clist_set_column_width(GTK_CLIST(clist), 0, 250); gtk_clist_set_column_width(GTK_CLIST(clist), 1, 70); gtk_clist_set_column_width(GTK_CLIST(clist), 2, 100); gtk_clist_set_column_width(GTK_CLIST(clist), 3, 10); gtk_signal_connect(GTK_OBJECT (clist), "click_column", (GtkSignalFunc)app_click_column, NULL); gtk_container_add(GTK_CONTAINER(scrolled_win), clist); gtk_widget_show(clist); gtk_widget_show(scrolled_win); if (!compact_mode) { hbox = gtk_hbox_new(FALSE, 0); but = gtk_button_new_with_label("Refresh"); gtk_widget_set_usize(GTK_WIDGET(but), 70, 24); gtk_signal_connect(GTK_OBJECT(but), "clicked", (GtkSignalFunc) app_refresh, clist); gtk_box_pack_start(GTK_BOX(hbox), but, FALSE, FALSE, 0); gtk_widget_show(but); but = gtk_button_new_with_label("Read"); gtk_widget_set_usize(GTK_WIDGET(but), 70, 24); gtk_signal_connect(GTK_OBJECT(but), "clicked", (GtkSignalFunc) app_article_browse, (gpointer)clist); gtk_box_pack_start(GTK_BOX(hbox), but, FALSE, FALSE, 0); gtk_widget_show(but); status = gtk_label_new(MSG_INIT); gtk_box_pack_start(GTK_BOX(hbox), status, FALSE, FALSE, 10); gtk_widget_show(status); but = gtk_button_new_with_label("Quit"); gtk_widget_set_usize(GTK_WIDGET(but), 70, 24); gtk_signal_connect(GTK_OBJECT(but), "clicked", (GtkSignalFunc) app_exit, NULL); gtk_box_pack_end(GTK_BOX(hbox), but, FALSE, FALSE, 0); gtk_widget_show(but); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_widget_show(hbox); } else { gtk_clist_column_titles_hide(GTK_CLIST(clist)); gtk_signal_connect(GTK_OBJECT (clist), "select_row", (GtkSignalFunc) app_article_browse, (gpointer)clist); status = gtk_label_new(""); } gtk_timeout_add(1000*refresh_timeout, (GtkFunction) app_timer_refresh, clist); gtk_widget_show(vbox); gtk_widget_show(window); app_refresh(NULL, clist); } #ifdef WIN32 int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd) { #else int main(int argc, char **argv) { #endif #ifdef WIN32 /* parse into a command line ala argv, argc */ char **argv, *work, *twrk; int cnt, len, argc; len = strlen(lpCmdLine); argc = 0; for (cnt = 0; cnt < len; cnt++) { if (lpCmdLine[cnt] == ' ') { argc++; } } argv = g_malloc(sizeof(char *) * (argc + 1)); argv[argc] = NULL; if (argc == 1) { argv[0] = g_malloc(sizeof(char) * (len + 1)); strcpy(argv[0], lpCmdLine); } else { work = g_malloc(sizeof(char) * (len + 1)); strcpy(work, lpCmdLine); twrk = (char *) strtok(work, " "); argv[0] = twrk; cnt = 1; while (twrk) { twrk = (char *) strtok(NULL, " "); argv[cnt] = twrk; cnt++; } argv[cnt] = work; } #endif /* WIN32 */ gtk_init(&argc, &argv); app_parse_rc(); app_window(); gtk_main(); return(0) ; }