/***********************************************************************\ * Yello, BOINC World! - the simplest BOINC program with graphics * * This is the 'simplest' BOINC app that shows something on the screen, * though it ain't much. It just turns the screen yellow. * * Although the only point of this program is graphics, we have enclosed * graphics code in #ifdef APP_BOINC_GRAPHICS to show how you can build * a non-graphics version by turning off that symbol. If you do this, * you basically get the BOINC hello.C program. * * Updated 30 October 2004 to use newest BOINC API as of vers. 4.52 * Updated 12 May 2005 to remove the older API code. * Updated (no changes, really) to BOINC 5.2 as of 14 January 2006 * Updated 4 July 2006 to match BOINC 5.5.4 * * Eric Myers - 6 July 2004 * @(#) $Date: 2007/04/18 14:03:26 $ + $Name: $ + $Revision: 1.17 $ ***********************************************************************/ #ifdef _WIN32 // Stuff we only need on Windows: #include "boinc_win.h" #include "util.h" // parse_command_line(), boinc_sleep(), dtime()... #include "str_util.h" // parse_command_line() #endif /* BOINC API */ #include "diagnostics.h" #include "boinc_api.h" #include "filesys.h" /* version.h is only used to get BOINC version numbers */ #include "version.h" /* Graphics header files */ #ifdef BOINC_APP_GRAPHICS # if defined _WIN32 /* Windows */ # include # elif defined __APPLE_CC__ /* MacOS X */ # include # include # include # else /* Unix */ # include # endif # include "graphics_api.h" /* General graphics API for BOINC */ #endif /* Length of the job/display, roughly 360 seconds on my Linux laptop. */ #define TIME_LIMIT 360 void do_work(); // worker function (defined below) int main(int argc, char **argv) { int rc; /* Before initializing BOINC itself, intialize diagnostics. This directs stderr to a file and turns on some other checks */ boinc_init_diagnostics(BOINC_DIAG_REDIRECTSTDERR| BOINC_DIAG_DUMPCALLSTACKENABLED| BOINC_DIAG_TRACETOSTDERR); /* Output written to stderr will be returned with the Result (task) */ fprintf(stderr, "Hello, stderr!\n"); /* Note the BOINC version (from version.h above) */ fprintf(stderr, "APP: compiled with BOINC version %s\n", BOINC_VERSION_STRING); fflush(NULL); // see it as soon as we can /* Use either boinc_init_graphics(worker) for graphical apps, * or use boinc_init() for non-graphical apps, but not both. */ #ifdef BOINC_APP_GRAPHICS fprintf(stderr,"APP: graphics are enabled. Starting worker...\n"); /* Note that on Unix you really should compile your graphics into * a separate .so library and use here * rc = boinc_init_graphics_lib(do_work, argv[0]); * so that the app fails more gracefully when graphics cannot be started. * See the cube or lalanne apps for examples */ rc = boinc_init_graphics(do_work); if (rc) { fprintf(stderr,"APP: boinc_init_graphics(do_work) failed. RC=%d\n", rc); boinc_finish(rc); } #else // BOINC_APP_GRAPHICS fprintf(stderr,"APP: graphics not enabled.\n"); rc = boinc_init(); if (rc){ fprintf(stderr, "APP: boinc_init() failed. RC=%d\n", rc); exit(rc); } do_work(); /* should not return */ #endif // BOINC_APP_GRAPHICS fprintf(stderr,"APP: should never get here!\n"); exit(47); } /***************************************************** * Computation thread: the calculations are done by a separate function, * the "worker thread" function which was named to boinc_graphics_init() * (or at least invoked at the end of main() if there are no graphics). * This trivial example just generates some random numbers to kill time. */ void do_work(){ int rc, i; double fraction_done; char resolved_name[512]; FILE* f; /* Open output file and write to it, just to show that we can */ rc = boinc_resolve_filename("out.txt", resolved_name, sizeof(resolved_name)); if (rc){ fprintf(stderr, "APP: cannot resolve output filename for out.txt.\n"); boinc_finish(rc); } f = boinc_fopen(resolved_name, "w"); fprintf(f, "Hello, BOINC World!\n"); /* Wait a while, so we can see the "picture" */ fprintf(f, "Starting some computation (%d iterations)...\n", TIME_LIMIT); for(i=0;i