Overflow, signedness and related fixes for images.
[bpt/emacs.git] / src / gtkutil.c
index dedb39a..70bc18a 100644 (file)
@@ -42,6 +42,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #ifdef HAVE_GTK3
 #include <gtk/gtkx.h>
+#include "emacsgtkfixed.h"
 #endif
 
 #define FRAME_TOTAL_PIXEL_HEIGHT(f) \
@@ -88,12 +89,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #define XG_BIN_CHILD(x) gtk_bin_get_child (GTK_BIN (x))
 
-/* Get the current value of the range, truncated to an integer.  */
-static int
-int_gtk_range_get_value (GtkRange *range)
-{
-  return gtk_range_get_value (range);
-}
+static void update_theme_scrollbar_width (void);
 
 \f
 /***********************************************************************
@@ -273,8 +269,8 @@ xg_get_pixbuf_from_pixmap (FRAME_PTR f, Pixmap pix)
                                       GDK_COLORSPACE_RGB,
                                       FALSE,
                                       xim->bitmap_unit,
-                                      (int) width,
-                                      (int) height,
+                                      width,
+                                      height,
                                       xim->bytes_per_line,
                                       NULL,
                                       NULL);
@@ -637,6 +633,9 @@ qttip_cb (GtkWidget  *widget,
   struct x_output *x = f->output_data.x;
   if (x->ttip_widget == NULL)
     {
+      GtkWidget *p;
+      GList *list, *iter;
+
       g_object_set (G_OBJECT (widget), "has-tooltip", FALSE, NULL);
       x->ttip_widget = tooltip;
       g_object_ref (G_OBJECT (tooltip));
@@ -644,6 +643,18 @@ qttip_cb (GtkWidget  *widget,
       g_object_ref (G_OBJECT (x->ttip_lbl));
       gtk_tooltip_set_custom (tooltip, x->ttip_lbl);
       x->ttip_window = GTK_WINDOW (gtk_widget_get_toplevel (x->ttip_lbl));
+
+      /* Change stupid Gtk+ default line wrapping.  */
+      p = gtk_widget_get_parent (x->ttip_lbl);
+      list = gtk_container_get_children (GTK_CONTAINER (p));
+      for (iter = list; iter; iter = g_list_next (iter))
+        {
+          GtkWidget *w = GTK_WIDGET (iter->data);
+          if (GTK_IS_LABEL (w))
+            gtk_label_set_line_wrap (GTK_LABEL (w), FALSE);
+        }
+      g_list_free (list);
+
       /* ATK needs an empty title for some reason.  */
       gtk_window_set_title (x->ttip_window, "");
       /* Realize so we can safely get screen later on.  */
@@ -663,8 +674,8 @@ qttip_cb (GtkWidget  *widget,
 
 int
 xg_prepare_tooltip (FRAME_PTR f,
-                      Lisp_Object string,
-                      int *width,
+                    Lisp_Object string,
+                    int *width,
                     int *height)
 {
 #ifndef USE_GTK_TOOLTIP
@@ -701,10 +712,9 @@ xg_prepare_tooltip (FRAME_PTR f,
                      (gtk_widget_get_display (GTK_WIDGET (x->ttip_window))),
                      "gdk-display-current-tooltip", NULL);
 
-  /* Put out dummy widget in so we can get callbacks for unrealize and
+  /* Put our dummy widget in so we can get callbacks for unrealize and
      hierarchy-changed.  */
   gtk_tooltip_set_custom (x->ttip_widget, widget);
-
   gtk_tooltip_set_text (x->ttip_widget, SSDATA (encoded_string));
   gtk_widget_get_preferred_size (GTK_WIDGET (x->ttip_window), NULL, &req);
   if (width) *width = req.width;
@@ -735,7 +745,7 @@ xg_show_tooltip (FRAME_PTR f, int root_x, int root_y)
 }
 
 /* Hide tooltip if shown.  Do nothing if not shown.
-   Return non-zero if tip was hidden, non-ero if not (i.e. not using
+   Return non-zero if tip was hidden, non-zero if not (i.e. not using
    system tooltips).  */
 
 int
@@ -1015,13 +1025,32 @@ style_changed_cb (GObject *go,
   struct input_event event;
   GdkDisplay *gdpy = (GdkDisplay *) user_data;
   const char *display_name = gdk_display_get_name (gdpy);
+  Display *dpy = GDK_DISPLAY_XDISPLAY (gdpy);
 
   EVENT_INIT (event);
   event.kind = CONFIG_CHANGED_EVENT;
-  event.frame_or_window = make_string (display_name, strlen (display_name));
+  event.frame_or_window = build_string (display_name);
   /* Theme doesn't change often, so intern is called seldom.  */
   event.arg = intern ("theme-name");
   kbd_buffer_store_event (&event);
+
+  update_theme_scrollbar_width ();
+
+  /* If scroll bar width changed, we need set the new size on all frames
+     on this display.  */
+  if (dpy)
+    {
+      Lisp_Object rest, frame;
+      FOR_EACH_FRAME (rest, frame)
+        {
+          FRAME_PTR f = XFRAME (frame);
+          if (FRAME_X_DISPLAY (f) == dpy)
+            {
+              x_set_scroll_bar_default_width (f);
+              xg_frame_set_char_size (f, FRAME_COLS (f), FRAME_LINES (f));
+            }
+        }
+    }
 }
 
 /* Called when a delete-event occurs on WIDGET.  */
@@ -1069,7 +1098,12 @@ xg_create_frame_widgets (FRAME_PTR f)
 
   wvbox = gtk_vbox_new (FALSE, 0);
   whbox = gtk_hbox_new (FALSE, 0);
-  wfixed = gtk_fixed_new ();  /* Must have this to place scroll bars  */
+
+#ifdef HAVE_GTK3
+  wfixed = emacs_fixed_new (f);
+#else
+  wfixed = gtk_fixed_new ();
+#endif
 
   if (! wtop || ! wvbox || ! whbox || ! wfixed)
     {
@@ -1162,6 +1196,7 @@ xg_create_frame_widgets (FRAME_PTR f)
   gtk_widget_modify_style (wfixed, style);
 #else
   gtk_widget_set_can_focus (wfixed, TRUE);
+  gtk_window_set_resizable (GTK_WINDOW (wtop), TRUE);
 #endif
 
 #ifdef USE_GTK_TOOLTIP
@@ -1303,7 +1338,7 @@ x_wm_set_size_hint (FRAME_PTR f, long int flags, int user_position)
     {
       BLOCK_INPUT;
       gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
-                                    NULL, &size_hints, hint_flags);
+                                     NULL, &size_hints, hint_flags);
       f->output_data.x->size_hints = size_hints;
       f->output_data.x->hint_flags = hint_flags;
       UNBLOCK_INPUT;
@@ -3250,6 +3285,10 @@ xg_event_is_for_menubar (FRAME_PTR f, XEvent *event)
 
 int xg_ignore_gtk_scrollbar;
 
+/* The width of the scroll bar for the current theme.  */
+
+static int scroll_bar_width_for_theme;
+
 /* Xlib's `Window' fits in 32 bits.  But we want to store pointers, and they
    may be larger than 32 bits.  Keep a mapping from integer index to widget
    pointers to get around the 32 bit limitation.  */
@@ -3326,8 +3365,8 @@ xg_get_widget_from_map (int idx)
   return 0;
 }
 
