]> Pileus Git - ~andy/gtk/blob - tests/testrichtext.c
intialize random number generator state upon program start, to enable
[~andy/gtk] / tests / testrichtext.c
1 /* testrichtext.c
2  * Copyright (C) 2006 Imendio AB
3  * Authors: Michael Natterer, Tim Janik
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <string.h>
22 #include <gtk/gtk.h>
23
24 static guint32 quick_rand32_accu = 2147483563;
25
26 static inline guint32
27 quick_rand32 (void)
28 {
29   quick_rand32_accu = 1664525 * quick_rand32_accu + 1013904223;
30   return quick_rand32_accu;
31 }
32
33 static gboolean
34 delete_event (GtkWidget   *widget,
35               GdkEventAny *event,
36               gpointer     user_data)
37 {
38   gtk_main_quit ();
39
40   return TRUE;
41 }
42
43 static void
44 text_tag_enqueue (GtkTextTag *tag,
45                   gpointer    data)
46 {
47   GSList **slist_p = data;
48   *slist_p = g_slist_prepend (*slist_p, tag);
49 }
50
51 static const gchar *example_text =
52 "vkndsk vfds vkfds vkdsv fdlksnvkfdvnkfdvnkdsnvs\n"
53 "kmvofdmvfdsvkv fdskvnkfdv nnd.mckfdvnknsknvdnvs"
54 "fdlvmfdsvlkfdsmvnskdnvfdsnvf sbskjnvlknfd cvdvnd"
55 "mvlfdsv vfdkjv m, ds vkfdks v df,v j kfds v d\n"
56 "vnfdskv kjvnfv  cfdkvndfnvcm fd,vk kdsf vj d\n"
57 "KLJHkjh kjh klhjKLJH Kjh kjl h34kj h34kj3h klj 23 "
58 "kjlkjlhsdjk 34kljh klj hklj 23k4jkjkjh234kjh 52kj "
59 "2h34 sdaf ukklj kjl32l jkkjl 23j jkl ljk23 jkl\n"
60 "hjhjhj2hj23jh jh jk jk2h3 hj kjj jk jh21 jhhj32.";
61
62 static GdkAtom
63 setup_buffer (GtkTextBuffer *buffer)
64 {
65   const guint tlen = strlen (example_text);
66   const guint tcount = 17;
67   GtkTextTag *tags[tcount];
68   GtkTextTagTable *ttable = gtk_text_buffer_get_tag_table (buffer);
69   GSList *node, *slist = NULL;
70   GdkAtom atom;
71   guint i;
72
73   /* cleanup */
74   gtk_text_buffer_set_text (buffer, "", 0);
75   gtk_text_tag_table_foreach (ttable, text_tag_enqueue, &slist);
76   for (node = slist; node; node = node->next)
77     gtk_text_tag_table_remove (ttable, node->data);
78   g_slist_free (slist);
79
80   /* create new tags */
81   for (i = 0; i < tcount; i++)
82     {
83       char *s = g_strdup_printf ("tag%u", i);
84       tags[i] = gtk_text_buffer_create_tag (buffer, s,
85                                             "weight", quick_rand32() >> 31 ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL,
86                                             "style", quick_rand32() >> 31 ? PANGO_STYLE_OBLIQUE : PANGO_STYLE_NORMAL,
87                                             "underline", quick_rand32() >> 31,
88                                             NULL);
89       g_free (s);
90     }
91
92   /* assign text and tags */
93   gtk_text_buffer_set_text (buffer, example_text, -1);
94   for (i = 0; i < tcount * 5; i++)
95     {
96       gint a = quick_rand32() % tlen, b = quick_rand32() % tlen;
97       GtkTextIter start, end;
98       gtk_text_buffer_get_iter_at_offset (buffer, &start, MIN (a, b));
99       gtk_text_buffer_get_iter_at_offset (buffer, &end,   MAX (a, b));
100       gtk_text_buffer_apply_tag (buffer, tags[i % tcount], &start, &end);
101     }
102
103   /* return serialization format */
104   atom = gtk_text_buffer_register_deserialize_tagset (buffer, NULL);
105   gtk_text_buffer_deserialize_set_can_create_tags (buffer, atom, TRUE);
106
107   return atom;
108 }
109
110 static gboolean
111 test_serialize_deserialize (GtkTextBuffer *buffer,
112                             GdkAtom        atom,
113                             GError       **error)
114 {
115   GtkTextIter  start, end;
116   guint8      *spew;
117   gsize        spew_length;
118   gboolean     success;
119
120   gtk_text_buffer_get_bounds (buffer, &start, &end);
121
122   spew = gtk_text_buffer_serialize (buffer, buffer, atom,
123                                     &start, &end, &spew_length);
124
125   success = gtk_text_buffer_deserialize (buffer, buffer, atom, &end,
126                                          spew, spew_length, error);
127
128   g_free (spew);
129
130   return success;
131 }
132
133 gint
134 main (gint   argc,
135       gchar *argv[])
136 {
137   GtkWidget     *window;
138   GtkWidget     *sw;
139   GtkWidget     *view;
140   GtkTextBuffer *buffer;
141   GdkAtom        atom;
142   guint          i, broken = 0;
143
144   gtk_init (&argc, &argv);
145
146   /* initialize random numbers, disable this for deterministic testing */
147   if (1)        
148     quick_rand32_accu = g_random_int();
149
150   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
151   gtk_widget_set_size_request (window, 400, 300);
152
153   sw = gtk_scrolled_window_new (NULL, NULL);
154   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
155                                        GTK_SHADOW_IN);
156   gtk_container_set_border_width (GTK_CONTAINER (sw), 12);
157   gtk_container_add (GTK_CONTAINER (window), sw);
158
159   g_signal_connect (window, "delete-event",
160                     G_CALLBACK (delete_event),
161                     NULL);
162
163   buffer = gtk_text_buffer_new (NULL);
164   view = gtk_text_view_new_with_buffer (buffer);
165   g_object_unref (buffer);
166
167   gtk_container_add (GTK_CONTAINER (sw), view);
168
169   gtk_widget_show_all (window);
170   if (0)
171     gtk_main ();
172
173   for (i = 0; i < 250; i++)
174     {
175       GError *error = NULL;
176       g_printerr ("creating randomly tagged text buffer with accu=0x%x...\n", quick_rand32_accu);
177       atom = setup_buffer (buffer);
178       if (test_serialize_deserialize (buffer, atom, &error))
179         g_printerr ("ok.\n");
180       else
181         {
182           g_printerr ("FAIL: serialization/deserialization failed:\n  %s\n", error->message);
183           broken += 1;
184         }
185       g_clear_error (&error);
186     }
187
188   return broken > 0;
189 }