From 17096ef891ce955a81d56527ce3f764121fb2deb Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 24 Jan 2010 01:46:17 +0000 Subject: Somewhat rationalise GTK throbber initialisation svn path=/trunk/netsurf/; revision=9872 --- gtk/gtk_gui.c | 76 ++++++++++++--------- gtk/gtk_throbber.c | 192 +++-------------------------------------------------- gtk/gtk_throbber.h | 5 +- 3 files changed, 56 insertions(+), 217 deletions(-) diff --git a/gtk/gtk_gui.c b/gtk/gtk_gui.c index d7c5fed18..f9e4dc556 100644 --- a/gtk/gtk_gui.c +++ b/gtk/gtk_gui.c @@ -105,10 +105,12 @@ static void nsgtk_PDF_set_pass(GtkButton *w, gpointer data); static void nsgtk_PDF_no_pass(GtkButton *w, gpointer data); #endif +#define THROBBER_FRAMES 9 + /** * Locate a shared resource file by searching known places in order. * - * \param buf buffer to write to. must be at least PATH_MAX chars + * \param buf buffer to write to. must be at least PATH_MAX chars. May be NULL and routine will allocate string which must be freed by caller. * \param filename file to look for * \param def default to return if file not found * \return buf @@ -123,6 +125,12 @@ static char *find_resource(char *buf, const char *filename, const char *def) char *cdir = getenv("HOME"); char t[PATH_MAX]; + if (buf == NULL) { + buf = malloc(PATH_MAX); + if (buf == NULL) + return NULL; + } + if (cdir != NULL) { strcpy(t, cdir); strcat(t, "/.netsurf/"); @@ -190,6 +198,39 @@ static void check_homedir(void) } } +/* This is an ugly hack to just get the new-style throbber going. + * It, along with the PNG throbber loader, need making more generic. + */ +static bool nsgtk_throbber_init(int framec) +{ + char **filenames; + char *filename; + char targetname[PATH_MAX]; + char targetdefault[PATH_MAX]; + int frame_num; + bool ret; + + filenames = calloc(framec, sizeof(char *)); + if (filenames == NULL) + return false; + + for (frame_num = 0; frame_num < framec; frame_num++) { + snprintf(targetname, PATH_MAX, "throbber/throbber%d.png", frame_num); + snprintf(targetdefault, PATH_MAX, "./gtk/res/%s", targetname); + filenames[frame_num] = find_resource(NULL, targetname, targetdefault); + } + + ret = nsgtk_throbber_initialise_from_png(frame_num, filenames); + + for (frame_num = 0; frame_num < framec; frame_num++) { + free(filenames[frame_num]); + } + free(filenames); + + return ret; + +} + static void *myrealloc(void *ptr, size_t len, void *pw) { return realloc(ptr, len); @@ -198,7 +239,10 @@ static void *myrealloc(void *ptr, size_t len, void *pw) /** Normal entry point from OS */ int main(int argc, char** argv) { + gtk_init(&argc, &argv); + setbuf(stderr, NULL); + return netsurf_main(argc, argv); } @@ -206,8 +250,6 @@ void gui_init(int argc, char** argv) { char buf[PATH_MAX]; - gtk_init(&argc, &argv); - check_homedir(); find_resource(buf, "netsurf.glade", "./gtk/res/netsurf.glade"); @@ -278,33 +320,7 @@ void gui_init(int argc, char** argv) nsgtk_completion_init(); - /* This is an ugly hack to just get the new-style throbber going. - * It, along with the PNG throbber loader, need making more generic. - */ - { -#define STROF(n) #n -#define FIND_THROB(n) find_resource(filenames[(n)], \ - "throbber/throbber" STROF(n) ".png", \ - "./gtk/res/throbber/throbber" STROF(n) ".png") - char filenames[9][PATH_MAX]; - FIND_THROB(0); - FIND_THROB(1); - FIND_THROB(2); - FIND_THROB(3); - FIND_THROB(4); - FIND_THROB(5); - FIND_THROB(6); - FIND_THROB(7); - FIND_THROB(8); - nsgtk_throbber_initialise_from_png(9, - filenames[0], filenames[1], filenames[2], filenames[3], - filenames[4], filenames[5], filenames[6], filenames[7], - filenames[8]); -#undef FIND_THROB -#undef STROF - } - - if (nsgtk_throbber == NULL) + if (nsgtk_throbber_init(THROBBER_FRAMES) == false) die("Unable to load throbber image.\n"); option_core_select_menu = true; diff --git a/gtk/gtk_throbber.c b/gtk/gtk_throbber.c index ea7cf43ac..5f79a2182 100644 --- a/gtk/gtk_throbber.c +++ b/gtk/gtk_throbber.c @@ -38,12 +38,12 @@ struct nsgtk_throbber *nsgtk_throbber = NULL; * \param ... Filenames of PNGs containing frames. * \return true on success. */ -bool nsgtk_throbber_initialise_from_png(const int frames, ...) +bool nsgtk_throbber_initialise_from_png(const int frames, char** frame_files) { - va_list filenames; GError *err = NULL; struct nsgtk_throbber *throb; /**< structure we generate */ bool errors_when_loading = false; /**< true if a frame failed */ + int frame_loop; if (frames < 2) { /* we need at least two frames - one for idle, one for active */ @@ -64,25 +64,20 @@ bool nsgtk_throbber_initialise_from_png(const int frames, ...) return false; } - va_start(filenames, frames); - - for (int i = 0; i < frames; i++) { - const char *fn = va_arg(filenames, const char *); - throb->framedata[i] = gdk_pixbuf_new_from_file(fn, &err); + for (frame_loop = 0; frame_loop < frames; frame_loop++) { + throb->framedata[frame_loop] = gdk_pixbuf_new_from_file(frame_files[frame_loop], &err); if (err != NULL) { LOG(("Error when loading %s: %s (%d)", - fn, err->message, err->code)); - throb->framedata[i] = NULL; + frame_files[frame_loop], err->message, err->code)); + throb->framedata[frame_loop] = NULL; errors_when_loading = true; } } - va_end(filenames); - if (errors_when_loading == true) { - for (int i = 0; i < frames; i++) { - if (throb->framedata[i] != NULL) - gdk_pixbuf_unref(throb->framedata[i]); + for (frame_loop = 0; frame_loop < frames; frame_loop++) { + if (throb->framedata[frame_loop] != NULL) + gdk_pixbuf_unref(throb->framedata[frame_loop]); } free(throb->framedata); @@ -96,175 +91,6 @@ bool nsgtk_throbber_initialise_from_png(const int frames, ...) return true; } -/** - * Creates the throbber using a single GIF, using the first frame as the - * inactive throbber, and the others for the active animation. The GIF must - * therefor have at least two frames. - * - * \param fn Filename of GIF to use. It must have at least two frames. - * \return true on success. - */ -#ifdef WITH_GIF -extern gif_bitmap_callback_vt gif_bitmap_callbacks; /**< external structure containing - * bitmap callback functions */ -bool nsgtk_throbber_initialise_from_gif(const char *fn) -{ - /* disect the GIF provided by filename in *fn into a series of - * GdkPixbuf for use later. - */ - gif_animation gif; - struct nsgtk_throbber *throb; /**< structure we generate */ - FILE *fh; - int res; - size_t size; - unsigned char *data; - int i; - - throb = calloc(1, sizeof(struct nsgtk_throbber)); - if (throb == NULL) - return false; - - fh = fopen(fn, "rb"); - if (fh == NULL) { - LOG(("Unable to open throbber image '%s' for reading!", fn)); - free(throb); - return false; - } - - /* discover the size of the data file. */ - fseek(fh, 0, SEEK_END); - size = ftell(fh); - fseek(fh, 0, SEEK_SET); - - /* allocate a block of sufficient size, and load the data in. */ - data = malloc(size); - if (data == NULL) { - fclose(fh); - free(throb); - return false; - } - - if (fread(data, size, 1, fh) != 1) { - /* interesting; we couldn't read it all in. */ - free(data); - fclose(fh); - free(throb); - return false; - } - fclose(fh); - - /* create our gif animation */ - gif_create(&gif, &gif_bitmap_callbacks); - - /* initialise the gif_animation structure. */ - do { - res = gif_initialise(&gif, size, data); - if (res != GIF_OK && res != GIF_WORKING) { - switch (res) { - case GIF_INSUFFICIENT_FRAME_DATA: - case GIF_FRAME_DATA_ERROR: - case GIF_INSUFFICIENT_DATA: - case GIF_DATA_ERROR: - LOG(("GIF image '%s' appears invalid!", fn)); - break; - case GIF_INSUFFICIENT_MEMORY: - LOG(("Ran out of memory decoding GIF image '%s'!", fn)); - break; - } - gif_finalise(&gif); - free(data); - free(throb); - return false; - } - } while (res != GIF_OK); - - throb->nframes = gif.frame_count; - - if (throb->nframes < 2) { - /* we need at least two frames - one for idle, one for active */ - LOG(("Insufficent number of frames in throbber image '%s'!", - fn)); - LOG(("(GIF contains %d frames, where 2 is a minimum.)", - throb->nframes)); - gif_finalise(&gif); - free(data); - free(throb); - return false; - } - - throb->framedata = malloc(sizeof(GdkPixbuf *) * throb->nframes); - if (throb->framedata == NULL) { - gif_finalise(&gif); - free(data); - free(throb); - return false; - } - - /* decode each frame in turn, extracting the struct bitmap * for each, - * and put that in our array of frames. - */ - for (i = 0; i < throb->nframes; i++) { - res = gif_decode_frame(&gif, i); - if (res != GIF_OK) { - switch (res) { - case GIF_INSUFFICIENT_FRAME_DATA: - case GIF_FRAME_DATA_ERROR: - case GIF_INSUFFICIENT_DATA: - case GIF_DATA_ERROR: - LOG(("GIF image '%s' appears invalid!", fn)); - break; - case GIF_INSUFFICIENT_MEMORY: - LOG(("Ran out of memory decoding GIF image '%s'!", fn)); - break; - } - - gif_finalise(&gif); - free(data); - while (i >= 0) { - if (throb->framedata[i] != NULL) - gdk_pixbuf_unref(throb->framedata[i]); - i--; - } - free(throb->framedata); - free(throb); - return false; - } - - throb->framedata[i] = gdk_pixbuf_copy( - gtk_bitmap_get_primary(gif.frame_image)); - if (throb->framedata[i] == NULL) { - gif_finalise(&gif); - free(data); - while (i >= 0) { - if (throb->framedata[i] != NULL) - gdk_pixbuf_unref(throb->framedata[i]); - i--; - } - free(throb->framedata); - free(throb); - return false; - } - } - - gif_finalise(&gif); - free(data); - - /* debug code: save out each frame as a PNG to make sure decoding is - * working correctly. - - for (i = 0; i < throb->nframes; i++) { - char fname[20]; - sprintf(fname, "frame%d.png", i); - gdk_pixbuf_save(throb->framedata[i], fname, "png", NULL, NULL); - } - */ - - nsgtk_throbber = throb; - - return true; -} -#endif - void nsgtk_throbber_finalise(void) { int i; diff --git a/gtk/gtk_throbber.h b/gtk/gtk_throbber.h index b7d3d8804..1463c9b26 100644 --- a/gtk/gtk_throbber.h +++ b/gtk/gtk_throbber.h @@ -29,10 +29,7 @@ struct nsgtk_throbber extern struct nsgtk_throbber *nsgtk_throbber; -#ifdef WITH_GIF -bool nsgtk_throbber_initialise_from_gif(const char *fn); -#endif -bool nsgtk_throbber_initialise_from_png(const int frames, ...); +bool nsgtk_throbber_initialise_from_png(const int frames, char** frame_files); void nsgtk_throbber_finalise(void); #endif /* __GTK_THROBBER_H__ */ -- cgit v1.2.3