1 /*******************************************************************************
2 * Copyright (c) 2000, 2013 IBM Corporation and others. All rights reserved.
3 * The contents of this file are made available under the terms
4 * of the GNU Lesser General Public License (LGPL) Version 2.1 that
5 * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
6 * available at http://www.gnu.org/licenses/lgpl.html.  If the version
7 * of the LGPL at http://www.gnu.org is different to the version of
8 * the LGPL accompanying this distribution and there is any conflict
9 * between the two license versions, the terms of the LGPL accompanying
10 * this distribution shall govern.
11 *
12 * Contributors:
13 *     IBM Corporation - initial API and implementation
14 *******************************************************************************/
15 
16 #include "swt.h"
17 #include "os_structs.h"
18 #include "os_stats.h"
19 
20 #define OS_NATIVE(func) Java_org_eclipse_swt_internal_gtk_OS_##func
21 
22 #ifndef NO_GDK_1WINDOWING_1X11
OS_NATIVE(GDK_1WINDOWING_1X11)23 JNIEXPORT jboolean JNICALL OS_NATIVE(GDK_1WINDOWING_1X11)
24 	(JNIEnv *env, jclass that)
25 {
26 	jboolean rc;
27 	OS_NATIVE_ENTER(env, that, GDK_1WINDOWING_1X11_FUNC)
28 #ifdef GDK_WINDOWING_X11
29 	rc = (jboolean)1;
30 #else
31 	rc = (jboolean)0;
32 #endif
33 	OS_NATIVE_EXIT(env, that, GDK_1WINDOWING_1X11_FUNC)
34 	return rc;
35 }
36 #endif
37 
38 #ifndef NO_GDK_1WINDOWING_1WAYLAND
OS_NATIVE(GDK_1WINDOWING_1WAYLAND)39 JNIEXPORT jboolean JNICALL OS_NATIVE(GDK_1WINDOWING_1WAYLAND)
40 	(JNIEnv *env, jclass that)
41 {
42 	jboolean rc;
43 	OS_NATIVE_ENTER(env, that, GDK_1WINDOWING_1WAYLAND_FUNC)
44 #ifdef GDK_WINDOWING_WAYLAND
45 	rc = (jboolean)1;
46 #else
47 	rc = (jboolean)0;
48 #endif
49 	OS_NATIVE_EXIT(env, that, GDK_1WINDOWING_1WAYLAND_FUNC)
50 	return rc;
51 }
52 #endif
53 
54 #ifndef NO_imContextNewProc_1CALLBACK
55 static jlong superIMContextNewProc;
56 static GtkIMContext* lastIMContext;
imContextNewProc(GType type,guint n_construct_properties,GObjectConstructParam * construct_properties)57 static GtkIMContext* imContextNewProc (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
58 	GtkIMContext* context = ((GtkIMContext * (*)(GType, guint, GObjectConstructParam *))superIMContextNewProc)(type, n_construct_properties, construct_properties);
59 	lastIMContext = context;
60 	return context;
61 }
62 #ifndef NO_imContextLast
OS_NATIVE(imContextLast)63 JNIEXPORT jlong JNICALL OS_NATIVE(imContextLast)
64 	(JNIEnv *env, jclass that)
65 {
66 	jlong rc = 0;
67 	OS_NATIVE_ENTER(env, that, imContextLast_FUNC);
68 	rc = (jlong)lastIMContext;
69 	OS_NATIVE_EXIT(env, that, imContextLast_FUNC);
70 	return rc;
71 }
72 #endif
73 
OS_NATIVE(imContextNewProc_1CALLBACK)74 JNIEXPORT jlong JNICALL OS_NATIVE(imContextNewProc_1CALLBACK)
75 	(JNIEnv *env, jclass that, jlong arg0)
76 {
77 	jlong rc = 0;
78 	OS_NATIVE_ENTER(env, that, imContextNewProc_1CALLBACK_FUNC);
79 	superIMContextNewProc = arg0;
80 	rc = (jlong)imContextNewProc;
81 	OS_NATIVE_EXIT(env, that, imContextNewProc_1CALLBACK_FUNC);
82 	return rc;
83 }
84 #endif
85 
86 #ifndef NO_pangoLayoutNewProc_1CALLBACK
87 static jlong superPangoLayoutNewProc;
pangoLayoutNewProc(GType type,guint n_construct_properties,GObjectConstructParam * construct_properties)88 static PangoLayout * pangoLayoutNewProc (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
89 	PangoLayout* layout = ((PangoLayout * (*)(GType, guint, GObjectConstructParam *))superPangoLayoutNewProc)(type, n_construct_properties, construct_properties);
90 	pango_layout_set_auto_dir (layout, 0);
91 	return layout;
92 }
OS_NATIVE(pangoLayoutNewProc_1CALLBACK)93 JNIEXPORT jlong JNICALL OS_NATIVE(pangoLayoutNewProc_1CALLBACK)
94 	(JNIEnv *env, jclass that, jlong arg0)
95 {
96 	jlong rc = 0;
97 	OS_NATIVE_ENTER(env, that, pangoLayoutNewProc_1CALLBACK_FUNC);
98 	superPangoLayoutNewProc = arg0;
99 	rc = (jlong)pangoLayoutNewProc;
100 	OS_NATIVE_EXIT(env, that, pangoLayoutNewProc_1CALLBACK_FUNC);
101 	return rc;
102 }
103 #endif
104 
105 #ifndef NO_pangoFontFamilyNewProc_1CALLBACK
106 static jlong superPangoFontFamilyNewProc;
pangoFontFamilyNewProc(GType type,guint n_construct_properties,GObjectConstructParam * construct_properties)107 static PangoFontFamily * pangoFontFamilyNewProc (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
108 	PangoFontFamily* fontFamily = ((PangoFontFamily * (*)(GType, guint, GObjectConstructParam *))superPangoFontFamilyNewProc)(type, n_construct_properties, construct_properties);
109 	return fontFamily;
110 }
OS_NATIVE(pangoFontFamilyNewProc_1CALLBACK)111 JNIEXPORT jlong JNICALL OS_NATIVE(pangoFontFamilyNewProc_1CALLBACK)
112 	(JNIEnv *env, jclass that, jlong arg0)
113 {
114 	jlong rc = 0;
115 	OS_NATIVE_ENTER(env, that, pangoFontFamilyNewProc_1CALLBACK_FUNC);
116 	superPangoFontFamilyNewProc = arg0;
117 	rc = (jlong)pangoFontFamilyNewProc;
118 	OS_NATIVE_EXIT(env, that, pangoFontFamilyNewProc_1CALLBACK_FUNC);
119 	return rc;
120 }
121 #endif
122 
123 #ifndef NO_pangoFontFaceNewProc_1CALLBACK
124 static jlong superPangoFontFaceNewProc;
pangoFontFaceNewProc(GType type,guint n_construct_properties,GObjectConstructParam * construct_properties)125 static PangoFontFace * pangoFontFaceNewProc (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
126 	PangoFontFace* fontFace = ((PangoFontFace * (*)(GType, guint, GObjectConstructParam *))superPangoFontFaceNewProc)(type, n_construct_properties, construct_properties);
127 	return fontFace;
128 }
OS_NATIVE(pangoFontFaceNewProc_1CALLBACK)129 JNIEXPORT jlong JNICALL OS_NATIVE(pangoFontFaceNewProc_1CALLBACK)
130 	(JNIEnv *env, jclass that, jlong arg0)
131 {
132 	jlong rc = 0;
133 	OS_NATIVE_ENTER(env, that, pangoFontFaceNewProc_1CALLBACK_FUNC);
134 	superPangoFontFaceNewProc = arg0;
135 	rc = (jlong)pangoFontFaceNewProc;
136 	OS_NATIVE_EXIT(env, that, pangoFontFaceNewProc_1CALLBACK_FUNC);
137 	return rc;
138 }
139 #endif
140 #ifndef NO_printerOptionWidgetNewProc_1CALLBACK
141 static jlong superPrinterOptionWidgetNewProc;
printerOptionWidgetNewProc(GType type,guint n_construct_properties,GObjectConstructParam * construct_properties)142 static GType * printerOptionWidgetNewProc (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
143 	GType* printerOptionWidget = ((GType * (*)(GType, guint, GObjectConstructParam *))superPrinterOptionWidgetNewProc)(type, n_construct_properties, construct_properties);
144 	return printerOptionWidget;
145 }
OS_NATIVE(printerOptionWidgetNewProc_1CALLBACK)146 JNIEXPORT jlong JNICALL OS_NATIVE(printerOptionWidgetNewProc_1CALLBACK)
147 	(JNIEnv *env, jclass that, jlong arg0)
148 {
149 	jlong rc = 0;
150 	OS_NATIVE_ENTER(env, that, printerOptionWidgetNewProc_1CALLBACK_FUNC);
151 	superPrinterOptionWidgetNewProc = arg0;
152 	rc = (jlong)printerOptionWidgetNewProc;
153 	OS_NATIVE_EXIT(env, that, printerOptionWidgetNewProc_1CALLBACK_FUNC);
154 	return rc;
155 }
156 #endif
157 
g_utf16_strlen(const gchar * str,glong max)158 glong g_utf16_strlen(const gchar *str, glong max) {
159 	const gchar *s = str;
160 	guchar ch;
161 	glong offset = 0;
162 	if (!s || max == 0) return 0;
163 	if (max < 0) {
164 		while (*s) {
165 			if (0xf0 <= *(guchar*)s && *(guchar*)s <= 0xfd) offset++;
166 			s = g_utf8_next_char (s);
167 			offset++;
168 		}
169 
170 	} else {
171 		while (*s) {
172 			ch = *(guchar*)s;
173 			s = g_utf8_next_char (s);
174 			if (s - str > max) break;
175 			if (0xf0 <= ch && ch <= 0xfd) offset++;
176 			offset++;
177 		}
178 	}
179 	return offset;
180 }
181 
g_utf16_pointer_to_offset(const gchar * str,const gchar * pos)182 glong g_utf16_pointer_to_offset(const gchar *str, const gchar * pos) {
183 	const gchar *s = str;
184 	glong offset = 0;
185 	if (!s || !pos) return 0;
186 	while (s < pos && *s) {
187 		if (0xf0 <= *(guchar*)s && *(guchar*)s <= 0xfd) offset++;
188 		s = g_utf8_next_char (s);
189 		offset++;
190 	}
191 	return offset;
192 }
193 
g_utf16_offset_to_pointer(const gchar * str,glong offset)194 gchar* g_utf16_offset_to_pointer(const gchar* str, glong offset) {
195 	const gchar *s = str;
196 	if (!s) return 0;
197 	while (offset-- > 0 && *s) {
198 		if (0xf0 <= *(guchar*)s && *(guchar*)s <= 0xfd) offset--;
199 		s = g_utf8_next_char (s);
200 	}
201 	return (gchar *)s;
202 }
203 
g_utf16_offset_to_utf8_offset(const gchar * str,glong offset)204 glong g_utf16_offset_to_utf8_offset(const gchar* str, glong offset) {
205 	glong r = 0;
206 	const gchar *s = str;
207 	if (!s) return 0;
208 	while (offset-- > 0 && *s) {
209 		if (0xf0 <= *(guchar*)s && *(guchar*)s <= 0xfd) offset--;
210 		s = g_utf8_next_char (s);
211 		r++;
212 	}
213 	return r;
214 }
215 
g_utf8_offset_to_utf16_offset(const gchar * str,glong offset)216 glong g_utf8_offset_to_utf16_offset(const gchar* str, glong offset) {
217 	glong r = 0;
218 	const gchar *s = str;
219 	if (!s) return 0;
220 	while (offset-- > 0 && *s) {
221 		if (0xf0 <= *(guchar*)s && *(guchar*)s <= 0xfd) r++;
222 		s = g_utf8_next_char (s);
223 		r++;
224 	}
225 	return r;
226 }
227 
228 #if !defined(GTK4)
229 
230 struct _SwtFixedPrivate {
231   GtkAdjustment *hadjustment;
232   GtkAdjustment *vadjustment;
233   guint hscroll_policy : 1;
234   guint vscroll_policy : 1;
235   GList *children;
236 };
237 
238 struct _SwtFixedChild
239 {
240   GtkWidget *widget;
241   gint x;
242   gint y;
243   gint width;
244   gint height;
245 };
246 typedef struct _SwtFixedChild SwtFixedChild;
247 
248 enum {
249    PROP_0,
250    PROP_HADJUSTMENT,
251    PROP_VADJUSTMENT,
252    PROP_HSCROLL_POLICY,
253    PROP_VSCROLL_POLICY,
254 };
255 
256 static void swt_fixed_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
257 static void swt_fixed_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
258 static void swt_fixed_finalize (GObject *object);
259 static void swt_fixed_realize (GtkWidget *widget);
260 static void swt_fixed_map (GtkWidget *widget);
261 static AtkObject *swt_fixed_get_accessible (GtkWidget *widget);
262 static void swt_fixed_get_preferred_width (GtkWidget *widget, gint *minimum, gint *natural);
263 static void swt_fixed_get_preferred_height (GtkWidget *widget, gint *minimum, gint *natural);
264 static void swt_fixed_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
265 static void swt_fixed_add (GtkContainer *container, GtkWidget *widget);
266 static void swt_fixed_remove (GtkContainer *container, GtkWidget *widget);
267 static void swt_fixed_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data);
268 
G_DEFINE_TYPE_WITH_CODE(SwtFixed,swt_fixed,GTK_TYPE_CONTAINER,G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE,NULL)G_ADD_PRIVATE (SwtFixed))269 G_DEFINE_TYPE_WITH_CODE (SwtFixed, swt_fixed, GTK_TYPE_CONTAINER,
270 		G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL)
271 		G_ADD_PRIVATE (SwtFixed))
272 
273 static void swt_fixed_class_init (SwtFixedClass *class) {
274 	GObjectClass *gobject_class = (GObjectClass*) class;
275 	GtkWidgetClass *widget_class = (GtkWidgetClass*) class;
276 	GtkContainerClass *container_class = (GtkContainerClass*) class;
277 
278 	/* GOject implementation */
279 	gobject_class->set_property = swt_fixed_set_property;
280 	gobject_class->get_property = swt_fixed_get_property;
281 	gobject_class->finalize = swt_fixed_finalize;
282 
283 	/* Scrollable implemetation */
284 	g_object_class_override_property (gobject_class, PROP_HADJUSTMENT,    "hadjustment");
285 	g_object_class_override_property (gobject_class, PROP_VADJUSTMENT,    "vadjustment");
286 	g_object_class_override_property (gobject_class, PROP_HSCROLL_POLICY, "hscroll-policy");
287 	g_object_class_override_property (gobject_class, PROP_VSCROLL_POLICY, "vscroll-policy");
288 
289 	/* Widget implementation */
290 	widget_class->realize = swt_fixed_realize;
291 	widget_class->map = swt_fixed_map;
292 	widget_class->get_preferred_width = swt_fixed_get_preferred_width;
293 	widget_class->get_preferred_height = swt_fixed_get_preferred_height;
294 	widget_class->size_allocate = swt_fixed_size_allocate;
295 
296 	/* Accessibility implementation */
297 	widget_class->get_accessible = swt_fixed_get_accessible;
298 
299 	/* Container implementation */
300 	container_class->add = swt_fixed_add;
301 	container_class->remove = swt_fixed_remove;
302 	container_class->forall = swt_fixed_forall;
303 
304 }
305 
swt_fixed_restack(SwtFixed * fixed,GtkWidget * widget,GtkWidget * sibling,gboolean above)306 void swt_fixed_restack (SwtFixed *fixed, GtkWidget *widget, GtkWidget *sibling, gboolean above) {
307 	SwtFixedPrivate *priv = fixed->priv;
308 	GList *list;
309 	SwtFixedChild *child, *sibling_child;
310 
311 	list = priv->children;
312 	while (list) {
313 		child = list->data;
314 		if (child->widget == widget) break;
315 		list = list->next;
316 	}
317 
318 	if (!list) return;
319 	priv->children = g_list_remove_link (priv->children, list);
320 	g_list_free_1 (list);
321 
322 	list = NULL;
323 	if (sibling) {
324 		list = priv->children;
325 		while (list) {
326 			sibling_child = list->data;
327 			if (sibling_child->widget == sibling) {
328 				break;
329 			}
330 			list = list->next;
331 		}
332 		if (list) {
333 			if (!above) list = list->next;
334 		}
335 	}
336 	if (!list) {
337 		list = above ? priv->children : NULL;
338 	}
339 	priv->children = g_list_insert_before (priv->children, list, child);
340 
341 	/*
342 	{
343 	GdkWindow *sibling_window = NULL;
344 	if (list) {
345 		child = list->data;
346 		sibling_window = gtk_widget_get_window (child);
347 	}
348 	gdk_window_restack (gtk_widget_get_window (widget), sibling_window, above);
349 	}
350 	*/
351 }
352 
swt_fixed_init(SwtFixed * widget)353 static void swt_fixed_init (SwtFixed *widget) {
354 	SwtFixedPrivate *priv;
355 
356 	priv = widget->priv = swt_fixed_get_instance_private (widget);
357 	priv->children = NULL;
358 	priv->hadjustment = NULL;
359 	priv->vadjustment = NULL;
360 }
361 
swt_fixed_finalize(GObject * object)362 static void swt_fixed_finalize (GObject *object) {
363 	SwtFixed *widget = SWT_FIXED (object);
364 	SwtFixedPrivate *priv = widget->priv;
365 
366 	g_object_unref (priv->hadjustment);
367 	g_object_unref (priv->vadjustment);
368 	g_clear_object (&widget->accessible);
369 
370 	G_OBJECT_CLASS (swt_fixed_parent_class)->finalize (object);
371 }
372 
swt_fixed_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)373 static void swt_fixed_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
374 	SwtFixed *widget = SWT_FIXED (object);
375 	SwtFixedPrivate *priv = widget->priv;
376 
377 	switch (prop_id) {
378 		case PROP_HADJUSTMENT:
379 			g_value_set_object (value, priv->hadjustment);
380 			break;
381 		case PROP_VADJUSTMENT:
382 			g_value_set_object (value, priv->vadjustment);
383 			break;
384 		case PROP_HSCROLL_POLICY:
385 			g_value_set_enum (value, priv->hscroll_policy);
386 			break;
387 		case PROP_VSCROLL_POLICY:
388 			g_value_set_enum (value, priv->vscroll_policy);
389 			break;
390 		default:
391 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
392 			break;
393 	}
394 }
395 
swt_fixed_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)396 static void swt_fixed_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) {
397 	SwtFixed *widget = SWT_FIXED (object);
398 	SwtFixedPrivate *priv = widget->priv;
399 	GtkAdjustment *adjustment;
400 
401 	switch (prop_id) {
402 		case PROP_HADJUSTMENT:
403 			adjustment = g_value_get_object (value);
404 			if (adjustment && priv->hadjustment == adjustment) return;
405 			if (priv->hadjustment != NULL) g_object_unref (priv->hadjustment);
406 			if (adjustment == NULL) adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
407 			priv->hadjustment = g_object_ref_sink (adjustment);
408 			g_object_notify (G_OBJECT (widget), "hadjustment");
409 			break;
410 		case PROP_VADJUSTMENT:
411 			adjustment = g_value_get_object (value);
412 			if (adjustment && priv->vadjustment == adjustment) return;
413 			if (priv->vadjustment != NULL) g_object_unref (priv->vadjustment);
414 			if (adjustment == NULL) adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
415 			priv->vadjustment = g_object_ref_sink (adjustment);
416 			g_object_notify (G_OBJECT (widget), "vadjustment");
417 			break;
418 		case PROP_HSCROLL_POLICY:
419 			priv->hscroll_policy = g_value_get_enum (value);
420 			break;
421 		case PROP_VSCROLL_POLICY:
422 			priv->vscroll_policy = g_value_get_enum (value);
423 			break;
424 		default:
425 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
426 			break;
427     }
428 }
429 
swt_fixed_realize(GtkWidget * widget)430 static void swt_fixed_realize (GtkWidget *widget) {
431 	GtkAllocation allocation;
432 	GdkWindow *window;
433 	GdkWindowAttr attributes;
434 	gint attributes_mask;
435 
436  	if (!gtk_widget_get_has_window (widget)) {
437     	GTK_WIDGET_CLASS (swt_fixed_parent_class)->realize (widget);
438     	return;
439     }
440 
441 	gtk_widget_set_realized (widget, TRUE);
442 
443 	gtk_widget_get_allocation (widget, &allocation);
444 
445 	attributes.window_type = GDK_WINDOW_CHILD;
446 	attributes.x = allocation.x;
447 	attributes.y = allocation.y;
448 	attributes.width = allocation.width;
449 	attributes.height = allocation.height;
450 	attributes.wclass = GDK_INPUT_OUTPUT;
451 	attributes.visual = gtk_widget_get_visual (widget);
452 	attributes.event_mask = GDK_EXPOSURE_MASK | GDK_SCROLL_MASK | 1 << 23 /*GDK_SMOOTH_SCROLL_MASK*/ | gtk_widget_get_events (widget);
453 	attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
454 	window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
455 	gtk_widget_set_window (widget, window);
456 	gdk_window_set_user_data (window, widget);
457 	if (NULL != gtk_check_version (3, 18, 0)) {
458 		gtk_style_context_set_background (gtk_widget_get_style_context (widget), window);
459 	}
460 }
461 
swt_fixed_map(GtkWidget * widget)462 static void swt_fixed_map (GtkWidget *widget) {
463 	SwtFixed *fixed = SWT_FIXED (widget);
464 	SwtFixedPrivate *priv = fixed->priv;
465 	GList *list;
466 
467 	gtk_widget_set_mapped (widget, TRUE);
468 	list = priv->children;
469 	while (list) {
470 		SwtFixedChild *child_data = list->data;
471 		GtkWidget *child = child_data->widget;
472 		list = list->next;
473 		if (gtk_widget_get_visible (child)) {
474 			if (!gtk_widget_get_mapped (child)) gtk_widget_map (child);
475 		}
476 	}
477 	if (gtk_widget_get_has_window (widget)) {
478 		//NOTE: contrary to most of GTK, swt_fixed_* container does not raise windows upon showing them.
479 		//This has the effect that widgets are drawn *beneath* the previous one.
480 		//E.g if this line is changed to gdk_window_show (..) then widgets are drawn on top of the previous one.
481 		//This affects mostly only the absolute layout with overlapping widgets, e.g minimizied panels that
482 		//pop-out in Eclipse (aka fast-view).
483 		//As such, be attentive to swt_fixed_forall(..); traversing children may need to be done in reverse in some
484 		//cases.
485 		gdk_window_show_unraised (gtk_widget_get_window (widget));
486 	}
487 }
488 
489 /* Accessibility */
swt_fixed_get_accessible(GtkWidget * widget)490 static AtkObject *swt_fixed_get_accessible (GtkWidget *widget) {
491 	SwtFixed *fixed = SWT_FIXED (widget);
492 
493 	if (!fixed->accessible) {
494 		fixed->accessible = swt_fixed_accessible_new (widget);
495 	}
496 	return fixed->accessible;
497 }
498 
swt_fixed_get_preferred_width(GtkWidget * widget,gint * minimum,gint * natural)499 static void swt_fixed_get_preferred_width (GtkWidget *widget, gint *minimum, gint *natural) {
500 	if (minimum) *minimum = 0;
501 	if (natural) *natural = 0;
502 }
503 
swt_fixed_get_preferred_height(GtkWidget * widget,gint * minimum,gint * natural)504 static void swt_fixed_get_preferred_height (GtkWidget *widget, gint *minimum, gint *natural) {
505 	if (minimum) *minimum = 0;
506 	if (natural) *natural = 0;
507 }
508 
swt_fixed_size_allocate(GtkWidget * widget,GtkAllocation * allocation)509 static void swt_fixed_size_allocate (GtkWidget *widget, GtkAllocation *allocation) {
510 	SwtFixed *fixed = SWT_FIXED (widget);
511 	SwtFixedPrivate *priv = fixed->priv;
512 	GList *list;
513 	GtkAllocation child_allocation;
514 	GtkRequisition requisition;
515 	gint w, h;
516 
517 	gtk_widget_set_allocation (widget, allocation);
518 
519 	if (gtk_widget_get_has_window (widget)) {
520 		if (gtk_widget_get_realized (widget)) {
521 			gdk_window_move_resize (gtk_widget_get_window (widget), allocation->x, allocation->y, allocation->width, allocation->height);
522 	    }
523 	}
524 
525 	list = priv->children;
526 
527 	while (list) {
528 		SwtFixedChild *child_data = list->data;
529 		GtkWidget *child = child_data->widget;
530 		list = list->next;
531 
532 		child_allocation.x = child_data->x;
533 		child_allocation.y = child_data->y;
534 		if (!gtk_widget_get_has_window (widget)) {
535           child_allocation.x += allocation->x;
536           child_allocation.y += allocation->y;
537         }
538 
539 		w = child_data->width;
540 		h = child_data->height;
541 		if (w == -1 || h == -1) {
542 			gtk_widget_get_preferred_size (child, &requisition, NULL);
543 			if (w == -1) w = requisition.width;
544 			if (h == -1) h = requisition.height;
545 		}
546 		// Feature in GTK: gtk_widget_preferred_size() has to be called before
547 		// gtk_widget_size_allocate otherwise a warning is thrown. See Bug 486068.
548 		gtk_widget_get_preferred_size (child, &requisition, NULL);
549 
550 		child_allocation.width = w;
551 		child_allocation.height = h;
552 
553 		gtk_widget_size_allocate (child, &child_allocation);
554     }
555 }
556 
swt_fixed_move(SwtFixed * fixed,GtkWidget * widget,gint x,gint y)557 void swt_fixed_move (SwtFixed *fixed, GtkWidget *widget, gint x, gint y) {
558 	SwtFixedPrivate *priv = fixed->priv;
559 	GList *list;
560 
561 	list = priv->children;
562 	while (list) {
563 		SwtFixedChild *child_data = list->data;
564 		GtkWidget *child = child_data->widget;
565 		if (child == widget) {
566 			child_data->x = x;
567 			child_data->y = y;
568 			break;
569 		}
570 		list = list->next;
571 	}
572 }
573 
swt_fixed_resize(SwtFixed * fixed,GtkWidget * widget,gint width,gint height)574 void swt_fixed_resize (SwtFixed *fixed, GtkWidget *widget, gint width, gint height) {
575 	SwtFixedPrivate *priv = fixed->priv;
576 	GList *list;
577 
578 	list = priv->children;
579 	while (list) {
580 		SwtFixedChild *child_data = list->data;
581 		GtkWidget *child = child_data->widget;
582 		if (child == widget) {
583 			child_data->width = width;
584 			child_data->height = height;
585 
586 			/*
587 			 * Feature in GTK: sometimes the sizing of child SwtFixed widgets
588 			 * does not happen quickly enough, causing miscalculations in SWT.
589 			 * Allocate the size of the child directly when swt_fixed_resize()
590 			 * is called. See bug 487160.
591 			 */
592 			GtkAllocation allocation, to_allocate;
593 			GtkRequisition req;
594 			gtk_widget_get_allocation(child, &allocation);
595 
596 			// Keep x and y values the same to prevent misplaced containers
597 			to_allocate.x = allocation.x;
598 			to_allocate.y = allocation.y;
599 			to_allocate.width = width;
600 			to_allocate.height = height;
601 
602 			// Call gtk_widget_get_preferred_size() and finish the allocation.
603 			gtk_widget_get_preferred_size (child, &req, NULL);
604 			gtk_widget_size_allocate(child, &to_allocate);
605 			break;
606 		}
607 		list = list->next;
608 	}
609 }
610 
swt_fixed_add(GtkContainer * container,GtkWidget * child)611 static void swt_fixed_add (GtkContainer *container, GtkWidget *child) {
612 	GtkWidget *widget = GTK_WIDGET (container);
613 	SwtFixed *fixed = SWT_FIXED (container);
614 	SwtFixedPrivate *priv = fixed->priv;
615 	SwtFixedChild *child_data;
616 
617 	child_data = g_new (SwtFixedChild, 1);
618 	child_data->widget = child;
619   	child_data->x = child_data->y = 0;
620   	child_data->width = child_data->height = -1;
621 
622 	priv->children = g_list_append (priv->children, child_data);
623 	gtk_widget_set_parent (child, widget);
624 }
625 
swt_fixed_remove(GtkContainer * container,GtkWidget * widget)626 static void swt_fixed_remove (GtkContainer *container, GtkWidget *widget) {
627 	SwtFixed *fixed = SWT_FIXED (container);
628 	SwtFixedPrivate *priv = fixed->priv;
629 	GList *list;
630 
631 	list = priv->children;
632 	while (list) {
633 		SwtFixedChild *child_data = list->data;
634 		GtkWidget *child = child_data->widget;
635 		if (child == widget) {
636 			gtk_widget_unparent (widget);
637 			priv->children = g_list_remove_link (priv->children, list);
638 			g_list_free_1 (list);
639 			g_free (child_data);
640 			break;
641 		}
642 		list = list->next;
643 	}
644 }
645 
swt_fixed_forall(GtkContainer * container,gboolean include_internals,GtkCallback callback,gpointer callback_data)646 static void swt_fixed_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data) {
647 	SwtFixed *fixed = SWT_FIXED (container);
648 	SwtFixedPrivate *priv = fixed->priv;
649 	GList *list;
650 
651 	list = priv->children;
652 
653 	// NOTE: The direction of the list traversal is conditional.
654 	//
655 	// 1) When we do a *_foreach() traversal (i.e, include_internals==FALSE), we traverse the list as normal
656 	// from front to back.
657 	// This is used to layout higher level widgets inside containers (e.g row/grid etc..) in the expected way.
658 	// If for a non-internal traversal we were to go in reverse, then widgets would get laid out in inverse order.
659 	// 2) When we do a *_forall() traversal (i.e, include_internals==TRUE), we traverse the list in *reverse* order.
660 	// This is an internal traversal of the internals of a widget. Reverse traversal is necessary for things like
661 	// DnD Drop and DnD Motion events to find the correct widget in the case of overlapping  widgets on an absolute layout.
662 	// Reversal is required because in swt_fixed_map(..) we do not raise the widget when we show it, as a result
663 	// the stack is in reverse.
664 	if (include_internals)
665 			list = g_list_last(list);
666 
667 	while (list) {
668 		SwtFixedChild *child_data = list->data;
669 		GtkWidget *child = child_data->widget;
670 
671 		if (include_internals)
672 			list = list->prev;
673 		else
674 			list = list->next;
675 
676 		(* callback) (child, callback_data);
677 	}
678 }
679 
680 #else
681 struct _SwtFixedPrivate {
682   GtkAdjustment *hadjustment;
683   GtkAdjustment *vadjustment;
684   guint hscroll_policy : 1;
685   guint vscroll_policy : 1;
686   GList *children;
687 };
688 
689 struct _SwtFixedChild
690 {
691   GtkWidget *widget;
692   gint x;
693   gint y;
694   gint width;
695   gint height;
696 };
697 typedef struct _SwtFixedChild SwtFixedChild;
698 
699 enum {
700    PROP_0,
701    PROP_HADJUSTMENT,
702    PROP_VADJUSTMENT,
703    PROP_HSCROLL_POLICY,
704    PROP_VSCROLL_POLICY,
705 };
706 
707 static void swt_fixed_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
708 static void swt_fixed_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
709 static void swt_fixed_finalize (GObject *object);
710 static void swt_fixed_map (GtkWidget *widget);
711 static AtkObject *swt_fixed_get_accessible (GtkWidget *widget);
712 static void swt_fixed_measure (GtkWidget *widget, GtkOrientation  orientation, int for_size, int *minimum,
713 		int *natural, int *minimum_baseline, int *natural_baseline);
714 static void swt_fixed_size_allocate (GtkWidget *widget, const GtkAllocation *allocation, int baseline);
715 static void swt_fixed_add (GtkContainer *container, GtkWidget *widget);
716 static void swt_fixed_remove (GtkContainer *container, GtkWidget *widget);
717 static void swt_fixed_forall (GtkContainer *container,  GtkCallback callback, gpointer callback_data);
718 
G_DEFINE_TYPE_WITH_CODE(SwtFixed,swt_fixed,GTK_TYPE_CONTAINER,G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE,NULL)G_ADD_PRIVATE (SwtFixed))719 G_DEFINE_TYPE_WITH_CODE (SwtFixed, swt_fixed, GTK_TYPE_CONTAINER,
720 		G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL)
721 		G_ADD_PRIVATE (SwtFixed))
722 
723 static void swt_fixed_class_init (SwtFixedClass *class) {
724 	GObjectClass *gobject_class = (GObjectClass*) class;
725 	GtkWidgetClass *widget_class = (GtkWidgetClass*) class;
726 	GtkContainerClass *container_class = (GtkContainerClass*) class;
727 
728 	/* GOject implementation */
729 	gobject_class->set_property = swt_fixed_set_property;
730 	gobject_class->get_property = swt_fixed_get_property;
731 	gobject_class->finalize = swt_fixed_finalize;
732 
733 	/* Scrollable implemetation */
734 	g_object_class_override_property (gobject_class, PROP_HADJUSTMENT,    "hadjustment");
735 	g_object_class_override_property (gobject_class, PROP_VADJUSTMENT,    "vadjustment");
736 	g_object_class_override_property (gobject_class, PROP_HSCROLL_POLICY, "hscroll-policy");
737 	g_object_class_override_property (gobject_class, PROP_VSCROLL_POLICY, "vscroll-policy");
738 
739 	/* Widget implementation */
740 	widget_class->map = swt_fixed_map;
741 	widget_class->measure = swt_fixed_measure;
742 	widget_class->size_allocate = swt_fixed_size_allocate;
743 
744 	/* Accessibility implementation */
745 	widget_class->get_accessible = swt_fixed_get_accessible;
746 
747 	/* Container implementation */
748 	container_class->add = swt_fixed_add;
749 	container_class->remove = swt_fixed_remove;
750 	container_class->forall = swt_fixed_forall;
751 
752 }
753 
swt_fixed_restack(SwtFixed * fixed,GtkWidget * widget,GtkWidget * sibling,gboolean above)754 void swt_fixed_restack (SwtFixed *fixed, GtkWidget *widget, GtkWidget *sibling, gboolean above) {
755 	SwtFixedPrivate *priv = fixed->priv;
756 	GList *list;
757 	SwtFixedChild *child, *sibling_child;
758 
759 	list = priv->children;
760 	while (list) {
761 		child = list->data;
762 		if (child->widget == widget) break;
763 		list = list->next;
764 	}
765 
766 	if (!list) return;
767 	priv->children = g_list_remove_link (priv->children, list);
768 	g_list_free_1 (list);
769 
770 	list = NULL;
771 	if (sibling) {
772 		list = priv->children;
773 		while (list) {
774 			sibling_child = list->data;
775 			if (sibling_child->widget == sibling) {
776 				break;
777 			}
778 			list = list->next;
779 		}
780 		if (list) {
781 			if (!above) list = list->next;
782 		}
783 	}
784 	if (!list) {
785 		list = above ? priv->children : NULL;
786 	}
787 	priv->children = g_list_insert_before (priv->children, list, child);
788 
789 	/*
790 	{
791 	GdkWindow *sibling_window = NULL;
792 	if (list) {
793 		child = list->data;
794 		sibling_window = gtk_widget_get_window (child);
795 	}
796 	gdk_window_restack (gtk_widget_get_window (widget), sibling_window, above);
797 	}
798 	*/
799 }
800 
swt_fixed_init(SwtFixed * widget)801 static void swt_fixed_init (SwtFixed *widget) {
802 	SwtFixedPrivate *priv;
803 
804 	priv = widget->priv = swt_fixed_get_instance_private (widget);
805 	priv->children = NULL;
806 	priv->hadjustment = NULL;
807 	priv->vadjustment = NULL;
808 
809 	gtk_widget_set_has_surface(GTK_WIDGET(widget), FALSE);
810 }
811 
swt_fixed_finalize(GObject * object)812 static void swt_fixed_finalize (GObject *object) {
813 	SwtFixed *widget = SWT_FIXED (object);
814 	SwtFixedPrivate *priv = widget->priv;
815 
816 	g_object_unref (priv->hadjustment);
817 	g_object_unref (priv->vadjustment);
818 	g_clear_object (&widget->accessible);
819 
820 	G_OBJECT_CLASS (swt_fixed_parent_class)->finalize (object);
821 }
822 
swt_fixed_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)823 static void swt_fixed_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
824 	SwtFixed *widget = SWT_FIXED (object);
825 	SwtFixedPrivate *priv = widget->priv;
826 
827 	switch (prop_id) {
828 		case PROP_HADJUSTMENT:
829 			g_value_set_object (value, priv->hadjustment);
830 			break;
831 		case PROP_VADJUSTMENT:
832 			g_value_set_object (value, priv->vadjustment);
833 			break;
834 		case PROP_HSCROLL_POLICY:
835 			g_value_set_enum (value, priv->hscroll_policy);
836 			break;
837 		case PROP_VSCROLL_POLICY:
838 			g_value_set_enum (value, priv->vscroll_policy);
839 			break;
840 		default:
841 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
842 			break;
843 	}
844 }
845 
swt_fixed_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)846 static void swt_fixed_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) {
847 	SwtFixed *widget = SWT_FIXED (object);
848 	SwtFixedPrivate *priv = widget->priv;
849 	GtkAdjustment *adjustment;
850 
851 	switch (prop_id) {
852 		case PROP_HADJUSTMENT:
853 			adjustment = g_value_get_object (value);
854 			if (adjustment && priv->hadjustment == adjustment) return;
855 			if (priv->hadjustment != NULL) g_object_unref (priv->hadjustment);
856 			if (adjustment == NULL) adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
857 			priv->hadjustment = g_object_ref_sink (adjustment);
858 			g_object_notify (G_OBJECT (widget), "hadjustment");
859 			break;
860 		case PROP_VADJUSTMENT:
861 			adjustment = g_value_get_object (value);
862 			if (adjustment && priv->vadjustment == adjustment) return;
863 			if (priv->vadjustment != NULL) g_object_unref (priv->vadjustment);
864 			if (adjustment == NULL) adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
865 			priv->vadjustment = g_object_ref_sink (adjustment);
866 			g_object_notify (G_OBJECT (widget), "vadjustment");
867 			break;
868 		case PROP_HSCROLL_POLICY:
869 			priv->hscroll_policy = g_value_get_enum (value);
870 			break;
871 		case PROP_VSCROLL_POLICY:
872 			priv->vscroll_policy = g_value_get_enum (value);
873 			break;
874 		default:
875 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
876 			break;
877     }
878 }
879 
880 /*
881 static void swt_fixed_realize (GtkWidget *widget) {
882 	GtkAllocation allocation;
883 	GdkSurface *surface;
884 
885  	if (!gtk_widget_get_has_surface (widget)) {
886     	GTK_WIDGET_CLASS (swt_fixed_parent_class)->realize (widget);
887     	return;
888     }
889 
890 	gtk_widget_get_allocation (widget, &allocation);
891 
892 	surface = gdk_surface_new_child (gtk_widget_get_parent_surface (widget), &allocation);
893 	gtk_widget_set_surface(widget, surface);
894 	gdk_surface_set_user_data (surface, widget);
895 	return GTK_WIDGET_CLASS (swt_fixed_parent_class)->realize (widget);
896 }*/
897 
swt_fixed_map(GtkWidget * widget)898 static void swt_fixed_map (GtkWidget *widget) {
899 	SwtFixed *fixed = SWT_FIXED (widget);
900 	SwtFixedPrivate *priv = fixed->priv;
901 	GList *list;
902 
903 	list = priv->children;
904 	while (list) {
905 		SwtFixedChild *child_data = list->data;
906 		GtkWidget *child = child_data->widget;
907 		list = list->next;
908 		if (gtk_widget_get_visible (child)) {
909 			if (!gtk_widget_get_mapped (child)) gtk_widget_map (child);
910 		}
911 	}
912 	if (gtk_widget_get_has_surface (widget)) {
913 		//NOTE: contrary to most of GTK, swt_fixed_* container does not raise windows upon showing them.
914 		//This has the effect that widgets are drawn *beneath* the previous one.
915 		//E.g if this line is changed to gdk_window_show (..) then widgets are drawn on top of the previous one.
916 		//This affects mostly only the absolute layout with overlapping widgets, e.g minimizied panels that
917 		//pop-out in Eclipse (aka fast-view).
918 		//As such, be attentive to swt_fixed_forall(..); traversing children may need to be done in reverse in some
919 		//cases.
920 		gdk_surface_show_unraised (gtk_widget_get_surface (widget));
921 	}
922 	return GTK_WIDGET_CLASS (swt_fixed_parent_class)->map (widget);
923 }
924 
925 /* Accessibility */
swt_fixed_get_accessible(GtkWidget * widget)926 static AtkObject *swt_fixed_get_accessible (GtkWidget *widget) {
927 	SwtFixed *fixed = SWT_FIXED (widget);
928 
929 	if (!fixed->accessible) {
930 		fixed->accessible = swt_fixed_accessible_new (widget);
931 	}
932 	return fixed->accessible;
933 }
934 
swt_fixed_measure(GtkWidget * widget,GtkOrientation orientation,int for_size,int * minimum,int * natural,int * minimum_baseline,int * natural_baseline)935 static void swt_fixed_measure (GtkWidget *widget, GtkOrientation  orientation, int for_size, int *minimum,
936 		int *natural, int *minimum_baseline, int *natural_baseline) {
937 	SwtFixed *fixed = SWT_FIXED (widget);
938 	SwtFixedPrivate *priv = fixed->priv;
939 	GList *list;
940 	int natural_size, child_nat;
941 
942 	list = priv->children;
943 	natural_size = 0;
944 
945 	while (list) {
946 		SwtFixedChild *child_data = list->data;
947 		GtkWidget *child = child_data->widget;
948 
949 		gtk_widget_measure(child, orientation, -1, NULL, &child_nat, NULL, NULL);
950 		if (child_nat > natural_size) natural_size = child_nat;
951 
952 		list = list->next;
953 	}
954 	if (natural) *natural = natural_size;
955 	if (minimum) *minimum = 0;
956 	if (minimum_baseline) *minimum_baseline = -1;
957 	if (natural_baseline) *natural_baseline = -1;
958 	return;
959 }
960 
swt_fixed_size_allocate(GtkWidget * widget,const GtkAllocation * allocation,int baseline)961 static void swt_fixed_size_allocate (GtkWidget *widget, const GtkAllocation *allocation, int baseline) {
962 	SwtFixed *fixed = SWT_FIXED (widget);
963 	SwtFixedPrivate *priv = fixed->priv;
964 	GList *list;
965 	GtkAllocation child_allocation;
966 	GtkRequisition requisition;
967 	gint w, h;
968 
969 	if (gtk_widget_get_has_surface (widget)) {
970 		if (gtk_widget_get_realized (widget)) {
971 			gdk_surface_move_resize (gtk_widget_get_surface (widget), allocation->x, allocation->y, allocation->width, allocation->height);
972 	    }
973 	}
974 
975 	list = priv->children;
976 
977 	while (list) {
978 		SwtFixedChild *child_data = list->data;
979 		GtkWidget *child = child_data->widget;
980 		list = list->next;
981 
982 		child_allocation.x = child_data->x;
983 		child_allocation.y = child_data->y;
984 		if (!gtk_widget_get_has_surface (widget)) {
985           child_allocation.x += allocation->x;
986           child_allocation.y += allocation->y;
987         }
988 
989 		w = child_data->width;
990 		h = child_data->height;
991 		if (w == -1 || h == -1) {
992 			gtk_widget_get_preferred_size (child, &requisition, NULL);
993 			if (w == -1) w = requisition.width;
994 			if (h == -1) h = requisition.height;
995 		}
996 		// Feature in GTK: gtk_widget_preferred_size() has to be called before
997 		// gtk_widget_size_allocate otherwise a warning is thrown. See Bug 486068.
998 		gtk_widget_get_preferred_size (child, &requisition, NULL);
999 
1000 		child_allocation.width = w;
1001 		child_allocation.height = h;
1002 
1003 		gtk_widget_size_allocate (child, &child_allocation, -1);
1004     }
1005 }
1006 
swt_fixed_move(SwtFixed * fixed,GtkWidget * widget,gint x,gint y)1007 void swt_fixed_move (SwtFixed *fixed, GtkWidget *widget, gint x, gint y) {
1008 	SwtFixedPrivate *priv = fixed->priv;
1009 	GList *list;
1010 
1011 	list = priv->children;
1012 	while (list) {
1013 		SwtFixedChild *child_data = list->data;
1014 		GtkWidget *child = child_data->widget;
1015 		if (child == widget) {
1016 			child_data->x = x;
1017 			child_data->y = y;
1018 			break;
1019 		}
1020 		list = list->next;
1021 	}
1022 }
1023 
swt_fixed_resize(SwtFixed * fixed,GtkWidget * widget,gint width,gint height)1024 void swt_fixed_resize (SwtFixed *fixed, GtkWidget *widget, gint width, gint height) {
1025 	SwtFixedPrivate *priv = fixed->priv;
1026 	GList *list;
1027 
1028 	list = priv->children;
1029 	while (list) {
1030 		SwtFixedChild *child_data = list->data;
1031 		GtkWidget *child = child_data->widget;
1032 		if (child == widget) {
1033 			child_data->width = width;
1034 			child_data->height = height;
1035 
1036 			/*
1037 			 * Feature in GTK: sometimes the sizing of child SwtFixed widgets
1038 			 * does not happen quickly enough, causing miscalculations in SWT.
1039 			 * Allocate the size of the child directly when swt_fixed_resize()
1040 			 * is called. See bug 487160.
1041 			 */
1042 			GtkAllocation allocation, to_allocate;
1043 			GtkRequisition req;
1044 			gtk_widget_get_allocation(child, &allocation);
1045 
1046 			// Keep x and y values the same to prevent misplaced containers
1047 			to_allocate.x = allocation.x;
1048 			to_allocate.y = allocation.y;
1049 			to_allocate.width = width;
1050 			to_allocate.height = height;
1051 
1052 			// Call gtk_widget_get_preferred_size() and finish the allocation.
1053 			gtk_widget_get_preferred_size (child, &req, NULL);
1054 			gtk_widget_size_allocate(child, &to_allocate, -1);
1055 			break;
1056 		}
1057 		list = list->next;
1058 	}
1059 }
1060 
swt_fixed_add(GtkContainer * container,GtkWidget * child)1061 static void swt_fixed_add (GtkContainer *container, GtkWidget *child) {
1062 	GtkWidget *widget = GTK_WIDGET (container);
1063 	SwtFixed *fixed = SWT_FIXED (container);
1064 	SwtFixedPrivate *priv = fixed->priv;
1065 	SwtFixedChild *child_data;
1066 
1067 	child_data = g_new (SwtFixedChild, 1);
1068 	child_data->widget = child;
1069   	child_data->x = child_data->y = 0;
1070   	child_data->width = child_data->height = -1;
1071 
1072 	priv->children = g_list_append (priv->children, child_data);
1073 	gtk_widget_set_parent (child, widget);
1074 }
1075 
swt_fixed_remove(GtkContainer * container,GtkWidget * widget)1076 static void swt_fixed_remove (GtkContainer *container, GtkWidget *widget) {
1077 	SwtFixed *fixed = SWT_FIXED (container);
1078 	SwtFixedPrivate *priv = fixed->priv;
1079 	GList *list;
1080 
1081 	list = priv->children;
1082 	while (list) {
1083 		SwtFixedChild *child_data = list->data;
1084 		GtkWidget *child = child_data->widget;
1085 		if (child == widget) {
1086 			gtk_widget_unparent (widget);
1087 			priv->children = g_list_remove_link (priv->children, list);
1088 			g_list_free_1 (list);
1089 			g_free (child_data);
1090 			break;
1091 		}
1092 		list = list->next;
1093 	}
1094 }
1095 
swt_fixed_forall(GtkContainer * container,GtkCallback callback,gpointer callback_data)1096 static void swt_fixed_forall (GtkContainer *container, GtkCallback callback, gpointer callback_data) {
1097 	SwtFixed *fixed = SWT_FIXED (container);
1098 	SwtFixedPrivate *priv = fixed->priv;
1099 	GList *list;
1100 
1101 	list = priv->children;
1102 
1103 	// NOTE: The direction of the list traversal is conditional.
1104 	//
1105 	// 1) When we do a *_foreach() traversal (i.e, include_internals==FALSE), we traverse the list as normal
1106 	// from front to back.
1107 	// This is used to layout higher level widgets inside containers (e.g row/grid etc..) in the expected way.
1108 	// If for a non-internal traversal we were to go in reverse, then widgets would get laid out in inverse order.
1109 	// 2) When we do a *_forall() traversal (i.e, include_internals==TRUE), we traverse the list in *reverse* order.
1110 	// This is an internal traversal of the internals of a widget. Reverse traversal is necessary for things like
1111 	// DnD Drop and DnD Motion events to find the correct widget in the case of overlapping  widgets on an absolute layout.
1112 	// Reversal is required because in swt_fixed_map(..) we do not raise the widget when we show it, as a result
1113 	// the stack is in reverse.
1114 
1115 	while (list) {
1116 		SwtFixedChild *child_data = list->data;
1117 		GtkWidget *child = child_data->widget;
1118 
1119 		list = list->next;
1120 
1121 		(* callback) (child, callback_data);
1122 	}
1123 }
1124 
1125 #endif
1126 static void swt_fixed_accessible_class_init (SwtFixedAccessibleClass *klass);
1127 static void swt_fixed_accessible_finalize (GObject *object);
1128 static void swt_fixed_accessible_initialize (AtkObject *obj, gpointer data);
1129 static AtkAttributeSet *swt_fixed_accessible_get_attributes (AtkObject *obj);
1130 static const gchar *swt_fixed_accessible_get_description (AtkObject *obj);
1131 static gint swt_fixed_accessible_get_index_in_parent (AtkObject *obj);
1132 static gint swt_fixed_accessible_get_n_children (AtkObject *obj);
1133 static const gchar *swt_fixed_accessible_get_name (AtkObject *obj);
1134 static AtkObject *swt_fixed_accessible_get_parent (AtkObject *obj);
1135 static AtkRole swt_fixed_accessible_get_role (AtkObject *obj);
1136 static AtkObject *swt_fixed_accessible_ref_child (AtkObject *obj, gint i);
1137 static AtkStateSet *swt_fixed_accesssible_ref_state_set (AtkObject *accessible);
1138 static void swt_fixed_accessible_action_iface_init (AtkActionIface *iface);
1139 static void swt_fixed_accessible_component_iface_init (AtkComponentIface *iface);
1140 static void swt_fixed_accessible_editable_text_iface_init (AtkEditableTextIface *iface);
1141 static void swt_fixed_accessible_hypertext_iface_init (AtkHypertextIface *iface);
1142 static void swt_fixed_accessible_selection_iface_init (AtkSelectionIface *iface);
1143 static void swt_fixed_accessible_table_iface_init (AtkTableIface *iface);
1144 static void swt_fixed_accessible_text_iface_init (AtkTextIface *iface);
1145 static void swt_fixed_accessible_value_iface_init (AtkValueIface *iface);
1146 
1147 struct _SwtFixedAccessiblePrivate {
1148 	// A boolean flag which is set to TRUE when an Accessible Java
1149 	// object has been created for this SwtFixedAccessible instance
1150 	gboolean has_accessible;
1151 
1152 	// The GtkWidget this SwtFixedAccessible instance maps to.
1153 	GtkWidget *widget;
1154 };
1155 
1156 G_DEFINE_TYPE_WITH_CODE (SwtFixedAccessible, swt_fixed_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
1157 			 G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, swt_fixed_accessible_action_iface_init)
1158 			 G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, swt_fixed_accessible_component_iface_init)
1159 			 G_IMPLEMENT_INTERFACE (ATK_TYPE_EDITABLE_TEXT, swt_fixed_accessible_editable_text_iface_init)
1160 			 G_IMPLEMENT_INTERFACE (ATK_TYPE_HYPERTEXT, swt_fixed_accessible_hypertext_iface_init)
1161 			 G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, swt_fixed_accessible_selection_iface_init)
1162 			 G_IMPLEMENT_INTERFACE (ATK_TYPE_TABLE, swt_fixed_accessible_table_iface_init)
1163 			 G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, swt_fixed_accessible_text_iface_init)
1164 			 G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, swt_fixed_accessible_value_iface_init)
1165 			 G_ADD_PRIVATE (SwtFixedAccessible))
1166 
1167 // Fully qualified Java class name for the Java implementation of ATK functions
1168 const char *ACCESSIBILITY_CLASS_NAME = "org/eclipse/swt/accessibility/AccessibleObject";
1169 
swt_fixed_accessible_init(SwtFixedAccessible * accessible)1170 static void swt_fixed_accessible_init (SwtFixedAccessible *accessible) {
1171 	// Initialize the SwtFixedAccessiblePrivate struct
1172 	accessible->priv = swt_fixed_accessible_get_instance_private (accessible);
1173 }
1174 
swt_fixed_accessible_class_init(SwtFixedAccessibleClass * klass)1175 static void swt_fixed_accessible_class_init (SwtFixedAccessibleClass *klass) {
1176 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
1177 	AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass);
1178 
1179 	// Override GObject functions
1180 	object_class->finalize = swt_fixed_accessible_finalize;
1181 
1182 	// Override AtkObject functions
1183 	atk_class->initialize = swt_fixed_accessible_initialize;
1184 	atk_class->get_attributes = swt_fixed_accessible_get_attributes;
1185 	atk_class->get_description = swt_fixed_accessible_get_description;
1186 	atk_class->get_index_in_parent = swt_fixed_accessible_get_index_in_parent;
1187 	atk_class->get_n_children = swt_fixed_accessible_get_n_children;
1188 	atk_class->get_name = swt_fixed_accessible_get_name;
1189 	atk_class->get_parent = swt_fixed_accessible_get_parent;
1190 	atk_class->get_role = swt_fixed_accessible_get_role;
1191 	atk_class->ref_child = swt_fixed_accessible_ref_child;
1192 	atk_class->ref_state_set = swt_fixed_accesssible_ref_state_set;
1193 
1194 }
1195 
swt_fixed_accessible_new(GtkWidget * widget)1196 AtkObject *swt_fixed_accessible_new (GtkWidget *widget) {
1197 	AtkObject *accessible;
1198 
1199 	g_return_val_if_fail (SWT_IS_FIXED (widget), NULL);
1200 
1201 	// Create the SwtFixedAccessible instance and call the initializer
1202 	accessible = g_object_new (SWT_TYPE_FIXED_ACCESSIBLE, NULL);
1203 	atk_object_initialize (accessible, widget);
1204 	// Set the widget for this accessible, as not all SwtFixed instances
1205 	// have a matching Java Accessible. See bug 536974.
1206 	gtk_accessible_set_widget (GTK_ACCESSIBLE (accessible), widget);
1207 
1208 	return accessible;
1209 }
1210 
swt_fixed_accessible_finalize(GObject * object)1211 static void swt_fixed_accessible_finalize (GObject *object) {
1212 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (object);
1213 	SwtFixedAccessiblePrivate *private = fixed->priv;
1214 	jlong returned_value = 0;
1215 
1216 	// Call the Java implementation to ensure AccessibleObjects are removed
1217 	// from the HashMap on the Java side.
1218 	if (private->has_accessible) {
1219 		returned_value = call_accessible_object_function("gObjectClass_finalize", "(J)J", object);
1220 		if (returned_value != 0) g_critical ("Undefined behavior calling gObjectClass_finalize from C\n");
1221 	}
1222 
1223 	// Chain up to the parent class
1224 	G_OBJECT_CLASS (swt_fixed_accessible_parent_class)->finalize (object);
1225 	return;
1226 }
1227 
1228 // This method is called from Java when an Accessible Java object that corresponds
1229 // to this SwtFixedAccessible instance has been created.
swt_fixed_accessible_register_accessible(AtkObject * obj,gboolean is_native,GtkWidget * to_map)1230 void swt_fixed_accessible_register_accessible (AtkObject *obj, gboolean is_native, GtkWidget *to_map) {
1231 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (obj);
1232 	SwtFixedAccessiblePrivate *private = fixed->priv;
1233 	private->has_accessible = TRUE;
1234 
1235 	if (!is_native) {
1236 		gtk_accessible_set_widget (GTK_ACCESSIBLE (obj), to_map);
1237 		private->widget = to_map;
1238 	} else {
1239 		// TODO_a11y: implement support for native GTK widgets on the Java side,
1240 		// some work might need to be done here.
1241 	}
1242 	return;
1243 }
1244 
swt_fixed_accessible_initialize(AtkObject * obj,gpointer data)1245 static void swt_fixed_accessible_initialize (AtkObject *obj, gpointer data) {
1246 	// Call parent class initializer function
1247 	if (ATK_OBJECT_CLASS (swt_fixed_accessible_parent_class)->initialize != NULL) {
1248 		ATK_OBJECT_CLASS (swt_fixed_accessible_parent_class)->initialize (obj, data);
1249 	}
1250 
1251 	SwtFixedAccessiblePrivate *private = SWT_FIXED_ACCESSIBLE (obj)->priv;
1252 	// If this SwtFixedAccessible instance has a corresponding Accessible
1253 	// Java object created for it, then we can map it to its widget. Otherwise,
1254 	// map it to NULL. This means that only widgets with an Accessible Java object
1255 	// created get ATK function/interface implementations.
1256 	if (private->has_accessible) {
1257 		gtk_accessible_set_widget (GTK_ACCESSIBLE (obj), GTK_WIDGET (data));
1258 	} else {
1259 		gtk_accessible_set_widget (GTK_ACCESSIBLE (obj), NULL);
1260 	}
1261 }
1262 
swt_fixed_accessible_get_attributes(AtkObject * obj)1263 static AtkAttributeSet *swt_fixed_accessible_get_attributes (AtkObject *obj) {
1264 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (obj);
1265 	SwtFixedAccessiblePrivate *private = fixed->priv;
1266 	jlong returned_value = 0;
1267 
1268 	if (private->has_accessible) {
1269 		returned_value = call_accessible_object_function("atkObject_get_attributes", "(J)J", obj);
1270 		return (AtkAttributeSet *) returned_value;
1271 	} else {
1272 		return ATK_OBJECT_CLASS (swt_fixed_accessible_parent_class)->get_attributes (obj);
1273 	}
1274 }
1275 
swt_fixed_accessible_get_description(AtkObject * obj)1276 static const gchar *swt_fixed_accessible_get_description (AtkObject *obj) {
1277 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (obj);
1278 	SwtFixedAccessiblePrivate *private = fixed->priv;
1279 	jlong returned_value = 0;
1280 
1281 	if (private->has_accessible) {
1282 		returned_value = call_accessible_object_function("atkObject_get_description", "(J)J", obj);
1283 		return (const gchar *) returned_value;
1284 	} else {
1285 		return ATK_OBJECT_CLASS (swt_fixed_accessible_parent_class)->get_description (obj);
1286 	}
1287 }
1288 
swt_fixed_accessible_get_index_in_parent(AtkObject * obj)1289 static gint swt_fixed_accessible_get_index_in_parent (AtkObject *obj) {
1290 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (obj);
1291 	SwtFixedAccessiblePrivate *private = fixed->priv;
1292 	jlong returned_value = 0;
1293 
1294 	if (private->has_accessible) {
1295 		returned_value = call_accessible_object_function("atkObject_get_index_in_parent", "(J)J", obj);
1296 		return (gint) returned_value;
1297 	} else {
1298 		return ATK_OBJECT_CLASS (swt_fixed_accessible_parent_class)->get_index_in_parent (obj);
1299 	}
1300 }
1301 
swt_fixed_accessible_get_n_children(AtkObject * obj)1302 static gint swt_fixed_accessible_get_n_children (AtkObject *obj) {
1303 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (obj);
1304 	SwtFixedAccessiblePrivate *private = fixed->priv;
1305 	jlong returned_value = 0;
1306 
1307 	if (private->has_accessible) {
1308 		returned_value = call_accessible_object_function("atkObject_get_n_children", "(J)J", obj);
1309 		return (gint) returned_value;
1310 	} else {
1311 		return ATK_OBJECT_CLASS (swt_fixed_accessible_parent_class)->get_n_children (obj);
1312 	}
1313 }
1314 
swt_fixed_accessible_get_name(AtkObject * obj)1315 static const gchar *swt_fixed_accessible_get_name (AtkObject *obj) {
1316 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (obj);
1317 	SwtFixedAccessiblePrivate *private = fixed->priv;
1318 	jlong returned_value = 0;
1319 
1320 	if (private->has_accessible) {
1321 		returned_value = call_accessible_object_function("atkObject_get_name", "(J)J", obj);
1322 		return (const gchar *) returned_value;
1323 	} else {
1324 		return ATK_OBJECT_CLASS (swt_fixed_accessible_parent_class)->get_name (obj);
1325 	}
1326 }
1327 
swt_fixed_accessible_get_parent(AtkObject * obj)1328 static AtkObject *swt_fixed_accessible_get_parent (AtkObject *obj) {
1329 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (obj);
1330 	SwtFixedAccessiblePrivate *private = fixed->priv;
1331 	jlong returned_value = 0;
1332 
1333 	if (private->has_accessible) {
1334 		returned_value = call_accessible_object_function("atkObject_get_parent", "(J)J", obj);
1335 		return (AtkObject *) returned_value;
1336 	} else {
1337 		return ATK_OBJECT_CLASS (swt_fixed_accessible_parent_class)->get_parent (obj);
1338 	}
1339 }
1340 
swt_fixed_accessible_get_role(AtkObject * obj)1341 static AtkRole swt_fixed_accessible_get_role (AtkObject *obj) {
1342 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (obj);
1343 	SwtFixedAccessiblePrivate *private = fixed->priv;
1344 	jlong returned_value = 0;
1345 
1346 	if (private->has_accessible) {
1347 		returned_value = call_accessible_object_function("atkObject_get_role", "(J)J", obj);
1348 		return returned_value;
1349 	} else {
1350 		return ATK_OBJECT_CLASS (swt_fixed_accessible_parent_class)->get_role (obj);
1351 	}
1352 }
1353 
swt_fixed_accessible_ref_child(AtkObject * obj,gint i)1354 static AtkObject *swt_fixed_accessible_ref_child (AtkObject *obj, gint i) {
1355 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (obj);
1356 	SwtFixedAccessiblePrivate *private = fixed->priv;
1357 	jlong returned_value = 0;
1358 
1359 	if (private->has_accessible) {
1360 		returned_value = call_accessible_object_function("atkObject_ref_child", "(JJ)J", obj, i);
1361 		return (AtkObject *) returned_value;
1362 	} else {
1363 		return ATK_OBJECT_CLASS (swt_fixed_accessible_parent_class)->ref_child (obj, i);
1364 	}
1365 }
1366 
swt_fixed_accesssible_ref_state_set(AtkObject * obj)1367 static AtkStateSet *swt_fixed_accesssible_ref_state_set (AtkObject *obj) {
1368 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (obj);
1369 	SwtFixedAccessiblePrivate *private = fixed->priv;
1370 	jlong returned_value = 0;
1371 
1372 	if (private->has_accessible) {
1373 		returned_value = call_accessible_object_function("atkObject_ref_state_set", "(J)J", obj);
1374 		return (AtkStateSet *) returned_value;
1375 	} else {
1376 		return ATK_OBJECT_CLASS (swt_fixed_accessible_parent_class)->ref_state_set (obj);
1377 	}
1378 }
1379 
swt_fixed_accessible_action_do_action(AtkAction * action,gint i)1380 static gboolean swt_fixed_accessible_action_do_action (AtkAction *action, gint i) {
1381 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (action);
1382 	SwtFixedAccessiblePrivate *private = fixed->priv;
1383 	jlong returned_value = 0;
1384 
1385 	if (private->has_accessible) {
1386 		returned_value = call_accessible_object_function("atkAction_do_action", "(JJ)J", action, i);
1387 	}
1388 	return ((gint) returned_value == 1) ? TRUE : FALSE;
1389 }
1390 
swt_fixed_accessible_action_get_description(AtkAction * action,gint i)1391 static const gchar *swt_fixed_accessible_action_get_description (AtkAction *action, gint i) {
1392 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (action);
1393 	SwtFixedAccessiblePrivate *private = fixed->priv;
1394 	jlong returned_value = 0;
1395 
1396 	if (private->has_accessible) {
1397 		returned_value = call_accessible_object_function("atkAction_get_description", "(JJ)J", action, i);
1398 	}
1399 	return (const gchar *) returned_value;
1400 }
1401 
swt_fixed_accessible_action_get_keybinding(AtkAction * action,gint i)1402 static const gchar *swt_fixed_accessible_action_get_keybinding (AtkAction *action, gint i) {
1403 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (action);
1404 	SwtFixedAccessiblePrivate *private = fixed->priv;
1405 	jlong returned_value = 0;
1406 
1407 	if (private->has_accessible) {
1408 		returned_value = call_accessible_object_function("atkAction_get_keybinding", "(JJ)J", action, i);
1409 	}
1410 	return (const gchar *) returned_value;
1411 }
1412 
swt_fixed_accessible_action_get_n_actions(AtkAction * action)1413 static gint swt_fixed_accessible_action_get_n_actions (AtkAction *action) {
1414 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (action);
1415 	SwtFixedAccessiblePrivate *private = fixed->priv;
1416 	jlong returned_value = 0;
1417 
1418 	if (private->has_accessible) {
1419 		returned_value = call_accessible_object_function("atkAction_get_n_actions", "(J)J", action);
1420 	}
1421 	return (gint) returned_value;
1422 }
1423 
swt_fixed_accessible_action_get_name(AtkAction * action,gint i)1424 static const gchar *swt_fixed_accessible_action_get_name (AtkAction *action, gint i) {
1425 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (action);
1426 	SwtFixedAccessiblePrivate *private = fixed->priv;
1427 	jlong returned_value = 0;
1428 
1429 	if (private->has_accessible) {
1430 		returned_value = call_accessible_object_function("atkAction_get_name", "(JJ)J", action, i);
1431 	}
1432 	return (const gchar *) returned_value;
1433 }
1434 
swt_fixed_accessible_component_get_extents(AtkComponent * component,gint * x,gint * y,gint * width,gint * height,AtkCoordType coord_type)1435 static void swt_fixed_accessible_component_get_extents (AtkComponent *component, gint *x, gint *y,
1436 		gint *width, gint *height, AtkCoordType coord_type) {
1437 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (component);
1438 	SwtFixedAccessiblePrivate *private = fixed->priv;
1439 	if (private->has_accessible) {
1440 		call_accessible_object_function("atkComponent_get_extents", "(JJJJJJ)J", component, x, y,
1441 			width, height, coord_type);
1442 	} else {
1443 		GtkWidget *widget = gtk_accessible_get_widget(GTK_ACCESSIBLE(fixed));
1444 		gint fixed_x, fixed_y;
1445 		GtkAllocation allocation;
1446 		gtk_widget_get_allocation(widget, &allocation);
1447 		#if defined(GTK4)
1448 			GdkSurface *surface = gtk_widget_get_surface(widget);
1449 			call_accessible_object_function("toDisplay", "(JJJ)J", surface, &fixed_x, &fixed_y);
1450 			if (coord_type == ATK_XY_SCREEN) {
1451 				*x = fixed_x;
1452 				*y = fixed_y;
1453 			}
1454 			if (coord_type == ATK_XY_WINDOW) {
1455 				GtkWidget *top = gtk_widget_get_toplevel(widget);
1456 				GdkSurface *top_surface = gtk_widget_get_surface(top);
1457 				gint top_x, top_y;
1458 				call_accessible_object_function("toDisplay", "(JJJ)J", top_surface, &top_x, &top_y);
1459 				*x = fixed_x - top_x;
1460 				*y = fixed_y - top_y;
1461 			}
1462 		#else
1463 			GdkWindow *window = gtk_widget_get_window(widget);
1464 			call_accessible_object_function("toDisplay", "(JJJ)J", window, &fixed_x, &fixed_y);
1465 			if (coord_type == ATK_XY_SCREEN) {
1466 				*x = fixed_x;
1467 				*y = fixed_y;
1468 			}
1469 			if (coord_type == ATK_XY_WINDOW) {
1470 				GtkWidget *top = gtk_widget_get_toplevel(widget);
1471 				GdkWindow *top_window = gtk_widget_get_window(top);
1472 				gint top_x, top_y;
1473 				call_accessible_object_function("toDisplay", "(JJJ)J", top_window, &top_x, &top_y);
1474 				*x = fixed_x - top_x;
1475 				*y = fixed_y - top_y;
1476 			}
1477 		#endif
1478 		*width = allocation.width;
1479 		*height = allocation.height;
1480 	}
1481 	return;
1482 }
1483 
swt_fixed_accessible_component_ref_accessible_at_point(AtkComponent * component,gint x,gint y,AtkCoordType coord_type)1484 static AtkObject *swt_fixed_accessible_component_ref_accessible_at_point (AtkComponent *component, gint x,
1485 		gint y, AtkCoordType coord_type) {
1486 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (component);
1487 	SwtFixedAccessiblePrivate *private = fixed->priv;
1488 	jlong returned_value = 0;
1489 
1490 	if (private->has_accessible) {
1491 		returned_value = call_accessible_object_function("atkComponent_ref_accessible_at_point", "(JJJJ)J",
1492 				component, x, y, coord_type);
1493 	}
1494 	return (AtkObject *) returned_value;
1495 }
1496 
swt_fixed_accessible_editable_text_copy_text(AtkEditableText * text,gint start_pos,gint end_pos)1497 static void swt_fixed_accessible_editable_text_copy_text (AtkEditableText *text, gint start_pos, gint end_pos) {
1498 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1499 	SwtFixedAccessiblePrivate *private = fixed->priv;
1500 
1501 	if (private->has_accessible) {
1502 		call_accessible_object_function("atkEditableText_copy_text", "(JJJ)J", text, start_pos, end_pos);
1503 	}
1504 	return;
1505 }
1506 
swt_fixed_accessible_editable_text_cut_text(AtkEditableText * text,gint start_pos,gint end_pos)1507 static void swt_fixed_accessible_editable_text_cut_text (AtkEditableText *text, gint start_pos, gint end_pos) {
1508 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1509 	SwtFixedAccessiblePrivate *private = fixed->priv;
1510 
1511 	if (private->has_accessible) {
1512 		call_accessible_object_function("atkEditableText_cut_text", "(JJJ)J", text, start_pos, end_pos);
1513 	}
1514 	return;
1515 }
1516 
swt_fixed_accessible_editable_text_delete_text(AtkEditableText * text,gint start_pos,gint end_pos)1517 static void swt_fixed_accessible_editable_text_delete_text (AtkEditableText *text, gint start_pos, gint end_pos) {
1518 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1519 	SwtFixedAccessiblePrivate *private = fixed->priv;
1520 
1521 	if (private->has_accessible) {
1522 		call_accessible_object_function("atkEditableText_delete_text", "(JJJ)J", text, start_pos, end_pos);
1523 	}
1524 	return;
1525 }
1526 
swt_fixed_accessible_editable_text_insert_text(AtkEditableText * text,const gchar * string,gint length,gint * position)1527 static void swt_fixed_accessible_editable_text_insert_text (AtkEditableText *text, const gchar *string,
1528 		gint length, gint *position) {
1529 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1530 	SwtFixedAccessiblePrivate *private = fixed->priv;
1531 
1532 	if (private->has_accessible) {
1533 		call_accessible_object_function("atkEditableText_insert_text", "(JJJJ)J", text, string, length, position);
1534 	}
1535 	return;
1536 }
1537 
swt_fixed_accessible_editable_text_paste_text(AtkEditableText * text,gint position)1538 static void swt_fixed_accessible_editable_text_paste_text (AtkEditableText *text, gint position) {
1539 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1540 	SwtFixedAccessiblePrivate *private = fixed->priv;
1541 
1542 	if (private->has_accessible) {
1543 		call_accessible_object_function("atkEditableText_paste_text", "(JJ)J", text, position);
1544 	}
1545 	return;
1546 }
1547 
swt_fixed_accessible_editable_text_set_run_attributes(AtkEditableText * text,AtkAttributeSet * attrib_set,gint start_offset,gint end_offset)1548 static gboolean swt_fixed_accessible_editable_text_set_run_attributes (AtkEditableText *text,
1549 		AtkAttributeSet *attrib_set, gint start_offset, gint end_offset) {
1550 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1551 	SwtFixedAccessiblePrivate *private = fixed->priv;
1552 	jlong returned_value = 0;
1553 
1554 	if (private->has_accessible) {
1555 		returned_value = call_accessible_object_function("atkEditableText_set_run_attributes", "(JJJJ)J",
1556 				attrib_set, start_offset, end_offset);
1557 	}
1558 	return ((gint) returned_value == 1) ? TRUE : FALSE;
1559 }
1560 
swt_fixed_accessible_editable_text_set_text_contents(AtkEditableText * text,const gchar * string)1561 static void swt_fixed_accessible_editable_text_set_text_contents (AtkEditableText *text, const gchar *string) {
1562 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1563 	SwtFixedAccessiblePrivate *private = fixed->priv;
1564 
1565 	if (private->has_accessible) {
1566 		call_accessible_object_function("atkEditableText_set_text_contents", "(JJ)J", text, string);
1567 	}
1568 	return;
1569 }
1570 
swt_fixed_accessible_hypertext_get_link(AtkHypertext * hypertext,gint link_index)1571 static AtkHyperlink *swt_fixed_accessible_hypertext_get_link (AtkHypertext *hypertext, gint link_index) {
1572 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (hypertext);
1573 	SwtFixedAccessiblePrivate *private = fixed->priv;
1574 	jlong returned_value = 0;
1575 
1576 	if (private->has_accessible) {
1577 		returned_value = call_accessible_object_function("atkHypertext_get_link", "(JJ)J", hypertext, link_index);
1578 	}
1579 	return (AtkHyperlink *) returned_value;
1580 }
1581 
swt_fixed_accessible_hypertext_get_link_index(AtkHypertext * hypertext,gint char_index)1582 static gint swt_fixed_accessible_hypertext_get_link_index (AtkHypertext *hypertext, gint char_index) {
1583 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (hypertext);
1584 	SwtFixedAccessiblePrivate *private = fixed->priv;
1585 	jlong returned_value = 0;
1586 
1587 	if (private->has_accessible) {
1588 		returned_value = call_accessible_object_function("atkHypertext_get_link_index", "(JJ)J", hypertext, char_index);
1589 	}
1590 	return (gint) returned_value;
1591 }
1592 
swt_fixed_accessible_hypertext_get_n_links(AtkHypertext * hypertext)1593 static gint swt_fixed_accessible_hypertext_get_n_links (AtkHypertext *hypertext) {
1594 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (hypertext);
1595 	SwtFixedAccessiblePrivate *private = fixed->priv;
1596 	jlong returned_value = 0;
1597 
1598 	if (private->has_accessible) {
1599 		returned_value = call_accessible_object_function("atkHypertext_get_n_links", "(J)J", hypertext);
1600 	}
1601 	return (gint) returned_value;
1602 }
1603 
swt_fixed_accessible_selection_is_child_selected(AtkSelection * selection,gint i)1604 static gboolean swt_fixed_accessible_selection_is_child_selected (AtkSelection *selection, gint i) {
1605 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (selection);
1606 	SwtFixedAccessiblePrivate *private = fixed->priv;
1607 	jlong returned_value = 0;
1608 
1609 	if (private->has_accessible) {
1610 		returned_value = call_accessible_object_function("atkSelection_is_child_selected", "(JJ)J", selection, i);
1611 	}
1612 	return ((gint) returned_value == 1) ? TRUE : FALSE;
1613 }
1614 
swt_fixed_accessible_selection_ref_selection(AtkSelection * selection,gint i)1615 static AtkObject *swt_fixed_accessible_selection_ref_selection (AtkSelection *selection, gint i) {
1616 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (selection);
1617 	SwtFixedAccessiblePrivate *private = fixed->priv;
1618 	jlong returned_value = 0;
1619 
1620 	if (private->has_accessible) {
1621 		returned_value = call_accessible_object_function("atkSelection_ref_selection", "(JJ)J", selection, i);
1622 	}
1623 	return (AtkObject *) returned_value;
1624 }
1625 
swt_fixed_accessible_table_ref_at(AtkTable * table,gint row,gint column)1626 static AtkObject *swt_fixed_accessible_table_ref_at (AtkTable *table, gint row, gint column) {
1627 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1628 	SwtFixedAccessiblePrivate *private = fixed->priv;
1629 	jlong returned_value = 0;
1630 
1631 	if (private->has_accessible) {
1632 		returned_value = call_accessible_object_function("atkTable_ref_at", "(JJJ)J", table, row, column);
1633 	}
1634 	return (AtkObject *) returned_value;
1635 }
1636 
swt_fixed_accessible_table_get_index_at(AtkTable * table,gint row,gint column)1637 static gint swt_fixed_accessible_table_get_index_at (AtkTable *table, gint row, gint column) {
1638 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1639 	SwtFixedAccessiblePrivate *private = fixed->priv;
1640 	jlong returned_value = 0;
1641 
1642 	if (private->has_accessible) {
1643 		returned_value = call_accessible_object_function("atkTable_get_index_at", "(JJJ)J", table, row, column);
1644 	}
1645 	return (gint) returned_value;
1646 }
1647 
swt_fixed_accessible_table_get_column_at_index(AtkTable * table,gint index)1648 static gint swt_fixed_accessible_table_get_column_at_index (AtkTable *table, gint index) {
1649 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1650 	SwtFixedAccessiblePrivate *private = fixed->priv;
1651 	jlong returned_value = 0;
1652 
1653 	if (private->has_accessible) {
1654 		returned_value = call_accessible_object_function("atkTable_get_column_at_index", "(JJ)J", table, index);
1655 	}
1656 	return (gint) returned_value;
1657 }
1658 
swt_fixed_accessible_table_get_row_at_index(AtkTable * table,gint index)1659 static gint swt_fixed_accessible_table_get_row_at_index (AtkTable *table, gint index) {
1660 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1661 	SwtFixedAccessiblePrivate *private = fixed->priv;
1662 	jlong returned_value = 0;
1663 
1664 	if (private->has_accessible) {
1665 		returned_value = call_accessible_object_function("atkTable_get_row_at_index", "(JJ)J", table, index);
1666 	}
1667 	return (gint) returned_value;
1668 }
1669 
swt_fixed_accessible_table_get_n_columns(AtkTable * table)1670 static gint swt_fixed_accessible_table_get_n_columns (AtkTable *table) {
1671 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1672 	SwtFixedAccessiblePrivate *private = fixed->priv;
1673 	jlong returned_value = 0;
1674 
1675 	if (private->has_accessible) {
1676 		returned_value = call_accessible_object_function("atkTable_get_n_columns", "(J)J", table);
1677 	}
1678 	return (gint) returned_value;
1679 }
1680 
swt_fixed_accessible_table_get_n_rows(AtkTable * table)1681 static gint swt_fixed_accessible_table_get_n_rows (AtkTable *table) {
1682 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1683 	SwtFixedAccessiblePrivate *private = fixed->priv;
1684 	jlong returned_value = 0;
1685 
1686 	if (private->has_accessible) {
1687 		returned_value = call_accessible_object_function("atkTable_get_n_rows", "(J)J", table);
1688 	}
1689 	return (gint) returned_value;
1690 }
1691 
swt_fixed_accessible_table_get_column_extent_at(AtkTable * table,gint row,gint column)1692 static gint swt_fixed_accessible_table_get_column_extent_at (AtkTable *table, gint row, gint column) {
1693 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1694 	SwtFixedAccessiblePrivate *private = fixed->priv;
1695 	jlong returned_value = 0;
1696 
1697 	if (private->has_accessible) {
1698 		returned_value = call_accessible_object_function("atkTable_get_column_extent_at", "(JJJ)J",
1699 			table, row, column);
1700 	}
1701 	return (gint) returned_value;
1702 }
1703 
swt_fixed_accessible_table_get_row_extent_at(AtkTable * table,gint row,gint column)1704 static gint swt_fixed_accessible_table_get_row_extent_at (AtkTable *table, gint row, gint column) {
1705 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1706 	SwtFixedAccessiblePrivate *private = fixed->priv;
1707 	jlong returned_value = 0;
1708 
1709 	if (private->has_accessible) {
1710 		returned_value = call_accessible_object_function("atkTable_get_row_extent_at", "(JJJ)J",
1711 			table, row, column);
1712 	}
1713 	return (gint) returned_value;
1714 }
1715 
swt_fixed_accessible_table_get_caption(AtkTable * table)1716 static AtkObject *swt_fixed_accessible_table_get_caption (AtkTable *table) {
1717 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1718 	SwtFixedAccessiblePrivate *private = fixed->priv;
1719 	jlong returned_value = 0;
1720 
1721 	if (private->has_accessible) {
1722 		returned_value = call_accessible_object_function("atkTable_get_caption", "(J)J", table);
1723 	}
1724 	return (AtkObject *) returned_value;
1725 }
1726 
swt_fixed_accessible_table_get_summary(AtkTable * table)1727 static AtkObject *swt_fixed_accessible_table_get_summary (AtkTable *table) {
1728 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1729 	SwtFixedAccessiblePrivate *private = fixed->priv;
1730 	jlong returned_value = 0;
1731 
1732 	if (private->has_accessible) {
1733 		returned_value = call_accessible_object_function("atkTable_get_summary", "(J)J", table);
1734 	}
1735 	return (AtkObject *) returned_value;
1736 }
1737 
swt_fixed_accessible_table_get_column_description(AtkTable * table,gint column)1738 static const gchar *swt_fixed_accessible_table_get_column_description (AtkTable *table, gint column) {
1739 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1740 	SwtFixedAccessiblePrivate *private = fixed->priv;
1741 	jlong returned_value = 0;
1742 
1743 	if (private->has_accessible) {
1744 		returned_value = call_accessible_object_function("atkTable_get_column_description", "(JJ)J",
1745 			table, column);
1746 	}
1747 	return (const gchar *) returned_value;
1748 }
1749 
swt_fixed_accessible_table_get_column_header(AtkTable * table,gint column)1750 static AtkObject *swt_fixed_accessible_table_get_column_header (AtkTable *table, gint column) {
1751 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1752 	SwtFixedAccessiblePrivate *private = fixed->priv;
1753 	jlong returned_value = 0;
1754 
1755 	if (private->has_accessible) {
1756 		returned_value = call_accessible_object_function("atkTable_get_column_header", "(JJ)J",
1757 			table, column);
1758 	}
1759 	return (AtkObject *) returned_value;
1760 }
1761 
swt_fixed_accessible_table_get_row_description(AtkTable * table,gint row)1762 static const gchar *swt_fixed_accessible_table_get_row_description (AtkTable *table, gint row) {
1763 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1764 	SwtFixedAccessiblePrivate *private = fixed->priv;
1765 	jlong returned_value = 0;
1766 
1767 	if (private->has_accessible) {
1768 		returned_value = call_accessible_object_function("atkTable_get_row_description", "(JJ)J",
1769 			table, row);
1770 	}
1771 	return (const gchar *) returned_value;
1772 }
1773 
swt_fixed_accessible_table_get_row_header(AtkTable * table,gint row)1774 static AtkObject *swt_fixed_accessible_table_get_row_header (AtkTable *table, gint row) {
1775 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1776 	SwtFixedAccessiblePrivate *private = fixed->priv;
1777 	jlong returned_value = 0;
1778 
1779 	if (private->has_accessible) {
1780 		returned_value = call_accessible_object_function("atkTable_get_row_header", "(JJ)J",
1781 			table, row);
1782 	}
1783 	return (AtkObject *) returned_value;
1784 }
1785 
swt_fixed_accessible_table_get_selected_rows(AtkTable * table,gint ** selected)1786 static gint swt_fixed_accessible_table_get_selected_rows (AtkTable *table, gint **selected) {
1787 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1788 	SwtFixedAccessiblePrivate *private = fixed->priv;
1789 	jlong returned_value = 0;
1790 
1791 	if (private->has_accessible) {
1792 		returned_value = call_accessible_object_function("atkTable_get_selected_rows", "(JJ)J",
1793 			table, selected);
1794 	}
1795 	return (gint) returned_value;
1796 }
1797 
swt_fixed_accessible_table_get_selected_columns(AtkTable * table,gint ** selected)1798 static gint swt_fixed_accessible_table_get_selected_columns (AtkTable *table, gint **selected) {
1799 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1800 	SwtFixedAccessiblePrivate *private = fixed->priv;
1801 	jlong returned_value = 0;
1802 
1803 	if (private->has_accessible) {
1804 		returned_value = call_accessible_object_function("atkTable_get_selected_columns", "(JJ)J",
1805 			table, selected);
1806 	}
1807 	return (gint) returned_value;
1808 }
1809 
swt_fixed_accessible_table_is_column_selected(AtkTable * table,gint column)1810 static gboolean swt_fixed_accessible_table_is_column_selected (AtkTable *table, gint column) {
1811 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1812 	SwtFixedAccessiblePrivate *private = fixed->priv;
1813 	jlong returned_value = 0;
1814 
1815 	if (private->has_accessible) {
1816 		returned_value = call_accessible_object_function("atkTable_is_column_selected", "(JJ)J",
1817 			table, column);
1818 	}
1819 	return ((gint) returned_value == 1) ? TRUE : FALSE;
1820 }
1821 
swt_fixed_accessible_table_is_row_selected(AtkTable * table,gint row)1822 static gboolean swt_fixed_accessible_table_is_row_selected (AtkTable *table, gint row) {
1823 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1824 	SwtFixedAccessiblePrivate *private = fixed->priv;
1825 	jlong returned_value = 0;
1826 
1827 	if (private->has_accessible) {
1828 		returned_value = call_accessible_object_function("atkTable_is_row_selected", "(JJ)J",
1829 			table, row);
1830 	}
1831 	return ((gint) returned_value == 1) ? TRUE : FALSE;
1832 }
1833 
swt_fixed_accessible_table_is_selected(AtkTable * table,gint row,gint column)1834 static gboolean swt_fixed_accessible_table_is_selected (AtkTable *table, gint row, gint column) {
1835 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1836 	SwtFixedAccessiblePrivate *private = fixed->priv;
1837 	jlong returned_value = 0;
1838 
1839 	if (private->has_accessible) {
1840 		returned_value = call_accessible_object_function("atkTable_is_selected", "(JJJ)J",
1841 			table, row, column);
1842 	}
1843 	return ((gint) returned_value == 1) ? TRUE : FALSE;
1844 }
1845 
swt_fixed_accessible_table_add_row_selection(AtkTable * table,gint row)1846 static gboolean swt_fixed_accessible_table_add_row_selection (AtkTable *table, gint row) {
1847 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1848 	SwtFixedAccessiblePrivate *private = fixed->priv;
1849 	jlong returned_value = 0;
1850 
1851 	if (private->has_accessible) {
1852 		returned_value = call_accessible_object_function("atkTable_add_row_selection", "(JJ)J",
1853 			table, row);
1854 	}
1855 	return ((gint) returned_value == 1) ? TRUE : FALSE;
1856 }
1857 
swt_fixed_accessible_table_remove_row_selection(AtkTable * table,gint row)1858 static gboolean swt_fixed_accessible_table_remove_row_selection (AtkTable *table, gint row) {
1859 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1860 	SwtFixedAccessiblePrivate *private = fixed->priv;
1861 	jlong returned_value = 0;
1862 
1863 	if (private->has_accessible) {
1864 		returned_value = call_accessible_object_function("atkTable_remove_row_selection", "(JJ)J",
1865 			table, row);
1866 	}
1867 	return ((gint) returned_value == 1) ? TRUE : FALSE;
1868 }
1869 
swt_fixed_accessible_table_add_column_selection(AtkTable * table,gint column)1870 static gboolean swt_fixed_accessible_table_add_column_selection (AtkTable *table, gint column) {
1871 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1872 	SwtFixedAccessiblePrivate *private = fixed->priv;
1873 	jlong returned_value = 0;
1874 
1875 	if (private->has_accessible) {
1876 		returned_value = call_accessible_object_function("atkTable_add_column_selection", "(JJ)J",
1877 			table, column);
1878 	}
1879 	return ((gint) returned_value == 1) ? TRUE : FALSE;
1880 }
1881 
swt_fixed_accessible_table_remove_column_selection(AtkTable * table,gint column)1882 static gboolean swt_fixed_accessible_table_remove_column_selection (AtkTable *table, gint column) {
1883 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (table);
1884 	SwtFixedAccessiblePrivate *private = fixed->priv;
1885 	jlong returned_value = 0;
1886 
1887 	if (private->has_accessible) {
1888 		returned_value = call_accessible_object_function("atkTable_remove_row_selection", "(JJ)J",
1889 			table, column);
1890 	}
1891 	return ((gint) returned_value == 1) ? TRUE : FALSE;
1892 }
1893 
swt_fixed_accessible_text_add_selection(AtkText * text,gint start_offset,gint end_offset)1894 static gboolean swt_fixed_accessible_text_add_selection (AtkText *text, gint start_offset, gint end_offset) {
1895 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1896 	SwtFixedAccessiblePrivate *private = fixed->priv;
1897 	jlong returned_value = 0;
1898 
1899 	if (private->has_accessible) {
1900 		returned_value = call_accessible_object_function("atkText_add_selection", "(JJJ)J",
1901 			text, start_offset, end_offset);
1902 	}
1903 	return ((gint) returned_value == 1) ? TRUE : FALSE;
1904 }
1905 
swt_fixed_accessible_text_get_bounded_ranges(AtkText * text,AtkTextRectangle * rect,AtkCoordType coord_type,AtkTextClipType x_clip_type,AtkTextClipType y_clip_type)1906 static AtkTextRange **swt_fixed_accessible_text_get_bounded_ranges (AtkText *text, AtkTextRectangle *rect,
1907 		AtkCoordType coord_type, AtkTextClipType x_clip_type, AtkTextClipType y_clip_type) {
1908 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1909 	SwtFixedAccessiblePrivate *private = fixed->priv;
1910 	jlong returned_value = 0;
1911 
1912 	if (private->has_accessible) {
1913 		returned_value = call_accessible_object_function("atkText_get_bounded_ranges", "(JJJJJ)J",
1914 			text, rect, coord_type, x_clip_type, y_clip_type);
1915 	}
1916 	return (AtkTextRange **) returned_value;
1917 }
1918 
swt_fixed_accessible_text_get_caret_offset(AtkText * text)1919 static gint swt_fixed_accessible_text_get_caret_offset (AtkText *text) {
1920 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1921 	SwtFixedAccessiblePrivate *private = fixed->priv;
1922 	jlong returned_value = 0;
1923 
1924 	if (private->has_accessible) {
1925 		returned_value = call_accessible_object_function("atkText_get_caret_offset", "(J)J", text);
1926 	}
1927 	return (gint) returned_value;
1928 }
1929 
swt_fixed_accessible_text_get_character_at_offset(AtkText * text,gint offset)1930 static gunichar swt_fixed_accessible_text_get_character_at_offset (AtkText *text, gint offset) {
1931 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1932 	SwtFixedAccessiblePrivate *private = fixed->priv;
1933 	jlong returned_value = 0;
1934 
1935 	if (private->has_accessible) {
1936 		returned_value = call_accessible_object_function("atkText_get_character_at_offset", "(JJ)J", text, offset);
1937 	}
1938 	return (gunichar) returned_value;
1939 }
1940 
swt_fixed_accessible_text_get_character_count(AtkText * text)1941 static gint swt_fixed_accessible_text_get_character_count (AtkText *text) {
1942 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1943 	SwtFixedAccessiblePrivate *private = fixed->priv;
1944 	jlong returned_value = 0;
1945 
1946 	if (private->has_accessible) {
1947 		returned_value = call_accessible_object_function("atkText_get_character_count", "(J)J", text);
1948 	}
1949 	return (gint) returned_value;
1950 }
1951 
swt_fixed_accessible_text_get_n_selections(AtkText * text)1952 static gint swt_fixed_accessible_text_get_n_selections (AtkText *text) {
1953 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1954 	SwtFixedAccessiblePrivate *private = fixed->priv;
1955 	jlong returned_value = 0;
1956 
1957 	if (private->has_accessible) {
1958 		returned_value = call_accessible_object_function("atkText_get_n_selections", "(J)J", text);
1959 	}
1960 	return (gint) returned_value;
1961 }
1962 
swt_fixed_accessible_text_get_offset_at_point(AtkText * text,gint x,gint y,AtkCoordType coords)1963 static gint swt_fixed_accessible_text_get_offset_at_point (AtkText *text, gint x, gint y,
1964 		AtkCoordType coords) {
1965 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1966 	SwtFixedAccessiblePrivate *private = fixed->priv;
1967 	jlong returned_value = 0;
1968 
1969 	if (private->has_accessible) {
1970 		returned_value = call_accessible_object_function("atkText_get_offset_at_point", "(JJJJ)J", text, x, y, coords);
1971 	}
1972 	return (gint) returned_value;
1973 }
1974 
swt_fixed_accessible_text_get_range_extents(AtkText * text,gint start_offset,gint end_offset,AtkCoordType coord_type,AtkTextRectangle * rect)1975 static void swt_fixed_accessible_text_get_range_extents (AtkText *text, gint start_offset, gint end_offset,
1976 		AtkCoordType coord_type, AtkTextRectangle *rect) {
1977 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1978 	SwtFixedAccessiblePrivate *private = fixed->priv;
1979 
1980 	if (private->has_accessible) {
1981 		call_accessible_object_function("atkText_get_range_extents", "(JJJJJ)J", text,
1982 			start_offset, end_offset, coord_type, rect);
1983 	}
1984 	return;
1985 }
1986 
swt_fixed_accessible_text_get_run_attributes(AtkText * text,gint offset,gint * start_offset,gint * end_offset)1987 static AtkAttributeSet *swt_fixed_accessible_text_get_run_attributes (AtkText *text, gint offset, gint *start_offset,
1988 		gint *end_offset) {
1989 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
1990 	SwtFixedAccessiblePrivate *private = fixed->priv;
1991 	jlong returned_value = 0;
1992 
1993 	if (private->has_accessible) {
1994 		returned_value = call_accessible_object_function("atkText_get_run_attributes", "(JJJJ)J", text,
1995 			offset, start_offset, end_offset);
1996 	}
1997 	return (AtkAttributeSet *) returned_value;
1998 }
1999 
swt_fixed_accessible_text_get_selection(AtkText * text,gint selection_num,gint * start_offset,gint * end_offset)2000 static gchar *swt_fixed_accessible_text_get_selection (AtkText *text, gint selection_num, gint *start_offset,
2001 		gint *end_offset) {
2002 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
2003 	SwtFixedAccessiblePrivate *private = fixed->priv;
2004 	jlong returned_value = 0;
2005 
2006 	if (private->has_accessible) {
2007 		returned_value = call_accessible_object_function("atkText_get_selection", "(JJJJ)J", text,
2008 			selection_num, start_offset, end_offset);
2009 	}
2010 	return (gchar *) returned_value;
2011 }
2012 
swt_fixed_accessible_text_get_text(AtkText * text,gint start_offset,gint end_offset)2013 static gchar *swt_fixed_accessible_text_get_text (AtkText *text, gint start_offset, gint end_offset) {
2014 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
2015 	SwtFixedAccessiblePrivate *private = fixed->priv;
2016 	jlong returned_value = 0;
2017 
2018 	if (private->has_accessible) {
2019 		returned_value = call_accessible_object_function("atkText_get_text", "(JJJ)J", text,
2020 			start_offset, end_offset);
2021 	}
2022 	return (gchar *) returned_value;
2023 }
2024 
swt_fixed_accessible_text_get_text_after_offset(AtkText * text,gint offset,AtkTextBoundary boundary_type,gint * start_offset,gint * end_offset)2025 static gchar *swt_fixed_accessible_text_get_text_after_offset (AtkText *text, gint offset,
2026 		AtkTextBoundary boundary_type, gint *start_offset, gint *end_offset) {
2027 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
2028 	SwtFixedAccessiblePrivate *private = fixed->priv;
2029 	jlong returned_value = 0;
2030 
2031 	if (private->has_accessible) {
2032 		returned_value = call_accessible_object_function("atkText_get_text_after_offset", "(JJJJJ)J", text,
2033 			offset, boundary_type, start_offset, end_offset);
2034 	}
2035 	return (gchar *) returned_value;
2036 }
2037 
swt_fixed_accessible_text_get_text_at_offset(AtkText * text,gint offset,AtkTextBoundary boundary_type,gint * start_offset,gint * end_offset)2038 static gchar *swt_fixed_accessible_text_get_text_at_offset (AtkText *text, gint offset,
2039 		AtkTextBoundary boundary_type, gint *start_offset, gint *end_offset) {
2040 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
2041 	SwtFixedAccessiblePrivate *private = fixed->priv;
2042 	jlong returned_value = 0;
2043 
2044 	if (private->has_accessible) {
2045 		returned_value = call_accessible_object_function("atkText_get_text_at_offset", "(JJJJJ)J", text,
2046 			offset, boundary_type, start_offset, end_offset);
2047 	}
2048 	return (gchar *) returned_value;
2049 }
2050 
swt_fixed_accessible_text_get_text_before_offset(AtkText * text,gint offset,AtkTextBoundary boundary_type,gint * start_offset,gint * end_offset)2051 static gchar *swt_fixed_accessible_text_get_text_before_offset (AtkText *text, gint offset,
2052 		AtkTextBoundary boundary_type, gint *start_offset, gint *end_offset) {
2053 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
2054 	SwtFixedAccessiblePrivate *private = fixed->priv;
2055 	jlong returned_value = 0;
2056 
2057 	if (private->has_accessible) {
2058 		returned_value = call_accessible_object_function("atkText_get_text_before_offset", "(JJJJJ)J", text,
2059 			offset, boundary_type, start_offset, end_offset);
2060 	}
2061 	return (gchar *) returned_value;
2062 }
2063 
swt_fixed_accessible_text_remove_selection(AtkText * text,gint selection_num)2064 static gboolean swt_fixed_accessible_text_remove_selection (AtkText *text, gint selection_num) {
2065 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
2066 	SwtFixedAccessiblePrivate *private = fixed->priv;
2067 	jlong returned_value = 0;
2068 
2069 	if (private->has_accessible) {
2070 		returned_value = call_accessible_object_function("atkText_remove_selection", "(JJ)J", text, selection_num);
2071 	}
2072 	return ((gint) returned_value == 1) ? TRUE : FALSE;
2073 }
2074 
swt_fixed_accessible_text_set_caret_offset(AtkText * text,gint offset)2075 static gboolean swt_fixed_accessible_text_set_caret_offset (AtkText *text, gint offset) {
2076 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
2077 	SwtFixedAccessiblePrivate *private = fixed->priv;
2078 	jlong returned_value = 0;
2079 
2080 	if (private->has_accessible) {
2081 		returned_value = call_accessible_object_function("atkText_set_caret_offset", "(JJ)J", text, offset);
2082 	}
2083 	return ((gint) returned_value == 1) ? TRUE : FALSE;
2084 }
2085 
swt_fixed_accessible_text_set_selection(AtkText * text,gint selection_num,gint start_offset,gint end_offset)2086 static gboolean swt_fixed_accessible_text_set_selection (AtkText *text, gint selection_num,
2087 		gint start_offset, gint end_offset) {
2088 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (text);
2089 	SwtFixedAccessiblePrivate *private = fixed->priv;
2090 	jlong returned_value = 0;
2091 
2092 	if (private->has_accessible) {
2093 		returned_value = call_accessible_object_function("atkText_set_selection", "(JJJJ)J", text,
2094 			selection_num, start_offset, end_offset);
2095 	}
2096 	return ((gint) returned_value == 1) ? TRUE : FALSE;
2097 }
2098 
swt_fixed_accessible_value_get_current_value(AtkValue * obj,GValue * value)2099 static void swt_fixed_accessible_value_get_current_value (AtkValue *obj, GValue *value) {
2100 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (obj);
2101 	SwtFixedAccessiblePrivate *private = fixed->priv;
2102 
2103 	if (private->has_accessible) {
2104 		call_accessible_object_function("atkValue_get_current_value", "(JJ)J", obj, value);
2105 	}
2106 	return;
2107 }
2108 
swt_fixed_accessible_value_get_maximum_value(AtkValue * obj,GValue * value)2109 static void swt_fixed_accessible_value_get_maximum_value (AtkValue *obj, GValue *value) {
2110 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (obj);
2111 	SwtFixedAccessiblePrivate *private = fixed->priv;
2112 
2113 	if (private->has_accessible) {
2114 		call_accessible_object_function("atkValue_get_maximum_value", "(JJ)J", obj, value);
2115 	}
2116 	return;
2117 }
2118 
swt_fixed_accessible_value_get_minimum_value(AtkValue * obj,GValue * value)2119 static void swt_fixed_accessible_value_get_minimum_value (AtkValue *obj, GValue *value) {
2120 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (obj);
2121 	SwtFixedAccessiblePrivate *private = fixed->priv;
2122 
2123 	if (private->has_accessible) {
2124 		call_accessible_object_function("atkValue_get_minimum_value", "(JJ)J", obj, value);
2125 	}
2126 	return;
2127 }
2128 
swt_fixed_accessible_value_set_current_value(AtkValue * obj,const GValue * value)2129 static gboolean swt_fixed_accessible_value_set_current_value (AtkValue *obj, const GValue *value) {
2130 	SwtFixedAccessible *fixed = SWT_FIXED_ACCESSIBLE (obj);
2131 	SwtFixedAccessiblePrivate *private = fixed->priv;
2132 	jlong returned_value = 0;
2133 
2134 	if (private->has_accessible) {
2135 		returned_value = call_accessible_object_function("atkValue_set_current_value", "(JJ)J", obj, value);
2136 	}
2137 	return ((gint) returned_value == 1) ? TRUE : FALSE;
2138 }
2139 
2140 // Interfaces initializers and implementations
swt_fixed_accessible_action_iface_init(AtkActionIface * iface)2141 static void swt_fixed_accessible_action_iface_init (AtkActionIface *iface) {
2142 	iface->do_action = swt_fixed_accessible_action_do_action;
2143 	iface->get_description = swt_fixed_accessible_action_get_description;
2144 	iface->get_keybinding = swt_fixed_accessible_action_get_keybinding;
2145 	iface->get_n_actions = swt_fixed_accessible_action_get_n_actions;
2146 	iface->get_name = swt_fixed_accessible_action_get_name;
2147 }
2148 
swt_fixed_accessible_component_iface_init(AtkComponentIface * iface)2149 static void swt_fixed_accessible_component_iface_init (AtkComponentIface *iface) {
2150 	iface->get_extents = swt_fixed_accessible_component_get_extents;
2151 	iface->ref_accessible_at_point = swt_fixed_accessible_component_ref_accessible_at_point;
2152 }
2153 
swt_fixed_accessible_editable_text_iface_init(AtkEditableTextIface * iface)2154 static void swt_fixed_accessible_editable_text_iface_init (AtkEditableTextIface *iface) {
2155 	iface->copy_text = swt_fixed_accessible_editable_text_copy_text;
2156 	iface->cut_text = swt_fixed_accessible_editable_text_cut_text;
2157 	iface->delete_text = swt_fixed_accessible_editable_text_delete_text;
2158 	iface->insert_text = swt_fixed_accessible_editable_text_insert_text;
2159 	iface->paste_text = swt_fixed_accessible_editable_text_paste_text;
2160 	iface->set_run_attributes = swt_fixed_accessible_editable_text_set_run_attributes;
2161 	iface->set_text_contents = swt_fixed_accessible_editable_text_set_text_contents;
2162 }
2163 
swt_fixed_accessible_hypertext_iface_init(AtkHypertextIface * iface)2164 static void swt_fixed_accessible_hypertext_iface_init (AtkHypertextIface *iface) {
2165 	iface->get_link = swt_fixed_accessible_hypertext_get_link;
2166 	iface->get_link_index = swt_fixed_accessible_hypertext_get_link_index;
2167 	iface->get_n_links = swt_fixed_accessible_hypertext_get_n_links;
2168 }
2169 
swt_fixed_accessible_selection_iface_init(AtkSelectionIface * iface)2170 static void swt_fixed_accessible_selection_iface_init (AtkSelectionIface *iface) {
2171 	iface->is_child_selected = swt_fixed_accessible_selection_is_child_selected;
2172 	iface->ref_selection = swt_fixed_accessible_selection_ref_selection;
2173 }
2174 
swt_fixed_accessible_table_iface_init(AtkTableIface * iface)2175 static void swt_fixed_accessible_table_iface_init (AtkTableIface *iface) {
2176 	iface->ref_at = swt_fixed_accessible_table_ref_at;
2177 	iface->get_index_at = swt_fixed_accessible_table_get_index_at;
2178 	iface->get_column_at_index = swt_fixed_accessible_table_get_column_at_index;
2179 	iface->get_row_at_index = swt_fixed_accessible_table_get_row_at_index;
2180 	iface->get_n_columns = swt_fixed_accessible_table_get_n_columns;
2181 	iface->get_n_rows = swt_fixed_accessible_table_get_n_rows;
2182 	iface->get_column_extent_at = swt_fixed_accessible_table_get_column_extent_at;
2183 	iface->get_row_extent_at = swt_fixed_accessible_table_get_row_extent_at;
2184 	iface->get_caption = swt_fixed_accessible_table_get_caption;
2185 	iface->get_summary = swt_fixed_accessible_table_get_summary;
2186 	iface->get_column_description = swt_fixed_accessible_table_get_column_description;
2187 	iface->get_column_header = swt_fixed_accessible_table_get_column_header;
2188 	iface->get_row_description = swt_fixed_accessible_table_get_row_description;
2189 	iface->get_row_header = swt_fixed_accessible_table_get_row_header;
2190 	iface->get_selected_columns = swt_fixed_accessible_table_get_selected_columns;
2191 	iface->get_selected_rows = swt_fixed_accessible_table_get_selected_rows;
2192 	iface->is_column_selected = swt_fixed_accessible_table_is_column_selected;
2193 	iface->is_row_selected = swt_fixed_accessible_table_is_row_selected;
2194 	iface->is_selected = swt_fixed_accessible_table_is_selected;
2195 	iface->add_row_selection = swt_fixed_accessible_table_add_row_selection;
2196 	iface->remove_row_selection = swt_fixed_accessible_table_remove_row_selection;
2197 	iface->add_column_selection = swt_fixed_accessible_table_add_column_selection;
2198 	iface->remove_column_selection = swt_fixed_accessible_table_remove_column_selection;
2199 }
2200 
swt_fixed_accessible_text_iface_init(AtkTextIface * iface)2201 static void swt_fixed_accessible_text_iface_init (AtkTextIface *iface) {
2202 	iface->add_selection = swt_fixed_accessible_text_add_selection;
2203 	iface->get_bounded_ranges = swt_fixed_accessible_text_get_bounded_ranges;
2204 	iface->get_caret_offset = swt_fixed_accessible_text_get_caret_offset;
2205 	iface->get_character_at_offset = swt_fixed_accessible_text_get_character_at_offset;
2206 	iface->get_character_count = swt_fixed_accessible_text_get_character_count;
2207 	iface->get_n_selections = swt_fixed_accessible_text_get_n_selections;
2208 	iface->get_offset_at_point = swt_fixed_accessible_text_get_offset_at_point;
2209 	iface->get_range_extents = swt_fixed_accessible_text_get_range_extents;
2210 	iface->get_run_attributes = swt_fixed_accessible_text_get_run_attributes;
2211 	iface->get_selection = swt_fixed_accessible_text_get_selection;
2212 	// TODO_a11y: add support for get_string_at_offset once Orca is updated
2213 	iface->get_text_before_offset = swt_fixed_accessible_text_get_text_before_offset;
2214 	iface->get_text_at_offset = swt_fixed_accessible_text_get_text_at_offset;
2215 	iface->get_text_after_offset = swt_fixed_accessible_text_get_text_after_offset;
2216 	iface->get_text = swt_fixed_accessible_text_get_text;
2217 	iface->remove_selection = swt_fixed_accessible_text_remove_selection;
2218 	iface->set_caret_offset = swt_fixed_accessible_text_set_caret_offset;
2219 	iface->set_selection = swt_fixed_accessible_text_set_selection;
2220 }
2221 
swt_fixed_accessible_value_iface_init(AtkValueIface * iface)2222 static void swt_fixed_accessible_value_iface_init (AtkValueIface *iface) {
2223 	/*
2224 	 * TODO_a11y: add support for get_range, get_value_and_text, and set_value
2225 	 * once Orca is updated.
2226 	 */
2227 	iface->get_current_value = swt_fixed_accessible_value_get_current_value;
2228 	iface->get_maximum_value = swt_fixed_accessible_value_get_maximum_value;
2229 	iface->get_minimum_value = swt_fixed_accessible_value_get_minimum_value;
2230 	iface->set_current_value = swt_fixed_accessible_value_set_current_value;
2231 }
2232 
call_accessible_object_function(const char * method_name,const char * method_signature,...)2233 jlong call_accessible_object_function (const char *method_name, const char *method_signature,...) {
2234 	jlong result = 0;
2235 	va_list arg_list;
2236 	jclass cls;
2237 	JNIEnv *env;
2238 	jmethodID mid;
2239 
2240 	if (method_name == NULL || method_signature == NULL) {
2241 		g_critical("Error calling Java method with JNI, check method name and signature\n");
2242 		return 0;
2243 	}
2244 
2245 	// Get the JNIEnv pointer
2246 	if ((*JVM)->GetEnv(JVM, (void **)&env, JNI_VERSION_1_2)) {
2247 		g_critical("Error fetching the JNIEnv pointer\n");
2248 		return 0;
2249 	}
2250 
2251 	// Find the class pointer
2252 	cls = (*env)->FindClass(env, ACCESSIBILITY_CLASS_NAME);
2253 	if (cls == NULL) {
2254 		g_critical("JNI class pointer is NULL for class %s\n", ACCESSIBILITY_CLASS_NAME);
2255 		return 0;
2256 	}
2257 
2258 	// Find the method ID
2259 	mid = (*env)->GetStaticMethodID(env, cls, method_name, method_signature);
2260 
2261 	// If the method ID isn't NULL
2262 	if (mid == NULL) {
2263 		g_critical("JNI method ID pointer is NULL for method %s\n", method_name);
2264 		return 0;
2265 	} else {
2266 		va_start(arg_list, method_signature);
2267 		result = (*env)->CallStaticLongMethodV(env, cls, mid, arg_list);
2268 		va_end(arg_list);
2269 	}
2270 
2271 	return result;
2272 }
2273 
2274 #if !defined(GTK4)
2275 //Add ability to debug gtk warnings for SWT snippets via SWT_FATAL_WARNINGS=1
2276 // env variable. Please see Eclipse bug 471477.
2277 // PLEASE NOTE: this functionality is only available on GTK3.
swt_debug_on_fatal_warnings()2278 void swt_debug_on_fatal_warnings() {
2279 	  // NOTE: gtk_parse_args() must be called before gtk_init() to take effect.
2280 	  int argcount = 2;
2281 	  char *argument[] = {"", "--g-fatal-warnings"};
2282 	  char **arg2 = (char **) &argument;
2283 	  gtk_parse_args(&argcount, &arg2);
2284 }
2285 #endif
2286