(fontset_find_font): Check if rfont_def is Qnil or not.
[bpt/emacs.git] / src / gtkutil.c
index 140796a..41f2518 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions for creating and updating GTK widgets.
 /* Functions for creating and updating GTK widgets.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
      Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
      Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -53,13 +53,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifdef HAVE_GTK_MULTIDISPLAY
 
 
 #ifdef HAVE_GTK_MULTIDISPLAY
 
-/* Gtk does not work well without any display open.  Emacs may close
-   all its displays.  In that case, keep a display around just for
-   the purpose of having one.  */
+/* Keep track of the default display, or NULL if there is none.  Emacs
+   may close all its displays.  */
 
 static GdkDisplay *gdpy_def;
 
 
 static GdkDisplay *gdpy_def;
 
-
 /* Return the GdkDisplay that corresponds to the X display DPY.  */
 
 static GdkDisplay *
 /* Return the GdkDisplay that corresponds to the X display DPY.  */
 
 static GdkDisplay *
@@ -121,8 +119,14 @@ xg_display_open (display_name, dpy)
   GdkDisplay *gdpy;
 
   gdpy = gdk_display_open (display_name);
   GdkDisplay *gdpy;
 
   gdpy = gdk_display_open (display_name);
-  *dpy = gdpy ? GDK_DISPLAY_XDISPLAY (gdpy) : NULL;
+  if (!gdpy_def && gdpy)
+    {
+      gdpy_def = gdpy;
+      gdk_display_manager_set_default_display (gdk_display_manager_get (),
+                                              gdpy);
+    }
 
 
+  *dpy = gdpy ? GDK_DISPLAY_XDISPLAY (gdpy) : NULL;
   return gdpy != NULL;
 
 #else /* not HAVE_GTK_MULTIDISPLAY */
   return gdpy != NULL;
 
 #else /* not HAVE_GTK_MULTIDISPLAY */
@@ -140,40 +144,30 @@ xg_display_close (Display *dpy)
 #ifdef HAVE_GTK_MULTIDISPLAY
   GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpy);
 
 #ifdef HAVE_GTK_MULTIDISPLAY
   GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpy);
 
-  /* If this is the default display, we must change it before calling
-     dispose, otherwise it will crash on some Gtk+ versions.  */
+  /* If this is the default display, try to change it before closing.
+     If there is no other display to use, gdpy_def is set to NULL, and
+     the next call to xg_display_open resets the default display.  */
   if (gdk_display_get_default () == gdpy)
     {
       struct x_display_info *dpyinfo;
   if (gdk_display_get_default () == gdpy)
     {
       struct x_display_info *dpyinfo;
-      Display *new_dpy = 0;
-      GdkDisplay *gdpy_new;
+      GdkDisplay *gdpy_new = NULL;
 
       /* Find another display.  */
       for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
         if (dpyinfo->display != dpy)
           {
 
       /* Find another display.  */
       for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
         if (dpyinfo->display != dpy)
           {
-            new_dpy = dpyinfo->display;
+           gdpy_new = gdk_x11_lookup_xdisplay (dpyinfo->display);
+           gdk_display_manager_set_default_display (gdk_display_manager_get (),
+                                                    gdpy_new);
             break;
           }
             break;
           }
-
-      if (new_dpy)
-        gdpy_new = gdk_x11_lookup_xdisplay (new_dpy);
-      else
-        {
-          if (!gdpy_def)
-            gdpy_def = gdk_display_open (gdk_display_get_name (gdpy));
-          gdpy_new = gdpy_def;
-        }
-
-      gdk_display_manager_set_default_display (gdk_display_manager_get (),
-                                               gdpy_new);
+      gdpy_def = gdpy_new;
     }
 
     }
 
-  /* GTK 2.2-2.8 has a bug that makes gdk_display_close crash (bug
-     http://bugzilla.gnome.org/show_bug.cgi?id=85715).  This way
-     we can continue running, but there will be memory leaks.  */
-
 #if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 10
 #if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 10
+  /* GTK 2.2-2.8 has a bug that makes gdk_display_close crash (bug
+     http://bugzilla.gnome.org/show_bug.cgi?id=85715).  This way we
+     can continue running, but there will be memory leaks.  */
   g_object_run_dispose (G_OBJECT (gdpy));
 #else
   /* This seems to be fixed in GTK 2.10. */
   g_object_run_dispose (G_OBJECT (gdpy));
 #else
   /* This seems to be fixed in GTK 2.10. */
