]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkcalendar.c
Replace a lot of idle and timeout calls by the new gdk_threads api.
[~andy/gtk] / gtk / gtkcalendar.c
index 239aabc5e29fe7a77c2fd232bfb5df537701e675..5e9f6cada83959c48dcac6073820172925580058 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 #include <time.h>
-#include <glib/gprintf.h>
+
+#include <glib.h>
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#endif
 
 #undef GTK_DISABLE_DEPRECATED
 #include "gtkcalendar.h"
-#define GTK_DISABLE_DEPRECATED
 
 #include "gtkdnd.h"
 #include "gtkintl.h"
 #include "gtkmain.h"
 #include "gtkmarshalers.h"
 #include "gtkprivate.h"
-#include "gtkintl.h"
 #include "gdk/gdkkeysyms.h"
 #include "gtkalias.h"
 
 /***************************************************************************/
-/* The following date routines are taken from the lib_date package.  Keep
- * them separate in case we want to update them if a newer lib_date comes
- * out with fixes.  */
-
-typedef         unsigned   int     N_int;
-typedef         unsigned   long    N_long;
-typedef         signed     long    Z_long;
-typedef enum { false = FALSE , true = TRUE } boolean;
-
-#define and        &&      /* logical (boolean) operators: lower case */
-#define or         ||
+/* The following date routines are taken from the lib_date package. 
+ * They have been minimally edited to avoid conflict with types defined
+ * in win32 headers.
+ */
 
