home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / interface.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  39.4 KB  |  1,307 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.  
  19. #include "config.h"
  20.  
  21. #include <string.h>
  22.  
  23. #include <gtk/gtk.h>
  24.  
  25. #include "apptypes.h"
  26.  
  27. #include "appenv.h"
  28. #include "app_procs.h"
  29. #include "color_area.h"
  30. #include "commands.h"
  31. #include "devices.h"
  32. #include "dialog_handler.h"
  33. #include "disp_callbacks.h"
  34. #include "fileops.h"
  35. #include "gdisplay.h"
  36. #include "gdisplay_ops.h"
  37. #include "gimage.h"
  38. #include "gimpdnd.h"
  39. #include "gimphelp.h"
  40. #include "gimprc.h"
  41. #include "gimpui.h"
  42. #include "gtkhwrapbox.h"
  43. #include "gtkvwrapbox.h"
  44. #include "indicator_area.h"
  45. #include "interface.h"
  46. #include "menus.h"
  47. #include "nav_window.h"
  48. #include "qmask.h"
  49. #include "session.h"
  50. #include "tools.h"
  51.  
  52. #include "pixmaps.h"
  53. #include "pixmaps/qmasksel.xpm"
  54. #include "pixmaps/qmasknosel.xpm"
  55. #include "pixmaps/navbutton.xpm"
  56.  
  57. #include "libgimp/gimpintl.h"
  58.  
  59.  
  60. /*  local functions  */
  61. static void  tools_select_update   (GtkWidget      *widget,
  62.                     gpointer        data);
  63. static gint  tools_button_press    (GtkWidget      *widget,
  64.                     GdkEventButton *bevent,
  65.                     gpointer        data);
  66. static void  gdisplay_destroy      (GtkWidget      *widget,
  67.                     GDisplay       *display);
  68.  
  69. static gint  gdisplay_delete       (GtkWidget      *widget,
  70.                     GdkEvent       *event,
  71.                     GDisplay       *display);
  72.  
  73. static void  toolbox_destroy       (void);
  74. static gint  toolbox_delete        (GtkWidget      *widget,
  75.                     GdkEvent       *event,
  76.                     gpointer        data);
  77. static gint  toolbox_check_device  (GtkWidget      *widget,
  78.                     GdkEvent       *event,
  79.                     gpointer        data);
  80.  
  81. static GdkPixmap *create_pixmap    (GdkWindow      *parent,
  82.                     GdkBitmap     **mask,
  83.                     gchar         **data,
  84.                     gint            width,
  85.                     gint            height);
  86.  
  87. static void     toolbox_style_set_callback (GtkWidget        *window,
  88.                         GtkStyle         *previous_style,
  89.                         gpointer          data);
  90. static void     toolbox_set_drag_dest      (GtkWidget        *widget);
  91. static gboolean toolbox_drag_drop          (GtkWidget        *widget,
  92.                         GdkDragContext   *context,
  93.                         gint              x,
  94.                         gint              y,
  95.                         guint             time);
  96. static ToolType toolbox_drag_tool          (GtkWidget        *widget,
  97.                         gpointer          data);
  98. static void     toolbox_drop_tool          (GtkWidget        *widget,
  99.                         ToolType          tool,
  100.                         gpointer          data);
  101.  
  102. static gint pixmap_colors[8][3] =
  103. {
  104.   { 0x00, 0x00, 0x00 }, /* a -   0 */
  105.   { 0x24, 0x24, 0x24 }, /* b -  36 */
  106.   { 0x49, 0x49, 0x49 }, /* c -  73 */
  107.   { 0x6D, 0x6D, 0x6D }, /* d - 109 */
  108.   { 0x92, 0x92, 0x92 }, /* e - 146 */
  109.   { 0xB6, 0xB6, 0xB6 }, /* f - 182 */
  110.   { 0xDB, 0xDB, 0xDB }, /* g - 219 */
  111.   { 0xFF, 0xFF, 0xFF }, /* h - 255 */
  112. };
  113.  
  114. #define COLUMNS 3
  115. #define ROWS    8
  116. #define MARGIN  2
  117.  
  118. /*  local variables  */
  119. static GdkColor    colors[11];
  120. static GtkWidget * toolbox_shell = NULL;
  121.  
  122. static GtkTargetEntry toolbox_target_table[] =
  123. {
  124.   GIMP_TARGET_URI_LIST,
  125.   GIMP_TARGET_TEXT_PLAIN,
  126.   GIMP_TARGET_NETSCAPE_URL,
  127.   GIMP_TARGET_LAYER,
  128.   GIMP_TARGET_CHANNEL,
  129.   GIMP_TARGET_LAYER_MASK,
  130.   GIMP_TARGET_TOOL
  131. };
  132. static guint toolbox_n_targets = (sizeof (toolbox_target_table) /
  133.                   sizeof (toolbox_target_table[0]));
  134.  
  135. static GtkTargetEntry tool_target_table[] =
  136. {
  137.   GIMP_TARGET_TOOL
  138. };
  139. static guint tool_n_targets = (sizeof (tool_target_table) /
  140.                    sizeof (tool_target_table[0]));
  141.  
  142. static GtkTargetEntry display_target_table[] =
  143. {
  144.   GIMP_TARGET_LAYER,
  145.   GIMP_TARGET_CHANNEL,
  146.   GIMP_TARGET_LAYER_MASK,
  147.   GIMP_TARGET_COLOR,
  148.   GIMP_TARGET_PATTERN
  149. };
  150. static guint display_n_targets = (sizeof (display_target_table) /
  151.                   sizeof (display_target_table[0]));
  152.  
  153. static void
  154. tools_select_update (GtkWidget *widget,
  155.              gpointer   data)
  156. {
  157.   ToolType tool_type;
  158.  
  159.   tool_type = (ToolType) data;
  160.  
  161.   if ((tool_type != -1) && GTK_TOGGLE_BUTTON (widget)->active)
  162.     gimp_context_set_tool (gimp_context_get_user (), tool_type);
  163. }
  164.  
  165. static gint
  166. tools_button_press (GtkWidget      *widget,
  167.             GdkEventButton *event,
  168.             gpointer        data)
  169. {
  170.   GDisplay * gdisp;
  171.   gdisp = data;
  172.  
  173.   if ((event->type == GDK_2BUTTON_PRESS) && (event->button == 1))
  174.     tool_options_dialog_show ();
  175.  
  176.   return FALSE;
  177. }
  178.  
  179. static gint
  180. toolbox_delete (GtkWidget *widget,
  181.         GdkEvent  *event,
  182.         gpointer   data)
  183. {
  184.   app_exit (FALSE);
  185.  
  186.   return TRUE;
  187. }
  188.  
  189. static void
  190. toolbox_destroy (void)
  191. {
  192.   app_exit_finish ();
  193. }
  194.  
  195. static gint
  196. toolbox_check_device (GtkWidget *widget,
  197.               GdkEvent  *event,
  198.               gpointer   data)
  199. {
  200.   devices_check_change (event);
  201.  
  202.   return FALSE;
  203. }
  204.  
  205. static void
  206. gdisplay_destroy (GtkWidget *widget,
  207.           GDisplay  *gdisp)
  208. {
  209.   gdisplay_remove_and_delete (gdisp);
  210. }
  211.  
  212. static gint
  213. gdisplay_delete (GtkWidget *widget,
  214.          GdkEvent  *event,
  215.          GDisplay  *gdisp)
  216. {
  217.   gdisplay_close_window (gdisp, FALSE);
  218.  
  219.   return TRUE;
  220. }
  221.  
  222. static void
  223. allocate_colors (GtkWidget *parent)
  224. {
  225.   GdkColormap *colormap;
  226.   gint i;
  227.  
  228.   gtk_widget_realize (parent);
  229.   colormap = gdk_window_get_colormap (parent->window);
  230.  
  231.   for (i = 0; i < 8; i++)
  232.     {
  233.       colors[i].red = pixmap_colors[i][0] << 8;
  234.       colors[i].green = pixmap_colors[i][1] << 8;
  235.       colors[i].blue = pixmap_colors[i][2] << 8;
  236.  
  237.       gdk_color_alloc (colormap, &colors[i]);
  238.     }
  239.  
  240.   colors[8] = parent->style->bg[GTK_STATE_NORMAL];
  241.   gdk_color_alloc (colormap, &colors[8]);
  242.  
  243.   colors[9] = parent->style->bg[GTK_STATE_ACTIVE];
  244.   gdk_color_alloc (colormap, &colors[9]);
  245.  
  246.   colors[10] = parent->style->bg[GTK_STATE_PRELIGHT];
  247.   gdk_color_alloc (colormap, &colors[10]);
  248. }
  249.  
  250. static void
  251. create_indicator_area (GtkWidget *parent)
  252. {
  253.   GtkWidget *frame;
  254.   GtkWidget *alignment;
  255.   GtkWidget *ind_area;
  256.  
  257.   if (! GTK_WIDGET_REALIZED (parent))
  258.     gtk_widget_realize (parent);
  259.  
  260.   frame = gtk_frame_new (NULL);
  261.   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
  262.   gtk_wrap_box_pack (GTK_WRAP_BOX (parent), frame, TRUE, TRUE, TRUE, TRUE);
  263.  
  264.   alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
  265.   gtk_container_set_border_width (GTK_CONTAINER (alignment), 3);
  266.   gtk_container_add (GTK_CONTAINER (frame), alignment);
  267.  
  268.   gimp_help_set_help_data (alignment, NULL, "#indicator_area");
  269.  
  270.   ind_area = indicator_area_create ();
  271.   gtk_container_add (GTK_CONTAINER (alignment), ind_area);
  272.  
  273.   gtk_widget_show (ind_area);
  274.   gtk_widget_show (alignment);
  275.   gtk_widget_show (frame);
  276. }
  277.  
  278. static void
  279. create_color_area (GtkWidget *parent)
  280. {
  281.   GtkWidget *frame;
  282.   GtkWidget *alignment;
  283.   GtkWidget *col_area;
  284.   GdkPixmap *default_pixmap;
  285.   GdkBitmap *default_mask;
  286.   GdkPixmap *swap_pixmap;
  287.   GdkBitmap *swap_mask;
  288.  
  289.   if (! GTK_WIDGET_REALIZED (parent))
  290.     gtk_widget_realize (parent);
  291.  
  292.   default_pixmap = create_pixmap (parent->window, &default_mask, default_bits,
  293.                   default_width, default_height);
  294.   swap_pixmap    = create_pixmap (parent->window, &swap_mask, swap_bits,
  295.                   swap_width, swap_height);
  296.  
  297.   frame = gtk_frame_new (NULL);
  298.   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
  299.   gtk_wrap_box_pack (GTK_WRAP_BOX (parent), frame, TRUE, TRUE, TRUE, TRUE);
  300.   gtk_wrap_box_set_child_forced_break (GTK_WRAP_BOX (parent), frame, TRUE);
  301.  
  302.   alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
  303.   gtk_container_set_border_width (GTK_CONTAINER (alignment), 3);
  304.   gtk_container_add (GTK_CONTAINER (frame), alignment);
  305.  
  306.   gimp_help_set_help_data (alignment, NULL, "#color_area");
  307.  
  308.   col_area = color_area_create (54, 42,
  309.                 default_pixmap, default_mask,
  310.                 swap_pixmap, swap_mask);
  311.   gtk_container_add (GTK_CONTAINER (alignment), col_area);
  312.   gimp_help_set_help_data
  313.     (col_area,
  314.      _("Foreground & background colors.  The black "
  315.        "and white squares reset colors.  The arrows swap colors. Double "
  316.        "click to select a color from a colorrequester."), NULL);
  317.  
  318.   gtk_widget_show (col_area);
  319.   gtk_widget_show (alignment);
  320.   gtk_widget_show (frame);
  321. }
  322.  
  323. /* creates all icons */
  324. static void
  325. create_tool_pixmaps (GtkWidget *parent)
  326. {
  327.   gint i;
  328.  
  329.   g_return_if_fail (parent != NULL);
  330.  
  331.   for (i = 0; i < num_tools; i++)
  332.     {
  333.       if (tool_info[i].icon_data)
  334.     tool_info[i].icon_pixmap = create_pixmap (parent->window, 
  335.                           &tool_info[i].icon_mask,
  336.                           tool_info[i].icon_data,
  337.                           22, 22);
  338.       else
  339.     tool_info[i].icon_pixmap = create_pixmap (parent->window,  
  340.                           &tool_info[i].icon_mask,
  341.                           dialog_bits,
  342.                           22, 22);
  343.     }
  344. }
  345.  
  346. static void
  347. create_tools (GtkWidget *parent)
  348. {
  349.   GtkWidget *wbox;
  350.   GtkWidget *button;
  351.   GtkWidget *alignment;
  352.   GtkWidget *pixmap;
  353.   GSList *group;
  354.   gint    i, j;
  355.  
  356.   wbox = parent;
  357.  
  358.   if (! GTK_WIDGET_REALIZED (gtk_widget_get_toplevel (wbox)))
  359.     gtk_widget_realize (gtk_widget_get_toplevel (wbox));
  360.  
  361.   create_tool_pixmaps (wbox);
  362.  
  363.   group = NULL;
  364.  
  365.   i = 0;
  366.   for (j = 0; j < num_tools; j++)
  367.     {
  368.       if (j <= LAST_TOOLBOX_TOOL &&
  369.       j != SCALE && j!= SHEAR && j != PERSPECTIVE)
  370.     {
  371.       tool_info[j].tool_widget = button = gtk_radio_button_new (group);
  372.       gtk_container_set_border_width (GTK_CONTAINER (button), 0);
  373.       group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  374.  
  375.       gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
  376.  
  377.       gtk_wrap_box_pack (GTK_WRAP_BOX (wbox), button,
  378.                  FALSE, FALSE, FALSE, FALSE);
  379.  
  380.       alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
  381.       gtk_container_set_border_width (GTK_CONTAINER (alignment), 0);
  382.       gtk_container_add (GTK_CONTAINER (button), alignment);
  383.  
  384.       pixmap = gtk_pixmap_new (tool_get_pixmap ((ToolType)j), 
  385.                    tool_get_mask ((ToolType)j));
  386.       gtk_container_add (GTK_CONTAINER (alignment), pixmap);
  387.  
  388.       gtk_signal_connect (GTK_OBJECT (button), "toggled",
  389.                   GTK_SIGNAL_FUNC (tools_select_update),
  390.                   (gpointer) tool_info[j].tool_id);
  391.  
  392.       gtk_signal_connect (GTK_OBJECT (button), "button_press_event",
  393.                   GTK_SIGNAL_FUNC (tools_button_press),
  394.                   (gpointer) tool_info[j].tool_id);
  395.  
  396.       /*  dnd stuff  */
  397.       gtk_drag_source_set (tool_info[j].tool_widget,
  398.                    GDK_BUTTON2_MASK,
  399.                    tool_target_table, tool_n_targets,
  400.                    GDK_ACTION_COPY);
  401.       gimp_dnd_tool_source_set (tool_info[j].tool_widget,
  402.                     toolbox_drag_tool, (gpointer) j);
  403.  
  404.       gimp_help_set_help_data (button,
  405.                    gettext(tool_info[j].tool_desc),
  406.                    tool_info[j].private_tip);
  407.  
  408.       gtk_widget_show (pixmap);
  409.       gtk_widget_show (alignment);
  410.       gtk_widget_show (button);
  411.       i++;
  412.     }
  413.       else
  414.     {
  415.       tool_info[j].tool_widget = button = gtk_radio_button_new (group);
  416.       group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  417.  
  418.       gtk_signal_connect (GTK_OBJECT (button), "clicked",
  419.                   GTK_SIGNAL_FUNC (tools_select_update),
  420.                   (gpointer) tool_info[j].tool_id);
  421.     }
  422.     }
  423.  
  424.   gtk_widget_show (wbox);
  425. }
  426.  
  427. static GdkPixmap *
  428. create_pixmap (GdkWindow  *parent,
  429.            GdkBitmap **mask,
  430.            gchar     **data,
  431.            gint        width,
  432.            gint        height)
  433. {
  434.   GdkPixmap   *pixmap;
  435.   GdkImage    *image;
  436.   GdkGC       *gc;
  437.   GdkVisual   *visual;
  438.   GdkColormap *cmap;
  439.   gint     r, s, t, cnt;
  440.   guchar  *mem;
  441.   guchar   value;
  442.   guint32  pixel;
  443.  
  444.   visual = gdk_window_get_visual (parent);
  445.   cmap = gdk_window_get_colormap (parent);
  446.   image = gdk_image_new (GDK_IMAGE_NORMAL, visual, width, height);
  447.   pixmap = gdk_pixmap_new (parent, width, height, -1);
  448.   gc = NULL;
  449.  
  450.   if (mask)
  451.     {
  452.       GdkColor tmp_color;
  453.  
  454.       *mask = gdk_pixmap_new (parent, width, height, 1);
  455.       gc = gdk_gc_new (*mask);
  456.       gdk_draw_rectangle (*mask, gc, TRUE, 0, 0, -1, -1);
  457.  
  458.       tmp_color.pixel = 1;
  459.       gdk_gc_set_foreground (gc, &tmp_color);
  460.     }
  461.  
  462.   for (r = 0; r < height; r++)
  463.     {
  464.       mem = image->mem;
  465.       mem += image->bpl * r;
  466.  
  467.       for (s = 0, cnt = 0; s < width; s++)
  468.     {
  469.       value = data[r][s];
  470.  
  471.       if (value == '.')
  472.         {
  473.           pixel = colors[8].pixel;
  474.  
  475.           if (mask)
  476.         {
  477.           if (cnt < s)
  478.             gdk_draw_line (*mask, gc, cnt, r, s - 1, r);
  479.           cnt = s + 1;
  480.         }
  481.         }
  482.       else
  483.         {
  484.           pixel = colors[value - 'a'].pixel;
  485.         }
  486.  
  487.       if (image->byte_order == GDK_LSB_FIRST)
  488.         {
  489.           for (t = 0; t < image->bpp; t++)
  490.         *mem++ = (guchar) ((pixel >> (t * 8)) & 0xFF);
  491.         }
  492.       else
  493.         {
  494.           for (t = 0; t < image->bpp; t++)
  495.         *mem++ = (guchar) ((pixel >> ((image->bpp - t - 1) * 8)) & 0xFF);
  496.         }
  497.     }
  498.  
  499.       if (mask && (cnt < s))
  500.     gdk_draw_line (*mask, gc, cnt, r, s - 1, r);
  501.     }
  502.  
  503.   if (mask)
  504.     gdk_gc_destroy (gc);
  505.  
  506.   gc = gdk_gc_new (parent);
  507.   gdk_draw_image (pixmap, gc, image, 0, 0, 0, 0, width, height);
  508.   gdk_gc_destroy (gc);
  509.   gdk_image_destroy (image);
  510.  
  511.   return pixmap;
  512. }
  513.  
  514. void
  515. create_toolbox (void)
  516. {
  517.   GtkWidget *window;
  518.   GtkWidget *main_vbox;
  519.   GtkWidget *wbox;
  520.   GtkWidget *menubar;
  521.   GList     *list;
  522.   GtkAccelGroup *table;
  523.  
  524.  
  525.   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  526.  
  527.   /* Register dialog */
  528.   dialog_register_toolbox (window);
  529.  
  530.   gtk_signal_connect (GTK_OBJECT (window), "delete_event",
  531.               GTK_SIGNAL_FUNC (toolbox_delete),
  532.               NULL);
  533.  
  534.   gtk_signal_connect (GTK_OBJECT (window), "destroy",
  535.               GTK_SIGNAL_FUNC (toolbox_destroy),
  536.               NULL);
  537.  
  538.   /* We need to know when the current device changes, so we can update
  539.    * the correct tool - to do this we connect to motion events.
  540.    * We can't just use EXTENSION_EVENTS_CURSOR though, since that
  541.    * would get us extension events for the mouse pointer, and our
  542.    * device would change to that and not change back. So we check
  543.    * manually that all devices have a cursor, before establishing the check.
  544.    */
  545.   for (list = gdk_input_list_devices (); list; list = g_list_next (list))
  546.     {
  547.       if (!((GdkDeviceInfo *) (list->data))->has_cursor)
  548.     break;
  549.     }
  550.  
  551.   if (!list)  /* all devices have cursor */
  552.     {
  553.       gtk_signal_connect (GTK_OBJECT (window), "motion_notify_event",
  554.               GTK_SIGNAL_FUNC (toolbox_check_device),
  555.               NULL);
  556.  
  557.       gtk_widget_set_events (window, GDK_POINTER_MOTION_MASK);
  558.       gtk_widget_set_extension_events (window, GDK_EXTENSION_EVENTS_CURSOR);
  559.     }
  560.   
  561.   /* set up the window geometry after the events have been set, 
  562.      since we need to realize the widget */
  563.   gtk_window_set_wmclass (GTK_WINDOW (window), "toolbox", "Gimp");
  564.   gtk_window_set_title (GTK_WINDOW (window), _("The GIMP"));
  565.   gtk_window_set_policy (GTK_WINDOW (window), TRUE, TRUE, FALSE);
  566.  
  567.   gtk_signal_connect (GTK_OBJECT (window), "style_set",
  568.               GTK_SIGNAL_FUNC (toolbox_style_set_callback),
  569.               NULL);
  570.  
  571.   session_set_window_geometry (window, &toolbox_session_info, TRUE);
  572.  
  573.   main_vbox = gtk_vbox_new (FALSE, 1);
  574.   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 1);
  575.   gtk_container_add (GTK_CONTAINER (window), main_vbox);
  576.   gtk_widget_show (main_vbox);
  577.  
  578.   /*  allocate the colors for creating pixmaps  */
  579.   allocate_colors (main_vbox);
  580.  
  581.   /*  tooltips  */
  582.   gimp_help_init ();
  583.   if (!show_tool_tips)
  584.     gimp_help_disable_tooltips ();
  585.  
  586.   /*  Build the menu bar with menus  */
  587.   menus_get_toolbox_menubar (&menubar, &table);
  588.   gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, TRUE, 0);
  589.   gtk_widget_show (menubar);
  590.  
  591.   /*  Install the accelerator table in the main window  */
  592.   gtk_window_add_accel_group (GTK_WINDOW (window), table);
  593.  
  594.   /*  Connect the "F1" help key  */
  595.   gimp_help_connect_help_accel (window,
  596.                 gimp_standard_help_func,
  597.                 "toolbox/toolbox.html");
  598.  
  599.   wbox = gtk_hwrap_box_new (FALSE);
  600.   gtk_wrap_box_set_justify (GTK_WRAP_BOX (wbox), GTK_JUSTIFY_TOP);
  601.   gtk_wrap_box_set_line_justify (GTK_WRAP_BOX (wbox), GTK_JUSTIFY_LEFT);
  602.   /*  magic number to set a default 5x5 layout  */
  603.   gtk_wrap_box_set_aspect_ratio (GTK_WRAP_BOX (wbox), 5.0 / 5.9);
  604.   gtk_container_set_border_width (GTK_CONTAINER (wbox), 0);
  605.   gtk_box_pack_start (GTK_BOX (main_vbox), wbox, TRUE, TRUE, 0);
  606.   gtk_widget_show (wbox);
  607.  
  608.   create_tools (wbox);
  609.  
  610.   create_color_area (wbox);
  611.   if (show_indicators)
  612.     create_indicator_area (wbox);
  613.  
  614.   gtk_widget_show (window);
  615.   toolbox_set_drag_dest (window);
  616.  
  617.   toolbox_shell = window;
  618. }
  619.  
  620. void
  621. toolbox_free (void)
  622. {
  623.   gint i;
  624.  
  625.   session_get_window_info (toolbox_shell, &toolbox_session_info);
  626.  
  627.   gtk_widget_destroy (toolbox_shell);
  628.   for (i = 0; i < num_tools; i++)
  629.     {
  630.       if (tool_info[i].icon_pixmap)
  631.     gdk_pixmap_unref (tool_info[i].icon_pixmap);
  632.       
  633.       if (!tool_info[i].icon_data)
  634.     gtk_object_sink (GTK_OBJECT (tool_info[i].tool_widget));
  635.     }
  636.   gimp_help_free ();
  637. }
  638.  
  639. void
  640. toolbox_raise_callback (GtkWidget *widget,
  641.             gpointer   data)
  642. {
  643.   gdk_window_raise (toolbox_shell->window);
  644. }
  645.  
  646. static void
  647. toolbox_style_set_callback (GtkWidget *window,
  648.                 GtkStyle  *previous_style,
  649.                 gpointer   data)
  650. {
  651.   GdkGeometry  geometry;
  652.   GtkStyle    *style;
  653.   gint         xthickness;
  654.   gint         ythickness;
  655.  
  656.   style = gtk_widget_get_style (window);
  657.   xthickness = ((GtkStyleClass *) style->klass)->xthickness;
  658.   ythickness = ((GtkStyleClass *) style->klass)->ythickness;
  659.   
  660.   geometry.min_width  =  2 + 24 + 2 * xthickness;
  661.   geometry.min_height = 80 + 24 + 2 * ythickness;
  662.   geometry.width_inc  =      24 + 2 * xthickness;
  663.   geometry.height_inc =      24 + 2 * ythickness;
  664.  
  665.   gtk_window_set_geometry_hints (GTK_WINDOW (window), 
  666.                  NULL,
  667.                  &geometry, 
  668.                  GDK_HINT_MIN_SIZE | GDK_HINT_RESIZE_INC);
  669. }
  670.  
  671. void
  672. create_display_shell (GDisplay *gdisp,
  673.               gint      width,
  674.               gint      height,
  675.               gchar    *title,
  676.               gint      type)
  677. {
  678.   static GtkWidget     *image_popup_menu  = NULL;
  679.   static GtkAccelGroup *image_accel_group = NULL;
  680.  
  681.   static GdkPixmap *qmasksel_pixmap   = NULL;
  682.   static GdkBitmap *qmasksel_mask     = NULL;
  683.   static GdkPixmap *qmasknosel_pixmap = NULL;
  684.   static GdkBitmap *qmasknosel_mask   = NULL;
  685.   static GdkPixmap *navbutton_pixmap  = NULL;
  686.   static GdkBitmap *navbutton_mask    = NULL;
  687.  
  688.   GtkWidget *main_vbox;
  689.   GtkWidget *disp_vbox;
  690.   GtkWidget *upper_hbox;
  691.   GtkWidget *lower_hbox;
  692.   GtkWidget *inner_table;
  693.   GtkWidget *status_hbox;
  694.   GtkWidget *arrow;
  695.   GtkWidget *pixmap;
  696.   GtkWidget *label_frame;
  697.   GtkWidget *nav_ebox;
  698.  
  699.   GSList *group = NULL;
  700.  
  701.   gint n_width, n_height;
  702.   gint s_width, s_height;
  703.   gint scalesrc, scaledest;
  704.   gint contextid;
  705.  
  706.   /*  adjust the initial scale -- so that window fits on screen */
  707.   /*  the 75% value is the same as in gdisplay_shrink_wrap. It  */
  708.   /*  probably should be a user-configurable option.            */
  709.   s_width  = gdk_screen_width () * 0.75;
  710.   s_height = gdk_screen_height () * 0.75;
  711.  
  712.   scalesrc  = SCALESRC (gdisp);
  713.   scaledest = SCALEDEST (gdisp);
  714.  
  715.   n_width  = SCALEX (gdisp, width);
  716.   n_height = SCALEX (gdisp, height);
  717.  
  718.   /*  Limit to the size of the screen...  */
  719.   while (n_width > s_width || n_height > s_height)
  720.     {
  721.       if (scaledest > 1)
  722.     scaledest--;
  723.       else
  724.     if (scalesrc < 0xff)
  725.       scalesrc++;
  726.  
  727.       n_width  = width * 
  728.     (scaledest * SCREEN_XRES (gdisp)) / (scalesrc * gdisp->gimage->xresolution);
  729.       n_height = height *
  730.     (scaledest * SCREEN_XRES (gdisp)) / (scalesrc * gdisp->gimage->xresolution);
  731.     }
  732.  
  733.   gdisp->scale = (scaledest << 8) + scalesrc;
  734.  
  735.   /*  the toplevel shell */
  736.   gdisp->shell = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  737.   gtk_widget_ref  (gdisp->shell);
  738.   gtk_window_set_title (GTK_WINDOW (gdisp->shell), title);
  739.   gtk_window_set_wmclass (GTK_WINDOW (gdisp->shell), "image_window", "Gimp");
  740.   gtk_window_set_policy (GTK_WINDOW (gdisp->shell), TRUE, TRUE, TRUE);
  741.   gtk_object_set_user_data (GTK_OBJECT (gdisp->shell), (gpointer) gdisp);
  742.   gtk_widget_set_events (gdisp->shell,
  743.              GDK_POINTER_MOTION_MASK |
  744.              GDK_POINTER_MOTION_HINT_MASK |
  745.              GDK_BUTTON_PRESS_MASK |
  746.              GDK_KEY_PRESS_MASK |
  747.              GDK_KEY_RELEASE_MASK);
  748.   gtk_signal_connect (GTK_OBJECT (gdisp->shell), "delete_event",
  749.               GTK_SIGNAL_FUNC (gdisplay_delete),
  750.               gdisp);
  751.   gtk_signal_connect (GTK_OBJECT (gdisp->shell), "destroy",
  752.               GTK_SIGNAL_FUNC (gdisplay_destroy),
  753.               gdisp);
  754.  
  755.   /*  active display callback  */
  756.   gtk_signal_connect (GTK_OBJECT (gdisp->shell), "button_press_event",
  757.               GTK_SIGNAL_FUNC (gdisplay_shell_events),
  758.               gdisp);
  759.   gtk_signal_connect (GTK_OBJECT (gdisp->shell), "key_press_event",
  760.               GTK_SIGNAL_FUNC (gdisplay_shell_events),
  761.               gdisp);
  762.  
  763.   /*  dnd stuff  */
  764.   gtk_drag_dest_set (gdisp->shell,
  765.              GTK_DEST_DEFAULT_ALL,
  766.              display_target_table, display_n_targets,
  767.              GDK_ACTION_COPY);
  768.   gtk_signal_connect (GTK_OBJECT (gdisp->shell), "drag_drop",
  769.               GTK_SIGNAL_FUNC (gdisplay_drag_drop),
  770.               gdisp);
  771.   gimp_dnd_color_dest_set (gdisp->shell, gdisplay_drop_color, gdisp);
  772.   gimp_dnd_pattern_dest_set (gdisp->shell, gdisplay_drop_pattern, gdisp);
  773.  
  774.   if (! image_popup_menu)
  775.     menus_get_image_menu (&image_popup_menu, &image_accel_group);
  776.  
  777.   /*  the popup menu  */
  778.   gdisp->popup = image_popup_menu;
  779.  
  780.   /*  The accelerator table for images  */
  781.   gtk_window_add_accel_group (GTK_WINDOW (gdisp->shell), image_accel_group);
  782.  
  783.   /*  connect the "F1" help key  */
  784.   gimp_help_connect_help_accel (gdisp->shell,
  785.                 gimp_standard_help_func,
  786.                 "image/image_window.html");
  787.  
  788.   /*  GtkTable widgets are not able to shrink a row/column correctly if
  789.    *  widgets are attached with GTK_EXPAND even if those widgets have
  790.    *  other rows/columns in their rowspan/colspan where they could
  791.    *  nicely expand without disturbing the row/column which is supposed
  792.    *  to shrink. --Mitch
  793.    *
  794.    *  Changed the packing to use hboxes and vboxes which behave nicer:
  795.    *
  796.    *  main_vbox
  797.    *     |
  798.    *     +-- disp_vbox
  799.    *     |      |
  800.    *     |      +-- upper_hbox
  801.    *     |      |      |
  802.    *     |      |      +-- inner_table
  803.    *     |      |      |      |
  804.    *     |      |      |      +-- origin
  805.    *     |      |      |      +-- hruler
  806.    *     |      |      |      +-- vruler
  807.    *     |      |      |      +-- canvas
  808.    *     |      |      |     
  809.    *     |      |      +-- vscrollbar
  810.    *     |      |    
  811.    *     |      +-- lower_hbox
  812.    *     |             |
  813.    *     |             +-- qmaskoff
  814.    *     |             +-- qmaskon
  815.    *     |             +-- hscrollbar
  816.    *     |             +-- navbutton
  817.    *     |
  818.    *     +-- statusarea
  819.    *            |
  820.    *            +-- cursorlabel
  821.    *            +-- statusbar
  822.    *            +-- progressbar
  823.    *            +-- cancelbutton
  824.    */
  825.  
  826.   /*  first, set up the container hierarchy  *********************************/
  827.  
  828.   /*  the vbox containing all widgets  */
  829.   main_vbox = gtk_vbox_new (FALSE, 2);
  830.   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 2);
  831.   gtk_container_add (GTK_CONTAINER (gdisp->shell), main_vbox);
  832.  
  833.   /*  another vbox for everything except the statusbar  */
  834.   disp_vbox = gtk_vbox_new (FALSE, 1);
  835.   gtk_box_pack_start (GTK_BOX (main_vbox), disp_vbox, TRUE, TRUE, 0);
  836.   gtk_widget_show (disp_vbox);
  837.  
  838.   /*  a hbox for the inner_table and the vertical scrollbar  */
  839.   upper_hbox = gtk_hbox_new (FALSE, 1);
  840.   gtk_box_pack_start (GTK_BOX (disp_vbox), upper_hbox, TRUE, TRUE, 0);
  841.   gtk_widget_show (upper_hbox);
  842.  
  843.   /*  the table containing origin, rulers and the canvas  */
  844.   inner_table = gtk_table_new (2, 2, FALSE);
  845.   gtk_table_set_col_spacing (GTK_TABLE (inner_table), 0, 1);
  846.   gtk_table_set_row_spacing (GTK_TABLE (inner_table), 0, 1);
  847.   gtk_box_pack_start (GTK_BOX (upper_hbox), inner_table, TRUE, TRUE, 0);
  848.   gtk_widget_show (inner_table);
  849.  
  850.   /*  the hbox containing qmask buttons, vertical scrollbar and nav button  */
  851.   lower_hbox = gtk_hbox_new (FALSE, 1);
  852.   gtk_box_pack_start (GTK_BOX (disp_vbox), lower_hbox, FALSE, FALSE, 0);
  853.   gtk_widget_show (lower_hbox);
  854.  
  855.   /*  eventbox and hbox for status area  */
  856.   gdisp->statusarea = gtk_event_box_new ();
  857.   gtk_box_pack_start (GTK_BOX (main_vbox), gdisp->statusarea, FALSE, FALSE, 0);
  858.  
  859.   gimp_help_set_help_data (gdisp->statusarea, NULL, "#status_area");
  860.  
  861.   status_hbox = gtk_hbox_new (FALSE, 2);
  862.   gtk_container_add (GTK_CONTAINER (gdisp->statusarea), status_hbox);
  863.   gtk_widget_show (status_hbox);
  864.  
  865.   gtk_container_set_resize_mode (GTK_CONTAINER (status_hbox),
  866.                  GTK_RESIZE_QUEUE);
  867.  
  868.   /*  create the scrollbars  *************************************************/
  869.  
  870.   /*  the horizontal scrollbar  */
  871.   gdisp->hsbdata =
  872.     GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, width, 1, 1, width));
  873.   gdisp->hsb = gtk_hscrollbar_new (gdisp->hsbdata);
  874.   GTK_WIDGET_UNSET_FLAGS (gdisp->hsb, GTK_CAN_FOCUS);
  875.  
  876.   /*  the vertical scrollbar  */
  877.   gdisp->vsbdata =
  878.     GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, height, 1, 1, height));
  879.   gdisp->vsb = gtk_vscrollbar_new (gdisp->vsbdata);
  880.   GTK_WIDGET_UNSET_FLAGS (gdisp->vsb, GTK_CAN_FOCUS);
  881.  
  882.   /*  create the contents of the inner_table  ********************************/
  883.  
  884.   /*  the menu popup button  */
  885.   gdisp->origin = gtk_button_new ();
  886.   GTK_WIDGET_UNSET_FLAGS (gdisp->origin, GTK_CAN_FOCUS);
  887.   gtk_widget_set_events (GTK_WIDGET (gdisp->origin),
  888.              GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
  889.   gtk_signal_connect (GTK_OBJECT (gdisp->origin), "button_press_event",
  890.               GTK_SIGNAL_FUNC (gdisplay_origin_button_press),
  891.               gdisp);
  892.  
  893.   gimp_help_set_help_data (gdisp->origin, NULL, "#origin_button");
  894.  
  895.   arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_OUT);
  896.   gtk_container_set_border_width (GTK_CONTAINER (gdisp->origin), 0);
  897.   gtk_container_add (GTK_CONTAINER (gdisp->origin), arrow);
  898.   gtk_widget_show (arrow);
  899.  
  900.   /*  the horizontal ruler  */
  901.   gdisp->hrule = gtk_hruler_new ();
  902.   gtk_widget_set_events (GTK_WIDGET (gdisp->hrule),
  903.              GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
  904.   gtk_signal_connect_object (GTK_OBJECT (gdisp->shell), "motion_notify_event",
  905.                  GTK_SIGNAL_FUNC (GTK_WIDGET_CLASS (GTK_OBJECT (gdisp->hrule)->klass)->motion_notify_event),
  906.                  GTK_OBJECT (gdisp->hrule));
  907.   gtk_signal_connect (GTK_OBJECT (gdisp->hrule), "button_press_event",
  908.               GTK_SIGNAL_FUNC (gdisplay_hruler_button_press),
  909.               gdisp);
  910.  
  911.   gimp_help_set_help_data (gdisp->hrule, NULL, "#ruler");
  912.  
  913.   /*  the vertical ruler  */
  914.   gdisp->vrule = gtk_vruler_new ();
  915.   gtk_widget_set_events (GTK_WIDGET (gdisp->vrule),
  916.              GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
  917.   gtk_signal_connect_object (GTK_OBJECT (gdisp->shell), "motion_notify_event",
  918.                  GTK_SIGNAL_FUNC (GTK_WIDGET_CLASS (GTK_OBJECT (gdisp->vrule)->klass)->motion_notify_event),
  919.                  GTK_OBJECT (gdisp->vrule));
  920.   gtk_signal_connect (GTK_OBJECT (gdisp->vrule), "button_press_event",
  921.               GTK_SIGNAL_FUNC (gdisplay_vruler_button_press),
  922.               gdisp);
  923.  
  924.   gimp_help_set_help_data (gdisp->vrule, NULL, "#ruler");
  925.  
  926.   /*  the canvas  */
  927.   gdisp->canvas = gtk_drawing_area_new ();
  928.   gtk_drawing_area_size (GTK_DRAWING_AREA (gdisp->canvas), n_width, n_height);
  929.   gtk_widget_set_events (gdisp->canvas, CANVAS_EVENT_MASK);
  930.   gtk_widget_set_extension_events (gdisp->canvas, GDK_EXTENSION_EVENTS_ALL);
  931.   GTK_WIDGET_SET_FLAGS (gdisp->canvas, GTK_CAN_FOCUS);
  932.   gtk_object_set_user_data (GTK_OBJECT (gdisp->canvas), (gpointer) gdisp);
  933.  
  934.   /*  set the active display before doing any other canvas event processing  */
  935.   gtk_signal_connect (GTK_OBJECT (gdisp->canvas), "event",
  936.               GTK_SIGNAL_FUNC (gdisplay_shell_events),
  937.               gdisp);
  938.   gtk_signal_connect (GTK_OBJECT (gdisp->canvas), "event",
  939.               GTK_SIGNAL_FUNC (gdisplay_canvas_events),
  940.               gdisp);
  941.  
  942.   /*  create the contents of the lower_hbox  *********************************/
  943.  
  944.   /*  the qmask buttons  */
  945.   gdisp->qmaskoff = gtk_radio_button_new (group);
  946.   group = gtk_radio_button_group (GTK_RADIO_BUTTON (gdisp->qmaskoff));
  947.   gtk_widget_set_usize (GTK_WIDGET (gdisp->qmaskoff), 15, 15);
  948.   gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (gdisp->qmaskoff), FALSE);
  949.   GTK_WIDGET_UNSET_FLAGS (gdisp->qmaskoff, GTK_CAN_FOCUS);
  950.   gtk_signal_connect (GTK_OBJECT (gdisp->qmaskoff), "toggled",
  951.               GTK_SIGNAL_FUNC (qmask_deactivate),
  952.               gdisp);
  953.   gtk_signal_connect (GTK_OBJECT (gdisp->qmaskoff), "button_press_event",
  954.               GTK_SIGNAL_FUNC (qmask_click_handler),
  955.               gdisp);
  956.  
  957.   gimp_help_set_help_data (gdisp->qmaskoff, NULL, "#qmask_off_button");
  958.  
  959.   gdisp->qmaskon = gtk_radio_button_new (group);
  960.   group = gtk_radio_button_group (GTK_RADIO_BUTTON (gdisp->qmaskon));
  961.   gtk_widget_set_usize (GTK_WIDGET (gdisp->qmaskon), 15, 15);
  962.   gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (gdisp->qmaskon), FALSE);
  963.   GTK_WIDGET_UNSET_FLAGS (gdisp->qmaskon, GTK_CAN_FOCUS);
  964.   gtk_signal_connect (GTK_OBJECT (gdisp->qmaskon), "toggled",
  965.               GTK_SIGNAL_FUNC (qmask_activate),
  966.               gdisp);
  967.   gtk_signal_connect (GTK_OBJECT (gdisp->qmaskon), "button_press_event",
  968.               GTK_SIGNAL_FUNC (qmask_click_handler),
  969.               gdisp);
  970.  
  971.   gimp_help_set_help_data (gdisp->qmaskon, NULL, "#qmask_on_button");
  972.  
  973.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gdisp->qmaskoff), TRUE);
  974.  
  975.   /*  the navigation window button  */
  976.   nav_ebox = gtk_event_box_new ();
  977.   gtk_signal_connect (GTK_OBJECT (nav_ebox), "button_press_event",
  978.               GTK_SIGNAL_FUNC (nav_popup_click_handler),
  979.               gdisp);
  980.  
  981.   gimp_help_set_help_data (nav_ebox, NULL, "#nav_window_button");
  982.  
  983.   /*  create the pixmaps  ****************************************************/
  984.   if (!qmasksel_pixmap)
  985.     {
  986.       GtkStyle *style;
  987.  
  988.       gtk_widget_realize (gdisp->shell);
  989.       style = gtk_widget_get_style (gdisp->shell);
  990.  
  991.       qmasksel_pixmap =
  992.     gdk_pixmap_create_from_xpm_d (gdisp->shell->window,
  993.                       &qmasksel_mask,
  994.                       &style->bg[GTK_STATE_NORMAL],
  995.                       qmasksel_xpm);   
  996.       qmasknosel_pixmap =
  997.     gdk_pixmap_create_from_xpm_d (gdisp->shell->window,
  998.                       &qmasknosel_mask,
  999.                       &style->bg[GTK_STATE_NORMAL],
  1000.                       qmasknosel_xpm);   
  1001.       navbutton_pixmap =
  1002.     gdk_pixmap_create_from_xpm_d (gdisp->shell->window,
  1003.                       &navbutton_mask,
  1004.                       &style->bg[GTK_STATE_NORMAL],
  1005.                       navbutton_xpm);   
  1006.     }
  1007.  
  1008.   /*  create the GtkPixmaps  */
  1009.   pixmap = gtk_pixmap_new (qmasksel_pixmap, qmasksel_mask);
  1010.   gtk_container_add (GTK_CONTAINER (gdisp->qmaskon), pixmap);
  1011.   gtk_widget_show (pixmap);
  1012.  
  1013.   pixmap = gtk_pixmap_new (qmasknosel_pixmap, qmasknosel_mask);
  1014.   gtk_container_add (GTK_CONTAINER (gdisp->qmaskoff), pixmap);
  1015.   gtk_widget_show (pixmap);
  1016.  
  1017.   pixmap = gtk_pixmap_new (navbutton_pixmap, navbutton_mask);
  1018.   gtk_container_add (GTK_CONTAINER (nav_ebox), pixmap); 
  1019.   gtk_widget_show (pixmap);
  1020.  
  1021.   /*  create the contents of the status area *********************************/
  1022.  
  1023.   /*  the cursor label  */
  1024.   label_frame = gtk_frame_new (NULL);
  1025.   gtk_frame_set_shadow_type (GTK_FRAME (label_frame), GTK_SHADOW_IN);
  1026.  
  1027.   gdisp->cursor_label = gtk_label_new (" ");
  1028.   gtk_container_add (GTK_CONTAINER (label_frame), gdisp->cursor_label);
  1029.   gtk_widget_show (gdisp->cursor_label);
  1030.  
  1031.   /*  the statusbar  */
  1032.   gdisp->statusbar = gtk_statusbar_new ();
  1033.   gtk_widget_set_usize (gdisp->statusbar, 1, -1);
  1034.   gtk_container_set_resize_mode (GTK_CONTAINER (gdisp->statusbar),
  1035.                  GTK_RESIZE_QUEUE);
  1036.   contextid = gtk_statusbar_get_context_id (GTK_STATUSBAR (gdisp->statusbar),
  1037.                         "title");
  1038.   gtk_statusbar_push (GTK_STATUSBAR (gdisp->statusbar),
  1039.               contextid,
  1040.               title);
  1041.  
  1042.   /*  the progress bar  */
  1043.   gdisp->progressbar = gtk_progress_bar_new ();
  1044.   gtk_widget_set_usize (gdisp->progressbar, 80, -1);
  1045.  
  1046.   /*  the cancel button  */
  1047.   gdisp->cancelbutton = gtk_button_new_with_label (_("Cancel"));
  1048.   gtk_widget_set_sensitive (gdisp->cancelbutton, FALSE);
  1049.  
  1050.   /*  pack all the widgets  **************************************************/
  1051.  
  1052.   /*  fill the upper_hbox  */
  1053.   gtk_box_pack_start (GTK_BOX (upper_hbox), gdisp->vsb, FALSE, FALSE, 0);
  1054.  
  1055.   /*  fill the inner_table  */
  1056.   gtk_table_attach (GTK_TABLE (inner_table), gdisp->origin, 0, 1, 0, 1,
  1057.             GTK_FILL, GTK_FILL, 0, 0);
  1058.   gtk_table_attach (GTK_TABLE (inner_table), gdisp->hrule, 1, 2, 0, 1,
  1059.             GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_FILL, 0, 0);
  1060.   gtk_table_attach (GTK_TABLE (inner_table), gdisp->vrule, 0, 1, 1, 2,
  1061.             GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
  1062.   gtk_table_attach (GTK_TABLE (inner_table), gdisp->canvas, 1, 2, 1, 2,
  1063.             GTK_EXPAND | GTK_SHRINK | GTK_FILL,
  1064.             GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
  1065.  
  1066.   /*  fill the lower_hbox  */
  1067.   gtk_box_pack_start (GTK_BOX (lower_hbox), gdisp->qmaskoff, FALSE, FALSE, 0);
  1068.   gtk_box_pack_start (GTK_BOX (lower_hbox), gdisp->qmaskon, FALSE, FALSE, 0);
  1069.   gtk_box_pack_start (GTK_BOX (lower_hbox), gdisp->hsb, TRUE, TRUE, 0);
  1070.   gtk_box_pack_start (GTK_BOX (lower_hbox), nav_ebox, FALSE, FALSE, 0);
  1071.  
  1072.   /*  fill the status area  */
  1073.   gtk_box_pack_start (GTK_BOX (status_hbox), label_frame, FALSE, FALSE, 0);
  1074.   gtk_box_pack_start (GTK_BOX (status_hbox), gdisp->statusbar, TRUE, TRUE, 0);
  1075.   gtk_box_pack_start (GTK_BOX (status_hbox), gdisp->progressbar, FALSE, FALSE, 0);
  1076.   gtk_box_pack_start (GTK_BOX (status_hbox), gdisp->cancelbutton, FALSE, FALSE, 0);
  1077.  
  1078.   /*  show everything  *******************************************************/
  1079.  
  1080.   if (show_rulers)
  1081.     {
  1082.       gtk_widget_show (gdisp->origin);
  1083.       gtk_widget_show (gdisp->hrule);
  1084.       gtk_widget_show (gdisp->vrule);
  1085.     }
  1086.   gtk_widget_show (gdisp->canvas);
  1087.  
  1088.   gtk_widget_show (gdisp->vsb);
  1089.   gtk_widget_show (gdisp->hsb);
  1090.  
  1091.   gtk_widget_show (gdisp->qmaskoff);
  1092.   gtk_widget_show (gdisp->qmaskon);
  1093.   gtk_widget_show (nav_ebox);
  1094.  
  1095.   gtk_widget_show (label_frame);
  1096.   gtk_widget_show (gdisp->statusbar);
  1097.   gtk_widget_show (gdisp->progressbar);
  1098.   gtk_widget_show (gdisp->cancelbutton);
  1099.   if (show_statusbar)
  1100.     {
  1101.       gtk_widget_show (gdisp->statusarea);
  1102.     }
  1103.  
  1104.   gtk_widget_realize (gdisp->canvas);
  1105.   gdk_window_set_back_pixmap (gdisp->canvas->window, NULL, FALSE);
  1106.  
  1107.   /*  we need to realize the cursor_label widget here, so the size gets
  1108.    *  computed correctly
  1109.    */
  1110.   gtk_widget_realize (gdisp->cursor_label);
  1111.   gdisplay_resize_cursor_label (gdisp);
  1112.  
  1113.   gtk_widget_show (main_vbox);
  1114.   gtk_widget_show (gdisp->shell);
  1115.  
  1116.   /*  set the focus to the canvas area  */
  1117.   gtk_widget_grab_focus (gdisp->canvas);
  1118. }
  1119.  
  1120. /* DnD functions */ 
  1121. static void
  1122. toolbox_set_drag_dest (GtkWidget *object)
  1123. {
  1124.   gtk_drag_dest_set (object,
  1125.              GTK_DEST_DEFAULT_ALL,
  1126.              toolbox_target_table, toolbox_n_targets,
  1127.              GDK_ACTION_COPY);
  1128.  
  1129.   gimp_dnd_file_dest_set (object);
  1130.  
  1131.   gtk_signal_connect (GTK_OBJECT (object), "drag_drop",
  1132.               GTK_SIGNAL_FUNC (toolbox_drag_drop),
  1133.               NULL);
  1134.  
  1135.   gimp_dnd_tool_dest_set (object, toolbox_drop_tool, NULL);
  1136. }
  1137.  
  1138. static gboolean
  1139. toolbox_drag_drop (GtkWidget      *widget,
  1140.            GdkDragContext *context,
  1141.            gint            x,
  1142.            gint            y,
  1143.            guint           time)
  1144. {
  1145.   GtkWidget *src_widget;
  1146.   gboolean return_val = FALSE;
  1147.  
  1148.   if ((src_widget = gtk_drag_get_source_widget (context)))
  1149.     {
  1150.       GimpDrawable *drawable       = NULL;
  1151.       Layer        *layer          = NULL;
  1152.       Channel      *channel        = NULL;
  1153.       LayerMask    *layer_mask     = NULL;
  1154.       GImage       *component      = NULL;
  1155.       ChannelType   component_type = -1;
  1156.  
  1157.       layer = (Layer *) gtk_object_get_data (GTK_OBJECT (src_widget),
  1158.                          "gimp_layer");
  1159.       channel = (Channel *) gtk_object_get_data (GTK_OBJECT (src_widget),
  1160.                          "gimp_channel");
  1161.       layer_mask = (LayerMask *) gtk_object_get_data (GTK_OBJECT (src_widget),
  1162.                               "gimp_layer_mask");
  1163.       component = (GImage *) gtk_object_get_data (GTK_OBJECT (src_widget),
  1164.                           "gimp_component");
  1165.  
  1166.       if (layer)
  1167.     {
  1168.       drawable = GIMP_DRAWABLE (layer);
  1169.     }
  1170.       else if (channel)
  1171.     {
  1172.       drawable = GIMP_DRAWABLE (channel);
  1173.     }
  1174.       else if (layer_mask)
  1175.     {
  1176.       drawable = GIMP_DRAWABLE (layer_mask);
  1177.     }
  1178.       else if (component)
  1179.     {
  1180.       component_type =
  1181.         (ChannelType) gtk_object_get_data (GTK_OBJECT (src_widget),
  1182.                            "gimp_component_type");
  1183.     }
  1184.  
  1185.       if (drawable)
  1186.     {
  1187.           GImage *gimage;
  1188.       GImage *new_gimage;
  1189.       Layer  *new_layer;
  1190.           gint    width, height;
  1191.       gint    off_x, off_y;
  1192.       gint    bytes;
  1193.  
  1194.       GimpImageBaseType type;
  1195.  
  1196.       gimage = gimp_drawable_gimage (drawable);
  1197.           width  = gimp_drawable_width  (drawable);
  1198.           height = gimp_drawable_height (drawable);
  1199.       bytes  = gimp_drawable_bytes  (drawable);
  1200.  
  1201.       switch (gimp_drawable_type (drawable))
  1202.         {
  1203.         case RGB_GIMAGE: case RGBA_GIMAGE:
  1204.           type = RGB; break;
  1205.         case GRAY_GIMAGE: case GRAYA_GIMAGE:
  1206.           type = GRAY; break;
  1207.         case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
  1208.           type = INDEXED; break;
  1209.         default:
  1210.           type = RGB; break;
  1211.         }
  1212.  
  1213.       new_gimage = gimage_new (width, height, type);
  1214.       gimage_disable_undo (new_gimage);
  1215.  
  1216.       if (type == INDEXED) /* copy the colormap */
  1217.         {
  1218.           new_gimage->num_cols = gimage->num_cols;
  1219.           memcpy (new_gimage->cmap, gimage->cmap, COLORMAP_SIZE);
  1220.         }
  1221.  
  1222.       gimage_set_resolution (new_gimage, gimage->xresolution, gimage->yresolution);
  1223.       gimage_set_unit (new_gimage, gimage->unit);
  1224.  
  1225.       if (layer)
  1226.         {
  1227.           new_layer = layer_copy (layer, FALSE);
  1228.         }
  1229.       else
  1230.         {
  1231.           /*  a non-layer drawable can't have an alpha channel,
  1232.            *  so add one
  1233.            */
  1234.           PixelRegion  srcPR, destPR;
  1235.           TileManager *tiles;
  1236.  
  1237.           tiles = tile_manager_new (width, height, bytes + 1);
  1238.  
  1239.           pixel_region_init (&srcPR, gimp_drawable_data (drawable),
  1240.                  0, 0, width, height, FALSE);
  1241.           pixel_region_init (&destPR, tiles,
  1242.                  0, 0, width, height, TRUE);
  1243.  
  1244.           add_alpha_region (&srcPR, &destPR);
  1245.  
  1246.           new_layer = layer_new_from_tiles (new_gimage, 
  1247.                                                 gimp_image_base_type_with_alpha(new_gimage), 
  1248.                                                 tiles,
  1249.                         "", OPAQUE_OPACITY, NORMAL_MODE);
  1250.  
  1251.           tile_manager_destroy (tiles);
  1252.         }
  1253.  
  1254.       gimp_drawable_set_gimage (GIMP_DRAWABLE (new_layer), new_gimage);
  1255.  
  1256.       layer_set_name (GIMP_LAYER (new_layer),
  1257.               gimp_drawable_get_name (drawable));
  1258.  
  1259.       if (layer)
  1260.         {
  1261.           LayerMask *mask;
  1262.           LayerMask *new_mask;
  1263.  
  1264.           mask     = layer_get_mask (layer);
  1265.           new_mask = layer_get_mask (new_layer);
  1266.  
  1267.           if (new_mask)
  1268.         {
  1269.           gimp_drawable_set_name (GIMP_DRAWABLE (new_mask),
  1270.                       gimp_drawable_get_name (GIMP_DRAWABLE (mask)));
  1271.         }
  1272.         }
  1273.  
  1274.       gimp_drawable_offsets (GIMP_DRAWABLE (new_layer), &off_x, &off_y);
  1275.       layer_translate (new_layer, -off_x, -off_y);
  1276.  
  1277.       gimage_add_layer (new_gimage, new_layer, 0);
  1278.  
  1279.       gimp_context_set_display (gimp_context_get_user (),
  1280.                     gdisplay_new (new_gimage, 0x0101));
  1281.  
  1282.       gimage_enable_undo (new_gimage);
  1283.  
  1284.       return_val = TRUE;
  1285.     }
  1286.     }
  1287.  
  1288.   gtk_drag_finish (context, return_val, FALSE, time);
  1289.  
  1290.   return return_val;
  1291. }
  1292.  
  1293. static ToolType
  1294. toolbox_drag_tool (GtkWidget *widget,
  1295.            gpointer   data)
  1296. {
  1297.   return (ToolType) data;
  1298. }
  1299.  
  1300. static void
  1301. toolbox_drop_tool (GtkWidget *widget,
  1302.            ToolType   tool,
  1303.            gpointer   data)
  1304. {
  1305.   gimp_context_set_tool (gimp_context_get_user (), tool);
  1306. }
  1307.