@@ -233,7 +227,7 @@ free_widget_value (wv)
     {
       /* When the number of already allocated cells is too big,
         We free it.  */
     {
       /* When the number of already allocated cells is too big,
         We free it.  */
-      free (wv);
+      xfree (wv);
       malloc_cpt--;
     }
   else
       malloc_cpt--;
     }
   else
@@ -531,7 +525,7 @@ get_utf8_string (str)
   if (!g_utf8_validate (str, -1, NULL))
     utf8_str = g_locale_to_utf8 (str, -1, 0, 0, 0);
 
   if (!g_utf8_validate (str, -1, NULL))
     utf8_str = g_locale_to_utf8 (str, -1, 0, 0, 0);
 
-  if (!utf8_str) 
+  if (!utf8_str)
     {
       /* Probably some control characters in str.  Escape them. */
       size_t nr_bad = 0;
     {
       /* Probably some control characters in str.  Escape them. */
       size_t nr_bad = 0;
@@ -551,7 +545,7 @@ get_utf8_string (str)
           error = NULL;
         }
 
           error = NULL;
         }
 
-      if (error) 
+      if (error)
         {
           g_error_free (error);
           error = NULL;
         {
           g_error_free (error);
           error = NULL;
@@ -574,12 +568,12 @@ get_utf8_string (str)
           error = NULL;
         }
 
           error = NULL;
         }
 
-      if (cp) 
+      if (cp)
         {
           strcat (utf8_str, cp);
           g_free (cp);
         }
         {
           strcat (utf8_str, cp);
           g_free (cp);
         }
-      if (error) 
+      if (error)
         {
           g_error_free (error);
           error = NULL;
         {
           g_error_free (error);
           error = NULL;
@@ -655,14 +649,9 @@ xg_frame_resized (f, pixelwidth, pixelheight)
       FRAME_PIXEL_WIDTH (f) = pixelwidth;
       FRAME_PIXEL_HEIGHT (f) = pixelheight;
 
       FRAME_PIXEL_WIDTH (f) = pixelwidth;
       FRAME_PIXEL_HEIGHT (f) = pixelheight;
 
-      if (rows != FRAME_LINES (f) || columns != FRAME_COLS (f)
-          || (f->new_text_lines != 0 && f->new_text_lines != rows)
-          || (f->new_text_cols != 0 && f->new_text_cols != columns))
-        {
-          change_frame_size (f, rows, columns, 0, 1, 0);
-          SET_FRAME_GARBAGED (f);
-          cancel_mouse_face (f);
-        }
+      change_frame_size (f, rows, columns, 0, 1, 0);
+      SET_FRAME_GARBAGED (f);
+      cancel_mouse_face (f);
     }
 }
 
     }
 }
 