-static const N_int month_length[2][13] =
+static const guint month_length[2][13] =
 {
   { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
   { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
 };
 
-static const N_int days_in_months[2][14] =
+static const guint days_in_months[2][14] =
 {
   { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
   { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
 };
 
-static Z_long  calc_days(N_int year, N_int mm, N_int dd);
-static N_int   day_of_week(N_int year, N_int mm, N_int dd);
-static Z_long  dates_difference(N_int year1, N_int mm1, N_int dd1,
-                               N_int year2, N_int mm2, N_int dd2);
-static N_int   weeks_in_year(N_int year);
+static glong  calc_days(guint year, guint mm, guint dd);
+static guint  day_of_week(guint year, guint mm, guint dd);
+static glong  dates_difference(guint year1, guint mm1, guint dd1,
+                              guint year2, guint mm2, guint dd2);
+static guint  weeks_in_year(guint year);
 
-static boolean 
-leap(N_int year)
+static gboolean 
+leap (guint year)
 {
-  return((((year % 4) == 0) and ((year % 100) != 0)) or ((year % 400) == 0));
+  return((((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0));
 }
 
-static N_int 
-day_of_week(N_int year, N_int mm, N_int dd)
+static guint 
+day_of_week (guint year, guint mm, guint dd)
 {
-  Z_long  days;
+  glong  days;
   
   days = calc_days(year, mm, dd);
   if (days > 0L)
@@ -104,53 +100,53 @@ day_of_week(N_int year, N_int mm, N_int dd)
       days %= 7L;
       days++;
     }
-  return( (N_int) days );
+  return( (guint) days );
 }
 
-static N_int weeks_in_year(N_int year)
+static guint weeks_in_year(guint year)
 {
-  return(52 + ((day_of_week(year,1,1)==4) or (day_of_week(year,12,31)==4)));
+  return(52 + ((day_of_week(year,1,1)==4) || (day_of_week(year,12,31)==4)));
 }
 
-static boolean 
-check_date(N_int year, N_int mm, N_int dd)
+static gboolean 
+check_date(guint year, guint mm, guint dd)
 {
-  if (year < 1) return(false);
-  if ((mm < 1) or (mm > 12)) return(false);
-  if ((dd < 1) or (dd > month_length[leap(year)][mm])) return(false);
-  return(true);
+  if (year < 1) return FALSE;
+  if ((mm < 1) || (mm > 12)) return FALSE;
+  if ((dd < 1) || (dd > month_length[leap(year)][mm])) return FALSE;
+  return TRUE;
 }
 
-static N_int 
-week_number(N_int year, N_int mm, N_int dd)
+static guint 
+week_number(guint year, guint mm, guint dd)
 {
-  N_int first;
+  guint first;
   
   first = day_of_week(year,1,1) - 1;
-  return( (N_int) ( (dates_difference(year,1,1, year,mm,dd) + first) / 7L ) +
+  return( (guint) ( (dates_difference(year,1,1, year,mm,dd) + first) / 7L ) +
          (first < 4) );
 }
 
-static Z_long 
-year_to_days(N_int year)
+static glong 
+year_to_days(guint year)
 {
   return( year * 365L + (year / 4) - (year / 100) + (year / 400) );
 }
 
 
-static Z_long 
-calc_days(N_int year, N_int mm, N_int dd)
+static glong 
+calc_days(guint year, guint mm, guint dd)
 {
-  boolean lp;
+  gboolean lp;
   
   if (year < 1) return(0L);
-  if ((mm < 1) or (mm > 12)) return(0L);
-  if ((dd < 1) or (dd > month_length[(lp = leap(year))][mm])) return(0L);
+  if ((mm < 1) || (mm > 12)) return(0L);
+  if ((dd < 1) || (dd > month_length[(lp = leap(year))][mm])) return(0L);
   return( year_to_days(--year) + days_in_months[lp][mm] + dd );
 }
 
-static boolean 
-week_of_year(N_int *week, N_int *year, N_int mm, N_int dd)
+static gboolean 
+week_of_year(guint *week, guint *year, guint mm, guint dd)
 {
   if (check_date(*year,mm,dd))
     {
@@ -162,14 +158,14 @@ week_of_year(N_int *week, N_int *year, N_int mm, N_int dd)
          *week = 1;
          (*year)++;
        }
-      return(true);
+      return TRUE;
     }
-  return(false);
+  return FALSE;
 }
 
-static Z_long 
-dates_difference(N_int year1, N_int mm1, N_int dd1,
-                N_int year2, N_int mm2, N_int dd2)
+static glong 
+dates_difference(guint year1, guint mm1, guint dd1,
+                guint year2, guint mm2, guint dd2)
 {
   return( calc_days(year2, mm2, dd2) - calc_days(year1, mm1, dd1) );
 }
@@ -188,6 +184,8 @@ dates_difference(N_int year1, N_int mm1, N_int dd1,
 #define DAY_XSEP                0 /* not really good for small calendar */
 #define DAY_YSEP                0 /* not really good for small calendar */
 
+#define SCROLL_DELAY_FACTOR      5
+
 /* Color usage */
 #define HEADER_FG_COLOR(widget)                 (& (widget)->style->fg[GTK_WIDGET_STATE (widget)])
 #define HEADER_BG_COLOR(widget)                 (& (widget)->style->bg[GTK_WIDGET_STATE (widget)])
@@ -495,7 +493,7 @@ gtk_calendar_class_init (GtkCalendarClass *class)
                                                         GTK_PARAM_READWRITE));
 
   gtk_calendar_signals[MONTH_CHANGED_SIGNAL] =
-    g_signal_new ("month_changed",
+    g_signal_new (I_("month_changed"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GtkCalendarClass, month_changed),
@@ -503,7 +501,7 @@ gtk_calendar_class_init (GtkCalendarClass *class)
                  _gtk_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
   gtk_calendar_signals[DAY_SELECTED_SIGNAL] =
-    g_signal_new ("day_selected",
+    g_signal_new (I_("day_selected"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GtkCalendarClass, day_selected),
@@ -511,7 +509,7 @@ gtk_calendar_class_init (GtkCalendarClass *class)
                  _gtk_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
   gtk_calendar_signals[DAY_SELECTED_DOUBLE_CLICK_SIGNAL] =
-    g_signal_new ("day_selected_double_click",
+    g_signal_new (I_("day_selected_double_click"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GtkCalendarClass, day_selected_double_click),
@@ -519,7 +517,7 @@ gtk_calendar_class_init (GtkCalendarClass *class)
                  _gtk_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
   gtk_calendar_signals[PREV_MONTH_SIGNAL] =
-    g_signal_new ("prev_month",
+    g_signal_new (I_("prev_month"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GtkCalendarClass, prev_month),
@@ -527,7 +525,7 @@ gtk_calendar_class_init (GtkCalendarClass *class)
                  _gtk_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
   gtk_calendar_signals[NEXT_MONTH_SIGNAL] =
-    g_signal_new ("next_month",
+    g_signal_new (I_("next_month"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GtkCalendarClass, next_month),
@@ -535,7 +533,7 @@ gtk_calendar_class_init (GtkCalendarClass *class)
                  _gtk_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
   gtk_calendar_signals[PREV_YEAR_SIGNAL] =
-    g_signal_new ("prev_year",
+    g_signal_new (I_("prev_year"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GtkCalendarClass, prev_year),
@@ -543,7 +541,7 @@ gtk_calendar_class_init (GtkCalendarClass *class)
                  _gtk_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
   gtk_calendar_signals[NEXT_YEAR_SIGNAL] =
-    g_signal_new ("next_year",
+    g_signal_new (I_("next_year"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GtkCalendarClass, next_year),
@@ -561,12 +559,23 @@ gtk_calendar_init (GtkCalendar *calendar)
   time_t secs;
   struct tm *tm;
   gint i;
+#ifdef G_OS_WIN32
+  wchar_t wbuffer[100];
+#else
   char buffer[255];
   time_t tmp_time;
+#endif
   GtkCalendarPrivate *priv;
   gchar *year_before;
+#ifdef HAVE__NL_TIME_FIRST_WEEKDAY
+  gchar *langinfo;
+  gint week_1stday = 0;
+  gint first_weekday = 1;
+  guint week_origin;
+#else
   gchar *week_start;
-  
+#endif
+
   priv = calendar->priv = G_TYPE_INSTANCE_GET_PRIVATE (calendar,
                                                       GTK_TYPE_CALENDAR,
                                                       GtkCalendarPrivate);
@@ -576,17 +585,33 @@ gtk_calendar_init (GtkCalendar *calendar)
   if (!default_abbreviated_dayname[0])
     for (i=0; i<7; i++)
       {
+#ifndef G_OS_WIN32
        tmp_time= (i+3)*86400;
        strftime ( buffer, sizeof (buffer), "%a", gmtime (&tmp_time));
        default_abbreviated_dayname[i] = g_locale_to_utf8 (buffer, -1, NULL, NULL, NULL);
+#else
+       if (!GetLocaleInfoW (GetThreadLocale (), LOCALE_SABBREVDAYNAME1 + (i+6)%7,
+                            wbuffer, G_N_ELEMENTS (wbuffer)))
+         default_abbreviated_dayname[i] = g_strdup_printf ("(%d)", i);
+       else
+         default_abbreviated_dayname[i] = g_utf16_to_utf8 (wbuffer, -1, NULL, NULL, NULL);
+#endif
       }
   
   if (!default_monthname[0])
     for (i=0; i<12; i++)
       {
+#ifndef G_OS_WIN32
        tmp_time=i*2764800;
        strftime ( buffer, sizeof (buffer), "%B", gmtime (&tmp_time));
        default_monthname[i] = g_locale_to_utf8 (buffer, -1, NULL, NULL, NULL);
+#else
+       if (!GetLocaleInfoW (GetThreadLocale (), LOCALE_SMONTHNAME1 + i,
+                            wbuffer, G_N_ELEMENTS (wbuffer)))
+         default_monthname[i] = g_strdup_printf ("(%d)", i);
+       else
+         default_monthname[i] = g_utf16_to_utf8 (wbuffer, -1, NULL, NULL, NULL);
+#endif
       }
   
   /* Set defaults */
@@ -595,8 +620,6 @@ gtk_calendar_init (GtkCalendar *calendar)
   calendar->month = tm->tm_mon;
   calendar->year  = 1900 + tm->tm_year;
 
-  calendar_compute_days (calendar);
-
   for (i=0;i<31;i++)
     calendar->marked_date[i] = FALSE;
   calendar->num_marked_dates = 0;
@@ -640,7 +663,7 @@ gtk_calendar_init (GtkCalendar *calendar)
    * Do *not* translate it to anything else, if it
    * it isn't calendar:YM or calendar:MY it will not work.
    *
-   * Note that this flipping is in top the text direction flipping,
+   * Note that this flipping is in top of the text direction flipping,
    * so if you have a default text direction of RTL and YM, then
    * the year will appear on the right.
    */
@@ -650,9 +673,33 @@ gtk_calendar_init (GtkCalendar *calendar)
   else if (strcmp (year_before, "calendar:MY") != 0)
     g_warning ("Whoever translated calendar:MY did so wrongly.\n");
 
+#ifdef G_OS_WIN32
+  priv->week_start = 0;
+  week_start = NULL;
+
+  if (GetLocaleInfoW (GetThreadLocale (), LOCALE_IFIRSTDAYOFWEEK,
+                     wbuffer, G_N_ELEMENTS (wbuffer)))
+    week_start = g_utf16_to_utf8 (wbuffer, -1, NULL, NULL, NULL);
+      
+  if (week_start != NULL)
+    {
+      priv->week_start = (week_start[0] - '0' + 1) % 7;
+      g_free(week_start);
+    }
+#else
 #ifdef HAVE__NL_TIME_FIRST_WEEKDAY
-  week_start = nl_langinfo (_NL_TIME_FIRST_WEEKDAY);
-  priv->week_start = *((unsigned char *) week_start) % 7 - 1;
+  langinfo = nl_langinfo (_NL_TIME_FIRST_WEEKDAY);
+  first_weekday = langinfo[0];
+  langinfo = nl_langinfo (_NL_TIME_WEEK_1STDAY);
+  week_origin = GPOINTER_TO_INT (langinfo);
+  if (week_origin == 19971130) /* Sunday */
+    week_1stday = 0;
+  else if (week_origin == 19971201) /* Monday */
+    week_1stday = 1;
+  else
+    g_warning ("Unknown value of _NL_TIME_WEEK_1STDAY.\n");
+
+  priv->week_start = (week_1stday + first_weekday - 1) % 7;
 #else
   /* Translate to calendar:week_start:0 if you want Sunday to be the
    * first day of the week to calendar:week_start:1 if you want Monday
@@ -671,6 +718,9 @@ gtk_calendar_init (GtkCalendar *calendar)
       priv->week_start = 0;
     }
 #endif
+#endif
+
+  calendar_compute_days (calendar);
 }
 
 \f
@@ -751,12 +801,9 @@ static void
 calendar_set_year_next (GtkCalendar *calendar)
 {
   gint month_len;
-  GtkWidget *widget;
   
   g_return_if_fail (GTK_IS_WIDGET (calendar));
   
-  widget = GTK_WIDGET (calendar);
-  
   calendar->year++;
   calendar_compute_days (calendar);
   g_signal_emit (calendar,
@@ -1256,7 +1303,7 @@ calendar_realize_arrows (GtkCalendar *calendar)
          attributes.x = rect.x;
          attributes.y = rect.y;
          attributes.width = rect.width;
-         attributes.height = rect.width;
+         attributes.height = rect.height;
          priv->arrow_win[i] = gdk_window_new (priv->header_win,
                                               &attributes, 
                                               attributes_mask);
@@ -1505,7 +1552,6 @@ gtk_calendar_size_request (GtkWidget        *widget,
 
   gint height;
   gint i;
-  gchar buffer[255];
   gint calendar_margin = CALENDAR_MARGIN;
   gint header_width, main_width;
   gint max_header_height = 0;
@@ -1570,26 +1616,29 @@ gtk_calendar_size_request (GtkWidget      *widget,
   /* Mainwindow labels width */
   
   priv->max_day_char_width = 0;
+  priv->max_day_char_ascent = 0;
+  priv->max_day_char_descent = 0;
   priv->min_day_width = 0;
-  priv->max_label_char_ascent = 0;
-  priv->max_label_char_descent = 0;
 
   for (i = 0; i < 9; i++)
     {
-      g_snprintf (buffer, sizeof (buffer), "%d%d", i, i);
+      gchar buffer[32];
+      g_snprintf (buffer, sizeof (buffer), Q_("calendar:day:digits|%d"), i * 11);
       pango_layout_set_text (layout, buffer, -1);        
       pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
       priv->min_day_width = MAX (priv->min_day_width,
                                         logical_rect.width);
 
-      priv->max_day_char_ascent = MAX (priv->max_label_char_ascent,
+      priv->max_day_char_ascent = MAX (priv->max_day_char_ascent,
                                               PANGO_ASCENT (logical_rect));
-      priv->max_day_char_descent = MAX (priv->max_label_char_descent, 
+      priv->max_day_char_descent = MAX (priv->max_day_char_descent, 
                                                PANGO_DESCENT (logical_rect));
     }
   /* We add one to max_day_char_width to be able to make the marked day "bold" */
   priv->max_day_char_width = priv->min_day_width / 2 + 1;
   
+  priv->max_label_char_ascent = 0;
+  priv->max_label_char_descent = 0;
   if (calendar->display_flags & GTK_CALENDAR_SHOW_DAY_NAMES)
     for (i = 0; i < 7; i++)
       {
@@ -1607,11 +1656,12 @@ gtk_calendar_size_request (GtkWidget      *widget,
   if (calendar->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS)
     for (i = 0; i < 9; i++)
       {
-       g_snprintf (buffer, sizeof (buffer), "%d%d", i, i);
+       gchar buffer[32];
+       g_snprintf (buffer, sizeof (buffer), Q_("calendar:week:digits|%d"), i * 11);
        pango_layout_set_text (layout, buffer, -1);       
        pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
        priv->max_week_char_width = MAX (priv->max_week_char_width,
-                                                logical_rect.width / 2);
+                                          logical_rect.width / 2);
       }
   
   main_width = (7 * (priv->min_day_width + (focus_padding + focus_width) * 2) + (DAY_XSEP * 6) + CALENDAR_MARGIN * 2
@@ -1669,16 +1719,10 @@ gtk_calendar_size_allocate (GtkWidget     *widget,
   GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget);
   gint xthickness = widget->style->xthickness;
   gint ythickness = widget->style->xthickness;
-  gboolean year_left;
   guint i;
   
   widget->allocation = *allocation;
-  
-  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) 
-    year_left = priv->year_before;
-  else
-    year_left = !priv->year_before;
-  
+    
   if (calendar->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS)
     {
       priv->day_width = (priv->min_day_width
@@ -1780,7 +1824,7 @@ calendar_paint_header (GtkCalendar *calendar)
   cairo_t *cr;
   char buffer[255];
   int x, y;
-  gint header_width, cal_height;
+  gint header_width;
   gint max_month_width;
   gint max_year_width;
   PangoLayout *layout;
@@ -1798,7 +1842,6 @@ calendar_paint_header (GtkCalendar *calendar)
   cr = gdk_cairo_create (priv->header_win);
   
   header_width = widget->allocation.width - 2 * widget->style->xthickness;
-  cal_height = widget->allocation.height;
   
   max_month_width = priv->max_month_width;
   max_year_width = priv->max_year_width;
@@ -1887,7 +1930,6 @@ calendar_paint_day_names (GtkCalendar *calendar)
   char buffer[255];
   int day,i;
   int day_width, cal_width;
-  gint cal_height;
   int day_wid_sep;
   PangoLayout *layout;
   PangoRectangle logical_rect;
@@ -1903,7 +1945,6 @@ calendar_paint_day_names (GtkCalendar *calendar)
   
   day_width = priv->day_width;
   cal_width = widget->allocation.width;
-  cal_height = widget->allocation.height;
   day_wid_sep = day_width + DAY_XSEP;
   
   /*
@@ -1969,7 +2010,7 @@ calendar_paint_week_numbers (GtkCalendar *calendar)
   cairo_t *cr;
   gint row, week = 0, year;
   gint x_loc;
-  char buffer[3];
+  char buffer[32];
   gint y_loc, day_height;
   PangoLayout *layout;
   PangoRectangle logical_rect;
@@ -2023,7 +2064,18 @@ calendar_paint_week_numbers (GtkCalendar *calendar)
                              + calendar->month) % 12 + 1, calendar->day[row][6]);
       g_return_if_fail (result);
 
-      g_snprintf (buffer, sizeof (buffer), "%d", week);
+      /* Translators: this defines whether the week numbers should use
+       * localized digits or the ones used in English (0123...).
+       *
+       * Translate to "%Id" if you want to use localized digits, or
+       * translate to "%d" otherwise.  Don't include the
+       * "calendar:week:digits|" part in the translation.
+       *
+       * Note that translating this doesn't guarantee that you get localized
+       * digits.  That needs support from your system and locale definition
+       * too.
+       */
+      g_snprintf (buffer, sizeof (buffer), Q_("calendar:week:digits|%d"), week);
       pango_layout_set_text (layout, buffer, -1);
       pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
 
@@ -2089,7 +2141,7 @@ calendar_paint_day (GtkCalendar *calendar,
   GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
   cairo_t *cr;
   GdkColor *text_color;
-  gchar buffer[255];
+  gchar buffer[32];
   gint day;
   gint x_loc, y_loc;
   GdkRectangle day_rect;
@@ -2116,14 +2168,14 @@ calendar_paint_day (GtkCalendar *calendar,
     } 
   else 
     {
-      /*
+#if 0      
       if (calendar->highlight_row == row && calendar->highlight_col == col)
        {
          cairo_set_source_color (cr, HIGHLIGHT_BG_COLOR (widget));
          gdk_cairo_rectangle (cr, &day_rect);
          cairo_fill (cr);
        }
-      */
+#endif     
       if (calendar->selected_day == day)
        {
          gdk_cairo_set_source_color (cr, SELECTED_BG_COLOR (widget));
@@ -2138,7 +2190,18 @@ calendar_paint_day (GtkCalendar *calendar,
        text_color = NORMAL_DAY_COLOR (widget);
     }
 
-  g_snprintf (buffer, sizeof (buffer), "%d", day);
+  /* Translators: this defines whether the day numbers should use
+   * localized digits or the ones used in English (0123...).
+   *
+   * Translate to "%Id" if you want to use localized digits, or
+   * translate to "%d" otherwise.  Don't include the "calendar:day:digits|"
+   * part in the translation.
+   *
+   * Note that translating this doesn't guarantee that you get localized
+   * digits.  That needs support from your system and locale definition
+   * too.
+   */
+  g_snprintf (buffer, sizeof (buffer), Q_("calendar:day:digits|%d"), day);
   layout = gtk_widget_create_pango_layout (widget, buffer);
   pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
   
@@ -2169,8 +2232,11 @@ calendar_paint_day (GtkCalendar *calendar,
       
       gtk_paint_focus (widget->style, 
                       priv->main_win,
+                      state,
+#if 0
                       (calendar->selected_day == day) 
                          ? GTK_STATE_SELECTED : GTK_STATE_NORMAL, 
+#endif
                       NULL, widget, "calendar-day",
                       day_rect.x,     day_rect.y, 
                       day_rect.width, day_rect.height);
@@ -2233,7 +2299,7 @@ calendar_paint_arrow (GtkCalendar *calendar,
        gtk_paint_arrow (widget->style, window, state, 
                         GTK_SHADOW_OUT, NULL, widget, "calendar",
                         GTK_ARROW_RIGHT, TRUE, 
-                        width/2 - 2, height/2 - 4, 8, 8);
+                        width/2 - 4, height/2 - 4, 8, 8);
     }
 }
 
@@ -2278,9 +2344,6 @@ gtk_calendar_expose (GtkWidget        *widget,
  *           Mouse handling             *
  ****************************************/
 
-#define CALENDAR_INITIAL_TIMER_DELAY    200
-#define CALENDAR_TIMER_DELAY            20
-
 static void
 calendar_arrow_action (GtkCalendar *calendar,
                       guint        arrow)
@@ -2311,25 +2374,28 @@ calendar_timer (gpointer data)
   GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
   gboolean retval = FALSE;
   
-  GDK_THREADS_ENTER ();
-
   if (priv->timer)
     {
       calendar_arrow_action (calendar, priv->click_child);
 
       if (priv->need_timer)
        {
+          GtkSettings *settings;
+          guint        timeout;
+
+          settings = gtk_widget_get_settings (GTK_WIDGET (calendar));
+          g_object_get (settings, "gtk-timeout-repeat", &timeout, NULL);
+
          priv->need_timer = FALSE;
-         priv->timer = g_timeout_add (CALENDAR_TIMER_DELAY, 
-                                              (GSourceFunc) calendar_timer, 
-                                              (gpointer) calendar);
+         priv->timer = gdk_threads_add_timeout_full (G_PRIORITY_DEFAULT_IDLE,
+                                           timeout * SCROLL_DELAY_FACTOR,
+                                           (GSourceFunc) calendar_timer,
+                                           (gpointer) calendar, NULL);
        }
       else 
        retval = TRUE;
     }
 
-  GDK_THREADS_LEAVE ();
-
   return retval;
 }
 
@@ -2343,10 +2409,17 @@ calendar_start_spinning (GtkCalendar *calendar,
   
   if (!priv->timer)
     {
+      GtkSettings *settings;
+      guint        timeout;
+
+      settings = gtk_widget_get_settings (GTK_WIDGET (calendar));
+      g_object_get (settings, "gtk-timeout-initial", &timeout, NULL);
+
       priv->need_timer = TRUE;
-      priv->timer = g_timeout_add (CALENDAR_INITIAL_TIMER_DELAY, 
-                                  calendar_timer,
-                                  calendar);
+      priv->timer = gdk_threads_add_timeout_full (G_PRIORITY_DEFAULT_IDLE,
+                                       timeout,
+                                       (GSourceFunc) calendar_timer,
+                                       (gpointer) calendar, NULL);
     }
 }
 
@@ -2746,12 +2819,12 @@ gtk_calendar_key_press (GtkWidget   *widget,
     case GDK_space:
       row = calendar->focus_row;
       col = calendar->focus_col;
-      day = calendar->day[row][col];
       
       if (row > -1 && col > -1)
        {
          return_val = TRUE;
 
+          day = calendar->day[row][col];
          if (calendar->day_month[row][col] == MONTH_PREV)
            calendar_set_month_prev (calendar);
          else if (calendar->day_month[row][col] == MONTH_NEXT)
@@ -2846,6 +2919,8 @@ gtk_calendar_focus_out (GtkWidget     *widget,
 {
   GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget);
 
+  gtk_widget_queue_draw (widget);
+
   calendar_stop_spinning (GTK_CALENDAR (widget));
   
   priv->in_drag = 0; 
@@ -2886,7 +2961,7 @@ set_status_pending (GdkDragContext *context,
                     GdkDragAction   suggested_action)
 {
   g_object_set_data (G_OBJECT (context),
-                     "gtk-calendar-status-pending",
+                     I_("gtk-calendar-status-pending"),
                      GINT_TO_POINTER (suggested_action));
 }
 
@@ -2926,7 +3001,7 @@ gtk_calendar_drag_motion (GtkWidget      *widget,
     }
   
   target = gtk_drag_dest_find_target (widget, context, NULL);
-  if (target == GDK_NONE)
+  if (target == GDK_NONE || context->suggested_action == 0)
     gdk_drag_status (context, 0, time);
   else
     {
@@ -3059,7 +3134,7 @@ gtk_calendar_new (void)
  *
  * Sets display options (whether to display the heading and the month headings).
  * 
- * Deprecated: Use gtk_calendar_set_display_options() instead
+ * Deprecated: 2.4: Use gtk_calendar_set_display_options() instead
  **/
 void
 gtk_calendar_display_options (GtkCalendar             *calendar,
@@ -3405,6 +3480,8 @@ gtk_calendar_get_date (GtkCalendar *calendar,
  * 
  * Does nothing. Previously locked the display of the calendar until
  * it was thawed with gtk_calendar_thaw().
+ *
+ * Deprecated: 2.8: 
  **/
 void
 gtk_calendar_freeze (GtkCalendar *calendar)
@@ -3418,6 +3495,8 @@ gtk_calendar_freeze (GtkCalendar *calendar)
  * 
  * Does nothing. Previously defrosted a calendar; all the changes made
  * since the last gtk_calendar_freeze() were displayed.
+ *
+ * Deprecated: 2.8: 
  **/
 void
 gtk_calendar_thaw (GtkCalendar *calendar)