home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / app_procs.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-25  |  21.2 KB  |  821 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18. #include "config.h"
  19.  
  20. #include <signal.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #ifdef HAVE_SYS_PARAM_H
  25. #include <sys/param.h>
  26. #endif
  27. #include <sys/types.h>
  28. #ifdef HAVE_DIRENT_H
  29. #include <dirent.h>
  30. #endif
  31. #ifdef HAVE_UNISTD_H
  32. #include <unistd.h>
  33. #endif
  34.  
  35. #ifdef G_OS_WIN32
  36. #include <process.h>        /* For _getpid() */
  37. #endif
  38.  
  39. #include <gtk/gtk.h>
  40.  
  41. #include "libgimp/gimpfeatures.h"
  42. #include "libgimp/gimpenv.h"
  43.  
  44. #include "apptypes.h"
  45.  
  46. #include "appenv.h"
  47. #include "app_procs.h"
  48. #include "batch.h"
  49. #include "brush_select.h"
  50. #include "color_transfer.h"
  51. #include "curves.h"
  52. #include "colormaps.h"
  53. #include "context_manager.h"
  54. #include "devices.h"
  55. #include "errorconsole.h"
  56. #include "fileops.h"
  57. #include "gdisplay.h"
  58. #include "gdisplay_ops.h"
  59. #include "gimpbrushlist.h"
  60. #include "gimprc.h"
  61. #include "gimpparasite.h"
  62. #include "gimpset.h"
  63. #include "gimpui.h"
  64. #include "global_edit.h"
  65. #include "gradient_select.h"
  66. #include "gradient.h"
  67. #include "gximage.h"
  68. #include "hue_saturation.h"
  69. #include "image_render.h"
  70. #include "interface.h"
  71. #include "internal_procs.h"
  72. #include "lc_dialog.h"
  73. #include "levels.h"
  74. #include "menus.h"
  75. #include "paint_funcs.h"
  76. #include "palette.h"
  77. #include "pattern_select.h"
  78. #include "patterns.h"
  79. #include "plug_in.h"
  80. #include "module_db.h"
  81. #include "procedural_db.h"
  82. #include "session.h"
  83. #include "temp_buf.h"
  84. #include "tile_swap.h"
  85. #include "tips_dialog.h"
  86. #include "tools.h"
  87. #include "undo.h"
  88. #include "unitrc.h"
  89. #include "xcf.h"
  90. #include "errors.h"
  91. #include "docindex.h"
  92. #include "colormap_dialog.h"
  93.  
  94. #ifdef DISPLAY_FILTERS
  95. #include "gdisplay_color.h"
  96. #endif /* DISPLAY_FILTERS */
  97.  
  98. #include "color_notebook.h"
  99. #include "color_select.h"
  100. #include "gimpparasite.h"
  101.  
  102. #include "libgimp/gimplimits.h"
  103. #include "libgimp/gimpintl.h"
  104.  
  105. #define LOGO_WIDTH_MIN  300
  106. #define LOGO_HEIGHT_MIN 110
  107. #define AUTHORS "Spencer Kimball & Peter Mattis"
  108.  
  109. #define SHOW_NEVER 0
  110. #define SHOW_LATER 1
  111. #define SHOW_NOW   2
  112.  
  113. /*  Function prototype for affirmation dialog when exiting application  */
  114. static void      really_quit_dialog                   (void);
  115. static void      make_initialization_status_window    (void);
  116. static void      destroy_initialization_status_window (void);
  117. static gboolean  splash_logo_load                     (GtkWidget *window);
  118. static gboolean  splash_logo_load_size                (GtkWidget *window);
  119. static void      splash_logo_draw                     (GtkWidget *widget);
  120. static void      splash_text_draw                     (GtkWidget *widget);
  121. static void      splash_logo_expose                   (GtkWidget *widget);
  122. static void      toast_old_temp_files                 (void);
  123.  
  124.  
  125. static gboolean is_app_exit_finish_done = FALSE;
  126. gboolean        we_are_exiting          = FALSE;
  127.  
  128. static GtkWidget *logo_area   = NULL;
  129. static GdkPixmap *logo_pixmap = NULL;
  130. static gint logo_width        = 0;
  131. static gint logo_height       = 0;
  132. static gint logo_area_width   = 0;
  133. static gint logo_area_height  = 0;
  134. static gint show_logo         = SHOW_NEVER;
  135. static gint max_label_length  = MAXPATHLEN;
  136.  
  137.  
  138. void
  139. gimp_init (gint    gimp_argc,
  140.        gchar **gimp_argv)
  141. {
  142.   /* Initialize the application */
  143.   app_init ();
  144.  
  145.   /* Parse the rest of the command line arguments as images to load */
  146.   if (gimp_argc > 0)
  147.     while (gimp_argc--)
  148.       {
  149.     if (*gimp_argv)
  150.       file_open (*gimp_argv, *gimp_argv);
  151.     gimp_argv++;
  152.       }
  153.  
  154.   batch_init ();
  155.  
  156.   /* Handle showing dialogs with gdk_quit_adds here  */
  157.   if (!no_interface && show_tips)
  158.     tips_dialog_create ();
  159. }
  160.  
  161. static gboolean
  162. splash_logo_load_size (GtkWidget *window)
  163. {
  164.   gchar buf[1024];
  165.   FILE *fp;
  166.  
  167.   if (logo_pixmap)
  168.     return TRUE;
  169.  
  170.   g_snprintf (buf, sizeof(buf), "%s" G_DIR_SEPARATOR_S "gimp_splash.ppm",
  171.           gimp_data_directory ());
  172.  
  173.   fp = fopen (buf, "rb");
  174.   if (!fp)
  175.     return FALSE;
  176.  
  177.   fgets (buf, sizeof (buf), fp);
  178.   if (strcmp (buf, "P6\n") != 0)
  179.     {
  180.       fclose (fp);
  181.       return FALSE;
  182.     }
  183.  
  184.   fgets (buf, sizeof (buf), fp);
  185.   fgets (buf, sizeof (buf), fp);
  186.   sscanf (buf, "%d %d", &logo_width, &logo_height);
  187.  
  188.   fclose (fp);
  189.  
  190.   return TRUE;
  191. }
  192.  
  193. static gboolean
  194. splash_logo_load (GtkWidget *window)
  195. {
  196.   GtkWidget *preview;
  197.   GdkGC *gc;
  198.   gchar   buf[1024];
  199.   guchar *pixelrow;
  200.   FILE *fp;
  201.   gint count;
  202.   gint i;
  203.  
  204.   if (logo_pixmap)
  205.     return TRUE;
  206.  
  207.   g_snprintf (buf, sizeof(buf), "%s" G_DIR_SEPARATOR_S "gimp_splash.ppm",
  208.           gimp_data_directory ());
  209.  
  210.   fp = fopen (buf, "rb");
  211.   if (!fp)
  212.     return FALSE;
  213.  
  214.   fgets (buf, sizeof (buf), fp);
  215.   if (strcmp (buf, "P6\n") != 0)
  216.     {
  217.       fclose (fp);
  218.       return FALSE;
  219.     }
  220.  
  221.   fgets (buf, sizeof (buf), fp);
  222.   fgets (buf, sizeof (buf), fp);
  223.   sscanf (buf, "%d %d", &logo_width, &logo_height);
  224.  
  225.   fgets (buf, sizeof (buf), fp);
  226.   if (strcmp (buf, "255\n") != 0)
  227.     {
  228.       fclose (fp);
  229.       return FALSE;
  230.     }
  231.  
  232.   preview = gtk_preview_new (GTK_PREVIEW_COLOR);
  233.   gtk_preview_size (GTK_PREVIEW (preview), logo_width, logo_height);
  234.   pixelrow = g_new (guchar, logo_width * 3);
  235.  
  236.   for (i = 0; i < logo_height; i++)
  237.     {
  238.       count = fread (pixelrow, sizeof (unsigned char), logo_width * 3, fp);
  239.       if (count != (logo_width * 3))
  240.     {
  241.       gtk_widget_destroy (preview);
  242.       g_free (pixelrow);
  243.       fclose (fp);
  244.       return FALSE;
  245.     }
  246.       gtk_preview_draw_row (GTK_PREVIEW (preview), pixelrow, 0, i, logo_width);
  247.     }
  248.  
  249.   gtk_widget_realize (window);
  250.   logo_pixmap = gdk_pixmap_new (window->window, logo_width, logo_height,
  251.                 gtk_preview_get_visual ()->depth);
  252.   gc = gdk_gc_new (logo_pixmap);
  253.   gtk_preview_put (GTK_PREVIEW (preview),
  254.            logo_pixmap, gc,
  255.            0, 0, 0, 0, logo_width, logo_height);
  256.   gdk_gc_destroy (gc);
  257.  
  258.   gtk_widget_unref (preview);
  259.   g_free (pixelrow);
  260.  
  261.   fclose (fp);
  262.  
  263.   return TRUE;
  264. }
  265.  
  266. static void
  267. splash_text_draw (GtkWidget *widget)
  268. {
  269.   GdkFont *font;
  270.  
  271.   /* this is a font, provide only one single font definition */
  272.   font = gdk_font_load (_("-*-helvetica-bold-r-normal--*-140-*-*-*-*-*-*"));
  273.   if (!font)
  274.     {
  275.       GtkStyle *style = gtk_widget_get_style (widget);
  276.       font = style->font;
  277.       gdk_font_ref (font);
  278.     }
  279.   
  280.   gdk_draw_string (widget->window,
  281.            font,
  282.            widget->style->fg_gc[GTK_STATE_NORMAL],
  283.            ((logo_area_width - gdk_string_width (font,  _("The GIMP"))) / 2),
  284.            (0.25 * logo_area_height),
  285.            _("The GIMP"));
  286.  
  287.   gdk_font_unref (font);
  288.   
  289.   /* this is a fontset, e.g. multiple comma-separated font definitions */
  290.   font = gdk_fontset_load (_("-*-helvetica-bold-r-normal--*-120-*-*-*-*-*-*,*"));
  291.   if (!font)
  292.     {
  293.       GtkStyle *style = gtk_widget_get_style (widget);
  294.       font = style->font;
  295.       gdk_font_ref (font);
  296.     }
  297.  
  298.   gdk_draw_string (widget->window,
  299.            font,
  300.            widget->style->fg_gc[GTK_STATE_NORMAL],
  301.            ((logo_area_width - gdk_string_width (font, GIMP_VERSION)) / 2),
  302.            (0.45 * logo_area_height),
  303.            GIMP_VERSION);
  304.   gdk_draw_string (widget->window,
  305.            font,
  306.            widget->style->fg_gc[GTK_STATE_NORMAL],
  307.            ((logo_area_width - gdk_string_width (font, _("brought to you by"))) / 2),
  308.            (0.65 * logo_area_height),
  309.            _("brought to you by"));
  310.   gdk_draw_string (widget->window,
  311.            font,
  312.            widget->style->fg_gc[GTK_STATE_NORMAL],
  313.            ((logo_area_width - gdk_string_width (font, AUTHORS)) / 2),
  314.            (0.80 * logo_area_height),
  315.            AUTHORS);
  316.  
  317.   gdk_font_unref (font);
  318. }
  319.  
  320. static void
  321. splash_logo_draw (GtkWidget *widget)
  322. {
  323.   gdk_draw_pixmap (widget->window,
  324.            widget->style->black_gc,
  325.            logo_pixmap,
  326.            0, 0,
  327.            ((logo_area_width - logo_width) / 2),
  328.            ((logo_area_height - logo_height) / 2),
  329.            logo_width, logo_height);
  330. }
  331.  
  332. static void
  333. splash_logo_expose (GtkWidget *widget)
  334. {
  335.   switch (show_logo)
  336.     {
  337.     case SHOW_NEVER:
  338.     case SHOW_LATER:
  339.       splash_text_draw (widget);
  340.       break;
  341.     case SHOW_NOW:
  342.       splash_logo_draw (widget);
  343.       break;
  344.     }
  345. }
  346.  
  347. static GtkWidget *win_initstatus = NULL;
  348. static GtkWidget *label1 = NULL;
  349. static GtkWidget *label2 = NULL;
  350. static GtkWidget *pbar   = NULL;
  351.  
  352. static void
  353. destroy_initialization_status_window (void)
  354. {
  355.   if (win_initstatus)
  356.     {
  357.       gtk_widget_destroy (win_initstatus);
  358.       if (logo_pixmap != NULL)
  359.     gdk_pixmap_unref (logo_pixmap);
  360.  
  361.       win_initstatus = label1 = label2 = pbar = logo_area = NULL;
  362.       logo_pixmap = NULL;
  363.     }
  364. }
  365.  
  366. static void
  367. make_initialization_status_window (void)
  368. {
  369.   GtkWidget *vbox;
  370.   GtkWidget *logo_hbox;
  371.   GtkStyle  *style;
  372.  
  373.   if (no_interface || no_splash)
  374.     return;
  375.  
  376.   win_initstatus = gtk_window_new (GTK_WINDOW_DIALOG);
  377.  
  378.   gtk_window_set_title (GTK_WINDOW (win_initstatus), _("GIMP Startup"));
  379.   gtk_window_set_wmclass (GTK_WINDOW (win_initstatus), "gimp_startup", "Gimp");
  380.   gtk_window_set_position (GTK_WINDOW (win_initstatus), GTK_WIN_POS_CENTER);
  381.   gtk_window_set_policy (GTK_WINDOW (win_initstatus), FALSE, FALSE, FALSE);
  382.  
  383.   gimp_dialog_set_icon (GTK_WINDOW (win_initstatus));
  384.  
  385.   if (no_splash_image == FALSE &&
  386.       splash_logo_load_size (win_initstatus))
  387.     {
  388.       show_logo = SHOW_LATER;
  389.     }
  390.  
  391.   vbox = gtk_vbox_new (FALSE, 4);
  392.   gtk_container_add (GTK_CONTAINER (win_initstatus), vbox);
  393.  
  394.   logo_hbox = gtk_hbox_new (FALSE, 0);
  395.   gtk_box_pack_start (GTK_BOX (vbox), logo_hbox, FALSE, TRUE, 0);
  396.  
  397.   logo_area = gtk_drawing_area_new ();
  398.  
  399.   gtk_signal_connect (GTK_OBJECT (logo_area), "expose_event",
  400.               GTK_SIGNAL_FUNC (splash_logo_expose),
  401.               NULL);
  402.  
  403.   logo_area_width  = MAX (logo_width, LOGO_WIDTH_MIN);
  404.   logo_area_height = MAX (logo_height, LOGO_HEIGHT_MIN);
  405.  
  406.   gtk_drawing_area_size (GTK_DRAWING_AREA (logo_area),
  407.              logo_area_width, logo_area_height);
  408.   gtk_box_pack_start (GTK_BOX(logo_hbox), logo_area, TRUE, FALSE, 0);
  409.  
  410.   label1 = gtk_label_new ("");
  411.   gtk_box_pack_start_defaults (GTK_BOX (vbox), label1);
  412.   label2 = gtk_label_new ("");
  413.   gtk_box_pack_start_defaults (GTK_BOX (vbox), label2);
  414.  
  415.   pbar = gtk_progress_bar_new ();
  416.   gtk_box_pack_start_defaults (GTK_BOX (vbox), pbar);
  417.  
  418.   gtk_widget_show (vbox);
  419.   gtk_widget_show (logo_hbox);
  420.   gtk_widget_show (logo_area);
  421.   gtk_widget_show (label1);
  422.   gtk_widget_show (label2);
  423.   gtk_widget_show (pbar);
  424.  
  425.   gtk_widget_show (win_initstatus);
  426.  
  427.   /*  This is a hack: we try to compute a good guess for the maximum 
  428.    *  number of charcters that will fit into the splash-screen using 
  429.    *  the default_font
  430.    */
  431.   style = gtk_widget_get_style (win_initstatus);
  432.   max_label_length = (0.8 * (gfloat) strlen (AUTHORS) *
  433.               ((gfloat) logo_area_width /
  434.                (gfloat) gdk_string_width (style->font, AUTHORS)));
  435. }
  436.  
  437. void
  438. app_init_update_status (gchar *label1val,
  439.                 gchar *label2val,
  440.                 float  pct_progress)
  441. {
  442.   gchar *temp;
  443.  
  444.   if (!no_interface && !no_splash && win_initstatus)
  445.     {
  446.       if (label1val && strcmp (label1val, GTK_LABEL (label1)->label))
  447.     gtk_label_set_text (GTK_LABEL (label1), label1val);
  448.  
  449.       if (label2val && strcmp (label2val, GTK_LABEL (label2)->label))
  450.     {
  451.       while (strlen (label2val) > max_label_length)
  452.         {
  453.           temp = strchr (label2val, G_DIR_SEPARATOR);
  454.           if (temp == NULL)  /* for sanity */
  455.         break;
  456.           temp++;
  457.           label2val = temp;
  458.         }
  459.  
  460.       gtk_label_set_text (GTK_LABEL (label2), label2val);
  461.     }
  462.  
  463.       if (pct_progress >= 0.0 && pct_progress <= 1.0 && 
  464.       gtk_progress_get_current_percentage (&(GTK_PROGRESS_BAR (pbar)->progress)) != pct_progress)
  465.     /*
  466.      GTK_PROGRESS_BAR(pbar)->percentage != pct_progress)
  467.     */
  468.     {
  469.       gtk_progress_bar_update (GTK_PROGRESS_BAR (pbar), pct_progress);
  470.     }
  471.  
  472.       while (gtk_events_pending ())
  473.     gtk_main_iteration ();
  474.  
  475.       /* We sync here to make sure things get drawn before continuing,
  476.        * is the improved look worth the time? I'm not sure...
  477.        */
  478.       gdk_flush ();
  479.     }
  480. }
  481.  
  482. /* #define RESET_BAR() app_init_update_status("", "", 0) */
  483. #define RESET_BAR()
  484.  
  485. void
  486. app_init (void)
  487. {
  488.   gchar *filename;
  489.   gchar *path;
  490.  
  491.   /*  parse the systemwide gtkrc  */
  492.   filename = gimp_gtkrc ();
  493.  
  494.   if (be_verbose)
  495.     g_print (_("parsing \"%s\"\n"), filename);
  496.  
  497.   gtk_rc_parse (filename);
  498.  
  499.   /*  parse the user gtkrc  */
  500.   filename = gimp_personal_rc_file ("gtkrc");
  501.  
  502.   if (be_verbose)
  503.     g_print (_("parsing \"%s\"\n"), filename);
  504.  
  505.   gtk_rc_parse (filename);
  506.  
  507.   g_free (filename);
  508.  
  509.   if (parse_buffers_init ())
  510.     {
  511.       parse_unitrc ();   /*  this needs to be done before gimprc loading  */
  512.       parse_gimprc ();   /*  parse the local GIMP configuration file      */
  513.     }
  514.  
  515.   if (!no_interface)
  516.     get_standard_colormaps ();
  517.  
  518.   make_initialization_status_window ();
  519.  
  520.   if (!no_interface && !no_splash && win_initstatus)
  521.     splash_text_draw (logo_area);
  522.  
  523.   /* Create the context of all existing images */
  524.   image_context = gimp_set_new (GIMP_TYPE_IMAGE, TRUE);
  525.  
  526.   /*  Initialize the context system before loading any data  */
  527.   context_manager_init ();
  528.  
  529.   /*  Initialize the procedural database
  530.    *    We need to do this first because any of the init
  531.    *    procedures might install or query it as needed.
  532.    */
  533.   procedural_db_init ();
  534.   RESET_BAR();
  535.   internal_procs_init ();
  536.  
  537. #ifdef DISPLAY_FILTERS
  538.   color_display_init ();
  539. #endif /* DISPLAY_FILTERS */
  540.  
  541.   RESET_BAR();
  542.   if (always_restore_session)
  543.     restore_session = TRUE;
  544.  
  545.   /* make sure the monitor resolution is valid */
  546.   if (monitor_xres < GIMP_MIN_RESOLUTION ||
  547.       monitor_yres < GIMP_MIN_RESOLUTION)
  548.     {
  549.       gdisplay_xserver_resolution (&monitor_xres, &monitor_yres);
  550.       using_xserver_resolution = TRUE;
  551.     }
  552.  
  553.   /* Now we are ready to draw the splash-screen-image to the start-up window */
  554.   if (no_interface == FALSE)
  555.     {
  556.       if (no_splash_image == FALSE && show_logo &&
  557.       splash_logo_load (win_initstatus))
  558.     {
  559.       show_logo = SHOW_NOW;
  560.       splash_logo_draw (logo_area);
  561.         }
  562.     }
  563.  
  564.   RESET_BAR();
  565.   file_ops_pre_init ();    /*  pre-initialize the file types  */
  566.   RESET_BAR();
  567.   xcf_init ();             /*  initialize the xcf file format routines */
  568.  
  569.   app_init_update_status (_("Looking for data files"), _("Parasites"), 0.00);
  570.   gimp_init_parasites ();          /*  initialize  the global parasite table  */
  571.   app_init_update_status (NULL, _("Brushes"), 0.20);
  572.   brushes_init (no_data);          /*  initialize the list of gimp brushes    */
  573.   app_init_update_status (NULL, _("Patterns"), 0.40);
  574.   patterns_init (no_data);         /*  initialize the list of gimp patterns   */
  575.   app_init_update_status (NULL, _("Palettes"), 0.60);
  576.   palettes_init (no_data);         /*  initialize the list of gimp palettes   */
  577.   app_init_update_status (NULL, _("Gradients"), 0.80);
  578.   gradients_init (no_data);        /*  initialize the list of gimp gradients  */
  579.   app_init_update_status (NULL, NULL, 1.00);
  580.  
  581.   plug_in_init ();           /*  initialize the plug in structures  */
  582.   module_db_init ();         /*  load any modules we need           */
  583.   RESET_BAR();
  584.   file_ops_post_init ();     /*  post-initialize the file types     */
  585.  
  586.   menus_reorder_plugins ();  /*  beautify some menus                */
  587.  
  588.   /* Add the swap file  */
  589.   if (swap_path == NULL)
  590.     swap_path = g_get_tmp_dir ();
  591.  
  592.   toast_old_temp_files ();
  593.   path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "gimpswap.%lu",
  594.               swap_path, (unsigned long) getpid ());
  595.   tile_swap_add (path, NULL, NULL);
  596.   g_free (path);
  597.  
  598.   destroy_initialization_status_window ();
  599.  
  600.   /*  Things to do only if there is an interface  */
  601.   if (no_interface == FALSE)
  602.     {
  603.       devices_init ();
  604.       session_init ();
  605.       create_toolbox ();
  606.  
  607.       /*  Fill the "last opened" menu items with the first last_opened_size
  608.        *  elements of the docindex
  609.        */
  610.       {
  611.     FILE   *fp;
  612.     gchar **filenames = g_new (gchar *, last_opened_size);
  613.     gint    i;
  614.  
  615.     if ((fp = document_index_parse_init ()))
  616.       {
  617.         /*  read the filenames...  */
  618.         for (i = 0; i < last_opened_size; i++)
  619.           if ((filenames[i] = document_index_parse_line (fp)) == NULL)
  620.         break;
  621.  
  622.         /*  ...and add them in reverse order  */
  623.         for (--i; i >= 0; i--)
  624.           {
  625.         menus_last_opened_add (filenames[i]);
  626.         g_free (filenames[i]);
  627.           }
  628.  
  629.         fclose (fp);
  630.       }
  631.     g_free (filenames);
  632.       }
  633.  
  634.       gximage_init ();
  635.       render_setup (transparency_type, transparency_size);
  636.       tool_options_dialog_new ();
  637.  
  638.       /*  EEK: force signal emission  */
  639.       if (gimp_context_get_tool (gimp_context_get_user ()) == RECT_SELECT)
  640.     {
  641.       gimp_context_tool_changed (gimp_context_get_user ());
  642.     }
  643.       else
  644.     {
  645.       gimp_context_set_tool (gimp_context_get_user (), RECT_SELECT);
  646.     }
  647.  
  648.       /*  FIXME: This needs to go in preferences  */
  649.       message_handler = MESSAGE_BOX;
  650.     }
  651.  
  652.   color_transfer_init ();
  653.   paint_funcs_setup ();
  654.  
  655.   /* register internal color selectors */
  656.   color_select_init ();
  657.  
  658.   if (no_interface == FALSE)
  659.     {
  660.       devices_restore ();
  661.       session_restore ();
  662.     }
  663. }
  664.  
  665. int
  666. app_exit_finish_done (void)
  667. {
  668.   return is_app_exit_finish_done;
  669. }
  670.  
  671. void
  672. app_exit_finish (void)
  673. {
  674.   if (app_exit_finish_done ())
  675.     return;
  676.   is_app_exit_finish_done = TRUE;
  677.  
  678.   message_handler = CONSOLE;
  679.   we_are_exiting = TRUE;
  680.  
  681.   /*  do this here before brushes and patterns are freed  */
  682.   if (!no_interface)
  683.     device_status_free ();
  684.  
  685.   module_db_free ();
  686.   lc_dialog_free ();
  687.   gdisplays_delete ();
  688.   global_edit_free ();
  689.   named_buffers_free ();
  690.   swapping_free ();
  691.   brush_dialog_free ();
  692.   brushes_free ();
  693.   pattern_dialog_free ();
  694.   patterns_free ();
  695.   palette_dialog_free ();
  696.   palettes_free ();
  697.   gradient_dialog_free ();
  698.   gradients_free ();
  699.   context_manager_free ();
  700.   hue_saturation_free ();
  701.   curves_free ();
  702.   levels_free ();
  703.   paint_funcs_free ();
  704.   plug_in_kill ();
  705.   procedural_db_free ();
  706.   error_console_free ();
  707.   menus_quit ();
  708.   tile_swap_exit ();
  709.   save_unitrc ();
  710.   gimp_parasiterc_save ();
  711.  
  712.   /*  Things to do only if there is an interface  */
  713.   if (!no_interface)
  714.     {
  715.       toolbox_free ();
  716.       document_index_free ();
  717.       gximage_free ();
  718.       render_free ();
  719.       tool_options_dialog_free ();
  720.       save_sessionrc ();
  721.     }
  722.  
  723.   /*  There used to be gtk_main_quit() here, but there's a chance 
  724.    *  that gtk_main() was never called before we reach this point. --Sven  
  725.    */
  726.   gtk_exit (0);   
  727. }
  728.  
  729. void
  730. app_exit (gboolean kill_it)
  731. {
  732.   /*  If it's the user's perogative, and there are dirty images  */
  733.   if (!kill_it && gdisplays_dirty () && !no_interface)
  734.     really_quit_dialog ();
  735.   else
  736.     app_exit_finish ();
  737. }
  738.  
  739. /*************************************************
  740.  *   Routines to query exiting the application   *
  741.  *************************************************/
  742.  
  743. static void
  744. really_quit_callback (GtkWidget *button,
  745.               gboolean   quit,
  746.               gpointer   data)
  747. {
  748.   if (quit)
  749.     {
  750.       app_exit_finish ();
  751.     }
  752.   else
  753.     {
  754.       menus_set_sensitive ("<Toolbox>/File/Quit", TRUE);
  755.       menus_set_sensitive ("<Image>/File/Quit", TRUE);
  756.     }
  757. }
  758.  
  759. static void
  760. really_quit_dialog (void)
  761. {
  762.   GtkWidget *dialog;
  763.  
  764.   menus_set_sensitive ("<Toolbox>/File/Quit", FALSE);
  765.   menus_set_sensitive ("<Image>/File/Quit", FALSE);
  766.  
  767.   dialog = gimp_query_boolean_box (_("Really Quit?"),
  768.                    gimp_standard_help_func,
  769.                    "dialogs/really_quit.html",
  770.                    TRUE,
  771.                    _("Some files unsaved.\n\nQuit the GIMP?"),
  772.                    _("Quit"), _("Cancel"),
  773.                    NULL, NULL,
  774.                    really_quit_callback,
  775.                    NULL);
  776.  
  777.   gtk_widget_show (dialog);
  778. }
  779.  
  780. static void
  781. toast_old_temp_files (void)
  782. {
  783.   DIR *dir;
  784.   struct dirent *entry;
  785.   GString *filename = g_string_new ("");
  786.  
  787.   dir = opendir (swap_path);
  788.  
  789.   if (!dir)
  790.     return;
  791.  
  792.   while ((entry = readdir (dir)) != NULL)
  793.     if (!strncmp (entry->d_name, "gimpswap.", 9))
  794.       {
  795.         /* don't try to kill swap files of running processes
  796.          * yes, I know they might not all be gimp processes, and when you
  797.          * unlink, it's refcounted, but lets not confuse the user by
  798.          * "where did my disk space go?" cause the filename is gone
  799.          * if the kill succeeds, and there running process isn't gimp
  800.          * we'll probably get it the next time around
  801.          */
  802.  
  803.     gint pid = atoi (entry->d_name + 9);
  804. #ifndef G_OS_WIN32
  805.     if (kill (pid, 0))
  806. #endif
  807.       {
  808.         /*  On Windows, you can't remove open files anyhow,
  809.          *  so no harm trying.
  810.          */
  811.         g_string_sprintf (filename, "%s" G_DIR_SEPARATOR_S "%s",
  812.                   swap_path, entry->d_name);
  813.         unlink (filename->str);
  814.       }
  815.       }
  816.  
  817.   closedir (dir);
  818.   
  819.   g_string_free (filename, TRUE);
  820. }
  821.