-int
-xg_get_default_scrollbar_width (FRAME_PTR f)
+static void
+update_theme_scrollbar_width (void)
 {
 #ifdef HAVE_GTK3
   GtkAdjustment *vadj;
@@ -3336,13 +3375,22 @@ xg_get_default_scrollbar_width (FRAME_PTR f)
 #endif
   GtkWidget *wscroll;
   int w = 0, b = 0;
+
   vadj = gtk_adjustment_new (XG_SB_MIN, XG_SB_MIN, XG_SB_MAX, 0.1, 0.1, 0.1);
   wscroll = gtk_vscrollbar_new (GTK_ADJUSTMENT (vadj));
+  g_object_ref_sink (G_OBJECT (wscroll));
   gtk_widget_style_get (wscroll, "slider-width", &w, "trough-border", &b, NULL);
   gtk_widget_destroy (wscroll);
+  g_object_unref (G_OBJECT (wscroll));
   w += 2*b;
   if (w < 16) w = 16;
-  return w;
+  scroll_bar_width_for_theme = w;
+}
+
+int
+xg_get_default_scrollbar_width (void)
+{
+  return scroll_bar_width_for_theme;
 }
 
 /* Return the scrollbar id for X Window WID on display DPY.
@@ -3528,6 +3576,15 @@ xg_update_scrollbar_pos (FRAME_PTR f,
     }
 }
 
+/* Get the current value of the range, truncated to an integer.  */
+
+static int
+int_gtk_range_get_value (GtkRange *range)
+{
+  return gtk_range_get_value (range);
+}
+
+
 /* Set the thumb size and position of scroll bar BAR.  We are currently
    displaying PORTION out of a whole WHOLE, and our position POSITION.  */
 
@@ -3589,7 +3646,7 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar,
              gtk_adjustment_set_page_size (adj, size);
              gtk_adjustment_set_step_increment (adj, new_step);
              /* Assume a page increment is about 95% of the page size  */
-             gtk_adjustment_set_page_increment (adj,(int) (0.95*size));
+             gtk_adjustment_set_page_increment (adj, size - size / 20);
              changed = 1;
            }
        }
@@ -4372,7 +4429,7 @@ update_frame_tool_bar (FRAME_PTR f)
       int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
       int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
       int idx;
-      int img_id;
+      ptrdiff_t img_id;
       int icon_size = 0;
       struct image *img = NULL;
       Lisp_Object image;
@@ -4680,6 +4737,7 @@ xg_initialize (void)
                                           (GTK_TYPE_MENU_SHELL));
   gtk_binding_entry_add_signal (binding_set, GDK_KEY_g, GDK_CONTROL_MASK,
                                 "cancel", 0);
+  update_theme_scrollbar_width ();
 }
 
 #endif /* USE_GTK */