1/* Gtk+ default value tests
2 * Copyright (C) 2007 Christian Persch
3 * 2007 Johan Dahlin
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library 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 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <string.h>
20#include <gtk/gtk.h>
21#include <gtk/gtkunixprint.h>
22
23static void
24check_property (const char *output,
25 GParamSpec *pspec,
26 GValue *value)
27{
28 GValue default_value = G_VALUE_INIT;
29 char *v, *dv, *msg;
30
31 if (g_param_value_defaults (pspec, value))
32 return;
33
34 g_value_init (value: &default_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
35 g_param_value_set_default (pspec, value: &default_value);
36
37 v = g_strdup_value_contents (value);
38 dv = g_strdup_value_contents (value: &default_value);
39
40 msg = g_strdup_printf (format: "%s %s.%s: %s != %s\n",
41 output,
42 g_type_name (type: pspec->owner_type),
43 pspec->name,
44 dv, v);
45 g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__,
46 G_STRFUNC, message: msg);
47 g_free (mem: msg);
48
49 g_free (mem: v);
50 g_free (mem: dv);
51 g_value_unset (value: &default_value);
52}
53
54static void
55test_type (gconstpointer data)
56{
57 GObjectClass *klass;
58 GObject *instance;
59 GParamSpec **pspecs;
60 guint n_pspecs, i;
61 GType type;
62 GdkDisplay *display;
63
64 type = * (GType *) data;
65
66 display = gdk_display_get_default ();
67
68 if (!G_TYPE_IS_CLASSED (type))
69 return;
70
71 if (G_TYPE_IS_ABSTRACT (type))
72 return;
73
74 if (!g_type_is_a (type, G_TYPE_OBJECT))
75 return;
76
77 /* These can't be freely constructed/destroyed */
78 if (g_type_is_a (type, GTK_TYPE_APPLICATION) ||
79 g_type_is_a (type, GDK_TYPE_PIXBUF_LOADER) ||
80 g_type_is_a (type, GTK_TYPE_LAYOUT_CHILD) ||
81#ifdef G_OS_UNIX
82 g_type_is_a (type, GTK_TYPE_PRINT_JOB) ||
83#endif
84 g_type_is_a (type, is_a_type: gdk_pixbuf_simple_anim_iter_get_type ()) ||
85 g_str_equal (v1: g_type_name (type), v2: "GdkX11DeviceManagerXI2") ||
86 g_str_equal (v1: g_type_name (type), v2: "GdkX11DeviceManagerCore") ||
87 g_str_equal (v1: g_type_name (type), v2: "GdkX11Display") ||
88 g_str_equal (v1: g_type_name (type), v2: "GdkX11Screen") ||
89 g_str_equal (v1: g_type_name (type), v2: "GdkX11GLContext"))
90 return;
91
92 /* This throws a critical when the connection is dropped */
93 if (g_type_is_a (type, GTK_TYPE_APP_CHOOSER_DIALOG))
94 return;
95
96 /* These leak their GDBusConnections */
97 if (g_type_is_a (type, GTK_TYPE_FILE_CHOOSER_DIALOG) ||
98 g_type_is_a (type, GTK_TYPE_FILE_CHOOSER_WIDGET) ||
99 g_str_equal (v1: g_type_name (type), v2: "GtkPlacesSidebar"))
100 return;
101
102 if (g_type_is_a (type, GTK_TYPE_SHORTCUT_TRIGGER) ||
103 g_type_is_a (type, GTK_TYPE_SHORTCUT_ACTION))
104 return;
105
106 klass = g_type_class_ref (type);
107
108 if (g_type_is_a (type, GTK_TYPE_SETTINGS))
109 instance = G_OBJECT (g_object_ref (gtk_settings_get_default ()));
110 else if (g_type_is_a (type, GDK_TYPE_SURFACE))
111 {
112 instance = G_OBJECT (g_object_ref (gdk_surface_new_toplevel (display)));
113 }
114 else if (g_type_is_a (type, GTK_TYPE_FILTER_LIST_MODEL) ||
115 g_type_is_a (type, GTK_TYPE_NO_SELECTION) ||
116 g_type_is_a (type, GTK_TYPE_SINGLE_SELECTION) ||
117 g_type_is_a (type, GTK_TYPE_MULTI_SELECTION))
118 {
119 GListStore *list_store = g_list_store_new (G_TYPE_OBJECT);
120 instance = g_object_new (object_type: type,
121 first_property_name: "model", list_store,
122 NULL);
123 g_object_unref (object: list_store);
124 }
125 else if (g_type_is_a (type, GSK_TYPE_GL_SHADER))
126 {
127 GBytes *bytes = g_bytes_new_static (data: "", size: 0);
128 instance = g_object_new (object_type: type, first_property_name: "source", bytes, NULL);
129 g_bytes_unref (bytes);
130 }
131 else if (g_type_is_a (type, GDK_TYPE_CLIPBOARD) ||
132 g_str_equal (v1: g_type_name (type), v2: "GdkX11Cursor"))
133 instance = g_object_new (object_type: type, first_property_name: "display", display, NULL);
134 else
135 instance = g_object_new (object_type: type, NULL);
136
137 if (g_type_is_a (type, G_TYPE_INITIALLY_UNOWNED))
138 g_object_ref_sink (instance);
139
140 pspecs = g_object_class_list_properties (oclass: klass, n_properties: &n_pspecs);
141 for (i = 0; i < n_pspecs; ++i)
142 {
143 GParamSpec *pspec = pspecs[i];
144 GValue value = G_VALUE_INIT;
145 gboolean check = TRUE;
146
147 if (pspec->owner_type != type)
148 continue;
149
150 if ((pspec->flags & G_PARAM_READABLE) == 0)
151 continue;
152
153 /* This is set via class_init, and we have a11y tests to verify it */
154 if (g_type_is_a (type, GTK_TYPE_ACCESSIBLE) &&
155 strcmp (s1: pspec->name, s2: "accessible-role") == 0)
156 check = FALSE;
157
158 /* This is set via construct property */
159 if (g_type_is_a (type, GTK_TYPE_BUILDER) &&
160 strcmp (s1: pspec->name, s2: "scope") == 0)
161 check = FALSE;
162
163 if (g_type_is_a (type, GDK_TYPE_CLIPBOARD) &&
164 strcmp (s1: pspec->name, s2: "display") == 0)
165 check = FALSE;
166
167 /* These are set in init() */
168 if ((g_type_is_a (type, GDK_TYPE_CLIPBOARD) ||
169 g_type_is_a (type, GDK_TYPE_CONTENT_PROVIDER) ||
170 g_type_is_a (type, GTK_TYPE_DROP_TARGET)) &&
171 strcmp (s1: pspec->name, s2: "formats") == 0)
172 check = FALSE;
173
174 if (g_type_is_a (type, GDK_TYPE_CONTENT_PROVIDER) &&
175 strcmp (s1: pspec->name, s2: "storable-formats") == 0)
176 check = FALSE;
177
178 /* set in the constructor */
179 if (g_type_is_a (type, GSK_TYPE_GL_SHADER) &&
180 strcmp (s1: pspec->name, s2: "source") == 0)
181 check = FALSE;
182
183 /* This one has a special-purpose default value */
184 if (g_type_is_a (type, GTK_TYPE_DIALOG) &&
185 (strcmp (s1: pspec->name, s2: "use-header-bar") == 0))
186 check = FALSE;
187
188 if (g_type_is_a (type, GTK_TYPE_ASSISTANT) &&
189 (strcmp (s1: pspec->name, s2: "use-header-bar") == 0 ||
190 strcmp (s1: pspec->name, s2: "pages") == 0)) /* pages always gets a non-NULL value */
191 check = FALSE;
192
193 if (g_type_is_a (type, GTK_TYPE_STACK) &&
194 (strcmp (s1: pspec->name, s2: "pages") == 0)) /* pages always gets a non-NULL value */
195 check = FALSE;
196
197 if (g_type_is_a (type, GTK_TYPE_NOTEBOOK) &&
198 (strcmp (s1: pspec->name, s2: "pages") == 0)) /* pages always gets a non-NULL value */
199 check = FALSE;
200
201 if (g_type_is_a (type, GTK_TYPE_COMBO_BOX) &&
202 (strcmp (s1: pspec->name, s2: "child") == 0))
203 check = FALSE;
204
205 if (g_type_is_a (type, GTK_TYPE_POPOVER) &&
206 (strcmp (s1: pspec->name, s2: "pointing-to") == 0))
207 check = FALSE;
208
209 if (g_type_is_a (type, GDK_TYPE_DISPLAY_MANAGER) &&
210 (strcmp (s1: pspec->name, s2: "default-display") == 0))
211 check = FALSE;
212
213 if (g_type_is_a (type, GDK_TYPE_MONITOR) &&
214 (strcmp (s1: pspec->name, s2: "geometry") == 0))
215 check = FALSE;
216
217 if (g_type_is_a (type, GTK_TYPE_ABOUT_DIALOG) &&
218 (strcmp (s1: pspec->name, s2: "program-name") == 0))
219 check = FALSE;
220
221 /* These are set to the current date */
222 if (g_type_is_a (type, GTK_TYPE_CALENDAR) &&
223 (strcmp (s1: pspec->name, s2: "year") == 0 ||
224 strcmp (s1: pspec->name, s2: "month") == 0 ||
225 strcmp (s1: pspec->name, s2: "day") == 0))
226 check = FALSE;
227
228 if (g_type_is_a (type, GTK_TYPE_CELL_AREA_CONTEXT) &&
229 (strcmp (s1: pspec->name, s2: "minimum-width") == 0 ||
230 strcmp (s1: pspec->name, s2: "minimum-height") == 0 ||
231 strcmp (s1: pspec->name, s2: "natural-width") == 0 ||
232 strcmp (s1: pspec->name, s2: "natural-height") == 0))
233 check = FALSE;
234
235 if (g_type_is_a (type, GTK_TYPE_CELL_RENDERER_TEXT) &&
236 (strcmp (s1: pspec->name, s2: "background-gdk") == 0 ||
237 strcmp (s1: pspec->name, s2: "foreground-gdk") == 0 ||
238 strcmp (s1: pspec->name, s2: "background-rgba") == 0 ||
239 strcmp (s1: pspec->name, s2: "foreground-rgba") == 0 ||
240 strcmp (s1: pspec->name, s2: "font") == 0 ||
241 strcmp (s1: pspec->name, s2: "font-desc") == 0))
242 check = FALSE;
243
244 if (g_type_is_a (type, GTK_TYPE_CELL_VIEW) &&
245 (strcmp (s1: pspec->name, s2: "background-gdk") == 0 ||
246 strcmp (s1: pspec->name, s2: "foreground-gdk") == 0 ||
247 strcmp (s1: pspec->name, s2: "foreground-rgba") == 0 ||
248 strcmp (s1: pspec->name, s2: "background-rgba") == 0 ||
249 strcmp (s1: pspec->name, s2: "cell-area") == 0 ||
250 strcmp (s1: pspec->name, s2: "cell-area-context") == 0))
251 check = FALSE;
252
253 if (g_type_is_a (type, GTK_TYPE_COLOR_BUTTON) &&
254 (strcmp (s1: pspec->name, s2: "color") == 0 ||
255 strcmp (s1: pspec->name, s2: "rgba") == 0))
256 check = FALSE;
257
258 if (g_type_is_a (type, GTK_TYPE_COLUMN_VIEW) &&
259 (strcmp (s1: pspec->name, s2: "columns") == 0 ||
260 strcmp (s1: pspec->name, s2: "sorter") == 0))
261 check = FALSE;
262
263G_GNUC_BEGIN_IGNORE_DEPRECATIONS
264
265 if (g_type_is_a (type, GTK_TYPE_COMBO_BOX) &&
266 (strcmp (s1: pspec->name, s2: "cell-area") == 0 ||
267 strcmp (s1: pspec->name, s2: "cell-area-context") == 0))
268 check = FALSE;
269
270G_GNUC_END_IGNORE_DEPRECATIONS
271
272 /* Default invisible char is determined at runtime,
273 * and buffer gets created on-demand
274 */
275 if (g_type_is_a (type, GTK_TYPE_ENTRY) &&
276 (strcmp (s1: pspec->name, s2: "invisible-char") == 0 ||
277 strcmp (s1: pspec->name, s2: "buffer") == 0))
278 check = FALSE;
279
280 if (g_type_is_a (type, GTK_TYPE_TEXT) &&
281 (strcmp (s1: pspec->name, s2: "invisible-char") == 0 ||
282 strcmp (s1: pspec->name, s2: "buffer") == 0))
283 check = FALSE;
284
285G_GNUC_BEGIN_IGNORE_DEPRECATIONS
286
287 if (g_type_is_a (type, GTK_TYPE_ENTRY_COMPLETION) &&
288 (strcmp (s1: pspec->name, s2: "cell-area") == 0 ||
289 strcmp (s1: pspec->name, s2: "cell-area-context") == 0))
290 check = FALSE;
291
292G_GNUC_END_IGNORE_DEPRECATIONS
293
294 if ((g_type_is_a (type, GTK_TYPE_FILTER_LIST_MODEL) ||
295 g_type_is_a (type, GTK_TYPE_NO_SELECTION) ||
296 g_type_is_a (type, GTK_TYPE_SINGLE_SELECTION) ||
297 g_type_is_a (type, GTK_TYPE_MULTI_SELECTION)) &&
298 strcmp (s1: pspec->name, s2: "model") == 0)
299 check = FALSE;
300
301 /* This is set in init() */
302 if (g_type_is_a (type, GTK_TYPE_FONT_CHOOSER_WIDGET) &&
303 strcmp (s1: pspec->name, s2: "tweak-action") == 0)
304 check = FALSE;
305
306G_GNUC_BEGIN_IGNORE_DEPRECATIONS
307
308 if (g_type_is_a (type, GTK_TYPE_ICON_VIEW) &&
309 (strcmp (s1: pspec->name, s2: "cell-area") == 0 ||
310 strcmp (s1: pspec->name, s2: "cell-area-context") == 0))
311 check = FALSE;
312
313G_GNUC_END_IGNORE_DEPRECATIONS
314
315 if (g_type_is_a (type, GTK_TYPE_MESSAGE_DIALOG) &&
316 (strcmp (s1: pspec->name, s2: "image") == 0 ||
317 strcmp (s1: pspec->name, s2: "message-area") == 0))
318 check = FALSE;
319
320 if (g_type_is_a (type, GTK_TYPE_PANED) &&
321 strcmp (s1: pspec->name, s2: "max-position") == 0)
322 check = FALSE;
323
324 if (g_type_is_a (type, GTK_TYPE_PRINT_OPERATION) &&
325 strcmp (s1: pspec->name, s2: "job-name") == 0)
326 check = FALSE;
327
328#ifdef G_OS_UNIX
329 if (g_type_is_a (type, GTK_TYPE_PRINT_UNIX_DIALOG) &&
330 (strcmp (s1: pspec->name, s2: "page-setup") == 0 ||
331 strcmp (s1: pspec->name, s2: "print-settings") == 0))
332 check = FALSE;
333#endif
334
335 if (g_type_is_a (type, GTK_TYPE_PROGRESS_BAR) &&
336 strcmp (s1: pspec->name, s2: "adjustment") == 0)
337 check = FALSE;
338
339 /* filename value depends on $HOME */
340 if (g_type_is_a (type, GTK_TYPE_RECENT_MANAGER) &&
341 (strcmp (s1: pspec->name, s2: "filename") == 0 ||
342 strcmp (s1: pspec->name, s2: "size") == 0))
343 check = FALSE;
344
345 if (g_type_is_a (type, GTK_TYPE_SCALE_BUTTON) &&
346 strcmp (s1: pspec->name, s2: "adjustment") == 0)
347 check = FALSE;
348
349 if (g_type_is_a (type, GTK_TYPE_SCROLLED_WINDOW) &&
350 (strcmp (s1: pspec->name, s2: "hadjustment") == 0 ||
351 strcmp (s1: pspec->name, s2: "vadjustment") == 0))
352 check = FALSE;
353
354 if (g_type_is_a (type, GTK_TYPE_SETTINGS))
355 check = FALSE;
356
357 if (g_type_is_a (type, GTK_TYPE_SHORTCUT) &&
358 (strcmp (s1: pspec->name, s2: "action") == 0 ||
359 strcmp (s1: pspec->name, s2: "trigger") == 0))
360 check = FALSE;
361
362 if (g_type_is_a (type, GTK_TYPE_SPIN_BUTTON) &&
363 (strcmp (s1: pspec->name, s2: "adjustment") == 0))
364 check = FALSE;
365
366 if (g_type_is_a (type, GTK_TYPE_STYLE_CONTEXT) &&
367 strcmp (s1: pspec->name, s2: "display") == 0)
368 check = FALSE;
369
370 if (g_type_is_a (type, GTK_TYPE_TEXT_BUFFER) &&
371 (strcmp (s1: pspec->name, s2: "tag-table") == 0 ||
372 strcmp (s1: pspec->name, s2: "copy-target-list") == 0 ||
373 strcmp (s1: pspec->name, s2: "paste-target-list") == 0))
374 check = FALSE;
375
376 /* language depends on the current locale */
377 if (g_type_is_a (type, GTK_TYPE_TEXT_TAG) &&
378 (strcmp (s1: pspec->name, s2: "background-gdk") == 0 ||
379 strcmp (s1: pspec->name, s2: "foreground-gdk") == 0 ||
380 strcmp (s1: pspec->name, s2: "language") == 0 ||
381 strcmp (s1: pspec->name, s2: "font") == 0 ||
382 strcmp (s1: pspec->name, s2: "font-desc") == 0))
383 check = FALSE;
384
385 if (g_type_is_a (type, GTK_TYPE_TEXT_VIEW) &&
386 strcmp (s1: pspec->name, s2: "buffer") == 0)
387 check = FALSE;
388
389 if (g_type_is_a (type, GTK_TYPE_TREE_VIEW) &&
390 (strcmp (s1: pspec->name, s2: "hadjustment") == 0 ||
391 strcmp (s1: pspec->name, s2: "vadjustment") == 0))
392 check = FALSE;
393
394 if (g_type_is_a (type, GTK_TYPE_TREE_VIEW_COLUMN) &&
395 (strcmp (s1: pspec->name, s2: "cell-area") == 0 ||
396 strcmp (s1: pspec->name, s2: "cell-area-context") == 0))
397 check = FALSE;
398
399 if (g_type_is_a (type, GTK_TYPE_VIEWPORT) &&
400 (strcmp (s1: pspec->name, s2: "hadjustment") == 0 ||
401 strcmp (s1: pspec->name, s2: "vadjustment") == 0))
402 check = FALSE;
403
404 if (g_type_is_a (type, GTK_TYPE_WIDGET) &&
405 (strcmp (s1: pspec->name, s2: "name") == 0 ||
406 strcmp (s1: pspec->name, s2: "display") == 0 ||
407 strcmp (s1: pspec->name, s2: "style") == 0))
408 check = FALSE;
409
410 /* resize-grip-visible is determined at runtime */
411 if (g_type_is_a (type, GTK_TYPE_WINDOW) &&
412 strcmp (s1: pspec->name, s2: "resize-grip-visible") == 0)
413 check = FALSE;
414
415 /* show-desktop depends on desktop environment */
416 if (g_str_equal (v1: g_type_name (type), v2: "GtkPlacesSidebar") &&
417 strcmp (s1: pspec->name, s2: "show-desktop") == 0)
418 check = FALSE;
419
420 /* GtkRange constructs an adjustment on its own if NULL is set and
421 * the property is a CONSTRUCT one, so the returned value is never NULL. */
422 if (g_type_is_a (type, GTK_TYPE_RANGE) &&
423 strcmp (s1: pspec->name, s2: "adjustment") == 0)
424 check = FALSE;
425
426 /* ... and GtkScrollbar wraps that property. */
427 if (g_type_is_a (type, GTK_TYPE_SCROLLBAR) &&
428 strcmp (s1: pspec->name, s2: "adjustment") == 0)
429 check = FALSE;
430
431 if (g_type_is_a (type, GTK_TYPE_DROP_DOWN) &&
432 strcmp (s1: pspec->name, s2: "factory") == 0)
433 check = FALSE;
434
435 if (g_type_is_a (type, GTK_TYPE_BOOKMARK_LIST) &&
436 (strcmp (s1: pspec->name, s2: "filename") == 0 ||
437 strcmp (s1: pspec->name, s2: "loading") == 0))
438 check = FALSE;
439
440 /* All the icontheme properties depend on the environment */
441 if (g_type_is_a (type, GTK_TYPE_ICON_THEME))
442 check = FALSE;
443
444 if (g_test_verbose ())
445 {
446 g_print (format: "Property %s:%s%s\n",
447 g_type_name (type: pspec->owner_type),
448 pspec->name,
449 check ? "" : " (no check)");
450 }
451
452 g_value_init (value: &value, G_PARAM_SPEC_VALUE_TYPE (pspec));
453 g_object_get_property (object: instance, property_name: pspec->name, value: &value);
454 if (check)
455 check_property (output: "Property", pspec, value: &value);
456 g_value_unset (value: &value);
457 }
458 g_free (mem: pspecs);
459
460 if (g_type_is_a (type, GDK_TYPE_SURFACE))
461 gdk_surface_destroy (GDK_SURFACE (instance));
462 else
463 g_object_unref (object: instance);
464
465 g_type_class_unref (g_class: klass);
466}
467
468static gboolean
469dbind_warning_handler (const char *log_domain,
470 GLogLevelFlags log_level,
471 const char *message,
472 gpointer user_data)
473{
474 if (strcmp (s1: log_domain, s2: "dbind") == 0 &&
475 log_level == (G_LOG_LEVEL_WARNING|G_LOG_FLAG_FATAL))
476 return FALSE;
477
478 return TRUE;
479}
480
481int
482main (int argc, char **argv)
483{
484 const GType *otypes;
485 guint i;
486 const char *display, *x_r_d;
487
488 /* These must be set before gtk_test_init */
489 g_setenv (variable: "GIO_USE_VFS", value: "local", TRUE);
490 g_setenv (variable: "GSETTINGS_BACKEND", value: "memory", TRUE);
491 g_setenv (variable: "G_ENABLE_DIAGNOSTIC", value: "0", TRUE);
492
493 /* g_test_dbus_up() helpfully clears these, so we have to re-set it */
494 display = g_getenv (variable: "DISPLAY");
495 x_r_d = g_getenv (variable: "XDG_RUNTIME_DIR");
496
497 if (display)
498 g_setenv (variable: "DISPLAY", value: display, TRUE);
499 if (x_r_d)
500 g_setenv (variable: "XDG_RUNTIME_DIR", value: x_r_d, TRUE);
501
502 g_test_log_set_fatal_handler (log_func: dbind_warning_handler, NULL);
503
504 gtk_test_init (argcp: &argc, argvp: &argv);
505 gtk_test_register_all_types();
506
507 otypes = gtk_test_list_all_types (NULL);
508 for (i = 0; otypes[i]; i++)
509 {
510 char *testname;
511
512 if (otypes[i] == GTK_TYPE_FILE_CHOOSER_NATIVE)
513 continue;
514
515 testname = g_strdup_printf (format: "/Default Values/%s",
516 g_type_name (type: otypes[i]));
517 g_test_add_data_func (testpath: testname,
518 test_data: &otypes[i],
519 test_func: test_type);
520 g_free (mem: testname);
521 }
522
523 return g_test_run();
524}
525

source code of gtk/testsuite/gtk/defaultvalue.c