@@ -934,97 +923,95 @@ x_wm_set_size_hint (f, flags, user_position)
      long flags;
      int user_position;
 {
      long flags;
      int user_position;
 {
-  if (FRAME_GTK_OUTER_WIDGET (f))
-  {
-    /* Must use GTK routines here, otherwise GTK resets the size hints
-       to its own defaults.  */
-    GdkGeometry size_hints;
-    gint hint_flags = 0;
-    int base_width, base_height;
-    int min_rows = 0, min_cols = 0;
-    int win_gravity = f->win_gravity;
-
-    if (flags)
-      {
-        memset (&size_hints, 0, sizeof (size_hints));
-        f->output_data.x->size_hints = size_hints;
-        f->output_data.x->hint_flags = hint_flags;
-      }
-     else
-       flags = f->size_hint_flags;
-
-    size_hints = f->output_data.x->size_hints;
-    hint_flags = f->output_data.x->hint_flags;
-
-    hint_flags |= GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE;
-    size_hints.width_inc = FRAME_COLUMN_WIDTH (f);
-    size_hints.height_inc = FRAME_LINE_HEIGHT (f);
-
-    hint_flags |= GDK_HINT_BASE_SIZE;
-    base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
-    base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0)
-      + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
-
-    check_frame_size (f, &min_rows, &min_cols);
-
-    size_hints.base_width = base_width;
-    size_hints.base_height = base_height;
-    size_hints.min_width  = base_width + min_cols * size_hints.width_inc;
-    size_hints.min_height = base_height + min_rows * size_hints.height_inc;
-
-
-    /* These currently have a one to one mapping with the X values, but I
-       don't think we should rely on that.  */
-    hint_flags |= GDK_HINT_WIN_GRAVITY;
-    size_hints.win_gravity = 0;
-    if (win_gravity == NorthWestGravity)
-      size_hints.win_gravity = GDK_GRAVITY_NORTH_WEST;
-    else if (win_gravity == NorthGravity)
-      size_hints.win_gravity = GDK_GRAVITY_NORTH;
-    else if (win_gravity == NorthEastGravity)
-      size_hints.win_gravity = GDK_GRAVITY_NORTH_EAST;
-    else if (win_gravity == WestGravity)
-      size_hints.win_gravity = GDK_GRAVITY_WEST;
-    else if (win_gravity == CenterGravity)
-      size_hints.win_gravity = GDK_GRAVITY_CENTER;
-    else if (win_gravity == EastGravity)
-      size_hints.win_gravity = GDK_GRAVITY_EAST;
-    else if (win_gravity == SouthWestGravity)
-      size_hints.win_gravity = GDK_GRAVITY_SOUTH_WEST;
-    else if (win_gravity == SouthGravity)
-      size_hints.win_gravity = GDK_GRAVITY_SOUTH;
-    else if (win_gravity == SouthEastGravity)
-      size_hints.win_gravity = GDK_GRAVITY_SOUTH_EAST;
-    else if (win_gravity == StaticGravity)
-      size_hints.win_gravity = GDK_GRAVITY_STATIC;
-
-    if (flags & PPosition) hint_flags |= GDK_HINT_POS;
-    if (flags & USPosition) hint_flags |= GDK_HINT_USER_POS;
-    if (flags & USSize) hint_flags |= GDK_HINT_USER_SIZE;
-
-    if (user_position)
-      {
-        hint_flags &= ~GDK_HINT_POS;
-        hint_flags |= GDK_HINT_USER_POS;
-      }
+  /* Don't set size hints during initialization; that apparently leads
+     to a race condition.  See the thread at
+     http://lists.gnu.org/archive/html/emacs-devel/2008-10/msg00033.html  */
+  if (NILP (Vafter_init_time) || !FRAME_GTK_OUTER_WIDGET (f))
+    return;
 
 
-    if (hint_flags != f->output_data.x->hint_flags
-        || memcmp (&size_hints,
-                   &f->output_data.x->size_hints,
-                   sizeof (size_hints)) != 0)
-      {
-        BLOCK_INPUT;
+  /* Must use GTK routines here, otherwise GTK resets the size hints
+     to its own defaults.  */
+  GdkGeometry size_hints;
+  gint hint_flags = 0;
+  int base_width, base_height;
+  int min_rows = 0, min_cols = 0;
+  int win_gravity = f->win_gravity;
 
 
-        gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
-                                       NULL,
-                                       &size_hints,
-                                       hint_flags);
+  if (flags)
+    {
+      memset (&size_hints, 0, sizeof (size_hints));
+      f->output_data.x->size_hints = size_hints;
+      f->output_data.x->hint_flags = hint_flags;
+    }
+  else
+    flags = f->size_hint_flags;
 
 
-        f->output_data.x->size_hints = size_hints;
-        f->output_data.x->hint_flags = hint_flags;
-        UNBLOCK_INPUT;
-      }
-  }
+  size_hints = f->output_data.x->size_hints;
+  hint_flags = f->output_data.x->hint_flags;
+
+  hint_flags |= GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE;
+  size_hints.width_inc = FRAME_COLUMN_WIDTH (f);
+  size_hints.height_inc = FRAME_LINE_HEIGHT (f);
+
+  hint_flags |= GDK_HINT_BASE_SIZE;
+  base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
+  base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0)
+    + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
+
+  check_frame_size (f, &min_rows, &min_cols);
+
+  size_hints.base_width = base_width;
+  size_hints.base_height = base_height;
+  size_hints.min_width  = base_width + min_cols * size_hints.width_inc;
+  size_hints.min_height = base_height + min_rows * size_hints.height_inc;
+
+  /* These currently have a one to one mapping with the X values, but I
+     don't think we should rely on that.  */
+  hint_flags |= GDK_HINT_WIN_GRAVITY;
+  size_hints.win_gravity = 0;
+  if (win_gravity == NorthWestGravity)
+    size_hints.win_gravity = GDK_GRAVITY_NORTH_WEST;
+  else if (win_gravity == NorthGravity)
+    size_hints.win_gravity = GDK_GRAVITY_NORTH;
+  else if (win_gravity == NorthEastGravity)
+    size_hints.win_gravity = GDK_GRAVITY_NORTH_EAST;
+  else if (win_gravity == WestGravity)
+    size_hints.win_gravity = GDK_GRAVITY_WEST;
+  else if (win_gravity == CenterGravity)
+    size_hints.win_gravity = GDK_GRAVITY_CENTER;
+  else if (win_gravity == EastGravity)
+    size_hints.win_gravity = GDK_GRAVITY_EAST;
+  else if (win_gravity == SouthWestGravity)
+    size_hints.win_gravity = GDK_GRAVITY_SOUTH_WEST;
+  else if (win_gravity == SouthGravity)
+    size_hints.win_gravity = GDK_GRAVITY_SOUTH;
+  else if (win_gravity == SouthEastGravity)
+    size_hints.win_gravity = GDK_GRAVITY_SOUTH_EAST;
+  else if (win_gravity == StaticGravity)
+    size_hints.win_gravity = GDK_GRAVITY_STATIC;
+
+  if (flags & PPosition) hint_flags |= GDK_HINT_POS;
+  if (flags & USPosition) hint_flags |= GDK_HINT_USER_POS;
+  if (flags & USSize) hint_flags |= GDK_HINT_USER_SIZE;
+
+  if (user_position)
+    {
+      hint_flags &= ~GDK_HINT_POS;
+      hint_flags |= GDK_HINT_USER_POS;
+    }
+
+  if (hint_flags != f->output_data.x->hint_flags
+      || memcmp (&size_hints,
+                &f->output_data.x->size_hints,
+                sizeof (size_hints)) != 0)
+    {
+      BLOCK_INPUT;
+      gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+                                    NULL, &size_hints, hint_flags);
+      f->output_data.x->size_hints = size_hints;
+      f->output_data.x->hint_flags = hint_flags;
+      UNBLOCK_INPUT;
+    }
 }
 
 /* Change background color of a frame.
 }
 
 /* Change background color of a frame.
@@ -1409,8 +1396,8 @@ xg_get_file_with_chooser (f, prompt, default_filename,
   wbox = gtk_vbox_new (FALSE, 0);
   gtk_widget_show (wbox);
   wtoggle = gtk_check_button_new_with_label ("Show hidden files.");
   wbox = gtk_vbox_new (FALSE, 0);
   gtk_widget_show (wbox);
   wtoggle = gtk_check_button_new_with_label ("Show hidden files.");
-  
-  if (x_gtk_show_hidden_files) 
+
+  if (x_gtk_show_hidden_files)
     {
       g_object_set (G_OBJECT (filewin), "show-hidden", TRUE, NULL);
       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wtoggle), TRUE);
     {
       g_object_set (G_OBJECT (filewin), "show-hidden", TRUE, NULL);
       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wtoggle), TRUE);
@@ -1431,7 +1418,7 @@ xg_get_file_with_chooser (f, prompt, default_filename,
       strcat (message, "\nIf you don't like this file selector, use the "
               "corresponding\nkey binding or customize "
               "use-file-dialog to turn it off.");
       strcat (message, "\nIf you don't like this file selector, use the "
               "corresponding\nkey binding or customize "
               "use-file-dialog to turn it off.");
-    
+
       wmessage = gtk_label_new (message);
       gtk_widget_show (wmessage);
     }
       wmessage = gtk_label_new (message);
       gtk_widget_show (wmessage);
     }
@@ -1454,7 +1441,7 @@ xg_get_file_with_chooser (f, prompt, default_filename,
          an absolute name starting with /.  */
       if (default_filename[0] != '/')
         file = Fexpand_file_name (file, Qnil);
          an absolute name starting with /.  */
       if (default_filename[0] != '/')
         file = Fexpand_file_name (file, Qnil);
