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