1 | /* Gtk+ testing utilities |
2 | * Copyright (C) 2007 Imendio AB |
3 | * Authors: 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, see <http://www.gnu.org/licenses/>. |
17 | */ |
18 | |
19 | |
20 | #include "config.h" |
21 | |
22 | #include "gtkspinbutton.h" |
23 | #include "gtkmain.h" |
24 | #include "gtkbox.h" |
25 | #include "gtklabel.h" |
26 | #include "gtkbutton.h" |
27 | #include "gtktextview.h" |
28 | #include "gtkrange.h" |
29 | |
30 | #include <locale.h> |
31 | #include <string.h> |
32 | #include <math.h> |
33 | |
34 | /* This is a hack. |
35 | * We want to include the same headers as gtktypefuncs.c but we are not |
36 | * allowed to include gtkx.h directly during GTK compilation. |
37 | * So.... |
38 | */ |
39 | #undef GTK_COMPILATION |
40 | #include <gtk/gtk.h> |
41 | #define GTK_COMPILATION |
42 | |
43 | #include <gsk/gl/gskglrenderer.h> |
44 | |
45 | #ifdef GDK_WINDOWING_BROADWAY |
46 | #include <gsk/broadway/gskbroadwayrenderer.h> |
47 | #endif |
48 | |
49 | #ifdef GDK_RENDERING_VULKAN |
50 | #include <gsk/vulkan/gskvulkanrenderer.h> |
51 | #endif |
52 | |
53 | #ifdef GDK_WINDOWING_X11 |
54 | #include <gdk/x11/gdkx.h> |
55 | #endif |
56 | |
57 | /** |
58 | * gtk_test_init: |
59 | * @argcp: Address of the `argc` parameter of the |
60 | * main() function. Changed if any arguments were handled. |
61 | * @argvp: (inout) (array length=argcp): Address of the `argv` |
62 | * parameter of main(). Any parameters understood by g_test_init() |
63 | * or gtk_init() are stripped before return. |
64 | * @...: currently unused |
65 | * |
66 | * This function is used to initialize a GTK test program. |
67 | * |
68 | * It will in turn call g_test_init() and gtk_init() to properly |
69 | * initialize the testing framework and graphical toolkit. It’ll |
70 | * also set the program’s locale to “C”. This is done to make test |
71 | * program environments as deterministic as possible. |
72 | * |
73 | * Like gtk_init() and g_test_init(), any known arguments will be |
74 | * processed and stripped from @argc and @argv. |
75 | */ |
76 | void |
77 | gtk_test_init (int *argcp, |
78 | char ***argvp, |
79 | ...) |
80 | { |
81 | /* g_test_init is defined as a macro that aborts if assertions |
82 | * are disabled. We don't want that, so we call the function. |
83 | */ |
84 | (g_test_init) (argc: argcp, argv: argvp, NULL); |
85 | gtk_disable_setlocale(); |
86 | setlocale (LC_ALL, locale: "en_US.UTF-8" ); |
87 | |
88 | gtk_init (); |
89 | } |
90 | |
91 | static gboolean |
92 | quit_main_loop_callback (GtkWidget *widget, |
93 | GdkFrameClock *frame_clock, |
94 | gpointer user_data) |
95 | { |
96 | gboolean *done = user_data; |
97 | |
98 | *done = TRUE; |
99 | |
100 | g_main_context_wakeup (NULL); |
101 | |
102 | return G_SOURCE_REMOVE; |
103 | } |
104 | |
105 | /** |
106 | * gtk_test_widget_wait_for_draw: |
107 | * @widget: the widget to wait for |
108 | * |
109 | * Enters the main loop and waits for @widget to be “drawn”. |
110 | * |
111 | * In this context that means it waits for the frame clock of |
112 | * @widget to have run a full styling, layout and drawing cycle. |
113 | * |
114 | * This function is intended to be used for syncing with actions that |
115 | * depend on @widget relayouting or on interaction with the display |
116 | * server. |
117 | */ |
118 | void |
119 | gtk_test_widget_wait_for_draw (GtkWidget *widget) |
120 | { |
121 | g_return_if_fail (GTK_IS_WIDGET (widget)); |
122 | gboolean done = FALSE; |
123 | |
124 | /* We can do this here because the whole tick procedure does not |
125 | * reenter the main loop. Otherwise we'd need to manually get the |
126 | * frame clock and connect to the after-paint signal. |
127 | */ |
128 | gtk_widget_add_tick_callback (widget, |
129 | callback: quit_main_loop_callback, |
130 | user_data: &done, |
131 | NULL); |
132 | |
133 | while (!done) |
134 | g_main_context_iteration (NULL, TRUE); |
135 | } |
136 | |
137 | static GType *all_registered_types = NULL; |
138 | static guint n_all_registered_types = 0; |
139 | |
140 | /** |
141 | * gtk_test_list_all_types: |
142 | * @n_types: location to store number of types |
143 | * |
144 | * Return the type ids that have been registered after |
145 | * calling gtk_test_register_all_types(). |
146 | * |
147 | * Returns: (array length=n_types zero-terminated=1) (transfer none): |
148 | * 0-terminated array of type ids |
149 | */ |
150 | const GType* |
151 | gtk_test_list_all_types (guint *n_types) |
152 | { |
153 | if (n_types) |
154 | *n_types = n_all_registered_types; |
155 | return all_registered_types; |
156 | } |
157 | |
158 | /** |
159 | * gtk_test_register_all_types: |
160 | * |
161 | * Force registration of all core GTK object types. |
162 | * |
163 | * This allowes to refer to any of those object types via |
164 | * g_type_from_name() after calling this function. |
165 | **/ |
166 | void |
167 | gtk_test_register_all_types (void) |
168 | { |
169 | if (!all_registered_types) |
170 | { |
171 | const guint max_gtk_types = 999; |
172 | GType *tp; |
173 | all_registered_types = g_new0 (GType, max_gtk_types); |
174 | tp = all_registered_types; |
175 | #include <gtktypefuncs.inc> |
176 | n_all_registered_types = tp - all_registered_types; |
177 | g_assert (n_all_registered_types + 1 < max_gtk_types); |
178 | *tp = 0; |
179 | } |
180 | } |
181 | |