]> Pileus Git - ~andy/gtk/blob - gtk/gtkoldeditable.c
840a20107b0b7f05e6fe361f517491a264e570aa
[~andy/gtk] / gtk / gtkoldeditable.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #undef GTK_DISABLE_DEPRECATED
28
29 #include <config.h>
30 #include <string.h>
31 #include "gdk/gdkkeysyms.h"
32 #include "gdk/gdki18n.h"
33 #include "gtkclipboard.h"
34 #include "gtkoldeditable.h"
35 #include "gtkmain.h"
36 #include "gtkmarshalers.h"
37 #include "gtkselection.h"
38 #include "gtksignal.h"
39 #include "gtkintl.h"
40
41 #define GTK_DISABLE_DEPRECATED
42 #include "gtkalias.h"
43
44 #define MIN_EDITABLE_WIDTH  150
45 #define DRAW_TIMEOUT     20
46 #define INNER_BORDER     2
47
48 enum {
49   /* Binding actions */
50   ACTIVATE,
51   SET_EDITABLE,
52   MOVE_CURSOR,
53   MOVE_WORD,
54   MOVE_PAGE,
55   MOVE_TO_ROW,
56   MOVE_TO_COLUMN,
57   KILL_CHAR,
58   KILL_WORD,
59   KILL_LINE,
60   CUT_CLIPBOARD,
61   COPY_CLIPBOARD,
62   PASTE_CLIPBOARD,
63   LAST_SIGNAL
64 };
65
66 enum {
67   ARG_0,
68   ARG_TEXT_POSITION,
69   ARG_EDITABLE
70 };
71
72 /* values for selection info */
73
74 enum {
75   TARGET_STRING,
76   TARGET_TEXT,
77   TARGET_COMPOUND_TEXT
78 };
79
80 static void  gtk_old_editable_editable_init        (GtkEditableClass    *iface);
81 static void  gtk_old_editable_set_arg              (GtkObject           *object,
82                                                     GtkArg              *arg,
83                                                     guint                arg_id);
84 static void  gtk_old_editable_get_arg              (GtkObject           *object,
85                                                     GtkArg              *arg,
86                                                     guint                arg_id);
87 static void *gtk_old_editable_get_public_chars     (GtkOldEditable      *old_editable,
88                                                     gint                 start,
89                                                     gint                 end);
90
91 static gint gtk_old_editable_selection_clear    (GtkWidget         *widget,
92                                                  GdkEventSelection *event);
93 static void gtk_old_editable_selection_get      (GtkWidget         *widget,
94                                                  GtkSelectionData  *selection_data,
95                                                  guint              info,
96                                                  guint              time);
97 static void gtk_old_editable_selection_received (GtkWidget         *widget,
98                                                  GtkSelectionData  *selection_data,
99                                                  guint              time);
100
101 static void  gtk_old_editable_set_selection        (GtkOldEditable      *old_editable,
102                                                     gint                 start,
103                                                     gint                 end);
104
105 static void gtk_old_editable_real_set_editable    (GtkOldEditable *old_editable,
106                                                    gboolean        is_editable);
107 static void gtk_old_editable_real_cut_clipboard   (GtkOldEditable *old_editable);
108 static void gtk_old_editable_real_copy_clipboard  (GtkOldEditable *old_editable);
109 static void gtk_old_editable_real_paste_clipboard (GtkOldEditable *old_editable);
110
111 static void     gtk_old_editable_insert_text         (GtkEditable *editable,
112                                                       const gchar *new_text,
113                                                       gint         new_text_length,
114                                                       gint        *position);
115 static void     gtk_old_editable_delete_text         (GtkEditable *editable,
116                                                       gint         start_pos,
117                                                       gint         end_pos);
118 static gchar *  gtk_old_editable_get_chars           (GtkEditable *editable,
119                                                       gint         start,
120                                                       gint         end);
121 static void     gtk_old_editable_set_selection_bounds (GtkEditable *editable,
122                                                        gint         start,
123                                                        gint         end);
124 static gboolean gtk_old_editable_get_selection_bounds (GtkEditable *editable,
125                                                        gint        *start,
126                                                        gint        *end);
127 static void     gtk_old_editable_set_position        (GtkEditable *editable,
128                                                       gint         position);
129 static gint     gtk_old_editable_get_position        (GtkEditable *editable);
130
131 static guint editable_signals[LAST_SIGNAL] = { 0 };
132
133 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GtkOldEditable, gtk_old_editable, GTK_TYPE_WIDGET,
134                                   G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
135                                                          gtk_old_editable_editable_init))
136
137 static void
138 gtk_old_editable_class_init (GtkOldEditableClass *class)
139 {
140   GtkObjectClass *object_class;
141   GtkWidgetClass *widget_class;
142
143   object_class = (GtkObjectClass*) class;
144   widget_class = (GtkWidgetClass*) class;
145
146   object_class->set_arg = gtk_old_editable_set_arg;
147   object_class->get_arg = gtk_old_editable_get_arg;
148
149   widget_class->selection_clear_event = gtk_old_editable_selection_clear;
150   widget_class->selection_received = gtk_old_editable_selection_received;
151   widget_class->selection_get = gtk_old_editable_selection_get;
152
153   class->activate = NULL;
154   class->set_editable = gtk_old_editable_real_set_editable;
155
156   class->move_cursor = NULL;
157   class->move_word = NULL;
158   class->move_page = NULL;
159   class->move_to_row = NULL;
160   class->move_to_column = NULL;
161
162   class->kill_char = NULL;
163   class->kill_word = NULL;
164   class->kill_line = NULL;
165
166   class->cut_clipboard = gtk_old_editable_real_cut_clipboard;
167   class->copy_clipboard = gtk_old_editable_real_copy_clipboard;
168   class->paste_clipboard = gtk_old_editable_real_paste_clipboard;
169
170   class->update_text = NULL;
171   class->get_chars = NULL;
172   class->set_selection = NULL;
173   class->set_position = NULL;
174
175   editable_signals[ACTIVATE] =
176     gtk_signal_new (I_("activate"),
177                     GTK_RUN_LAST | GTK_RUN_ACTION,
178                     GTK_CLASS_TYPE (object_class),
179                     GTK_SIGNAL_OFFSET (GtkOldEditableClass, activate),
180                     _gtk_marshal_NONE__NONE,
181                     GTK_TYPE_NONE, 0);
182   widget_class->activate_signal = editable_signals[ACTIVATE];
183
184   editable_signals[SET_EDITABLE] =
185     gtk_signal_new (I_("set-editable"),
186                     GTK_RUN_LAST | GTK_RUN_ACTION,
187                     GTK_CLASS_TYPE (object_class),
188                     GTK_SIGNAL_OFFSET (GtkOldEditableClass, set_editable),
189                     _gtk_marshal_NONE__BOOLEAN,
190                     GTK_TYPE_NONE, 1,
191                     GTK_TYPE_BOOL);
192
193   editable_signals[MOVE_CURSOR] =
194     gtk_signal_new (I_("move_cursor"),
195                     GTK_RUN_LAST | GTK_RUN_ACTION,
196                     GTK_CLASS_TYPE (object_class),
197                     GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_cursor),
198                     _gtk_marshal_NONE__INT_INT,
199                     GTK_TYPE_NONE, 2, 
200                     GTK_TYPE_INT, 
201                     GTK_TYPE_INT);
202
203   editable_signals[MOVE_WORD] =
204     gtk_signal_new (I_("move_word"),
205                     GTK_RUN_LAST | GTK_RUN_ACTION,
206                     GTK_CLASS_TYPE (object_class),
207                     GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_word),
208                     _gtk_marshal_NONE__INT,
209                     GTK_TYPE_NONE, 1, 
210                     GTK_TYPE_INT);
211
212   editable_signals[MOVE_PAGE] =
213     gtk_signal_new (I_("move_page"),
214                     GTK_RUN_LAST | GTK_RUN_ACTION,
215                     GTK_CLASS_TYPE (object_class),
216                     GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_page),
217                     _gtk_marshal_NONE__INT_INT,
218                     GTK_TYPE_NONE, 2, 
219                     GTK_TYPE_INT, 
220                     GTK_TYPE_INT);
221
222   editable_signals[MOVE_TO_ROW] =
223     gtk_signal_new (I_("move_to_row"),
224                     GTK_RUN_LAST | GTK_RUN_ACTION,
225                     GTK_CLASS_TYPE (object_class),
226                     GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_to_row),
227                     _gtk_marshal_NONE__INT,
228                     GTK_TYPE_NONE, 1, 
229                     GTK_TYPE_INT);
230
231   editable_signals[MOVE_TO_COLUMN] =
232     gtk_signal_new (I_("move_to_column"),
233                     GTK_RUN_LAST | GTK_RUN_ACTION,
234                     GTK_CLASS_TYPE (object_class),
235                     GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_to_column),
236                     _gtk_marshal_NONE__INT,
237                     GTK_TYPE_NONE, 1, 
238                     GTK_TYPE_INT);
239
240   editable_signals[KILL_CHAR] =
241     gtk_signal_new (I_("kill_char"),
242                     GTK_RUN_LAST | GTK_RUN_ACTION,
243                     GTK_CLASS_TYPE (object_class),
244                     GTK_SIGNAL_OFFSET (GtkOldEditableClass, kill_char),
245                     _gtk_marshal_NONE__INT,
246                     GTK_TYPE_NONE, 1, 
247                     GTK_TYPE_INT);
248
249   editable_signals[KILL_WORD] =
250     gtk_signal_new (I_("kill_word"),
251                     GTK_RUN_LAST | GTK_RUN_ACTION,
252                     GTK_CLASS_TYPE (object_class),
253                     GTK_SIGNAL_OFFSET (GtkOldEditableClass, kill_word),
254                     _gtk_marshal_NONE__INT,
255                     GTK_TYPE_NONE, 1, 
256                     GTK_TYPE_INT);
257
258   editable_signals[KILL_LINE] =
259     gtk_signal_new (I_("kill_line"),
260                     GTK_RUN_LAST | GTK_RUN_ACTION,
261                     GTK_CLASS_TYPE (object_class),
262                     GTK_SIGNAL_OFFSET (GtkOldEditableClass, kill_line),
263                     _gtk_marshal_NONE__INT,
264                     GTK_TYPE_NONE, 1, 
265                     GTK_TYPE_INT);
266
267   editable_signals[CUT_CLIPBOARD] =
268     gtk_signal_new (I_("cut_clipboard"),
269                     GTK_RUN_LAST | GTK_RUN_ACTION,
270                     GTK_CLASS_TYPE (object_class),
271                     GTK_SIGNAL_OFFSET (GtkOldEditableClass, cut_clipboard),
272                     _gtk_marshal_NONE__NONE,
273                     GTK_TYPE_NONE, 0);
274
275   editable_signals[COPY_CLIPBOARD] =
276     gtk_signal_new (I_("copy_clipboard"),
277                     GTK_RUN_LAST | GTK_RUN_ACTION,
278                     GTK_CLASS_TYPE (object_class),
279                     GTK_SIGNAL_OFFSET (GtkOldEditableClass, copy_clipboard),
280                     _gtk_marshal_NONE__NONE,
281                     GTK_TYPE_NONE, 0);
282
283   editable_signals[PASTE_CLIPBOARD] =
284     gtk_signal_new (I_("paste_clipboard"),
285                     GTK_RUN_LAST | GTK_RUN_ACTION,
286                     GTK_CLASS_TYPE (object_class),
287                     GTK_SIGNAL_OFFSET (GtkOldEditableClass, paste_clipboard),
288                     _gtk_marshal_NONE__NONE,
289                     GTK_TYPE_NONE, 0);
290
291   gtk_object_add_arg_type ("GtkOldEditable::text-position", GTK_TYPE_INT, GTK_ARG_READWRITE | G_PARAM_STATIC_NAME, ARG_TEXT_POSITION);
292   gtk_object_add_arg_type ("GtkOldEditable::editable", GTK_TYPE_BOOL, GTK_ARG_READWRITE | G_PARAM_STATIC_NAME, ARG_EDITABLE);
293 }
294
295 static void
296 gtk_old_editable_editable_init (GtkEditableClass *iface)
297 {
298   iface->do_insert_text = gtk_old_editable_insert_text;
299   iface->do_delete_text = gtk_old_editable_delete_text;
300   iface->get_chars = gtk_old_editable_get_chars;
301   iface->set_selection_bounds = gtk_old_editable_set_selection_bounds;
302   iface->get_selection_bounds = gtk_old_editable_get_selection_bounds;
303   iface->set_position = gtk_old_editable_set_position;
304   iface->get_position = gtk_old_editable_get_position;
305 }
306
307 static void
308 gtk_old_editable_set_arg (GtkObject *object,
309                           GtkArg    *arg,
310                           guint      arg_id)
311 {
312   GtkEditable *editable = GTK_EDITABLE (object);
313
314   switch (arg_id)
315     {
316     case ARG_TEXT_POSITION:
317       gtk_editable_set_position (editable, GTK_VALUE_INT (*arg));
318       break;
319     case ARG_EDITABLE:
320       gtk_signal_emit (object, editable_signals[SET_EDITABLE],
321                        GTK_VALUE_BOOL (*arg) != FALSE);
322       break;
323     default:
324       break;
325     }
326 }
327
328 static void
329 gtk_old_editable_get_arg (GtkObject *object,
330                           GtkArg    *arg,
331                           guint      arg_id)
332 {
333   GtkOldEditable *old_editable;
334
335   old_editable = GTK_OLD_EDITABLE (object);
336
337   switch (arg_id)
338     {
339     case ARG_TEXT_POSITION:
340       GTK_VALUE_INT (*arg) = old_editable->current_pos;
341       break;
342     case ARG_EDITABLE:
343       GTK_VALUE_BOOL (*arg) = old_editable->editable;
344       break;
345     default:
346       arg->type = GTK_TYPE_INVALID;
347       break;
348     }
349 }
350
351 static void
352 gtk_old_editable_init (GtkOldEditable *old_editable)
353 {
354   static const GtkTargetEntry targets[] = {
355     { "UTF8_STRING", 0, 0 },
356     { "STRING", 0, 0 },
357     { "TEXT",   0, 0 }, 
358     { "COMPOUND_TEXT", 0, 0 }
359   };
360
361   GTK_WIDGET_SET_FLAGS (old_editable, GTK_CAN_FOCUS);
362
363   old_editable->selection_start_pos = 0;
364   old_editable->selection_end_pos = 0;
365   old_editable->has_selection = FALSE;
366   old_editable->editable = 1;
367   old_editable->visible = 1;
368   old_editable->clipboard_text = NULL;
369
370   gtk_selection_add_targets (GTK_WIDGET (old_editable), GDK_SELECTION_PRIMARY,
371                              targets, G_N_ELEMENTS (targets));
372 }
373
374 static void
375 gtk_old_editable_insert_text (GtkEditable *editable,
376                               const gchar *new_text,
377                               gint         new_text_length,
378                               gint        *position)
379 {
380   gchar buf[64];
381   gchar *text;
382
383   gtk_widget_ref (GTK_WIDGET (editable));
384
385   if (new_text_length <= 63)
386     text = buf;
387   else
388     text = g_new (gchar, new_text_length + 1);
389
390   text[new_text_length] = '\0';
391   strncpy (text, new_text, new_text_length);
392   
393   g_signal_emit_by_name (editable, "insert_text", text, new_text_length,
394                          position);
395   g_signal_emit_by_name (editable, "changed");
396   
397   if (new_text_length > 63)
398     g_free (text);
399
400   gtk_widget_unref (GTK_WIDGET (editable));
401 }
402
403 static void
404 gtk_old_editable_delete_text (GtkEditable *editable,
405                               gint         start_pos,
406                               gint         end_pos)
407 {
408   GtkOldEditable *old_editable = GTK_OLD_EDITABLE (editable);
409
410   gtk_widget_ref (GTK_WIDGET (old_editable));
411
412   g_signal_emit_by_name (editable, "delete_text", start_pos, end_pos);
413   g_signal_emit_by_name (editable, "changed");
414
415   if (old_editable->selection_start_pos == old_editable->selection_end_pos &&
416       old_editable->has_selection)
417     gtk_old_editable_claim_selection (old_editable, FALSE, GDK_CURRENT_TIME);
418   
419   gtk_widget_unref (GTK_WIDGET (old_editable));
420 }
421
422 static void
423 gtk_old_editable_update_text (GtkOldEditable *old_editable,
424                               gint            start_pos,
425                               gint            end_pos)
426 {
427   GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (old_editable);
428   klass->update_text (GTK_OLD_EDITABLE (old_editable), start_pos, end_pos);
429 }
430
431 static gchar *    
432 gtk_old_editable_get_chars  (GtkEditable      *editable,
433                              gint              start,
434                              gint              end)
435 {
436   GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (editable);
437   return klass->get_chars (GTK_OLD_EDITABLE (editable), start, end);
438 }
439
440 /*
441  * Like gtk_editable_get_chars, but if the editable is not
442  * visible, return asterisks; also convert result to UTF-8.
443  */
444 static void *    
445 gtk_old_editable_get_public_chars (GtkOldEditable   *old_editable,
446                                    gint              start,
447                                    gint              end)
448 {
449   gchar *str = NULL;
450   const gchar *charset;
451   gboolean need_conversion = !g_get_charset (&charset);
452
453   if (old_editable->visible)
454     {
455       GError *error = NULL;
456       gchar *tmp = gtk_editable_get_chars (GTK_EDITABLE (old_editable), start, end);
457
458       if (need_conversion)
459         {
460           str = g_convert (tmp, -1,
461                            "UTF-8", charset,
462                            NULL, NULL, &error);
463           
464           if (!str)
465             {
466               g_warning ("Cannot convert text from charset to UTF-8 %s: %s", charset, error->message);
467               g_error_free (error);
468             }
469
470           g_free (tmp);
471         }
472       else
473         str = tmp;
474     }
475   else
476     {
477       gint i;
478       gint nchars = end - start;
479        
480       if (nchars < 0)
481         nchars = -nchars;
482
483       str = g_new (gchar, nchars + 1);
484       for (i = 0; i<nchars; i++)
485         str[i] = '*';
486       str[i] = '\0';
487     }
488
489   return str;
490 }
491
492 static void
493 gtk_old_editable_set_selection (GtkOldEditable *old_editable,
494                                 gint            start_pos,
495                                 gint            end_pos)
496 {
497   GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (old_editable);
498   klass->set_selection (old_editable, start_pos, end_pos);
499 }
500
501 static void
502 gtk_old_editable_set_position (GtkEditable *editable,
503                                gint            position)
504 {
505   GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (editable);
506
507   klass->set_position (GTK_OLD_EDITABLE (editable), position);
508 }
509
510 static gint
511 gtk_old_editable_get_position (GtkEditable *editable)
512 {
513   return GTK_OLD_EDITABLE (editable)->current_pos;
514 }
515
516 static gint
517 gtk_old_editable_selection_clear (GtkWidget         *widget,
518                                   GdkEventSelection *event)
519 {
520   GtkOldEditable *old_editable = GTK_OLD_EDITABLE (widget);
521   
522   /* Let the selection handling code know that the selection
523    * has been changed, since we've overriden the default handler */
524   if (!GTK_WIDGET_CLASS (gtk_old_editable_parent_class)->selection_clear_event (widget, event))
525     return FALSE;
526   
527   if (old_editable->has_selection)
528     {
529       old_editable->has_selection = FALSE;
530       gtk_old_editable_update_text (old_editable, old_editable->selection_start_pos,
531                                     old_editable->selection_end_pos);
532     }
533   
534   return TRUE;
535 }
536
537 static void
538 gtk_old_editable_selection_get (GtkWidget        *widget,
539                                 GtkSelectionData *selection_data,
540                                 guint             info,
541                                 guint             time)
542 {
543   GtkOldEditable *old_editable = GTK_OLD_EDITABLE (widget);
544   gint selection_start_pos;
545   gint selection_end_pos;
546
547   gchar *str;
548
549   selection_start_pos = MIN (old_editable->selection_start_pos, old_editable->selection_end_pos);
550   selection_end_pos = MAX (old_editable->selection_start_pos, old_editable->selection_end_pos);
551
552   str = gtk_old_editable_get_public_chars (old_editable, 
553                                            selection_start_pos, 
554                                            selection_end_pos);
555
556   if (str)
557     {
558       gtk_selection_data_set_text (selection_data, str, -1);
559       g_free (str);
560     }
561 }
562
563 static void
564 gtk_old_editable_paste_received (GtkOldEditable *old_editable,
565                                  const gchar    *text,
566                                  gboolean        is_clipboard)
567 {
568   const gchar *str = NULL;
569   const gchar *charset;
570   gboolean need_conversion = FALSE;
571
572   if (text)
573     {
574       GError *error = NULL;
575       
576       need_conversion = !g_get_charset (&charset);
577
578       if (need_conversion)
579         {
580           str = g_convert_with_fallback (text, -1,
581                                          charset, "UTF-8", NULL,
582                                          NULL, NULL, &error);
583           if (!str)
584             {
585               g_warning ("Cannot convert text from UTF-8 to %s: %s",
586                          charset, error->message);
587               g_error_free (error);
588               return;
589             }
590         }
591       else
592         str = text;
593     }
594
595   if (str)
596     {
597       gboolean reselect;
598       gint old_pos;
599       gint tmp_pos;
600   
601       reselect = FALSE;
602
603       if ((old_editable->selection_start_pos != old_editable->selection_end_pos) && 
604           (!old_editable->has_selection || is_clipboard))
605         {
606           reselect = TRUE;
607           
608           /* Don't want to call gtk_editable_delete_selection here if we are going
609            * to reclaim the selection to avoid extra server traffic */
610           if (old_editable->has_selection)
611             {
612               gtk_editable_delete_text (GTK_EDITABLE (old_editable),
613                                         MIN (old_editable->selection_start_pos, old_editable->selection_end_pos),
614                                         MAX (old_editable->selection_start_pos, old_editable->selection_end_pos));
615             }
616           else
617             gtk_editable_delete_selection (GTK_EDITABLE (old_editable));
618         }
619       
620       tmp_pos = old_pos = old_editable->current_pos;
621       
622       gtk_editable_insert_text (GTK_EDITABLE (old_editable), str, -1, &tmp_pos);
623
624       if (reselect)
625         gtk_old_editable_set_selection (old_editable, old_pos, old_editable->current_pos);
626
627       if (str && str != text)
628         g_free ((gchar *) str);
629     }
630 }
631
632 static void
633 gtk_old_editable_selection_received  (GtkWidget         *widget,
634                                       GtkSelectionData  *selection_data,
635                                       guint              time)
636 {
637   GtkOldEditable *old_editable = GTK_OLD_EDITABLE (widget);
638
639   guchar *text = gtk_selection_data_get_text (selection_data);
640
641   if (!text)
642     {
643       /* If we asked for UTF8 and didn't get it, try text; if we asked
644        * for text and didn't get it, try string.  If we asked for
645        * anything else and didn't get it, give up.
646        */
647       if (selection_data->target == gdk_atom_intern_static_string ("UTF8_STRING"))
648         {
649           gtk_selection_convert (widget, GDK_SELECTION_PRIMARY,
650                                  gdk_atom_intern_static_string ("TEXT"),
651                                  time);
652           return;
653         }
654       else if (selection_data->target == gdk_atom_intern_static_string ("TEXT"))
655         {
656           gtk_selection_convert (widget, GDK_SELECTION_PRIMARY,
657                                  GDK_TARGET_STRING,
658                                  time);
659           return;
660         }
661     }
662
663   if (text)
664     {
665       gtk_old_editable_paste_received (old_editable, (gchar *) text, FALSE);
666       g_free (text);
667     }
668 }
669
670 static void
671 old_editable_text_received_cb (GtkClipboard *clipboard,
672                                const gchar  *text,
673                                gpointer      data)
674 {
675   GtkOldEditable *old_editable = GTK_OLD_EDITABLE (data);
676
677   gtk_old_editable_paste_received (old_editable, text, TRUE);
678   g_object_unref (G_OBJECT (old_editable));
679 }
680
681 /**
682  * gtk_old_editable_claim_selection:
683  * @old_editable: a #GtkOldEditable
684  * @claim: if %TRUE, claim ownership of the selection, if %FALSE, give
685  *   up ownership
686  * @time_: timestamp for this operation
687  * 
688  * Claims or gives up ownership of the selection.
689  */
690 void
691 gtk_old_editable_claim_selection (GtkOldEditable *old_editable, 
692                                   gboolean        claim, 
693                                   guint32         time)
694 {
695   GtkWidget *widget = GTK_WIDGET (old_editable);
696   GdkDisplay *display = gtk_widget_get_display (widget);
697   
698   g_return_if_fail (GTK_IS_OLD_EDITABLE (old_editable));
699   g_return_if_fail (GTK_WIDGET_REALIZED (old_editable));
700
701   old_editable->has_selection = FALSE;
702   
703   if (claim)
704     {
705       if (gtk_selection_owner_set_for_display (display, widget,
706                                                GDK_SELECTION_PRIMARY, time))
707         old_editable->has_selection = TRUE;
708     }
709   else
710     {
711       if (gdk_selection_owner_get_for_display (display, GDK_SELECTION_PRIMARY) == widget->window)
712         gtk_selection_owner_set_for_display (display,
713                                              NULL,
714                                              GDK_SELECTION_PRIMARY, time);
715     }
716 }
717
718 static void
719 gtk_old_editable_set_selection_bounds (GtkEditable *editable,
720                                        gint         start,
721                                        gint         end)
722 {
723   GtkOldEditable *old_editable = GTK_OLD_EDITABLE (editable);
724   
725   if (GTK_WIDGET_REALIZED (editable))
726     gtk_old_editable_claim_selection (old_editable, start != end, GDK_CURRENT_TIME);
727   
728   gtk_old_editable_set_selection (old_editable, start, end);
729 }
730
731 static gboolean
732 gtk_old_editable_get_selection_bounds (GtkEditable *editable,
733                                        gint        *start,
734                                        gint        *end)
735 {
736   GtkOldEditable *old_editable = GTK_OLD_EDITABLE (editable);
737
738   *start = old_editable->selection_start_pos;
739   *end = old_editable->selection_end_pos;
740
741   return (old_editable->selection_start_pos != old_editable->selection_end_pos);
742 }
743
744 static void
745 gtk_old_editable_real_set_editable (GtkOldEditable *old_editable,
746                                     gboolean        is_editable)
747 {
748   is_editable = is_editable != FALSE;
749
750   if (old_editable->editable != is_editable)
751     {
752       old_editable->editable = is_editable;
753       gtk_widget_queue_draw (GTK_WIDGET (old_editable));
754     }
755 }
756
757 static void
758 gtk_old_editable_real_cut_clipboard (GtkOldEditable *old_editable)
759 {
760   gtk_old_editable_real_copy_clipboard (old_editable);
761   gtk_editable_delete_selection (GTK_EDITABLE (old_editable));
762 }
763
764 static void
765 gtk_old_editable_real_copy_clipboard (GtkOldEditable *old_editable)
766 {
767   gint selection_start_pos; 
768   gint selection_end_pos;
769
770   selection_start_pos = MIN (old_editable->selection_start_pos, old_editable->selection_end_pos);
771   selection_end_pos = MAX (old_editable->selection_start_pos, old_editable->selection_end_pos);
772
773   if (selection_start_pos != selection_end_pos)
774     {
775       gchar *text = gtk_old_editable_get_public_chars (old_editable,
776                                                        selection_start_pos,
777                                                        selection_end_pos);
778
779       if (text)
780         {
781           GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (old_editable),
782                                                               GDK_SELECTION_CLIPBOARD);
783           
784           gtk_clipboard_set_text (clipboard, text, -1);
785           g_free (text);
786         }
787     }
788 }
789
790 static void
791 gtk_old_editable_real_paste_clipboard (GtkOldEditable *old_editable)
792 {
793   GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (old_editable), 
794                                                       GDK_SELECTION_CLIPBOARD);
795
796   g_object_ref (G_OBJECT (old_editable));
797   gtk_clipboard_request_text (clipboard, old_editable_text_received_cb, old_editable);
798 }
799
800 /**
801  * gtk_old_editable_changed:
802  * @old_editable: a #GtkOldEditable
803  *
804  * Emits the ::changed signal on @old_editable.
805  */
806 void
807 gtk_old_editable_changed (GtkOldEditable *old_editable)
808 {
809   g_return_if_fail (GTK_IS_OLD_EDITABLE (old_editable));
810   
811   g_signal_emit_by_name (old_editable, "changed");
812 }
813
814 #define __GTK_OLD_EDITABLE_C__
815 #include "gtkaliasdef.c"