Re: [gimp-devel] Starting the GIMP



I have been thinking a bit more about this "splash screen" idea for
the GIMP.  I'm CC'ing this message to the gtk-list because a similar
problem could occur with other GTK applications.  For those who are
only on that list, here is an excerpt of what I wrote yesterday:

> So, back to my original question: how can I display a window (and if
> possible refresh it from time to time) without calling gtk_main(),
> which cannot be called until the initialization is complete?
> 
> The two (ugly) solutions are still:
> - bypassing gtk and using raw Xlib calls
> - creating a separate process which can call its own gtk_main()
> 
> Or is there a way to tell gtk to perform some operations and check for
> events in a non-blocking way before entering gtk_main(), like this can
> be done in Xt and other toolkits?

Well, maybe there is another solution, but I am not sure that it would
work without nasty side-effects, so I would like some comments from
people who are more familiar with GTK and with the startup phase of
the GIMP...

Instead of doing all the initializations (which take a long time) and
then calling gtk_main(), I could re-write all this in such a way that
gtk_main() is called very early during the startup phase, probably
just after gtk_rc_parse().  Then all the time-consuming tasks would be
done in a callback function that would call the init functions one by
one, giving the control back to GTK for a short while after each step.
That callback would be started by gtk_idle_add() or gtk_timeout_add().

In pseudo-C-code, I would replace the current code which looks like
this:

  main(...)
  {
    gtk_init(...);
    ...
    app_init();
    gtk_main();
  }

  app_init()
  {
    ...
    gtk_rc_parse(...);
    parse_gimprc();
    brushes_init();
    patterns_init();
    palettes_init();
    gradients_init();
    plug_in_init();
    if (nointerface == FALSE)
      {
        get_standard_colormaps();
        create_toolbox();
        gximage_init();
        ...
      }
    ...
  }

By the following code, which uses a callback for calling all the init
functions in sequence:

  main(...)
  {
    gtk_init(...);
    ...
    gtk_rc_parse(...);
    if (nointerface == FALSE)
      {
        get_standard_colormaps();
        display_the_nice_splash_screen();
      }
    gtk_idle_add(init_callback, NULL);   /* or gtk_timeout_add(1, ...) */
    gtk_main();
  }

  init_callback()
  {
    static int init_sequence = 0;

    switch (init_sequence)
    {
      case 0: parse_gimprc(); break;
      case 1: brushes_init(); break;
      case 2: patterns_init(); break;
      case 3: palettes_init(); break;
      case 4: gradients_init(); break;
      case 5: plug_in_init(); break;
      default:
              if (nointerface == FALSE)
              {
                destroy_the_nice_splash_screen();
                create_toolbox();
                gximage_init();
                ...
              }
              return FALSE;
    }
    ...
    update_the_nice_splash_screen();
    init_sequence++;
    return TRUE;    /* gtk should process some events then call this again */
  }

Of course, the actual code is a bit different because the GIMP also
checks if it has been installed correctly and does a few other routine
tests, but the principle is similar.

I am planning to implement that over the week-end if nobody objects.

Any comments?  Do you thing this will work?  I can already see a
problem with get_standard_colormaps() which should be called after
parse_gimprc(), but maybe there is a way around that.  Did I forget
any other depencies that would force me to do one thing before
another, thus preventing me from opening the first window before the
initialization is complete?  Note that the splash screen does not
really need to check the .gimprc first, because it will be destroyed
anyway.  It is only the toolbox that needs the stuff in .gimprc.

-Raphael



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]