]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/gtk+/gtk+-2.6.4-1.osso7/gtkentry.c.diff
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / gtk+ / gtk+-2.6.4-1.osso7 / gtkentry.c.diff
1 --- gtk+-2.6.4/gtk/gtkentry.c   2005-02-04 17:36:02.000000000 +0200
2 +++ gtk+-2.6.4/gtk/gtkentry.c   2005-04-06 16:19:36.466994536 +0300
3 @@ -24,6 +24,10 @@
4   * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
5   */
6  
7 + /* Modified for Nokia Oyj during 2002-2003. See CHANGES file for list
8 +  * of changes.
9 +  */
10 +
11  #include <config.h>
12  #include <string.h>
13  
14 @@ -53,6 +57,7 @@
15  #include "gtktreeselection.h"
16  #include "gtkentryprivate.h"
17  #include "gtkcelllayout.h"
18 +#include "gtkscrolledwindow.h"
19  
20  #define GTK_ENTRY_COMPLETION_KEY "gtk-entry-completion-key"
21  
22 @@ -60,6 +65,8 @@
23  #define DRAW_TIMEOUT     20
24  #define INNER_BORDER     2
25  #define COMPLETION_TIMEOUT 300
26 +#define HILDON_EDITED_CHARACTER_MAX 8
27 +#define HILDON_EDITED_CHARACTER_MS 600  /* 0.6 seconds */
28  
29  /* Initial size of buffer, in bytes */
30  #define MIN_SIZE 16
31 @@ -75,6 +82,18 @@
32  {
33    gfloat xalign;
34    gint insert_pos;
35 +  /* Hildon additions:
36 +   * following variables are needed
37 +   * for Hildon password 'preview'
38 +   * functionality; last inputted character
39 +   * is showed for defined period, before it is
40 +   * rendered to '*'
41 +   */
42 +  gchar hildon_edited_character[HILDON_EDITED_CHARACTER_MAX];
43 +  gboolean  hildon_edited_character_timeout;
44 +  gint  hildon_edited_character_length;
45 +  gboolean keep_focus;
46 +  gboolean menu_popped; 
47  };
48  
49  enum {
50 @@ -104,7 +123,9 @@
51    PROP_WIDTH_CHARS,
52    PROP_SCROLL_OFFSET,
53    PROP_TEXT,
54 -  PROP_XALIGN
55 +  PROP_XALIGN,
56 +  PROP_AUTOCAP,
57 +  PROP_INPUT_MODE
58  };
59  
60  static guint signals[LAST_SIGNAL] = { 0 };
61 @@ -324,6 +345,23 @@
62                                                         gint           *y,
63                                                         gint           *width,
64                                                         gint           *height);
65 +static void        gtk_entry_update_scrolled_window   (GtkEntry       *entry);
66 +static void         gtk_entry_set_autocap              (GtkEntry       *entry,
67 +                                                        gboolean       autocap);
68 +static gboolean     gtk_entry_get_autocap              (GtkEntry       *entry);
69 +static void         gtk_entry_set_input_mode           (GtkEntry       *entry,
70 +                                                        gboolean       mode);
71 +static gint         gtk_entry_get_input_mode           (GtkEntry       *entry);
72 +
73 +/*Change for Hildon
74 + *returns an iterator to the character at position x,y of the
75 + *layout
76 + *returns NULL if no iterator was found at that position
77 + *Caller must call pango_layout_free_iter on the returned iterator
78 + */
79 +static PangoLayoutIter *get_char_at_pos( PangoLayout *layout, gint x, gint y );
80 +
81 +static gboolean hildon_remove_visible_character( gpointer data );
82  
83  /* Completion */
84  static gint         gtk_entry_completion_timeout       (gpointer            data);
85 @@ -523,7 +561,25 @@
86                                                          P_("FALSE displays the \"invisible char\" instead of the actual text (password mode)"),
87                                                           TRUE,
88                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
89 -
90 +  
91 +  g_object_class_install_property (gobject_class,
92 +                                   PROP_AUTOCAP,
93 +                                   g_param_spec_boolean ("autocap",
94 +                                                         P_("auto capitalization"),
95 +                                                         P_("Enable autocap support"),
96 +                                                         TRUE,
97 +                                                         G_PARAM_READABLE | G_PARAM_WRITABLE)); 
98 +  
99 +  g_object_class_install_property (gobject_class,
100 +                                   PROP_INPUT_MODE,
101 +                                   g_param_spec_int ("input_mode",
102 +                                                     P_("input mode"),
103 +                                                     P_("Define widget's input mode"),
104 +                                                     0,
105 +                                                     9, /* keep me updated */
106 +                                                     0,
107 +                                                     G_PARAM_READABLE | G_PARAM_WRITABLE)); 
108 +  
109    g_object_class_install_property (gobject_class,
110                                     PROP_HAS_FRAME,
111                                     g_param_spec_boolean ("has_frame",
112 @@ -593,6 +649,40 @@
113                                                        0.0,
114                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
115    
116 + gtk_widget_class_install_style_property (widget_class,
117 +                                          g_param_spec_int ("horizontal-border",
118 +                                                             P_("Horizontal borders for entry"),
119 +                                                             P_("Set left/right borders"),
120 +                                                             0,
121 +                                                             G_MAXINT,
122 +                                                             INNER_BORDER,
123 +                                                             G_PARAM_READWRITE));
124 +
125 +  gtk_widget_class_install_style_property (widget_class,
126 +                                          g_param_spec_int ("vertical-border",
127 +                                                             P_("Vertical borders for entry"),
128 +                                                             P_("Set top/bottom borders"),
129 +                                                             0,
130 +                                                             G_MAXINT,
131 +                                                             INNER_BORDER,
132 +                                                             G_PARAM_READWRITE));
133 +
134 +  gtk_widget_class_install_style_property (widget_class,
135 +                                          g_param_spec_int ("icon-width",
136 +                                                             P_("Icon Width"),
137 +                                                             P_("Size of the purpose icon."),
138 +                                                             0,
139 +                                                             G_MAXINT,
140 +                                                             0,
141 +                                                             G_PARAM_READWRITE));
142 +  
143 +  gtk_widget_class_install_style_property (widget_class,
144 +                                          g_param_spec_boolean ("show-last-char",
145 +                                                             P_("Show last char in invisible mode for a while"),
146 +                                                             P_("Last char is shown before it is rendered to asterisk"),
147 +                                                             FALSE,
148 +                                                             G_PARAM_READABLE | G_PARAM_WRITABLE));
149 +
150    signals[POPULATE_POPUP] =
151      g_signal_new ("populate_popup",
152                   G_OBJECT_CLASS_TYPE (gobject_class),
153 @@ -853,6 +943,22 @@
154    iface->start_editing = gtk_entry_start_editing;
155  }
156  
157 +/* HILDON: Timed function to hide the most recently inputted character in password mode
158 +*/
159 +static gboolean
160 + hildon_remove_visible_character( gpointer data )
161 +{
162 +    g_return_val_if_fail (GTK_IS_WIDGET (data), FALSE);
163 +
164 +    GtkEntry * entry = GTK_ENTRY( data );
165 +                                                                                        
166 +    /* Force the string to redrawn, but now without a visible character */
167 +    gtk_entry_recompute( entry );
168 +                                                                                        
169 +    /* Return false so this timeout is not called again and destroyed */
170 +    return FALSE;
171 +}
172 +
173  static void
174  gtk_entry_set_property (GObject         *object,
175                          guint            prop_id,
176 @@ -867,9 +973,10 @@
177        {
178          gboolean new_value = g_value_get_boolean (value);
179  
180 +       gtk_widget_set_sensitive( GTK_WIDGET( entry ), entry->editable );
181         if (new_value != entry->editable)
182           {
183 -           if (!new_value)
184 +            if (!new_value)
185               {
186                 gtk_entry_reset_im_context (entry);
187                 if (GTK_WIDGET_HAS_FOCUS (entry))
188 @@ -896,6 +1003,14 @@
189      case PROP_VISIBILITY:
190        gtk_entry_set_visibility (entry, g_value_get_boolean (value));
191        break;
192 +      
193 +    case PROP_AUTOCAP:
194 +      gtk_entry_set_autocap (entry, g_value_get_boolean (value));
195 +      break;
196 +
197 +    case PROP_INPUT_MODE:
198 +      gtk_entry_set_input_mode (entry, g_value_get_int (value));
199 +      break;
200  
201      case PROP_HAS_FRAME:
202        gtk_entry_set_has_frame (entry, g_value_get_boolean (value));
203 @@ -954,6 +1069,12 @@
204      case PROP_VISIBILITY:
205        g_value_set_boolean (value, entry->visible);
206        break;
207 +    case PROP_AUTOCAP:
208 +      g_value_set_boolean (value, gtk_entry_get_autocap (entry));
209 +      break;
210 +    case PROP_INPUT_MODE:
211 +      g_value_set_int (value, gtk_entry_get_input_mode (entry));
212 +      break;
213      case PROP_HAS_FRAME:
214        g_value_set_boolean (value, entry->has_frame);
215        break;
216 @@ -1000,7 +1121,20 @@
217    entry->width_chars = -1;
218    entry->is_cell_renderer = FALSE;
219    entry->editing_canceled = FALSE;
220 -  entry->has_frame = TRUE;
221 +#ifdef HILDON_SINGLE_LINE_EDITOR
222 +  entry->has_frame = FALSE;
223 +#else
224 +    entry->has_frame = TRUE;
225 +#endif
226 +
227 +  /* Hildon */
228 +  memset( &priv->hildon_edited_character, 0x00, HILDON_EDITED_CHARACTER_MAX );
229 +  priv->hildon_edited_character_length = 0;
230 +  priv->hildon_edited_character_timeout = FALSE;
231 +  
232 +  priv->keep_focus = FALSE;
233 +  priv->menu_popped = FALSE;
234 +  
235    priv->xalign = 0.0;
236  
237    gtk_drag_dest_set (GTK_WIDGET (entry),
238 @@ -1013,6 +1147,10 @@
239     * to it; so we create it here and destroy it in finalize().
240     */
241    entry->im_context = gtk_im_multicontext_new ();
242 +  /* Set default stuff. */
243 +  gtk_entry_set_autocap (entry, TRUE);
244 +  gtk_entry_set_input_mode (entry, 0); /* alpha-numeric-special */
245 +  g_object_set (G_OBJECT (entry->im_context), "use-show-hide", TRUE, NULL);
246    
247    g_signal_connect (entry->im_context, "commit",
248                     G_CALLBACK (gtk_entry_commit_cb), entry);
249 @@ -1058,7 +1196,8 @@
250  gtk_entry_finalize (GObject *object)
251  {
252    GtkEntry *entry = GTK_ENTRY (object);
253 -
254 +  GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (GTK_WIDGET (entry));
255
256    gtk_entry_set_completion (entry, NULL);
257  
258    if (entry->cached_layout)
259 @@ -1072,6 +1211,9 @@
260    if (entry->recompute_idle)
261      g_source_remove (entry->recompute_idle);
262  
263 +  if (priv->hildon_edited_character_timeout)
264 +    g_source_remove (priv->hildon_edited_character_timeout);
265 +
266    entry->text_size = 0;
267  
268    if (entry->text)
269 @@ -1213,7 +1355,14 @@
270    PangoFontMetrics *metrics;
271    gint xborder, yborder;
272    PangoContext *context;
273 -  
274 +  gint border_x, border_y;
275 +  gint icon_width;
276 +
277 +  gtk_widget_style_get (widget,
278 +                        "horizontal-border", &border_x,
279 +                        "vertical-border", &border_y,
280 +                        "icon-width", &icon_width, NULL);
281 +
282    gtk_widget_ensure_style (widget);
283    context = gtk_widget_get_pango_context (widget);
284    metrics = pango_context_get_metrics (context,
285 @@ -1225,21 +1374,22 @@
286    
287    _gtk_entry_get_borders (entry, &xborder, &yborder);
288    
289 -  xborder += INNER_BORDER;
290 -  yborder += INNER_BORDER;
291 +  xborder += border_x<<1;
292 +  yborder += border_y<<1;
293    
294    if (entry->width_chars < 0)
295 -    requisition->width = MIN_ENTRY_WIDTH + xborder * 2;
296 +    requisition->width = MIN_ENTRY_WIDTH + xborder;
297    else
298      {
299        gint char_width = pango_font_metrics_get_approximate_char_width (metrics);
300        gint digit_width = pango_font_metrics_get_approximate_digit_width (metrics);
301        gint char_pixels = (MAX (char_width, digit_width) + PANGO_SCALE - 1) / PANGO_SCALE;
302        
303 -      requisition->width = char_pixels * entry->width_chars + xborder * 2;
304 +      requisition->width = char_pixels * entry->width_chars + xborder;
305      }
306 -    
307 -  requisition->height = PANGO_PIXELS (entry->ascent + entry->descent) + yborder * 2;
308 +  
309 +  requisition->width += icon_width;  
310 +  requisition->height = PANGO_PIXELS (entry->ascent + entry->descent) + yborder;
311  
312    pango_font_metrics_unref (metrics);
313  }
314 @@ -1253,23 +1403,39 @@
315  {
316    gint xborder, yborder;
317    GtkRequisition requisition;
318 +  gint icon_width;
319    GtkWidget *widget = GTK_WIDGET (entry);
320  
321 +  gtk_widget_style_get (widget, "icon-width", &icon_width, NULL);
322 +  
323    gtk_widget_get_child_requisition (widget, &requisition);
324  
325    _gtk_entry_get_borders (entry, &xborder, &yborder);
326  
327    if (x)
328 -    *x = xborder;
329 +    *x = xborder + icon_width;
330  
331    if (y)
332 +  {
333      *y = yborder;
334 +    if( widget->allocation.height < requisition.height )
335 +      *y += ((widget->allocation.height - requisition.height) / 2);
336 +    if( *y < yborder )
337 +      *y = yborder;
338 +  }
339    
340    if (width)
341 -    *width = GTK_WIDGET (entry)->allocation.width - xborder * 2;
342 +    *width = GTK_WIDGET (entry)->allocation.width - xborder * 2 - icon_width;
343  
344    if (height)
345 -    *height = requisition.height - yborder * 2;
346 +  {
347 +    if( widget->allocation.height < requisition.height )
348 +      *height = widget->allocation.height - yborder * 2;
349 +    else
350 +      *height = widget->requisition.height - yborder * 2;
351 +    if( *height <=0 )
352 +      *height = 1;
353 +  }
354  }
355  
356  static void
357 @@ -1289,10 +1455,9 @@
358  
359    if (y)
360      {
361 -      if (entry->is_cell_renderer)
362 -       *y = widget->allocation.y;
363 -      else
364 -       *y = widget->allocation.y + (widget->allocation.height - requisition.height) / 2;
365 +       *y = widget->allocation.y;
366 +      if( widget->allocation.height > requisition.height )
367 +       *y += ((widget->allocation.height - requisition.height) / 2);
368      }
369  
370    if (width)
371 @@ -1300,10 +1465,10 @@
372  
373    if (height)
374      {
375 -      if (entry->is_cell_renderer)
376 -       *height = widget->allocation.height;
377 -      else
378 +      if( widget->allocation.height > requisition.height )
379         *height = requisition.height;
380 +      else
381 +       *height = widget->allocation.height;
382      }
383  }
384  
385 @@ -1383,20 +1548,19 @@
386                   GdkEventExpose *event)
387  {
388    GtkEntry *entry = GTK_ENTRY (widget);
389 +  gint area_width, area_height;
390 +  
391 +  get_widget_window_size (entry, NULL, NULL, &area_width, &area_height);
392  
393    if (widget->window == event->window)
394 -    gtk_entry_draw_frame (widget);
395 +    {
396 +      gtk_paint_box (widget->style, widget->window,
397 +                     GTK_WIDGET_STATE (widget), GTK_SHADOW_NONE,
398 +                     NULL, widget, "entry_frame",
399 +                     0, 0, area_width, area_height);
400 +    }
401    else if (entry->text_area == event->window)
402      {
403 -      gint area_width, area_height;
404 -
405 -      get_text_area_size (entry, NULL, NULL, &area_width, &area_height);
406 -
407 -      gtk_paint_flat_box (widget->style, entry->text_area, 
408 -                         GTK_WIDGET_STATE(widget), GTK_SHADOW_NONE,
409 -                         NULL, widget, "entry_bg", 
410 -                         0, 0, area_width, area_height);
411 -      
412        if ((entry->visible || entry->invisible_char != 0) &&
413           GTK_WIDGET_HAS_FOCUS (widget) &&
414           entry->selection_bound == entry->current_pos && entry->cursor_visible)
415 @@ -1490,16 +1654,19 @@
416      return FALSE;
417  
418    entry->button = event->button;
419 -  
420 +
421    if (!GTK_WIDGET_HAS_FOCUS (widget))
422      {
423        entry->in_click = TRUE;
424        gtk_widget_grab_focus (widget);
425        entry->in_click = FALSE;
426      }
427 -  
428 +
429 +  /* Hildon: we need to reset IM context so pre-edit string can be committed */
430 +  gtk_entry_reset_im_context (entry);
431 +
432    tmp_pos = gtk_entry_find_position (entry, event->x + entry->scroll_offset);
433 -    
434 +  
435    if (event->button == 1)
436      {
437        gboolean have_selection = gtk_editable_get_selection_bounds (editable, &sel_start, &sel_end);
438 @@ -1509,8 +1676,6 @@
439  
440        if (event->state & GDK_SHIFT_MASK)
441         {
442 -         gtk_entry_reset_im_context (entry);
443 -         
444           if (!have_selection) /* select from the current position to the clicked position */
445             sel_start = sel_end = entry->current_pos;
446           
447 @@ -1575,9 +1740,20 @@
448               entry->drag_start_x = event->x + entry->scroll_offset;
449               entry->drag_start_y = event->y + entry->scroll_offset;
450             }
451 -         else
452 -           gtk_editable_set_position (editable, tmp_pos);
453 -         break;
454 +         else {
455 +            /* HILDON: do not move the cursor inside the textarea if invisible
456 +            *  as per the specifications */
457 +            if (!entry->visible)
458 +             if(tmp_pos == strlen(gtk_entry_get_text(entry))){
459 +               gtk_editable_set_position( editable, entry->text_length);
460 +             } else {
461 +               gtk_editable_select_region (editable, 0, -1);
462 +             }
463 +             else 
464 +                gtk_editable_set_position (editable, tmp_pos);
465 +         }
466 +
467 +          break;
468   
469         case GDK_2BUTTON_PRESS:
470           /* We ALWAYS receive a GDK_BUTTON_PRESS immediately before 
471 @@ -1614,8 +1790,16 @@
472      }
473    else if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
474      {
475 +      /* Hildon: if we are in password mode selection and Cut & Copy should
476 +         be disabled. */
477 +      if (!entry->visible)
478 +        {
479 +           gtk_editable_set_position (GTK_EDITABLE(entry), 0);
480 +        }
481 +
482        gtk_entry_do_popup (entry, event);
483        entry->button = 0;       /* Don't wait for release, since the menu will gtk_grab_add */
484 +      priv->keep_focus = TRUE;
485  
486        return TRUE;
487      }
488 @@ -1632,11 +1816,23 @@
489    if (event->window != entry->text_area || entry->button != event->button)
490      return FALSE;
491  
492 +  if (entry->editable)
493 +    gtk_im_context_show (entry->im_context);
494 +
495    if (entry->in_drag)
496      {
497        gint tmp_pos = gtk_entry_find_position (entry, entry->drag_start_x);
498  
499 -      gtk_editable_set_position (GTK_EDITABLE (entry), tmp_pos);
500 +      /* HILDON: If not visible, do not allow cursor to be positioned inside the string */
501 +      if (!entry->visible){
502 +       if(tmp_pos == strlen(gtk_entry_get_text(entry))){
503 +         gtk_editable_set_position( GTK_EDITABLE(entry), entry->text_length);    
504 +       } else {
505 +         gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);       
506 +       }
507 +      } else {
508 +       gtk_editable_set_position (GTK_EDITABLE (entry), tmp_pos);
509 +      }
510  
511        entry->in_drag = 0;
512      }
513 @@ -1822,6 +2018,13 @@
514          }
515      }
516  
517 +  if (event->keyval == GDK_Return)
518 +    return FALSE;      
519 +  if (event->keyval == GDK_KP_Enter)           
520 +    g_signal_emit_by_name (G_OBJECT(gtk_widget_get_ancestor (widget,           
521 +                            GTK_TYPE_WINDOW)), "move-focus",           
522 +                           GTK_DIR_TAB_FORWARD);               
523 +
524    if (GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event))
525      /* Activate key bindings
526       */
527 @@ -1835,6 +2038,8 @@
528                        GdkEventKey *event)
529  {
530    GtkEntry *entry = GTK_ENTRY (widget);
531 +  
532 +  gtk_entry_update_scrolled_window( entry );
533  
534    if (entry->editable)
535      {
536 @@ -1853,7 +2058,35 @@
537                     GdkEventFocus *event)
538  {
539    GtkEntry *entry = GTK_ENTRY (widget);
540 -  
541 +  GtkEntryPrivate *priv;
542 +
543 +  priv = GTK_ENTRY_GET_PRIVATE (widget);
544 +  /* Hildon : If the text doesn't fit the entry, upon focusing
545 +   * to an text field, move the caret to the end of the entry. 
546 +   * Force the entry to recompute, otherwise it doesn't update
547 +   * if the cursor is currently at the end*/
548 +  /* hildon : If the text has no selection and focus returned with
549 +     other means than pointer click, set cursor before first
550 +      character of the text, otherwise behave normally */
551 +
552 +  if (!entry->in_click)
553 +    {
554 +      /*gboolean has_selection;
555 +      has_selection = gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), NULL, NULL);
556 +      if (!has_selection)
557 +        {
558 +         gtk_editable_set_position (GTK_EDITABLE (entry), -1);
559 +        }*//*FIXME need a better hack here*/
560 +      /* Hildon: If in SecretEditor mode highlight selection if entry got focus
561 +       * otherways than mouse/stylus */
562 +      if (!entry->visible && priv->keep_focus)
563 +        {
564 +          gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
565 +        }
566 +    }
567 +
568 +  gtk_entry_recompute (GTK_ENTRY (entry));
569 +
570    gtk_widget_queue_draw (widget);
571    
572    if (entry->editable)
573 @@ -1876,6 +2109,8 @@
574                      GdkEventFocus *event)
575  {
576    GtkEntry *entry = GTK_ENTRY (widget);
577 +  GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget);
578 +  guint tmp_pos;
579    GtkEntryCompletion *completion;
580    
581    gtk_widget_queue_draw (widget);
582 @@ -1886,6 +2121,20 @@
583        gtk_im_context_focus_out (entry->im_context);
584      }
585  
586 +  tmp_pos = gtk_editable_get_position (GTK_EDITABLE (widget));
587 +  if (priv->keep_focus){
588 +    if (!entry->visible)
589 +      gtk_editable_set_position (GTK_EDITABLE (widget), tmp_pos);
590 +    priv->keep_focus = FALSE;
591 +  }
592 +  else {
593 +    if (priv->menu_popped)
594 +      priv->menu_popped = FALSE;
595 +    else gtk_editable_set_position (GTK_EDITABLE (widget), tmp_pos);
596 +  }
597 +
598 +  gtk_widget_queue_draw(widget);
599 +  
600    gtk_entry_check_cursor_blink (entry);
601    
602    g_signal_handlers_disconnect_by_func (gdk_keymap_get_for_display (gtk_widget_get_display (widget)),
603 @@ -1902,7 +2151,6 @@
604  static void
605  gtk_entry_grab_focus (GtkWidget        *widget)
606  {
607 -  GtkEntry *entry = GTK_ENTRY (widget);
608    gboolean select_on_focus;
609    
610    GTK_WIDGET_CLASS (parent_class)->grab_focus (widget);
611 @@ -1912,8 +2160,8 @@
612                 &select_on_focus,
613                 NULL);
614    
615 -  if (select_on_focus && entry->editable && !entry->in_click)
616 -    gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
617 +/* Hildon : When focusing to an entry, it shouldn't become
618 + * highlighted. */
619  }
620  
621  static void 
622 @@ -1987,7 +2235,7 @@
623  
624    if (new_text_length > 63)
625      g_free (text);
626 -
627 +  gtk_entry_update_scrolled_window( entry );
628    g_object_unref (editable);
629  }
630  
631 @@ -2074,7 +2322,7 @@
632    if (end < 0)
633      end = entry->text_length;
634    
635 -  gtk_entry_reset_im_context (entry);
636 +  /*gtk_entry_reset_im_context (entry);*//*FIXME tmp kludge, might break something*/
637  
638    gtk_entry_set_positions (entry,
639                            MIN (end, entry->text_length),
640 @@ -2168,13 +2416,19 @@
641  {
642    gint index;
643    gint n_chars;
644 +  gboolean show_last_char = FALSE;
645  
646    GtkEntry *entry = GTK_ENTRY (editable);
647 -
648 +  GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (GTK_WIDGET (entry));
649    if (new_text_length < 0)
650      new_text_length = strlen (new_text);
651  
652    n_chars = g_utf8_strlen (new_text, new_text_length);
653 +
654 +
655 +  gtk_widget_style_get (GTK_WIDGET (entry), "show-last-char",
656 +                        &show_last_char, NULL);
657 +
658    if (entry->text_max_length > 0 && n_chars + entry->text_length > entry->text_max_length)
659      {
660        gdk_display_beep (gtk_widget_get_display (GTK_WIDGET (entry)));
661 @@ -2238,6 +2492,14 @@
662    
663    if (entry->selection_bound > *position)
664      entry->selection_bound += n_chars;
665 +  
666 +  /* Hildon: store this addition IF it was only 1 char (user inputted) and we are currently in secret mode (invisible) */
667 +                          
668 +  if (show_last_char && n_chars == 1 && !entry->visible && (new_text_length < HILDON_EDITED_CHARACTER_MAX)) {
669 +        memset( &priv->hildon_edited_character, 0x00, HILDON_EDITED_CHARACTER_MAX );
670 +        priv->hildon_edited_character_length = new_text_length;
671 +        memcpy( &priv->hildon_edited_character, new_text, new_text_length );  /* Guaranteed to be < total length */
672 +  }
673  
674    *position += n_chars;
675  
676 @@ -2339,6 +2601,11 @@
677  
678    gtk_entry_reset_im_context (entry);
679  
680 +  /* Hildon, if not visible set the position to the end */
681 +  /* New SecretEditor specs say that with cursor should move
682 +   * With left/right arrows
683 +   */
684 +  
685    if (entry->current_pos != entry->selection_bound && !extend_selection)
686      {
687        /* If we have a current selection and aren't extending it, move to the
688 @@ -2445,7 +2712,7 @@
689    gint start_pos = entry->current_pos;
690    gint end_pos = entry->current_pos;
691    
692 -  gtk_entry_reset_im_context (entry);
693 +  /* Hildon: code removed - backspace should not clear the word completion */
694  
695    if (!entry->editable)
696      return;
697 @@ -2515,7 +2782,8 @@
698    GtkEditable *editable = GTK_EDITABLE (entry);
699    gint prev_pos;
700  
701 -  gtk_entry_reset_im_context (entry);
702 +/*  gtk_entry_reset_im_context (entry); */ /*backspace should not clear
703 +                                             the word completion*/
704  
705    if (!entry->editable || !entry->text)
706      return;
707 @@ -2883,21 +3151,28 @@
708        ++i;
709      }
710  }
711 -     
712 +
713 +#define HILDON_EDITED_CHARACTER_MS 600  /* 0.6 seconds */
714 +
715  static PangoLayout *
716  gtk_entry_create_layout (GtkEntry *entry,
717                          gboolean  include_preedit)
718  {
719    GtkWidget *widget = GTK_WIDGET (entry);
720 +  GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
721    PangoLayout *layout = gtk_widget_create_pango_layout (widget, NULL);
722    PangoAttrList *tmp_attrs = pango_attr_list_new ();
723    
724    gchar *preedit_string = NULL;
725    gint preedit_length = 0;
726    PangoAttrList *preedit_attrs = NULL;
727 +  gboolean show_last_char = FALSE;
728  
729    pango_layout_set_single_paragraph_mode (layout, TRUE);
730    
731 +  gtk_widget_style_get (widget, "show-last-char",
732 +                        &show_last_char, NULL);
733 +
734    if (include_preedit)
735      {
736        gtk_im_context_get_preedit_string (entry->im_context,
737 @@ -3003,7 +3278,49 @@
738            else
739              invisible_char = ' '; /* just pick a char */
740            
741 -          append_char (str, invisible_char, entry->text_length);
742 +          if (!show_last_char)
743 +            append_char (str, invisible_char, entry->text_length);
744 +          else if (show_last_char)
745 +            {
746 +              /* Hildon */
747 +              if (priv->hildon_edited_character_length > 0)
748 +                {
749 +                                                                                                                          
750 +                  /* If we have an outstanding timeout, remove it, because the character it is set to hide
751 +                   * is already hidden now. We do this first to prevent possible race conditions if the timout
752 +                   * were to trigger while in here
753 +                   */
754 +                                                                                                                          
755 +                  if (priv->hildon_edited_character_timeout)
756 +                    {
757 +                      g_source_remove( priv->hildon_edited_character_timeout );
758 +                      priv->hildon_edited_character_timeout = FALSE;
759 +                    }
760 +                                                                                                                          
761 +                  /* Draw the secret character length-1 times, because the last char will be visible */
762 +                  append_char (str, invisible_char, entry->text_length > 1 ? entry->text_length - 1 : 0);
763 +                                                                                                                          
764 +                  /* Add our visible char, the most recently inputted one */
765 +                  g_string_append_len (str, (char *)&priv->hildon_edited_character, priv->hildon_edited_character_length);
766 +                                                                                                                          
767 +                  /* Now remove this last inputted character, don't need it anymore */
768 +                                                                                                                          
769 +                  memset( priv->hildon_edited_character, 0x00, HILDON_EDITED_CHARACTER_MAX );
770 +                  priv->hildon_edited_character_length = 0;
771 +                                                                                     
772 +                  priv->hildon_edited_character_timeout = g_timeout_add( HILDON_EDITED_CHARACTER_MS, (GSourceFunc)
773 +                                                                                                                             hildon_remove_visible_character, entry );
774 +                                                                                                                          
775 +                } 
776 +              else 
777 +                {
778 +                  /* No last character known. This could be for example because the application has filled
779 +                   * in the password already. In that case we of course don't want to view it
780 +                   */
781 +                  append_char (str, invisible_char, entry->text_length);
782 +                }
783 +            }
784 +    
785            pango_layout_set_text (layout, str->str, str->len);
786            g_string_free (str, TRUE);
787          }
788 @@ -3048,12 +3365,17 @@
789    gint area_width, area_height;
790    gint y_pos;
791    PangoLayoutLine *line;
792 -  
793 +  gint border_x, border_y;
794 +
795 +  gtk_widget_style_get (GTK_WIDGET (entry), "horizontal-border", &border_x,
796 +                                           "vertical-border", &border_y,
797 +                                           NULL);
798 +
799    layout = gtk_entry_ensure_layout (entry, TRUE);
800  
801    get_text_area_size (entry, NULL, NULL, &area_width, &area_height);      
802        
803 -  area_height = PANGO_SCALE * (area_height - 2 * INNER_BORDER);
804 +  area_height = PANGO_SCALE * (area_height - 2 * border_y);
805    
806    line = pango_layout_get_lines (layout)->data;
807    pango_layout_line_get_extents (line, NULL, &logical_rect);
808 @@ -3070,10 +3392,10 @@
809    else if (y_pos + logical_rect.height > area_height)
810      y_pos = area_height - logical_rect.height;
811    
812 -  y_pos = INNER_BORDER + y_pos / PANGO_SCALE;
813 +  y_pos = border_y + y_pos / PANGO_SCALE;
814  
815    if (x)
816 -    *x = INNER_BORDER - entry->scroll_offset;
817 +    *x = border_x - entry->scroll_offset;
818  
819    if (y)
820      *y = y_pos;
821 @@ -3083,6 +3405,10 @@
822  gtk_entry_draw_text (GtkEntry *entry)
823  {
824    GtkWidget *widget;
825 +  gint border_y, border_x;
826 +
827 +  gtk_widget_style_get (GTK_WIDGET (entry), "horizontal-border", &border_x,
828 +                 "vertical-border", &border_y, NULL);
829    
830    if (!entry->visible && entry->invisible_char == 0)
831      return;
832 @@ -3092,14 +3418,76 @@
833        PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE);
834        gint x, y;
835        gint start_pos, end_pos;
836 +      GdkRectangle clip_rect;
837        
838        widget = GTK_WIDGET (entry);
839        
840        get_layout_position (entry, &x, &y);
841  
842 +      /* Use a clipping rectangle so that we always get enough empty space around
843 +       * the text.
844 +       */
845 +      clip_rect.x = border_x;
846 +      clip_rect.y = 0;
847 +
848 +      gdk_drawable_get_size (entry->text_area, &clip_rect.width, &clip_rect.height);
849 +      clip_rect.width -= border_x * 2;
850 +
851 +      /*changes for Hildon
852 +       *Reduce the size of the clip rect, so that only full characters are displayed
853 +      */
854 +
855 +         /* NOTE: Commented out because it does not work with bidi text where
856 +the indexes are in random
857 +          * left-right or right-left order. Code causes Pango assert aborts. Because gtkentry itself
858 +          * is broken with regard to bidi anyway (bug #478) we ignore this requirement of the spec
859 +          * until gtkentry itself is fixed. (bug #477)
860 +          */
861 +
862 +       /* Better yet, let's enable this only when not in RTL mode */
863 +
864 +       /* Note: BUG #857. patched gtkentry crashed when pasting scalable fonts. This is pango problem
865 +        * and we tested patched gtkentry with pango version 1.3.2 and it appears to be fixed. Section is commented
866 +        out until we upgrade to new version of pango
867 +          if (gtk_widget_get_direction( entry ) != GTK_TEXT_DIR_RTL)
868 +          {
869 +           PangoRectangle char_rect; // used for getting character's onscreen pos
870 +           PangoLayoutIter *iter; // used to iterate over the text
871 +
872 +           // get the position of the character currently at the clip border
873 +           iter = get_char_at_pos( layout, (clip_rect.x + clip_rect.width + entry->scroll_offset), 0 );
874 +           if ( iter )
875 +           {
876 +               // get the position of that character on the screen
877 +               pango_layout_iter_get_char_extents( iter, &char_rect );
878 +               char_rect.x /= PANGO_SCALE;
879 +               char_rect.x -= entry->scroll_offset;
880 +               char_rect.width /= PANGO_SCALE;
881 +
882 +               // if the ending position is > the clip rectangle, then the
883 +               // character is only partially visible, and we should
884 +               // clip the entire character.
885 +
886 +               if ( char_rect.x + char_rect.width > clip_rect.x + clip_rect.width )
887 +               {
888 +                   clip_rect.width = char_rect.x;
889 +               }
890 +
891 +               pango_layout_iter_free( iter );
892 +           }
893 +
894 +         }
895 +                       */
896 +       /******************************************************************/
897 +
898 +      gdk_gc_set_clip_rectangle (widget->style->text_gc [widget->state], &clip_rect);
899 +
900        gdk_draw_layout (entry->text_area, widget->style->text_gc [widget->state],       
901                         x, y,
902                        layout);
903 +
904 +      gdk_gc_set_clip_rectangle (widget->style->text_gc [widget->state], NULL);
905 +
906        
907        if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos))
908         {
909 @@ -3128,7 +3516,7 @@
910             {
911               GdkRectangle rect;
912  
913 -             rect.x = INNER_BORDER - entry->scroll_offset + ranges[2 * i];
914 +             rect.x = border_x - entry->scroll_offset + ranges[2 * i];
915               rect.y = y;
916               rect.width = ranges[2 * i + 1];
917               rect.height = logical_rect.height;
918 @@ -3177,14 +3565,18 @@
919  {
920    GdkKeymap *keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (entry)));
921    PangoDirection keymap_direction = gdk_keymap_get_direction (keymap);
922 +  gint border_x, border_y;
923    
924 +  gtk_widget_style_get (GTK_WIDGET (entry), "horizontal-border", &border_x,
925 +                                           "vertical-border", &border_y,
926 +                                           NULL);
927    if (GTK_WIDGET_DRAWABLE (entry))
928      {
929        GtkWidget *widget = GTK_WIDGET (entry);
930        GdkRectangle cursor_location;
931        gboolean split_cursor;
932  
933 -      gint xoffset = INNER_BORDER - entry->scroll_offset;
934 +      gint xoffset = border_x - entry->scroll_offset;
935        gint strong_x, weak_x;
936        gint text_area_height;
937        PangoDirection dir1 = PANGO_DIRECTION_NEUTRAL;
938 @@ -3221,9 +3613,9 @@
939         }
940  
941        cursor_location.x = xoffset + x1;
942 -      cursor_location.y = INNER_BORDER;
943 +      cursor_location.y = border_y;
944        cursor_location.width = 0;
945 -      cursor_location.height = text_area_height - 2 * INNER_BORDER ;
946 +      cursor_location.height = text_area_height - 2 * border_y;
947  
948        draw_insertion_cursor (entry,
949                              &cursor_location, TRUE, dir1,
950 @@ -3249,11 +3641,8 @@
951  static void
952  gtk_entry_reset_im_context (GtkEntry *entry)
953  {
954 -  if (entry->need_im_reset)
955 -    {
956 -      entry->need_im_reset = 0;
957 -      gtk_im_context_reset (entry->im_context);
958 -    }
959 +  /* Hildon: We want reset to be sent more often */ 
960 +  gtk_im_context_reset (entry->im_context);
961  }
962  
963  static gint
964 @@ -3266,8 +3655,12 @@
965    gint pos;
966    gboolean trailing;
967    const gchar *text;
968 -  gint cursor_index;
969 -  
970 +  gint border_x, cursor_index;
971 +
972 +  gtk_widget_style_get (GTK_WIDGET (entry), "horizontal-border", &border_x,
973 +                                           NULL);
974 +  x -= border_x;
975 +
976    layout = gtk_entry_ensure_layout (entry, TRUE);
977    text = pango_layout_get_text (layout);
978    cursor_index = g_utf8_offset_to_pointer (text, entry->current_pos) - text;
979 @@ -3355,12 +3748,17 @@
980    PangoLayout *layout;
981    PangoLayoutLine *line;
982    PangoRectangle logical_rect;
983 +  gint border_x, border_y;
984 +
985 +  gtk_widget_style_get (GTK_WIDGET (entry), "horizontal-border", &border_x,
986 +                                           "vertical-border", &border_y,
987 +                                           NULL);
988  
989    if (!GTK_WIDGET_REALIZED (entry))
990      return;
991    
992    gdk_drawable_get_size (entry->text_area, &text_area_width, NULL);
993 -  text_area_width -= 2 * INNER_BORDER;
994 +  text_area_width -= 2 * border_x;
995  
996    layout = gtk_entry_ensure_layout (entry, TRUE);
997    line = pango_layout_get_lines (layout)->data;
998 @@ -3390,13 +3788,13 @@
999    entry->scroll_offset = CLAMP (entry->scroll_offset, min_offset, max_offset);
1000  
1001    /* And make sure cursors are on screen. Note that the cursor is
1002 -   * actually drawn one pixel into the INNER_BORDER space on
1003 +   * actually drawn one pixel into the border_x space on
1004     * the right, when the scroll is at the utmost right. This
1005     * looks better to to me than confining the cursor inside the
1006     * border entirely, though it means that the cursor gets one
1007     * pixel closer to the edge of the widget on the right than
1008     * on the left. This might need changing if one changed
1009 -   * INNER_BORDER from 2 to 1, as one would do on a
1010 +   * border_x from 2 to 1, as one would do on a
1011     * small-screen-real-estate display.
1012     *
1013     * We always make sure that the strong cursor is on screen, and
1014 @@ -3430,6 +3828,52 @@
1015        entry->scroll_offset += weak_xoffset - text_area_width;
1016      }
1017  
1018 +  /*Changes for Hildon
1019 +   * now we make it so that if a character is partially visible,
1020 +   * then we also scroll that off the screen.
1021 +   */
1022 +         
1023 +       /* NOTE: Commented out because it does not work with bidi text where the indexes are in random
1024 +          * left-right or right-left order. Code causes Pango assert aborts. Because gtkentry itself
1025 +          * is broken with regard to bidi anyway (bug #478) we ignore this requirement of the spec
1026 +          * until gtkentry itself is fixed. (bug #477)
1027 +          */
1028 +
1029 +       /* Better yet, let's disable this (for now) only when using RTL text */
1030 +  
1031 +/*Note: BUG #857. patched gtkentry crashed when pasting scalable fonts. This is pango problem
1032 +  * and we tested patched gtkentry with pango version 1.3.2 and it appears to be fixed. Section is comment          ed out until we upgrade to new version of pango
1033 + if (gtk_widget_get_direction( entry ) != GTK_TEXT_DIR_RTL)
1034 +  {
1035 +    PangoLayoutIter *iter = get_char_at_pos( layout, entry->scroll_offset, 0 );
1036 +    // if we found the char we were looking for
1037 +    if ( iter )
1038 +    {
1039 +        PangoRectangle char_rect; // used for getting character's onscreen pos
1040 +
1041 +        // get the position of that character on the screen
1042 +        pango_layout_iter_get_char_extents( iter, &char_rect );
1043 +        char_rect.x /= PANGO_SCALE;
1044 +
1045 +        // if the starting position is < the current scroll offset, then the
1046 +        // character is only partially visible, and we should scroll to the
1047 +        // start of the next character instead
1048 +         
1049 +        if ( char_rect.x < entry->scroll_offset )
1050 +        {
1051 +            if ( pango_layout_iter_next_char( iter ) )
1052 +            {
1053 +                pango_layout_iter_get_char_extents( iter, &char_rect);
1054 +                entry->scroll_offset = char_rect.x / PANGO_SCALE;
1055 +            }
1056 +        }
1057 +
1058 +        pango_layout_iter_free( iter );
1059 +    }
1060 +       
1061 +
1062 +  }*/
1063
1064    g_object_notify (G_OBJECT (entry), "scroll_offset");
1065  }
1066  
1067 @@ -3552,8 +3996,9 @@
1068        pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
1069        
1070        /* Find the next word end */
1071 +                       /*Hildon: cursor should seek to the start of the next word*/
1072        new_pos++;
1073 -      while (new_pos < n_attrs && !log_attrs[new_pos].is_word_end)
1074 +      while (new_pos < n_attrs && !log_attrs[new_pos].is_word_start)
1075         new_pos++;
1076  
1077        g_free (log_attrs);
1078 @@ -3648,14 +4093,9 @@
1079    
1080    if (entry->visible)
1081      return gtk_editable_get_chars (GTK_EDITABLE (entry), start, end);
1082 -  else if (!entry->invisible_char)
1083 +  /*Hildon: when not visible, no chars are public*/
1084 +  else 
1085      return g_strdup ("");
1086 -  else
1087 -    {
1088 -      GString *str = g_string_new (NULL);
1089 -      append_char (str, entry->invisible_char, end - start);
1090 -      return g_string_free (str, FALSE);
1091 -    }
1092  }
1093  
1094  static void
1095 @@ -3678,9 +4118,12 @@
1096        
1097    if (text)
1098      {
1099 -      gint pos, start, end;
1100 +      gint pos, start, end, index;
1101        GtkEntryCompletion *completion = gtk_entry_get_completion (entry);
1102  
1103 +      /* when pasting multiline text, ignore everything but the first line */
1104 +      for (index = 0; text[index] != 0 && text[index] != '\n'; index++);
1105 +
1106        if (completion)
1107         {
1108           g_signal_handler_block (entry, completion->priv->changed_id);
1109 @@ -3692,7 +4135,7 @@
1110          gtk_editable_delete_text (editable, start, end);
1111  
1112        pos = entry->current_pos;
1113 -      gtk_editable_insert_text (editable, text, -1, &pos);
1114 +      gtk_editable_insert_text (editable, text, index, &pos);
1115        gtk_editable_set_position (editable, pos);
1116  
1117        if (completion)
1118 @@ -3888,6 +4331,7 @@
1119  {
1120    g_return_if_fail (GTK_IS_ENTRY (entry));
1121  
1122 +  g_object_set(G_OBJECT(entry->im_context), "visibility", visible, NULL);
1123    entry->visible = visible ? TRUE : FALSE;
1124    g_object_notify (G_OBJECT (entry), "visibility");
1125    gtk_entry_recompute (entry);
1126 @@ -4569,6 +5013,7 @@
1127                      GdkEventButton *event)
1128  {
1129    PopupInfo *info = g_new (PopupInfo, 1);
1130 +  GtkEntryPrivate *priv;
1131  
1132    /* In order to know what entries we should make sensitive, we
1133     * ask for the current targets of the clipboard, and when
1134 @@ -4576,6 +5021,8 @@
1135     */
1136    info->entry = g_object_ref (entry);
1137    
1138 +  priv = GTK_ENTRY_GET_PRIVATE (entry);
1139 +
1140    if (event)
1141      {
1142        info->button = event->button;
1143 @@ -4591,6 +5038,8 @@
1144                                   gdk_atom_intern ("TARGETS", FALSE),
1145                                   popup_targets_received,
1146                                   info);
1147 +
1148 +  priv->menu_popped = TRUE;
1149  }
1150  
1151  static gboolean
1152 @@ -5389,3 +5838,156 @@
1153  
1154    return completion;
1155  }
1156 +
1157 +static PangoLayoutIter *get_char_at_pos( PangoLayout *layout, gint x, gint y )
1158 +{
1159 +     gint index = 0; /*the index of the first character */
1160 +     gint trailing = 0; /*not used*/
1161 +     PangoLayoutIter *iter; /*used to iterate over the text*/
1162 +     gboolean valid_char = TRUE;
1163 +
1164 +     /*get the position of the character currently at the scroll offset*/
1165 +     pango_layout_xy_to_index( layout, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing );
1166 +     iter = pango_layout_get_iter( layout );
1167 +
1168 +     /*iterate until we get to the character at the same index*/
1169 +     while ( valid_char && pango_layout_iter_get_index( iter ) != index )
1170 +     {
1171 +         valid_char = pango_layout_iter_next_char( iter );
1172 +     }
1173 +
1174 +     if ( valid_char == FALSE )
1175 +         iter = NULL;
1176 +
1177 +     return iter;
1178 +}
1179 +
1180 +static void gtk_entry_update_scrolled_window( GtkEntry  *entry)
1181 +{
1182 +  GtkWidget *parent;
1183 +  GtkWidget *widget;
1184 +  GtkWidget *direct_parent = NULL;
1185 +  GtkScrolledWindow *sw = NULL;
1186 +  gboolean need_update = FALSE;
1187 +  GtkAdjustment *vadjustment;
1188 +  gdouble value;
1189 +
1190 +  widget = parent = GTK_WIDGET(entry);
1191 +  if(parent->parent != NULL)
1192 +    direct_parent = parent->parent;
1193 +  while(parent && !GTK_WIDGET_TOPLEVEL(parent))
1194 +  {
1195 +    if(GTK_IS_SCROLLED_WINDOW(parent))
1196 +    {
1197 +      need_update = TRUE;
1198 +      sw =  GTK_SCROLLED_WINDOW(parent);
1199 +      break;   
1200 +    }
1201 +    parent = parent->parent;
1202 +  }
1203 +
1204 +  if(need_update)
1205 +  {
1206 +    gint x=0, y=0;
1207 +    vadjustment = gtk_scrolled_window_get_vadjustment(sw);
1208 +    value = gtk_adjustment_get_value(vadjustment);
1209 +
1210 +    if(direct_parent != NULL)
1211 +      gtk_widget_translate_coordinates( direct_parent, parent,
1212 +          widget->allocation.x, widget->allocation.y, &x, &y );
1213 +    
1214 +    if( (gdouble) y < 0 )
1215 +    {
1216 +      value = value + (gdouble) y;
1217 +      if (value < vadjustment->lower)
1218 +        value = vadjustment->lower;
1219 +    }
1220 +    else if( (gdouble )y + widget->allocation.height > vadjustment->page_size)
1221 +    {
1222 +      value = value + (gdouble)y + widget->allocation.height
1223 +        - vadjustment->page_size;
1224 +      if(value > vadjustment->upper - vadjustment->page_size)
1225 +        value = vadjustment->upper - vadjustment->page_size;
1226 +    }
1227 +    gtk_adjustment_set_value(vadjustment, value);
1228 +    gtk_scrolled_window_set_vadjustment(sw, GTK_ADJUSTMENT(vadjustment));
1229 +  }
1230 +}
1231 +
1232 +/*
1233 + * gtk_entry_set_autocap:
1234 + * @entry: a #GtkEntry
1235 + * @autocap: autocap
1236 + *
1237 + * Sets autocapitalization of the widget.
1238 + */
1239 +static void
1240 +gtk_entry_set_autocap (GtkEntry *entry,
1241 +                       gboolean autocap)
1242 +{
1243 +  g_return_if_fail (GTK_IS_ENTRY (entry));
1244 +
1245 +  if (gtk_entry_get_autocap (entry) != autocap)
1246 +  {
1247 +    g_object_set (G_OBJECT (entry->im_context), "autocap", autocap, NULL);
1248 +    g_object_notify (G_OBJECT (entry), "autocap");
1249 +  }
1250 +}
1251 +
1252 +/*
1253 + * gtk_entry_get_autocap:
1254 + * @entry: a #GtkEntry
1255 + *
1256 + * Gets autocapitalization state of the widget.
1257 + *
1258 + * Return value: a state
1259 + */
1260 +static gboolean
1261 +gtk_entry_get_autocap (GtkEntry *entry)
1262 +{
1263 +  gboolean autocap;
1264 +  g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE);
1265 +
1266 +  g_object_get (G_OBJECT (entry->im_context), "autocap", &autocap, NULL);
1267 +
1268 +  return autocap;
1269 +}
1270 +
1271 +/*
1272 + * gtk_entry_set_input_mode:
1273 + * @entry: a #GtkEntry
1274 + * @autocap: input mode
1275 + *
1276 + * Sets autocapitalization of the widget.
1277 + */
1278 +static void
1279 +gtk_entry_set_input_mode (GtkEntry *entry,
1280 +                          gint      mode)
1281 +{
1282 +  g_return_if_fail (GTK_IS_ENTRY (entry));
1283 +
1284 +  if (gtk_entry_get_input_mode (entry) != mode)
1285 +  {
1286 +    g_object_set (G_OBJECT (entry->im_context), "input_mode", mode, NULL);
1287 +    g_object_notify (G_OBJECT (entry), "input_mode");
1288 +  }
1289 +}
1290 +
1291 +/*
1292 + * gtk_entry_get_input_mode:
1293 + * @entry: a #GtkEntry
1294 + *
1295 + * Gets input mode of the widget.
1296 + *
1297 + * Return value: input mode
1298 + */
1299 +static gint
1300 +gtk_entry_get_input_mode (GtkEntry *entry)
1301 +{
1302 +  gint mode;
1303 +  g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE);
1304 +
1305 +  g_object_get (G_OBJECT (entry->im_context), "input_mode", &mode, NULL);
1306 +
1307 +  return mode;
1308 +}