-      
+
       utf8_filename = SSDATA (ENCODE_UTF_8 (file));
       if (! NILP (Ffile_directory_p (file)))
         gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (filewin),
       utf8_filename = SSDATA (ENCODE_UTF_8 (file));
       if (! NILP (Ffile_directory_p (file)))
         gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (filewin),
@@ -2604,7 +2591,7 @@ xg_update_menubar (menubar, f, list, iter, pos, val,
 /* Update the menu item W so it corresponds to VAL.
    SELECT_CB is the callback to use when a menu item is selected.
    HIGHLIGHT_CB is the callback to call when entering/leaving menu items.
 /* Update the menu item W so it corresponds to VAL.
    SELECT_CB is the callback to use when a menu item is selected.
    HIGHLIGHT_CB is the callback to call when entering/leaving menu items.
-   CL_DATA is the data to set in the widget for menu invokation.  */
+   CL_DATA is the data to set in the widget for menu invocation.  */
 
 static void
 xg_update_menu_item (val, w, select_cb, highlight_cb, cl_data)
 
 static void
 xg_update_menu_item (val, w, select_cb, highlight_cb, cl_data)
@@ -3150,7 +3137,7 @@ xg_gtk_scroll_destroy (widget, data)
 }
 
 /* Callback for button press/release events.  Used to start timer so that
 }
 
 /* Callback for button press/release events.  Used to start timer so that
-   the scroll bar repetition timer in GTK gets handeled.
+   the scroll bar repetition timer in GTK gets handled.
    Also, sets bar->dragging to Qnil when dragging (button release) is done.
    WIDGET is the scroll bar widget the event is for (not used).
    EVENT contains the event.
    Also, sets bar->dragging to Qnil when dragging (button release) is done.
    WIDGET is the scroll bar widget the event is for (not used).
    EVENT contains the event.
@@ -3466,17 +3453,21 @@ xg_tool_bar_callback (w, client_data)
      to `(tool_bar)', see keyboard.c.  */
   event.kind = TOOL_BAR_EVENT;
   event.frame_or_window = frame;
      to `(tool_bar)', see keyboard.c.  */
   event.kind = TOOL_BAR_EVENT;
   event.frame_or_window = frame;
-  event.arg = frame;    
-  kbd_buffer_store_event (&event);      
-  
-  event.kind = TOOL_BAR_EVENT;          
+  event.arg = frame;
+  kbd_buffer_store_event (&event);
+
+  event.kind = TOOL_BAR_EVENT;
   event.frame_or_window = frame;
   event.arg = key;
   /* Convert between the modifier bits GDK uses and the modifier bits
   event.frame_or_window = frame;
   event.arg = key;
   /* Convert between the modifier bits GDK uses and the modifier bits
-     Emacs uses.  This assumes GDK an X masks are the same, which they are when
+     Emacs uses.  This assumes GDK and X masks are the same, which they are when
      this is written.  */
   event.modifiers = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), mod);
   kbd_buffer_store_event (&event);
      this is written.  */
   event.modifiers = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), mod);
   kbd_buffer_store_event (&event);
+   /* Return focus to the frame after we have clicked on a detached
+      tool bar button. */
+   Fx_focus_frame (frame);
 }
 
 /* Callback function invoked when a tool bar item is pressed in a detached
 }
 
 /* Callback function invoked when a tool bar item is pressed in a detached
@@ -3494,6 +3485,8 @@ xg_tool_bar_proxy_callback (w, client_data)
   GtkWidget *wbutton = GTK_WIDGET (g_object_get_data (G_OBJECT (w),
                                                       XG_TOOL_BAR_PROXY_BUTTON));
   xg_tool_bar_callback (wbutton, client_data);
   GtkWidget *wbutton = GTK_WIDGET (g_object_get_data (G_OBJECT (w),
                                                       XG_TOOL_BAR_PROXY_BUTTON));
   xg_tool_bar_callback (wbutton, client_data);
+  FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (wbutton),
+                                               XG_FRAME_DATA);
 }
 
 /* This callback is called when a tool item should create a proxy item,
 }
 
 /* This callback is called when a tool item should create a proxy item,
@@ -3511,7 +3504,7 @@ xg_tool_bar_menu_proxy (toolitem, user_data)
   GtkWidget *wmenuitem = gtk_image_menu_item_new ();
   GtkWidget *wmenuimage;
 
   GtkWidget *wmenuitem = gtk_image_menu_item_new ();
   GtkWidget *wmenuimage;
 
-  if (gtk_button_get_use_stock (wbutton)) 
+  if (gtk_button_get_use_stock (wbutton))
     wmenuimage = gtk_image_new_from_stock (gtk_button_get_label (wbutton),
                                            GTK_ICON_SIZE_MENU);
   else
     wmenuimage = gtk_image_new_from_stock (gtk_button_get_label (wbutton),
                                            GTK_ICON_SIZE_MENU);
   else
@@ -3536,7 +3529,7 @@ xg_tool_bar_menu_proxy (toolitem, user_data)
       else if (store_type == GTK_IMAGE_PIXBUF)
         {
           gint width, height;
       else if (store_type == GTK_IMAGE_PIXBUF)
         {
           gint width, height;
-      
+
           if (settings &&
               gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU,
                                                  &width, &height))
           if (settings &&
               gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU,
                                                  &width, &height))
@@ -3555,7 +3548,7 @@ xg_tool_bar_menu_proxy (toolitem, user_data)
               abort ();
             }
         }
               abort ();
             }
         }
-      else if (store_type == GTK_IMAGE_ICON_NAME) 
+      else if (store_type == GTK_IMAGE_ICON_NAME)
         {
           const gchar *icon_name;
           GtkIconSize icon_size;
         {
           const gchar *icon_name;
           GtkIconSize icon_size;
@@ -3575,7 +3568,7 @@ xg_tool_bar_menu_proxy (toolitem, user_data)
 
   g_signal_connect (G_OBJECT (wmenuitem),
                     "activate",
 
   g_signal_connect (G_OBJECT (wmenuitem),
                     "activate",
-                    GTK_SIGNAL_FUNC (xg_tool_bar_proxy_callback),
+                    G_CALLBACK (xg_tool_bar_proxy_callback),
                     user_data);
 
   g_object_set_data (G_OBJECT (wmenuitem), XG_TOOL_BAR_PROXY_BUTTON,
                     user_data);
 
   g_object_set_data (G_OBJECT (wmenuitem), XG_TOOL_BAR_PROXY_BUTTON,
@@ -3797,7 +3790,7 @@ find_rtl_image (f, image, rtl)
   for (i = 0; i < f->n_tool_bar_items; ++i)
     {
       Lisp_Object rtl_image = PROP (TOOL_BAR_ITEM_IMAGES);
   for (i = 0; i < f->n_tool_bar_items; ++i)
     {
       Lisp_Object rtl_image = PROP (TOOL_BAR_ITEM_IMAGES);
-      if (!NILP (file = file_for_image (rtl_image))) 
+      if (!NILP (file = file_for_image (rtl_image)))
         {
           file = call1 (intern ("file-name-sans-extension"),
                        Ffile_name_nondirectory (file));
         {
           file = call1 (intern ("file-name-sans-extension"),
                        Ffile_name_nondirectory (file));
@@ -3873,7 +3866,7 @@ update_frame_tool_bar (f)
       int icon_size = 0;
       struct image *img = NULL;
       Lisp_Object image;
       int icon_size = 0;
       struct image *img = NULL;
       Lisp_Object image;
-      Lisp_Object stock;
+      Lisp_Object stock = Qnil;
       GtkStockItem stock_item;
       char *stock_name = NULL;
       char *icon_name = NULL;
       GtkStockItem stock_item;
       char *stock_name = NULL;
       char *icon_name = NULL;
@@ -3923,7 +3916,7 @@ update_frame_tool_bar (f)
             }
           else if (gtk_stock_lookup (SSDATA (stock), &stock_item))
               icon_size = gtk_toolbar_get_icon_size (wtoolbar);
             }
           else if (gtk_stock_lookup (SSDATA (stock), &stock_item))
               icon_size = gtk_toolbar_get_icon_size (wtoolbar);
-          else 
+          else
             {
               stock = Qnil;
               stock_name = NULL;
             {
               stock = Qnil;
               stock_name = NULL;
@@ -3963,7 +3956,7 @@ update_frame_tool_bar (f)
           img_id = lookup_image (f, image);
           img = IMAGE_FROM_ID (f, img_id);
           prepare_image_for_display (f, img);
           img_id = lookup_image (f, image);
           img = IMAGE_FROM_ID (f, img_id);
           prepare_image_for_display (f, img);
-      
+
           if (img->load_failed_p || img->pixmap == None)
             {
                 if (ti)
           if (img->load_failed_p || img->pixmap == None)
             {
                 if (ti)
@@ -3995,7 +3988,7 @@ update_frame_tool_bar (f)
                                       (gpointer) xstrdup (stock_name),
                                       (GDestroyNotify) xfree);
             }
                                       (gpointer) xstrdup (stock_name),
                                       (GDestroyNotify) xfree);
             }
-          else if (icon_name) 
+          else if (icon_name)
             {
               w = gtk_image_new_from_icon_name (icon_name, icon_size);
               g_object_set_data_full (G_OBJECT (w), XG_TOOL_BAR_ICON_NAME,
             {
               w = gtk_image_new_from_icon_name (icon_name, icon_size);
               g_object_set_data_full (G_OBJECT (w), XG_TOOL_BAR_ICON_NAME,
@@ -4025,11 +4018,11 @@ update_frame_tool_bar (f)
 
           /* The EMACS_INT cast avoids a warning. */
           g_signal_connect (G_OBJECT (ti), "create-menu-proxy",
 
           /* The EMACS_INT cast avoids a warning. */
           g_signal_connect (G_OBJECT (ti), "create-menu-proxy",
-                            GTK_SIGNAL_FUNC (xg_tool_bar_menu_proxy),
+                            G_CALLBACK (xg_tool_bar_menu_proxy),
                             (gpointer) (EMACS_INT) i);
 
           g_signal_connect (G_OBJECT (wbutton), "clicked",
                             (gpointer) (EMACS_INT) i);
 
           g_signal_connect (G_OBJECT (wbutton), "clicked",
-                            GTK_SIGNAL_FUNC (xg_tool_bar_callback),
+                            G_CALLBACK (xg_tool_bar_callback),
                             (gpointer) (EMACS_INT) i);
 
           gtk_widget_show_all (GTK_WIDGET (ti));
                             (gpointer) (EMACS_INT) i);
 
           gtk_widget_show_all (GTK_WIDGET (ti));
@@ -4046,12 +4039,12 @@ update_frame_tool_bar (f)
 
           gtk_widget_set_sensitive (wbutton, enabled_p);
           gtk_tool_item_set_homogeneous (ti, FALSE);
 
           gtk_widget_set_sensitive (wbutton, enabled_p);
           gtk_tool_item_set_homogeneous (ti, FALSE);
-          
+
           /* Callback to save modifyer mask (Shift/Control, etc).  GTK makes
              no distinction based on modifiers in the activate callback,
              so we have to do it ourselves.  */
           g_signal_connect (wbutton, "button-release-event",
           /* Callback to save modifyer mask (Shift/Control, etc).  GTK makes
              no distinction based on modifiers in the activate callback,
              so we have to do it ourselves.  */
           g_signal_connect (wbutton, "button-release-event",
-                            GTK_SIGNAL_FUNC (xg_tool_bar_button_cb),
+                            G_CALLBACK (xg_tool_bar_button_cb),
                             NULL);
 
           g_object_set_data (G_OBJECT (wbutton), XG_FRAME_DATA, (gpointer)f);
                             NULL);
 
           g_object_set_data (G_OBJECT (wbutton), XG_FRAME_DATA, (gpointer)f);
@@ -4224,12 +4217,13 @@ xg_initialize ()
 
   /* Make dialogs close on C-g.  Since file dialog inherits from
      dialog, this works for them also.  */
 
   /* Make dialogs close on C-g.  Since file dialog inherits from
      dialog, this works for them also.  */
-  binding_set = gtk_binding_set_by_class (gtk_type_class (GTK_TYPE_DIALOG));
+  binding_set = gtk_binding_set_by_class (g_type_class_ref (GTK_TYPE_DIALOG));
   gtk_binding_entry_add_signal (binding_set, GDK_g, GDK_CONTROL_MASK,
                                 "close", 0);
 
   /* Make menus close on C-g.  */
   gtk_binding_entry_add_signal (binding_set, GDK_g, GDK_CONTROL_MASK,
                                 "close", 0);
 
   /* Make menus close on C-g.  */
-  binding_set = gtk_binding_set_by_class (gtk_type_class (GTK_TYPE_MENU_SHELL));
+  binding_set = gtk_binding_set_by_class (g_type_class_ref
+                                          (GTK_TYPE_MENU_SHELL));
   gtk_binding_entry_add_signal (binding_set, GDK_g, GDK_CONTROL_MASK,
                                 "cancel", 0);
 }
   gtk_binding_entry_add_signal (binding_set, GDK_g, GDK_CONTROL_MASK,
                                 "cancel", 0);
 }