1 /*
2 * ghbcompat.h
3 * Copyright (C) John Stebbins 2008-2021 <stebbins@stebbins>
4 *
5 * ghbcompat.h is free software.
6 *
7 * You may redistribute it and/or modify it under the terms of the
8 * GNU General Public License version 2, as published by the Free Software
9 * Foundation.
10 *
11 * ghbcompat.h is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with callbacks.h. If not, write to:
18 * The Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #if !defined(_GHB_COMPAT_H_)
24 #define _GHB_COMPAT_H_
25
26 #include <gtk/gtk.h>
27 #include <gdk/gdk.h>
28 #include <string.h>
29
30 #if defined(_WIN32)
31 #define GHB_UNSAFE_FILENAME_CHARS "/:<>\"\\|?*"
32 #else
33 #define GHB_UNSAFE_FILENAME_CHARS "/"
34 #endif
35
36 #if GTK_CHECK_VERSION(3, 90, 0)
37 #define GHB_ICON_SIZE_BUTTON GTK_ICON_SIZE_NORMAL
38 #else
39 #define GHB_ICON_SIZE_BUTTON GTK_ICON_SIZE_BUTTON
40 #endif
41
42 #if !GTK_CHECK_VERSION(3, 10, 0)
43 #define gtk_image_set_from_icon_name gtk_image_set_from_stock
44 #define GHB_PLAY_ICON "gtk-media-play"
45 #define GHB_PAUSE_ICON "gtk-media-pause"
46 #else
47 #define GHB_PLAY_ICON "media-playback-start"
48 #define GHB_PAUSE_ICON "media-playback-pause"
49 #endif
50
51 #if !GTK_CHECK_VERSION(3, 10, 0)
52 #define GHB_STOCK_OPEN GTK_STOCK_OPEN
53 #define GHB_STOCK_CANCEL GTK_STOCK_CANCEL
54 #define GHB_STOCK_SAVE GTK_STOCK_SAVE
55 #else
56 #define GHB_STOCK_OPEN "_Open"
57 #define GHB_STOCK_CANCEL "_Cancel"
58 #define GHB_STOCK_SAVE "_Save"
59 #endif
60
ghb_widget_get_preferred_width(GtkWidget * widget,gint * min_width,gint * natural_width)61 static inline void ghb_widget_get_preferred_width(
62 GtkWidget *widget, gint *min_width, gint * natural_width)
63 {
64 #if GTK_CHECK_VERSION(3, 90, 0)
65 GtkRequisition min_req, nat_req;
66
67 gtk_widget_get_preferred_size(widget, &min_req, &nat_req);
68 if (min_width != NULL)
69 {
70 *min_width = min_req.width;
71 }
72 if (natural_width != NULL)
73 {
74 *natural_width = nat_req.width;
75 }
76 #else
77 gtk_widget_get_preferred_width(widget, min_width, natural_width);
78 #endif
79 }
80
ghb_widget_get_preferred_height(GtkWidget * widget,gint * min_height,gint * natural_height)81 static inline void ghb_widget_get_preferred_height(
82 GtkWidget *widget, gint *min_height, gint * natural_height)
83 {
84 #if GTK_CHECK_VERSION(3, 90, 0)
85 GtkRequisition min_req, nat_req;
86
87 gtk_widget_get_preferred_size(widget, &min_req, &nat_req);
88 if (min_height != NULL)
89 {
90 *min_height = min_req.height;
91 }
92 if (natural_height != NULL)
93 {
94 *natural_height = nat_req.height;
95 }
96 #else
97 gtk_widget_get_preferred_height(widget, min_height, natural_height);
98 #endif
99 }
100
ghb_button_set_icon_name(GtkButton * button,const char * name)101 static inline void ghb_button_set_icon_name(GtkButton *button,
102 const char * name)
103 {
104 #if GTK_CHECK_VERSION(3, 90, 0)
105 gtk_button_set_icon_name(button, name);
106 #else
107 GtkImage *image;
108
109 image = GTK_IMAGE(gtk_image_new_from_icon_name(name, GTK_ICON_SIZE_BUTTON));
110 gtk_button_set_image(button, GTK_WIDGET(image));
111 #endif
112 }
113
ghb_get_expand_fill(GtkBox * box,GtkWidget * child,gboolean * expand,gboolean * fill)114 static inline void ghb_get_expand_fill(GtkBox * box, GtkWidget * child,
115 gboolean *expand, gboolean *fill)
116 {
117 if (gtk_orientable_get_orientation(GTK_ORIENTABLE(box)) ==
118 GTK_ORIENTATION_HORIZONTAL)
119 {
120 *expand = gtk_widget_get_hexpand(child);
121 *fill = gtk_widget_get_halign(child) == GTK_ALIGN_FILL;
122 }
123 else
124 {
125 *expand = gtk_widget_get_vexpand(child);
126 *fill = gtk_widget_get_valign(child) == GTK_ALIGN_FILL;
127 }
128 }
129
ghb_box_append_child(GtkBox * box,GtkWidget * child)130 static inline void ghb_box_append_child(GtkBox * box, GtkWidget * child)
131 {
132 #if GTK_CHECK_VERSION(3, 90, 0)
133 GtkWidget * sibling = NULL;
134
135 sibling = gtk_widget_get_last_child(GTK_WIDGET(box));
136 gtk_box_insert_child_after(box, child, sibling);
137 #else
138 gboolean expand, fill;
139
140 ghb_get_expand_fill(box, child, &expand, &fill);
141 gtk_box_pack_start(box, child, expand, fill, 0);
142 #endif
143 }
144
ghb_css_provider_load_from_data(GtkCssProvider * provider,const gchar * data,gssize length)145 static inline void ghb_css_provider_load_from_data(GtkCssProvider *provider,
146 const gchar *data,
147 gssize length)
148 {
149 #if GTK_CHECK_VERSION(3, 90, 0)
150 gtk_css_provider_load_from_data(provider, data, length);
151 #else
152 gtk_css_provider_load_from_data(provider, data, length, NULL);
153 #endif
154 }
155
ghb_event_get_event_type(const GdkEvent * event)156 static inline GdkEventType ghb_event_get_event_type(const GdkEvent *event)
157 {
158 #if GTK_CHECK_VERSION(3, 10, 0)
159 return gdk_event_get_event_type(event);
160 #else
161 return event->type;
162 #endif
163 }
164
ghb_event_get_keyval(const GdkEvent * event,guint * keyval)165 static inline gboolean ghb_event_get_keyval(const GdkEvent *event,
166 guint *keyval)
167 {
168 #if GTK_CHECK_VERSION(3, 2, 0)
169 return gdk_event_get_keyval(event, keyval);
170 #else
171 *keyval = ((GdkEventKey*)event)->keyval;
172 return TRUE;
173 #endif
174 }
175
ghb_event_get_button(const GdkEvent * event,guint * button)176 static inline gboolean ghb_event_get_button(const GdkEvent *event,
177 guint *button)
178 {
179 #if GTK_CHECK_VERSION(3, 2, 0)
180 return gdk_event_get_button(event, button);
181 #else
182 *keyval = ((GdkEventButton*)event)->button;
183 return TRUE;
184 #endif
185 }
186
ghb_widget_get_font(GtkWidget * widget)187 static inline PangoFontDescription* ghb_widget_get_font(GtkWidget *widget)
188 {
189 PangoFontDescription *font = NULL;
190
191 #if GTK_CHECK_VERSION(3, 0, 0)
192 GtkStyleContext *style;
193
194 style = gtk_widget_get_style_context(widget);
195
196 #if GTK_CHECK_VERSION(3, 8, 0)
197 gtk_style_context_get(style, GTK_STATE_FLAG_NORMAL,
198 "font", &font, NULL);
199 #else
200 font = gtk_style_context_get_font(style, GTK_STATE_FLAG_NORMAL);
201 #endif
202 #endif
203
204 return font;
205 }
206
207 #if GTK_CHECK_VERSION(3, 90, 0)
208 typedef GdkSurface GhbSurface;
209 typedef GdkSurfaceHints GhbSurfaceHints;
210
ghb_widget_get_surface(GtkWidget * widget)211 static inline GhbSurface * ghb_widget_get_surface(GtkWidget * widget)
212 {
213 return gtk_widget_get_surface(widget);
214 }
215
216 static inline GdkMonitor *
ghb_display_get_monitor_at_surface(GdkDisplay * display,GhbSurface * surface)217 ghb_display_get_monitor_at_surface(GdkDisplay * display, GhbSurface * surface)
218 {
219 return gdk_display_get_monitor_at_surface(display, surface);
220 }
221
222 static inline void
ghb_surface_set_geometry_hints(GhbSurface * surface,const GdkGeometry * geometry,GhbSurfaceHints geom_mask)223 ghb_surface_set_geometry_hints(GhbSurface * surface,
224 const GdkGeometry * geometry,
225 GhbSurfaceHints geom_mask)
226 {
227 gdk_surface_set_geometry_hints(surface, geometry, geom_mask);
228 }
229 #else
230 typedef GdkWindow GhbSurface;
231 typedef GdkWindowHints GhbSurfaceHints;
232
ghb_widget_get_surface(GtkWidget * widget)233 static inline GhbSurface * ghb_widget_get_surface(GtkWidget * widget)
234 {
235 return gtk_widget_get_window(widget);
236 }
237
238 static inline GdkMonitor *
ghb_display_get_monitor_at_surface(GdkDisplay * display,GhbSurface * surface)239 ghb_display_get_monitor_at_surface(GdkDisplay * display, GhbSurface * surface)
240 {
241 return gdk_display_get_monitor_at_window(display, surface);
242 }
243
244 static inline void
ghb_surface_set_geometry_hints(GhbSurface * surface,const GdkGeometry * geometry,GhbSurfaceHints geom_mask)245 ghb_surface_set_geometry_hints(GhbSurface * surface,
246 const GdkGeometry * geometry,
247 GhbSurfaceHints geom_mask)
248 {
249 gdk_window_set_geometry_hints(surface, geometry, geom_mask);
250 }
251 #endif
252
ghb_monitor_get_size(GtkWidget * widget,gint * w,gint * h)253 static inline void ghb_monitor_get_size(GtkWidget *widget, gint *w, gint *h)
254 {
255 *w = *h = 0;
256
257 #if GTK_CHECK_VERSION(3, 22, 0)
258 GdkDisplay * display = gtk_widget_get_display(widget);
259 GhbSurface * surface = ghb_widget_get_surface(widget);
260 if (surface != NULL && display != NULL)
261 {
262 GdkMonitor * monitor;
263
264 monitor = ghb_display_get_monitor_at_surface(display, surface);
265 if (monitor != NULL)
266 {
267 GdkRectangle rect;
268
269 gdk_monitor_get_geometry(monitor, &rect);
270 *w = rect.width;
271 *h = rect.height;
272 }
273 }
274 #else
275 GdkScreen *ss;
276
277 ss = gdk_screen_get_default();
278 if (ss != NULL)
279 {
280 *w = gdk_screen_get_width(ss);
281 *h = gdk_screen_get_height(ss);
282 }
283 #endif
284 }
285
ghb_strv_contains(const char ** strv,const char * str)286 static inline gboolean ghb_strv_contains(const char ** strv, const char * str)
287 {
288 #if GLIB_CHECK_VERSION(2, 44, 0)
289 return g_strv_contains(strv, str);
290 #else
291 int ii;
292
293 if (strv == NULL)
294 {
295 return FALSE;
296 }
297 for (ii = 0; strv[ii] != NULL; ii++)
298 {
299 if (!strcmp(strv[ii], str))
300 {
301 return TRUE;
302 }
303 }
304 return FALSE;
305 #endif
306 }
307
308 #if GTK_CHECK_VERSION(3, 90, 0)
309
310 #define ghb_editable_get_text(e) gtk_editable_get_text(GTK_EDITABLE(e))
311 #define ghb_editable_set_text(e,t) gtk_editable_set_text(GTK_EDITABLE(e), (t))
312
313 #else
314
315 #define ghb_editable_get_text(e) gtk_entry_get_text(GTK_ENTRY(e))
316 #define ghb_editable_set_text(e,t) gtk_entry_set_text(GTK_ENTRY(e), (t))
317
318 #endif
319
320 #if GTK_CHECK_VERSION(3, 90, 0)
321 static inline void
ghb_image_set_from_icon_name(GtkImage * image,const gchar * name,GtkIconSize size)322 ghb_image_set_from_icon_name(GtkImage * image, const gchar * name,
323 GtkIconSize size)
324 {
325 gtk_image_set_from_icon_name(image, name);
326 gtk_image_set_icon_size(image, size);
327 }
328
329 static inline GtkWidget *
ghb_image_new_from_icon_name(const gchar * name,GtkIconSize size)330 ghb_image_new_from_icon_name(const gchar * name, GtkIconSize size)
331 {
332 GtkWidget * image;
333
334 image = gtk_image_new_from_icon_name(name);
335 gtk_image_set_icon_size(GTK_IMAGE(image), size);
336
337 return image;
338 }
339
340 static inline GtkWidget *
ghb_button_new_from_icon_name(const gchar * name)341 ghb_button_new_from_icon_name(const gchar * name)
342 {
343 return gtk_button_new_from_icon_name(name);
344 }
345
346 static inline GtkWidget *
ghb_scale_button_new(gdouble min,gdouble max,gdouble step,const gchar ** icons)347 ghb_scale_button_new(gdouble min, gdouble max, gdouble step,
348 const gchar ** icons)
349 {
350 return gtk_scale_button_new(min, max, step, icons);
351 }
352 #else
353 static inline void
ghb_image_set_from_icon_name(GtkImage * image,const gchar * name,GtkIconSize size)354 ghb_image_set_from_icon_name(GtkImage * image, const gchar * name,
355 GtkIconSize size)
356 {
357 gtk_image_set_from_icon_name(image, name, size);
358 }
359
360 static inline GtkWidget *
ghb_image_new_from_icon_name(const gchar * name,GtkIconSize size)361 ghb_image_new_from_icon_name(const gchar * name, GtkIconSize size)
362 {
363 return gtk_image_new_from_icon_name(name, size);
364 }
365
366 static inline GtkWidget *
ghb_button_new_from_icon_name(const gchar * name)367 ghb_button_new_from_icon_name(const gchar * name)
368 {
369 return gtk_button_new_from_icon_name(name, GHB_ICON_SIZE_BUTTON);
370 }
371
372 static inline GtkWidget *
ghb_scale_button_new(gdouble min,gdouble max,gdouble step,const gchar ** icons)373 ghb_scale_button_new(gdouble min, gdouble max, gdouble step,
374 const gchar ** icons)
375 {
376 return gtk_scale_button_new(GHB_ICON_SIZE_BUTTON, min, max, step, icons);
377 }
378 #endif
379
380 #if GTK_CHECK_VERSION(3, 90, 0)
ghb_drag_status(GdkDrop * ctx,GdkDragAction action,guint32 time)381 static inline void ghb_drag_status(GdkDrop * ctx, GdkDragAction action,
382 guint32 time)
383 {
384 gdk_drop_status(ctx, action);
385 }
386 #else
ghb_drag_status(GdkDragContext * ctx,GdkDragAction action,guint32 time)387 static inline void ghb_drag_status(GdkDragContext * ctx, GdkDragAction action,
388 guint32 time)
389 {
390 gdk_drag_status(ctx, action, time);
391 }
392 #endif
393
394 #if GTK_CHECK_VERSION(3, 90, 0)
ghb_entry_set_width_chars(GtkEntry * entry,gint n_chars)395 static inline void ghb_entry_set_width_chars(GtkEntry * entry, gint n_chars)
396 {
397 gtk_editable_set_width_chars(GTK_EDITABLE(entry), n_chars);
398 }
399 #else
ghb_entry_set_width_chars(GtkEntry * entry,gint n_chars)400 static inline void ghb_entry_set_width_chars(GtkEntry * entry, gint n_chars)
401 {
402 gtk_entry_set_width_chars(entry, n_chars);
403 }
404 #endif
405
406 #if GTK_CHECK_VERSION(3, 90, 0)
ghb_atom_string(const char * str)407 static inline GdkAtom ghb_atom_string(const char * str)
408 {
409 return g_intern_static_string(str);
410 }
411 #else
ghb_atom_string(const char * str)412 static inline GdkAtom ghb_atom_string(const char * str)
413 {
414 return gdk_atom_intern_static_string(str);
415 }
416 #endif
417
418 #endif // _GHB_COMPAT_H_
419