1 /*******************************************************************************
2  * Copyright (c) 2000, 2019 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.swt.widgets;
15 
16 
17 import java.util.*;
18 
19 import org.eclipse.swt.*;
20 import org.eclipse.swt.events.*;
21 import org.eclipse.swt.internal.*;
22 import org.eclipse.swt.internal.gtk.*;
23 import org.eclipse.swt.internal.gtk3.*;
24 import org.eclipse.swt.internal.gtk4.*;
25 
26 /**
27  * This class is the abstract superclass of all user interface objects.
28  * Widgets are created, disposed and issue notification to listeners
29  * when events occur which affect them.
30  * <dl>
31  * <dt><b>Styles:</b></dt>
32  * <dd>(none)</dd>
33  * <dt><b>Events:</b></dt>
34  * <dd>Dispose</dd>
35  * </dl>
36  * <p>
37  * IMPORTANT: This class is intended to be subclassed <em>only</em>
38  * within the SWT implementation. However, it has not been marked
39  * final to allow those outside of the SWT development team to implement
40  * patched versions of the class in order to get around specific
41  * limitations in advance of when those limitations can be addressed
42  * by the team.  Any class built using subclassing to access the internals
43  * of this class will likely fail to compile or run between releases and
44  * may be strongly platform specific. Subclassing should not be attempted
45  * without an intimate and detailed understanding of the workings of the
46  * hierarchy. No support is provided for user-written classes which are
47  * implemented as subclasses of this class.
48  * </p>
49  *
50  * @see #checkSubclass
51  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
52  */
53 public abstract class Widget {
54 	/**
55 	 * the handle to the OS resource
56 	 * (Warning: This field is platform dependent)
57 	 * <p>
58 	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
59 	 * public API. It is marked public only so that it can be shared
60 	 * within the packages provided by SWT. It is not available on all
61 	 * platforms and should never be accessed from application code.
62 	 * </p>
63 	 *
64 	 * @noreference This field is not intended to be referenced by clients.
65 	 */
66 	public long handle;
67 	int style, state;
68 	Display display;
69 	EventTable eventTable;
70 	Object data;
71 
72 	/* Global state flags
73 	 *
74 	 * Common code pattern:
75 	 * & - think of AND as removing.
76 	 * | - think of OR as adding.
77 	 * state & ~flag  -- Think as "removing flag"
78 	 * state |  flag  -- Think as "adding flag"
79 	 *
80 	 * state |= flag  -- Flag is being added to state.
81 	 * state &= ~flag -- Flag is being removed from state.
82 	 * state & flag != 0 -- true if flag is present (think >0 = true)
83 	 * state & flag == 0 -- true if flag is absent  (think 0 = false)
84 	 *
85 	 * (state & (flag1 | flag2)) != 0 -- true if either of the flags are present.
86 	 * (state & (flag1 | flag2)) == 0 -- true if both flag1 & flag2 are absent.
87 	 */
88 	static final int DISPOSED = 1<<0;
89 	static final int CANVAS = 1<<1;
90 	static final int KEYED_DATA = 1<<2;
91 	static final int HANDLE = 1<<3;
92 	static final int DISABLED = 1<<4;
93 	static final int MENU = 1<<5;
94 	static final int OBSCURED = 1<<6;
95 	static final int MOVED = 1<<7;
96 	static final int RESIZED = 1<<8;
97 	static final int ZERO_WIDTH = 1<<9;
98 	static final int ZERO_HEIGHT = 1<<10;
99 	static final int HIDDEN = 1<<11;
100 	static final int FOREGROUND = 1<<12;
101 	static final int BACKGROUND = 1<<13;
102 	static final int FONT = 1<<14;
103 	static final int PARENT_BACKGROUND = 1<<15;
104 	static final int THEME_BACKGROUND = 1<<16;
105 
106 	/* A layout was requested on this widget */
107 	static final int LAYOUT_NEEDED	= 1<<17;
108 
109 	/* The preferred size of a child has changed */
110 	static final int LAYOUT_CHANGED = 1<<18;
111 
112 	/* A layout was requested in this widget hierachy */
113 	static final int LAYOUT_CHILD = 1<<19;
114 
115 	/* More global state flags */
116 	static final int RELEASED = 1<<20;
117 	static final int DISPOSE_SENT = 1<<21;
118 	static final int FOREIGN_HANDLE = 1<<22;
119 	static final int DRAG_DETECT = 1<<23;
120 
121 	/* Notify of the opportunity to skin this widget */
122 	static final int SKIN_NEEDED = 1<<24;
123 
124 	/* Should sub-windows be checked when EnterNotify received */
125 	static final int CHECK_SUBWINDOW = 1<<25;
126 
127 	/* Bidi "auto" text direction */
128 	static final int HAS_AUTO_DIRECTION = 0;
129 
130 	/* Bidi flag and for auto text direction */
131 	static final int AUTO_TEXT_DIRECTION = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
132 
133 	/* Default size for widgets */
134 	static final int DEFAULT_WIDTH	= 64;
135 	static final int DEFAULT_HEIGHT	= 64;
136 
137 	/* GTK signals data */
138 	static final int ACTIVATE = 1;
139 	static final int BUTTON_PRESS_EVENT = 2;
140 	static final int BUTTON_PRESS_EVENT_INVERSE = 3;
141 	static final int BUTTON_RELEASE_EVENT = 4;
142 	static final int BUTTON_RELEASE_EVENT_INVERSE = 5;
143 	static final int CHANGED = 6;
144 	static final int CHANGE_VALUE = 7;
145 	static final int CLICKED = 8;
146 	static final int COMMIT = 9;
147 	static final int CONFIGURE_EVENT = 10;
148 	static final int DELETE_EVENT = 11;
149 	static final int DELETE_RANGE = 12;
150 	static final int DELETE_TEXT = 13;
151 	static final int ENTER_NOTIFY_EVENT = 14;
152 	static final int EVENT = 15;
153 	static final int EVENT_AFTER = 16;
154 	static final int EXPAND_COLLAPSE_CURSOR_ROW = 17;
155 	static final int EXPOSE_EVENT = 18;
156 	static final int DRAW = EXPOSE_EVENT;
157 	static final int EXPOSE_EVENT_INVERSE = 19;
158 	static final int FOCUS = 20;
159 	static final int FOCUS_IN_EVENT = 21;
160 	static final int FOCUS_OUT_EVENT = 22;
161 	static final int GRAB_FOCUS = 23;
162 	static final int HIDE = 24;
163 	static final int INPUT = 25;
164 	static final int INSERT_TEXT = 26;
165 	static final int KEY_PRESS_EVENT = 27;
166 	static final int KEY_RELEASE_EVENT = 28;
167 	static final int LEAVE_NOTIFY_EVENT = 29;
168 	static final int MAP = 30;
169 	static final int MAP_EVENT = 31;
170 	static final int MNEMONIC_ACTIVATE = 32;
171 	static final int MOTION_NOTIFY_EVENT = 33;
172 	static final int MOTION_NOTIFY_EVENT_INVERSE = 34;
173 	static final int MOVE_FOCUS = 35;
174 	static final int OUTPUT = 36;
175 	static final int POPULATE_POPUP = 37;
176 	static final int POPUP_MENU = 38;
177 	static final int PREEDIT_CHANGED = 39;
178 	static final int REALIZE = 40;
179 	static final int ROW_ACTIVATED = 41;
180 	static final int SCROLL_CHILD = 42;
181 	static final int SCROLL_EVENT = 43;
182 	static final int SELECT = 44;
183 	static final int SHOW = 45;
184 	static final int SHOW_HELP = 46;
185 	static final int SIZE_ALLOCATE = 47;
186 	static final int STYLE_UPDATED = 48;
187 	static final int SWITCH_PAGE = 49;
188 	static final int TEST_COLLAPSE_ROW = 50;
189 	static final int TEST_EXPAND_ROW = 51;
190 	static final int TEXT_BUFFER_INSERT_TEXT = 52;
191 	static final int TOGGLED = 53;
192 	static final int UNMAP = 54;
193 	static final int UNMAP_EVENT = 55;
194 	static final int UNREALIZE = 56;
195 	static final int VALUE_CHANGED = 57;
196 	static final int WINDOW_STATE_EVENT = 59;
197 	static final int ACTIVATE_INVERSE = 60;
198 	static final int DAY_SELECTED = 61;
199 	static final int MONTH_CHANGED = 62;
200 	static final int STATUS_ICON_POPUP_MENU = 63;
201 	static final int ROW_INSERTED = 64;
202 	static final int ROW_DELETED = 65;
203 	static final int DAY_SELECTED_DOUBLE_CLICK = 66;
204 	static final int ICON_RELEASE = 67;
205 	static final int SELECTION_DONE = 68;
206 	static final int START_INTERACTIVE_SEARCH = 69;
207 	static final int BACKSPACE = 70;
208 	static final int BACKSPACE_INVERSE = 71;
209 	static final int COPY_CLIPBOARD = 72;
210 	static final int COPY_CLIPBOARD_INVERSE = 73;
211 	static final int CUT_CLIPBOARD = 74;
212 	static final int CUT_CLIPBOARD_INVERSE = 75;
213 	static final int PASTE_CLIPBOARD = 76;
214 	static final int PASTE_CLIPBOARD_INVERSE = 77;
215 	static final int DELETE_FROM_CURSOR = 78;
216 	static final int DELETE_FROM_CURSOR_INVERSE = 79;
217 	static final int MOVE_CURSOR = 80;
218 	static final int MOVE_CURSOR_INVERSE = 81;
219 	static final int DIRECTION_CHANGED = 82;
220 	static final int CREATE_MENU_PROXY = 83;
221 	static final int ROW_HAS_CHILD_TOGGLED = 84;
222 	static final int POPPED_UP = 85;
223 	static final int FOCUS_IN = 86;
224 	static final int FOCUS_OUT = 87;
225 	static final int IM_UPDATE = 88;
226 	static final int KEY_PRESSED = 89;
227 	static final int KEY_RELEASED = 90;
228 	static final int DECELERATE = 91;
229 	static final int SCROLL = 92;
230 	static final int SCROLL_BEGIN = 93;
231 	static final int SCROLL_END = 94;
232 	static final int ENTER = 95;
233 	static final int LEAVE = 96;
234 	static final int MOTION = 97;
235 	static final int MOTION_INVERSE = 98;
236 	static final int CLOSE_REQUEST = 99;
237 	static final int GESTURE_PRESSED = 100;
238 	static final int GESTURE_RELEASED = 101;
239 	static final int NOTIFY_STATE = 102;
240 	static final int SIZE_ALLOCATE_GTK4 = 103;
241 	static final int DPI_CHANGED = 104;
242 	static final int LAST_SIGNAL = 105;
243 
244 	static final String IS_ACTIVE = "org.eclipse.swt.internal.control.isactive"; //$NON-NLS-1$
245 	static final String KEY_CHECK_SUBWINDOW = "org.eclipse.swt.internal.control.checksubwindow"; //$NON-NLS-1$
246 	static final String KEY_GTK_CSS = "org.eclipse.swt.internal.gtk.css"; //$NON-NLS-1$
247 
248 	static Callback gdkSeatGrabPrepareFunc;
249 
250 /**
251  * Prevents uninitialized instances from being created outside the package.
252  */
Widget()253 Widget () {}
254 
255 /**
256  * Constructs a new instance of this class given its parent
257  * and a style value describing its behavior and appearance.
258  * <p>
259  * The style value is either one of the style constants defined in
260  * class <code>SWT</code> which is applicable to instances of this
261  * class, or must be built by <em>bitwise OR</em>'ing together
262  * (that is, using the <code>int</code> "|" operator) two or more
263  * of those <code>SWT</code> style constants. The class description
264  * lists the style constants that are applicable to the class.
265  * Style bits are also inherited from superclasses.
266  * </p>
267  *
268  * @param parent a widget which will be the parent of the new instance (cannot be null)
269  * @param style the style of widget to construct
270  *
271  * @exception IllegalArgumentException <ul>
272  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
273  *    <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li>
274  * </ul>
275  * @exception SWTException <ul>
276  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
277  *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
278  * </ul>
279  *
280  * @see SWT
281  * @see #checkSubclass
282  * @see #getStyle
283  */
Widget(Widget parent, int style)284 public Widget (Widget parent, int style) {
285 	checkSubclass ();
286 	checkParent (parent);
287 	this.style = style;
288 	display = parent.display;
289 	reskinWidget ();
290 }
291 
_addListener(int eventType, Listener listener)292 void _addListener (int eventType, Listener listener) {
293 	if (eventTable == null) eventTable = new EventTable ();
294 	eventTable.hook (eventType, listener);
295 }
296 
297 /**
298  * Adds the listener to the collection of listeners who will
299  * be notified when an event of the given type occurs. When the
300  * event does occur in the widget, the listener is notified by
301  * sending it the <code>handleEvent()</code> message. The event
302  * type is one of the event constants defined in class <code>SWT</code>.
303  *
304  * @param eventType the type of event to listen for
305  * @param listener the listener which should be notified when the event occurs
306  *
307  * @exception IllegalArgumentException <ul>
308  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
309  * </ul>
310  * @exception SWTException <ul>
311  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
312  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
313  * </ul>
314  *
315  * @see Listener
316  * @see SWT
317  * @see #getListeners(int)
318  * @see #removeListener(int, Listener)
319  * @see #notifyListeners
320  */
addListener(int eventType, Listener listener)321 public void addListener (int eventType, Listener listener) {
322 	checkWidget ();
323 	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
324 	_addListener (eventType, listener);
325 }
326 
327 /**
328  * Adds the listener to the collection of listeners who will
329  * be notified when the widget is disposed. When the widget is
330  * disposed, the listener is notified by sending it the
331  * <code>widgetDisposed()</code> message.
332  *
333  * @param listener the listener which should be notified when the receiver is disposed
334  *
335  * @exception IllegalArgumentException <ul>
336  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
337  * </ul>
338  * @exception SWTException <ul>
339  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
340  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
341  * </ul>
342  *
343  * @see DisposeListener
344  * @see #removeDisposeListener
345  */
addDisposeListener(DisposeListener listener)346 public void addDisposeListener (DisposeListener listener) {
347 	checkWidget ();
348 	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
349 	TypedListener typedListener = new TypedListener (listener);
350 	addListener (SWT.Dispose, typedListener);
351 }
352 
paintWindow()353 long paintWindow () {
354 	return 0;
355 }
356 
paintSurface()357 long paintSurface () {
358 	return 0;
359 }
360 
cssHandle()361 long cssHandle() {
362 	return handle;
363 }
364 
checkBits(int style, int int0, int int1, int int2, int int3, int int4, int int5)365 static int checkBits (int style, int int0, int int1, int int2, int int3, int int4, int int5) {
366 	int mask = int0 | int1 | int2 | int3 | int4 | int5;
367 	if ((style & mask) == 0) style |= int0;
368 	if ((style & int0) != 0) style = (style & ~mask) | int0;
369 	if ((style & int1) != 0) style = (style & ~mask) | int1;
370 	if ((style & int2) != 0) style = (style & ~mask) | int2;
371 	if ((style & int3) != 0) style = (style & ~mask) | int3;
372 	if ((style & int4) != 0) style = (style & ~mask) | int4;
373 	if ((style & int5) != 0) style = (style & ~mask) | int5;
374 	return style;
375 }
376 
cellDataProc(long tree_column, long cell, long tree_model, long iter, long data)377 long cellDataProc (long tree_column, long cell, long tree_model, long iter, long data) {
378 	return 0;
379 }
380 
checkOpen()381 void checkOpen () {
382 	/* Do nothing */
383 }
384 
checkOrientation(Widget parent)385 void checkOrientation (Widget parent) {
386 	style &= ~SWT.MIRRORED;
387 	if ((style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT)) == 0) {
388 		if (parent != null) {
389 			if ((parent.style & SWT.LEFT_TO_RIGHT) != 0) style |= SWT.LEFT_TO_RIGHT;
390 			if ((parent.style & SWT.RIGHT_TO_LEFT) != 0) style |= SWT.RIGHT_TO_LEFT;
391 		}
392 	}
393 	style = checkBits (style, SWT.LEFT_TO_RIGHT, SWT.RIGHT_TO_LEFT, 0, 0, 0, 0);
394 }
395 
396 /**
397  * Throws an exception if the specified widget can not be
398  * used as a parent for the receiver.
399  *
400  * @exception IllegalArgumentException <ul>
401  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
402  *    <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li>
403  * </ul>
404  * @exception SWTException <ul>
405  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
406  * </ul>
407  */
checkParent(Widget parent)408 void checkParent (Widget parent) {
409 	if (parent == null) error (SWT.ERROR_NULL_ARGUMENT);
410 	if (parent.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
411 	parent.checkWidget ();
412 	parent.checkOpen ();
413 }
414 
415 /**
416  * Checks that this class can be subclassed.
417  * <p>
418  * The SWT class library is intended to be subclassed
419  * only at specific, controlled points (most notably,
420  * <code>Composite</code> and <code>Canvas</code> when
421  * implementing new widgets). This method enforces this
422  * rule unless it is overridden.
423  * </p><p>
424  * <em>IMPORTANT:</em> By providing an implementation of this
425  * method that allows a subclass of a class which does not
426  * normally allow subclassing to be created, the implementer
427  * agrees to be fully responsible for the fact that any such
428  * subclass will likely fail between SWT releases and will be
429  * strongly platform specific. No support is provided for
430  * user-written classes which are implemented in this fashion.
431  * </p><p>
432  * The ability to subclass outside of the allowed SWT classes
433  * is intended purely to enable those not on the SWT development
434  * team to implement patches in order to get around specific
435  * limitations in advance of when those limitations can be
436  * addressed by the team. Subclassing should not be attempted
437  * without an intimate and detailed understanding of the hierarchy.
438  * </p>
439  *
440  * @exception SWTException <ul>
441  *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
442  * </ul>
443  */
checkSubclass()444 protected void checkSubclass () {
445 	if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
446 }
447 
448 /**
449  * Throws an <code>SWTException</code> if the receiver can not
450  * be accessed by the caller. This may include both checks on
451  * the state of the receiver and more generally on the entire
452  * execution context. This method <em>should</em> be called by
453  * widget implementors to enforce the standard SWT invariants.
454  * <p>
455  * Currently, it is an error to invoke any method (other than
456  * <code>isDisposed()</code>) on a widget that has had its
457  * <code>dispose()</code> method called. It is also an error
458  * to call widget methods from any thread that is different
459  * from the thread that created the widget.
460  * </p><p>
461  * In future releases of SWT, there may be more or fewer error
462  * checks and exceptions may be thrown for different reasons.
463  * </p>
464  *
465  * @exception SWTException <ul>
466  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
467  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
468  * </ul>
469  */
checkWidget()470 protected void checkWidget () {
471 	Display display = this.display;
472 	if (display == null) error (SWT.ERROR_WIDGET_DISPOSED);
473 	if (display.thread != Thread.currentThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
474 	if ((state & DISPOSED) != 0) error (SWT.ERROR_WIDGET_DISPOSED);
475 }
476 
createHandle(int index)477 void createHandle (int index) {
478 }
479 
createWidget(int index)480 void createWidget (int index) {
481 	createHandle (index);
482 	setOrientation (true);
483 	hookEvents ();
484 	register ();
485 }
486 
deregister()487 void deregister () {
488 	if (handle == 0) return;
489 	if ((state & HANDLE) != 0) display.removeWidget (handle);
490 }
491 
destroyWidget()492 void destroyWidget () {
493 	long topHandle = topHandle ();
494 	releaseHandle ();
495 	if (topHandle != 0 && (state & HANDLE) != 0) {
496 		if (GTK.GTK4) {
497 			GTK.gtk_widget_unparent(topHandle);
498 		} else {
499 			GTK3.gtk_widget_destroy(topHandle);
500 		}
501 	}
502 }
503 
504 /**
505  * Disposes of the operating system resources associated with
506  * the receiver and all its descendants. After this method has
507  * been invoked, the receiver and all descendants will answer
508  * <code>true</code> when sent the message <code>isDisposed()</code>.
509  * Any internal connections between the widgets in the tree will
510  * have been removed to facilitate garbage collection.
511  * This method does nothing if the widget is already disposed.
512  * <p>
513  * NOTE: This method is not called recursively on the descendants
514  * of the receiver. This means that, widget implementers can not
515  * detect when a widget is being disposed of by re-implementing
516  * this method, but should instead listen for the <code>Dispose</code>
517  * event.
518  * </p>
519  *
520  * @exception SWTException <ul>
521  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
522  * </ul>
523  *
524  * @see #addDisposeListener
525  * @see #removeDisposeListener
526  * @see #checkWidget
527  */
dispose()528 public void dispose () {
529 	/*
530 	* Note:  It is valid to attempt to dispose a widget
531 	* more than once.  If this happens, fail silently.
532 	*/
533 	if (isDisposed ()) return;
534 	if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
535 	release (true);
536 }
537 
dpiChanged(long object, long arg0)538 long dpiChanged (long object, long arg0) {
539 	int oldScaleFactor = DPIUtil.getDeviceZoom() / 100;
540 	int newScaleFactor = GTK.gtk_widget_get_scale_factor(object);
541 
542 	if (oldScaleFactor != newScaleFactor) {
543 		display.dpiChanged(newScaleFactor);
544 
545 		Event event = new Event();
546 		event.type = SWT.ZoomChanged;
547 		event.widget = this;
548 		event.detail = newScaleFactor;
549 		event.doit = true;
550 		notifyListeners(SWT.ZoomChanged, event);
551 	}
552 
553 	return 0;
554 }
555 
error(int code)556 void error (int code) {
557 	SWT.error (code);
558 }
559 
560 /**
561  * Returns the application defined widget data associated
562  * with the receiver, or null if it has not been set. The
563  * <em>widget data</em> is a single, unnamed field that is
564  * stored with every widget.
565  * <p>
566  * Applications may put arbitrary objects in this field. If
567  * the object stored in the widget data needs to be notified
568  * when the widget is disposed of, it is the application's
569  * responsibility to hook the Dispose event on the widget and
570  * do so.
571  * </p>
572  *
573  * @return the widget data
574  *
575  * @exception SWTException <ul>
576  *    <li>ERROR_WIDGET_DISPOSED - when the receiver has been disposed</li>
577  *    <li>ERROR_THREAD_INVALID_ACCESS - when called from the wrong thread</li>
578  * </ul>
579  *
580  * @see #setData(Object)
581  */
getData()582 public Object getData () {
583 	checkWidget();
584 	return (state & KEYED_DATA) != 0 ? ((Object []) data) [0] : data;
585 }
586 /**
587  * Returns the application defined property of the receiver
588  * with the specified name, or null if it has not been set.
589  * <p>
590  * Applications may have associated arbitrary objects with the
591  * receiver in this fashion. If the objects stored in the
592  * properties need to be notified when the widget is disposed
593  * of, it is the application's responsibility to hook the
594  * Dispose event on the widget and do so.
595  * </p>
596  *
597  * @param	key the name of the property
598  * @return the value of the property or null if it has not been set
599  *
600  * @exception IllegalArgumentException <ul>
601  *    <li>ERROR_NULL_ARGUMENT - if the key is null</li>
602  * </ul>
603  * @exception SWTException <ul>
604  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
605  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
606  * </ul>
607  *
608  * @see #setData(String, Object)
609  */
getData(String key)610 public Object getData (String key) {
611 	checkWidget();
612 	if (key == null) error (SWT.ERROR_NULL_ARGUMENT);
613 	if (key.equals (KEY_CHECK_SUBWINDOW)) {
614 		return (state & CHECK_SUBWINDOW) != 0;
615 	}
616 	if (key.equals(IS_ACTIVE)) return isActive ();
617 	if ((state & KEYED_DATA) != 0) {
618 		Object [] table = (Object []) data;
619 		for (int i=1; i<table.length; i+=2) {
620 			if (key.equals (table [i])) return table [i+1];
621 		}
622 	}
623 	return null;
624 }
625 
626 /**
627  * Returns the <code>Display</code> that is associated with
628  * the receiver.
629  * <p>
630  * A widget's display is either provided when it is created
631  * (for example, top level <code>Shell</code>s) or is the
632  * same as its parent's display.
633  * </p>
634  *
635  * @return the receiver's display
636  *
637  * @exception SWTException <ul>
638  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
639  * </ul>
640  */
getDisplay()641 public Display getDisplay () {
642 	Display display = this.display;
643 	if (display == null) error (SWT.ERROR_WIDGET_DISPOSED);
644 	return display;
645 }
646 
647 /**
648  * Returns an array of listeners who will be notified when an event
649  * of the given type occurs. The event type is one of the event constants
650  * defined in class <code>SWT</code>.
651  *
652  * @param eventType the type of event to listen for
653  * @return an array of listeners that will be notified when the event occurs
654  *
655  * @exception SWTException <ul>
656  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
657  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
658  * </ul>
659  *
660  * @see Listener
661  * @see SWT
662  * @see #addListener(int, Listener)
663  * @see #removeListener(int, Listener)
664  * @see #notifyListeners
665  *
666  * @since 3.4
667  */
getListeners(int eventType)668 public Listener[] getListeners (int eventType) {
669 	checkWidget();
670 	if (eventTable == null) return new Listener[0];
671 	return eventTable.getListeners(eventType);
672 }
673 
getName()674 String getName () {
675 //	String string = getClass ().getName ();
676 //	int index = string.lastIndexOf ('.');
677 //	if (index == -1) return string;
678 	String string = getClass ().getName ();
679 	int index = string.length ();
680 	while ((--index > 0) && (string.charAt (index) != '.')) {}
681 	return string.substring (index + 1, string.length ());
682 }
683 
getNameText()684 String getNameText () {
685 	return "";
686 }
687 
688 /**
689  * Returns the receiver's style information.
690  * <p>
691  * Note that the value which is returned by this method <em>may
692  * not match</em> the value which was provided to the constructor
693  * when the receiver was created. This can occur when the underlying
694  * operating system does not support a particular combination of
695  * requested styles. For example, if the platform widget used to
696  * implement a particular SWT widget always has scroll bars, the
697  * result of calling this method would always have the
698  * <code>SWT.H_SCROLL</code> and <code>SWT.V_SCROLL</code> bits set.
699  * </p>
700  *
701  * @return the style bits
702  *
703  * @exception SWTException <ul>
704  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
705  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
706  * </ul>
707  */
getStyle()708 public int getStyle () {
709 	checkWidget ();
710 	return style;
711 }
712 
713 
gtk_activate(long widget)714 long gtk_activate (long widget) {
715 	return 0;
716 }
717 
gtk_adjustment_get(long adjustmentHandle, GtkAdjustment adjustment)718 void gtk_adjustment_get(long adjustmentHandle, GtkAdjustment adjustment) {
719 	adjustment.lower = GTK.gtk_adjustment_get_lower(adjustmentHandle);
720 	adjustment.upper = GTK.gtk_adjustment_get_upper(adjustmentHandle);
721 	adjustment.page_increment = GTK.gtk_adjustment_get_page_increment(adjustmentHandle);
722 	adjustment.step_increment = GTK.gtk_adjustment_get_step_increment(adjustmentHandle);
723 	adjustment.page_size = GTK.gtk_adjustment_get_page_size(adjustmentHandle);
724 	adjustment.value = GTK.gtk_adjustment_get_value(adjustmentHandle);
725 }
726 
gtk_button_press_event(long widget, long event)727 long gtk_button_press_event (long widget, long event) {
728 	return 0;
729 }
730 
gtk_button_release_event(long widget, long event)731 long gtk_button_release_event (long widget, long event) {
732 	return 0;
733 }
734 
gtk_gesture_press_event(long gesture, int n_press, double x, double y, long event)735 void gtk_gesture_press_event (long gesture, int n_press, double x, double y, long event) {
736 }
737 
gtk_gesture_release_event(long gesture, int n_press, double x, double y, long event)738 void gtk_gesture_release_event (long gesture, int n_press, double x, double y, long event) {
739 }
740 
gtk_changed(long widget)741 long gtk_changed (long widget) {
742 	return 0;
743 }
744 
gtk_change_value(long widget, int scroll, double value, long user_data)745 boolean gtk_change_value (long widget, int scroll, double value, long user_data) {
746 	return false;
747 }
748 
gtk_clicked(long widget)749 long gtk_clicked (long widget) {
750 	return 0;
751 }
752 
gtk_close_request(long widget)753 long gtk_close_request (long widget) {
754 	return 0;
755 }
756 
gtk_commit(long imcontext, long text)757 long gtk_commit (long imcontext, long text) {
758 	return 0;
759 }
760 
gtk_configure_event(long widget, long event)761 long gtk_configure_event (long widget, long event) {
762 	return 0;
763 }
764 
gtk_create_menu_proxy(long widget)765 long gtk_create_menu_proxy (long widget) {
766 	return 0;
767 }
768 
gtk_day_selected(long widget)769 long gtk_day_selected (long widget) {
770 	return 0;
771 }
772 
gtk_day_selected_double_click(long widget)773 long gtk_day_selected_double_click (long widget) {
774 	return 0;
775 }
776 
gtk_delete_event(long widget, long event)777 long gtk_delete_event (long widget, long event) {
778 	return 0;
779 }
780 
gtk_delete_range(long widget, long iter1, long iter2)781 long gtk_delete_range (long widget, long iter1, long iter2) {
782 	return 0;
783 }
784 
gtk_delete_text(long widget, long start_pos, long end_pos)785 long gtk_delete_text (long widget, long start_pos, long end_pos) {
786 	return 0;
787 }
788 
gtk_enter_notify_event(long widget, long event)789 long gtk_enter_notify_event (long widget, long event) {
790 	return 0;
791 }
792 
gtk_event_after(long widget, long event)793 long gtk_event_after (long widget, long event) {
794 	return 0;
795 }
796 
gtk_expand_collapse_cursor_row(long widget, long logical, long expand, long open_all)797 long gtk_expand_collapse_cursor_row (long widget, long logical, long expand, long open_all) {
798 	return 0;
799 }
800 
gtk_draw(long widget, long cairo)801 long gtk_draw (long widget, long cairo) {
802 	return 0;
803 }
804 
gtk_focus(long widget, long event)805 long gtk_focus (long widget, long event) {
806 	return 0;
807 }
808 
gtk_focus_in_event(long widget, long event)809 long gtk_focus_in_event (long widget, long event) {
810 	return 0;
811 }
812 
gtk_focus_out_event(long widget, long event)813 long gtk_focus_out_event (long widget, long event) {
814 	return 0;
815 }
816 
gtk_grab_focus(long widget)817 long gtk_grab_focus (long widget) {
818 	return 0;
819 }
820 
gtk_hide(long widget)821 long gtk_hide (long widget) {
822 	return 0;
823 }
824 
gtk_icon_release(long widget, long icon_pos, long event)825 long gtk_icon_release (long widget, long icon_pos, long event) {
826 	return 0;
827 }
828 
gtk_input(long widget, long arg1)829 long gtk_input (long widget, long arg1) {
830 	return 0;
831 }
832 
gtk_insert_text(long widget, long new_text, long new_text_length, long position)833 long gtk_insert_text (long widget, long new_text, long new_text_length, long position) {
834 	return 0;
835 }
836 
gtk_key_press_event(long widget, long event)837 long gtk_key_press_event (long widget, long event) {
838 	return sendKeyEvent (SWT.KeyDown, event) ? 0 : 1;
839 }
840 
gtk_key_release_event(long widget, long event)841 long gtk_key_release_event (long widget, long event) {
842 	return sendKeyEvent (SWT.KeyUp, event) ? 0 : 1;
843 }
844 
gtk_leave_notify_event(long widget, long event)845 long gtk_leave_notify_event (long widget, long event) {
846 	return 0;
847 }
848 
gtk_map(long widget)849 long gtk_map (long widget) {
850 	return 0;
851 }
852 
gtk_map_event(long widget, long event)853 long gtk_map_event (long widget, long event) {
854 	return 0;
855 }
856 
857 /**
858  * <p>GTK3.22+ has API which allows clients of GTK to connect a menu to the "popped-up" signal.
859  * This callback is triggered after the menu is popped up/shown to the user, and provides
860  * information about the actual position and size of the menu, as shown to the user.</p>
861  *
862  * <p>SWT clients can enable this functionality by launching their application with the
863  * SWT_MENU_LOCATION_DEBUGGING environment variable set to 1. If enabled, the previously mentioned
864  * positioning and size information will be printed to the console. The information comes from GTK
865  * internals and is stored in the method parameters.</p>
866  *
867  * @param widget the memory address of the menu which was popped up
868  * @param flipped_rect a pointer to the GdkRectangle containing the flipped location and size of the menu
869  * @param final_rect a pointer to the GdkRectangle containing the final (after all internal adjustments)
870  * location and size of the menu
871  * @param flipped_x a boolean flag indicating whether the menu has been inverted along the X-axis
872  * @param flipped_y a boolean flag indicating whether the menu has been inverted along the Y-axis
873  */
gtk_menu_popped_up(long widget, long flipped_rect, long final_rect, long flipped_x, long flipped_y)874 long gtk_menu_popped_up (long widget, long flipped_rect, long final_rect, long flipped_x, long flipped_y) {
875 	return 0;
876 }
877 
gtk_mnemonic_activate(long widget, long arg1)878 long gtk_mnemonic_activate (long widget, long arg1) {
879 	return 0;
880 }
881 
gtk_month_changed(long widget)882 long gtk_month_changed (long widget) {
883 	return 0;
884 }
885 
gtk_motion_notify_event(long widget, long event)886 long gtk_motion_notify_event (long widget, long event) {
887 	return 0;
888 }
889 
gtk_move_focus(long widget, long event)890 long gtk_move_focus (long widget, long event) {
891 	return 0;
892 }
893 
gtk_output(long widget)894 long gtk_output (long widget) {
895 	return 0;
896 }
897 
gtk_populate_popup(long widget, long menu)898 long gtk_populate_popup (long widget, long menu) {
899 	return 0;
900 }
901 
gtk_popup_menu(long widget)902 long gtk_popup_menu (long widget) {
903 	return 0;
904 }
905 
gtk_preedit_changed(long imcontext)906 long gtk_preedit_changed (long imcontext) {
907 	return 0;
908 }
909 
gtk_realize(long widget)910 long gtk_realize (long widget) {
911 	return 0;
912 }
913 
gtk_row_activated(long tree, long path, long column)914 long gtk_row_activated (long tree, long path, long column) {
915 	return 0;
916 	// Note on SWT Tree/Table/List. This signal is no longer used for sending events, instead
917 	// Send DefaultSelection is manually emitted. We use this function to know whether a
918 	// 'row-activated' is triggered. See Bug 312568, 518414.
919 }
920 
gtk_row_deleted(long model, long path)921 long gtk_row_deleted (long model, long path) {
922 	return 0;
923 }
924 
gtk_row_inserted(long model, long path, long iter)925 long gtk_row_inserted (long model, long path, long iter) {
926 	return 0;
927 }
928 
gtk_row_has_child_toggled(long model, long path, long iter)929 long gtk_row_has_child_toggled (long model, long path, long iter) {
930 	return 0;
931 }
932 
gtk_scroll_child(long widget, long scrollType, long horizontal)933 long gtk_scroll_child (long widget, long scrollType, long horizontal) {
934 	return 0;
935 }
936 
gtk_scroll_event(long widget, long event)937 long gtk_scroll_event (long widget, long event) {
938 	return 0;
939 }
940 
gtk_select(long item)941 long gtk_select (long item) {
942 	return 0;
943 }
944 
gtk_selection_done(long menushell)945 long gtk_selection_done (long menushell) {
946 	return 0;
947 }
948 
gtk_show(long widget)949 long gtk_show (long widget) {
950 	return 0;
951 }
952 
gtk_show_help(long widget, long helpType)953 long gtk_show_help (long widget, long helpType) {
954 	return 0;
955 }
956 
gtk_size_allocate(long widget, long allocation)957 long gtk_size_allocate (long widget, long allocation) {
958 	return 0;
959 }
960 
gtk_status_icon_popup_menu(long handle, long button, long activate_time)961 long gtk_status_icon_popup_menu (long handle, long button, long activate_time) {
962 	return 0;
963 }
964 
gtk_start_interactive_search(long widget)965 long gtk_start_interactive_search (long widget) {
966 	return 0;
967 }
968 
gtk_style_updated(long widget)969 long gtk_style_updated (long widget) {
970 	return 0;
971 }
972 
gtk_switch_page(long notebook, long page, int page_num)973 long gtk_switch_page (long notebook, long page, int page_num) {
974 	return 0;
975 }
976 
gtk_test_collapse_row(long tree, long iter, long path)977 long gtk_test_collapse_row (long tree, long iter, long path) {
978 	return 0;
979 }
980 
gtk_test_expand_row(long tree, long iter, long path)981 long gtk_test_expand_row (long tree, long iter, long path) {
982 	return 0;
983 }
984 
gtk_text_buffer_insert_text(long widget, long iter, long text, long length)985 long gtk_text_buffer_insert_text (long widget, long iter, long text, long length) {
986 	return 0;
987 }
988 
gtk_timer()989 long gtk_timer () {
990 	return 0;
991 }
992 
gtk_toggled(long renderer, long pathStr)993 long gtk_toggled (long renderer, long pathStr) {
994 	return 0;
995 }
996 
997 /*
998  * Bug 498165: gtk_tree_view_column_cell_get_position() sets off rendererGetPreferredWidthCallback in GTK3 which is an issue
999  * if there is an ongoing MeasureEvent listener. Disabling it and re-enabling the callback after the method is called
1000  * prevents a stack overflow from occurring.
1001  */
gtk_tree_view_column_cell_get_position(long column, long cell_renderer, int[] start_pos, int[] width)1002 boolean gtk_tree_view_column_cell_get_position (long column, long cell_renderer, int[] start_pos, int[] width) {
1003 	Callback.setEnabled(false);
1004 	boolean result = GTK.gtk_tree_view_column_cell_get_position (column, cell_renderer, start_pos, width);
1005 	Callback.setEnabled(true);
1006 	return result;
1007 }
1008 
gtk_unmap(long widget)1009 long gtk_unmap (long widget) {
1010 	return 0;
1011 }
1012 
gtk_unmap_event(long widget, long event)1013 long gtk_unmap_event (long widget, long event) {
1014 	return 0;
1015 }
1016 
gtk_unrealize(long widget)1017 long gtk_unrealize (long widget) {
1018 	return 0;
1019 }
1020 
gtk_value_changed(long range)1021 long gtk_value_changed(long range) {
1022 	return 0;
1023 }
1024 
gtk_window_state_event(long widget, long event)1025 long gtk_window_state_event (long widget, long event) {
1026 	return 0;
1027 }
1028 
fontHeight(long font, long widgetHandle)1029 int fontHeight (long font, long widgetHandle) {
1030 	long context = GTK.gtk_widget_get_pango_context (widgetHandle);
1031 	long lang = OS.pango_context_get_language (context);
1032 	long metrics = OS.pango_context_get_metrics (context, font, lang);
1033 	int ascent = OS.pango_font_metrics_get_ascent (metrics);
1034 	int descent = OS.pango_font_metrics_get_descent (metrics);
1035 	OS.pango_font_metrics_unref (metrics);
1036 	return OS.PANGO_PIXELS (ascent + descent);
1037 }
1038 
filterProc(long xEvent, long gdkEvent, long data2)1039 long filterProc(long xEvent, long gdkEvent, long data2) {
1040 	return 0;
1041 }
1042 
filters(int eventType)1043 boolean filters (int eventType) {
1044 	return display.filters (eventType);
1045 }
1046 
fixMnemonic(String string)1047 char [] fixMnemonic (String string) {
1048 	return fixMnemonic (string, true);
1049 }
1050 
fixMnemonic(String string, boolean replace)1051 char [] fixMnemonic (String string, boolean replace) {
1052 	return fixMnemonic (string, replace, false);
1053 }
1054 
fixMnemonic(String string, boolean replace, boolean removeAppended)1055 char [] fixMnemonic (String string, boolean replace, boolean removeAppended) {
1056 	int length = string.length ();
1057 	char [] text = new char [length];
1058 	string.getChars (0, length, text, 0);
1059 	int i = 0, j = 0;
1060 	char [] result = new char [length * 2];
1061 	while (i < length) {
1062 		switch (text [i]) {
1063 			case '&':
1064 				if (i + 1 < length && text [i + 1] == '&') {
1065 					result [j++] = text [i++];
1066 				} else {
1067 					if (replace) result [j++] = '_';
1068 				}
1069 				i++;
1070 				break;
1071 				/*
1072 				 * In Japanese like languages where mnemonics are not taken from the
1073 				 * source label text but appended in parentheses like "(&M)" at end. In order to
1074 				 * allow the reuse of such label text as a tool-tip text as well, "(&M)" like
1075 				 * character sequence has to be removed from the end of CJK-style mnemonics.
1076 				 */
1077 			case '(':
1078 				if (removeAppended && i + 4 == string.length () && text [i + 1] == '&' && text [i + 3] == ')') {
1079 					if (replace) result [j++] = ' ';
1080 					i += 4;
1081 					break; // break switch case only if we are removing the mnemonic
1082 				}
1083 				else {
1084 					// otherwise fall through (default case applies)
1085 					result [j++] = text [i++];
1086 					break;
1087 				}
1088 			case '_':
1089 				if (replace) result [j++] = '_';
1090 				//FALL THROUGH
1091 			default:
1092 				result [j++] = text [i++];
1093 		}
1094 	}
1095 	return result;
1096 }
1097 
isActive()1098 boolean isActive () {
1099 	return true;
1100 }
1101 
1102 /**
1103  * Returns <code>true</code> if the widget has auto text direction,
1104  * and <code>false</code> otherwise.
1105  *
1106  * @return <code>true</code> when the widget has auto direction and <code>false</code> otherwise
1107  *
1108  * @see SWT#AUTO_TEXT_DIRECTION
1109  *
1110  * @since 3.105
1111  */
isAutoDirection()1112 public boolean isAutoDirection () {
1113 	return false;
1114 }
1115 
1116 /**
1117  * Returns <code>true</code> if the widget has been disposed,
1118  * and <code>false</code> otherwise.
1119  * <p>
1120  * This method gets the dispose state for the widget.
1121  * When a widget has been disposed, it is an error to
1122  * invoke any other method (except {@link #dispose()}) using the widget.
1123  * </p>
1124  *
1125  * @return <code>true</code> when the widget is disposed and <code>false</code> otherwise
1126  */
isDisposed()1127 public boolean isDisposed () {
1128 	return (state & DISPOSED) != 0;
1129 }
1130 
1131 /**
1132  * Returns <code>true</code> if there are any listeners
1133  * for the specified event type associated with the receiver,
1134  * and <code>false</code> otherwise. The event type is one of
1135  * the event constants defined in class <code>SWT</code>.
1136  *
1137  * @param eventType the type of event
1138  * @return true if the event is hooked
1139  *
1140  * @exception SWTException <ul>
1141  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1142  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1143  * </ul>
1144  *
1145  * @see SWT
1146  */
isListening(int eventType)1147 public boolean isListening (int eventType) {
1148 	checkWidget ();
1149 	return hooks (eventType);
1150 }
1151 
isValidThread()1152 boolean isValidThread () {
1153 	return getDisplay ().isValidThread ();
1154 }
1155 
isValidSubclass()1156 boolean isValidSubclass() {
1157 	return Display.isValidClass(getClass());
1158 }
1159 
hookEvents()1160 void hookEvents () {
1161 	if (handle != 0) {
1162 		OS.g_signal_connect (handle, OS.dpi_changed, display.notifyProc, Widget.DPI_CHANGED);
1163 	}
1164 }
1165 
1166 /*
1167  * Returns <code>true</code> if the specified eventType is
1168  * hooked, and <code>false</code> otherwise. Implementations
1169  * of SWT can avoid creating objects and sending events
1170  * when an event happens in the operating system but
1171  * there are no listeners hooked for the event.
1172  *
1173  * @param eventType the event to be checked
1174  *
1175  * @return <code>true</code> when the eventType is hooked and <code>false</code> otherwise
1176  *
1177  * @see #isListening
1178  */
hooks(int eventType)1179 boolean hooks (int eventType) {
1180 	if (eventTable == null) return false;
1181 	return eventTable.hooks (eventType);
1182 }
1183 
hoverProc(long widget)1184 long hoverProc (long widget) {
1185 	return 0;
1186 }
1187 
mnemonicHit(long mnemonicHandle, char key)1188 boolean mnemonicHit (long mnemonicHandle, char key) {
1189 	if (!mnemonicMatch (mnemonicHandle, key)) return false;
1190 	OS.g_signal_handlers_block_matched (mnemonicHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, MNEMONIC_ACTIVATE);
1191 	boolean result = GTK.gtk_widget_mnemonic_activate (mnemonicHandle, false);
1192 	OS.g_signal_handlers_unblock_matched (mnemonicHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, MNEMONIC_ACTIVATE);
1193 	return result;
1194 }
1195 
mnemonicMatch(long mnemonicHandle, char key)1196 boolean mnemonicMatch (long mnemonicHandle, char key) {
1197 	long keyval1 = GDK.gdk_keyval_to_lower (GDK.gdk_unicode_to_keyval (key));
1198 	long keyval2 = GDK.gdk_keyval_to_lower (GTK.gtk_label_get_mnemonic_keyval (mnemonicHandle));
1199 	return keyval1 == keyval2;
1200 }
1201 
1202 /**
1203  * Notifies all of the receiver's listeners for events
1204  * of the given type that one such event has occurred by
1205  * invoking their <code>handleEvent()</code> method.  The
1206  * event type is one of the event constants defined in class
1207  * <code>SWT</code>.
1208  *
1209  * @param eventType the type of event which has occurred
1210  * @param event the event data
1211  *
1212  * @exception SWTException <ul>
1213  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1214  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1215  * </ul>
1216  *
1217  * @see SWT
1218  * @see #addListener
1219  * @see #getListeners(int)
1220  * @see #removeListener(int, Listener)
1221  */
notifyListeners(int eventType, Event event)1222 public void notifyListeners (int eventType, Event event) {
1223 	checkWidget();
1224 	if (event == null) event = new Event ();
1225 	sendEvent (eventType, event);
1226 }
1227 
postEvent(int eventType)1228 void postEvent (int eventType) {
1229 	sendEvent (eventType, null, false);
1230 }
1231 
postEvent(int eventType, Event event)1232 void postEvent (int eventType, Event event) {
1233 	sendEvent (eventType, event, false);
1234 }
1235 
register()1236 void register () {
1237 	if (handle == 0) return;
1238 	if ((state & HANDLE) != 0) display.addWidget (handle, this);
1239 }
1240 
release(boolean destroy)1241 void release (boolean destroy) {
1242 	if ((state & DISPOSE_SENT) == 0) {
1243 		state |= DISPOSE_SENT;
1244 		sendEvent (SWT.Dispose);
1245 	}
1246 	if ((state & DISPOSED) == 0) {
1247 		releaseChildren (destroy);
1248 	}
1249 	if ((state & RELEASED) == 0) {
1250 		state |= RELEASED;
1251 		if (destroy) {
1252 			releaseParent ();
1253 			releaseWidget ();
1254 			destroyWidget ();
1255 		} else {
1256 			releaseWidget ();
1257 			releaseHandle ();
1258 		}
1259 	}
1260 }
1261 
releaseChildren(boolean destroy)1262 void releaseChildren (boolean destroy) {
1263 }
1264 
releaseHandle()1265 void releaseHandle () {
1266 	handle = 0;
1267 	state |= DISPOSED;
1268 	display = null;
1269 }
1270 
releaseParent()1271 void releaseParent () {
1272 	/* Do nothing */
1273 }
1274 
releaseWidget()1275 void releaseWidget () {
1276 	deregister ();
1277 	eventTable = null;
1278 	data = null;
1279 }
1280 
1281 /**
1282  * Removes the listener from the collection of listeners who will
1283  * be notified when an event of the given type occurs. The event
1284  * type is one of the event constants defined in class <code>SWT</code>.
1285  *
1286  * @param eventType the type of event to listen for
1287  * @param listener the listener which should no longer be notified
1288  *
1289  * @exception IllegalArgumentException <ul>
1290  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1291  * </ul>
1292  * @exception SWTException <ul>
1293  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1294  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1295  * </ul>
1296  *
1297  * @see Listener
1298  * @see SWT
1299  * @see #addListener
1300  * @see #getListeners(int)
1301  * @see #notifyListeners
1302  */
removeListener(int eventType, Listener listener)1303 public void removeListener (int eventType, Listener listener) {
1304 	checkWidget ();
1305 	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1306 	if (eventTable == null) return;
1307 	eventTable.unhook (eventType, listener);
1308 }
1309 
1310 /**
1311  * Removes the listener from the collection of listeners who will
1312  * be notified when an event of the given type occurs.
1313  * <p>
1314  * <b>IMPORTANT:</b> This method is <em>not</em> part of the SWT
1315  * public API. It is marked public only so that it can be shared
1316  * within the packages provided by SWT. It should never be
1317  * referenced from application code.
1318  * </p>
1319  *
1320  * @param eventType the type of event to listen for
1321  * @param listener the listener which should no longer be notified
1322  *
1323  * @exception IllegalArgumentException <ul>
1324  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1325  * </ul>
1326  * @exception SWTException <ul>
1327  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1328  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1329  * </ul>
1330  *
1331  * @see Listener
1332  * @see #addListener
1333  *
1334  * @noreference This method is not intended to be referenced by clients.
1335  * @nooverride This method is not intended to be re-implemented or extended by clients.
1336  */
removeListener(int eventType, SWTEventListener handler)1337 protected void removeListener (int eventType, SWTEventListener handler) {
1338 	checkWidget ();
1339 	if (handler == null) error (SWT.ERROR_NULL_ARGUMENT);
1340 	if (eventTable == null) return;
1341 	eventTable.unhook (eventType, handler);
1342 }
1343 
rendererGetPreferredWidthProc(long cell, long handle, long minimun_size, long natural_size)1344 long rendererGetPreferredWidthProc (long cell, long handle, long minimun_size, long natural_size) {
1345 	return 0;
1346 }
1347 
rendererRenderProc(long cell, long cr, long handle, long background_area, long cell_area, long flags)1348 long rendererRenderProc (long cell, long cr, long handle, long background_area, long cell_area, long flags) {
1349 	return 0;
1350 }
1351 
rendererSnapshotProc(long cell, long snapshot, long handle, long background_area, long cell_area, long flags)1352 long rendererSnapshotProc (long cell, long snapshot, long handle, long background_area, long cell_area, long flags) {
1353 	return 0;
1354 }
1355 
1356 /**
1357  * Marks the widget to be skinned.
1358  * <p>
1359  * The skin event is sent to the receiver's display when appropriate (usually before the next event
1360  * is handled). Widgets are automatically marked for skinning upon creation as well as when its skin
1361  * id or class changes. The skin id and/or class can be changed by calling {@link Display#setData(String, Object)}
1362  * with the keys {@link SWT#SKIN_ID} and/or {@link SWT#SKIN_CLASS}. Once the skin event is sent to a widget, it
1363  * will not be sent again unless <code>reskin(int)</code> is called on the widget or on an ancestor
1364  * while specifying the <code>SWT.ALL</code> flag.
1365  * </p>
1366  * <p>
1367  * The parameter <code>flags</code> may be either:
1368  * </p>
1369  * <dl>
1370  * <dt><b>{@link SWT#ALL}</b></dt>
1371  * <dd>all children in the receiver's widget tree should be skinned</dd>
1372  * <dt><b>{@link SWT#NONE}</b></dt>
1373  * <dd>only the receiver should be skinned</dd>
1374  * </dl>
1375  * @param flags the flags specifying how to reskin
1376  *
1377  * @exception SWTException
1378  * <ul>
1379  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1380  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1381  * </ul>
1382  * @since 3.6
1383  */
reskin(int flags)1384 public void reskin (int flags) {
1385 	checkWidget ();
1386 	reskinWidget ();
1387 	if ((flags & SWT.ALL) != 0) reskinChildren (flags);
1388 }
1389 
reskinChildren(int flags)1390 void reskinChildren (int flags) {
1391 }
1392 
reskinWidget()1393 void reskinWidget() {
1394 	if ((state & SKIN_NEEDED) != SKIN_NEEDED) {
1395 		this.state |= SKIN_NEEDED;
1396 		display.addSkinnableWidget(this);
1397 	}
1398 }
1399 
1400 /**
1401  * Removes the listener from the collection of listeners who will
1402  * be notified when the widget is disposed.
1403  *
1404  * @param listener the listener which should no longer be notified
1405  *
1406  * @exception IllegalArgumentException <ul>
1407  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1408  * </ul>
1409  * @exception SWTException <ul>
1410  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1411  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1412  * </ul>
1413  *
1414  * @see DisposeListener
1415  * @see #addDisposeListener
1416  */
removeDisposeListener(DisposeListener listener)1417 public void removeDisposeListener (DisposeListener listener) {
1418 	checkWidget ();
1419 	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1420 	if (eventTable == null) return;
1421 	eventTable.unhook (SWT.Dispose, listener);
1422 }
1423 
sendEvent(Event event)1424 void sendEvent (Event event) {
1425 	Display display = event.display;
1426 	if (!display.filterEvent (event)) {
1427 		if (eventTable != null) display.sendEvent(eventTable, event);
1428 	}
1429 }
1430 
sendEvent(int eventType)1431 void sendEvent (int eventType) {
1432 	sendEvent (eventType, null, true);
1433 }
1434 
sendEvent(int eventType, Event event)1435 void sendEvent (int eventType, Event event) {
1436 	sendEvent (eventType, event, true);
1437 }
1438 
sendEvent(int eventType, Event event, boolean send)1439 void sendEvent (int eventType, Event event, boolean send) {
1440 	if (eventTable == null && !display.filters (eventType)) {
1441 		return;
1442 	}
1443 	if (event == null) {
1444 		event = new Event();
1445 	}
1446 	event.type = eventType;
1447 	event.display = display;
1448 	event.widget = this;
1449 	if (event.time == 0) {
1450 		event.time = display.getLastEventTime ();
1451 	}
1452 	if (send) {
1453 		sendEvent (event);
1454 	} else {
1455 		display.postEvent (event);
1456 	}
1457 }
1458 
sendKeyEvent(int type, long event)1459 boolean sendKeyEvent (int type, long event) {
1460 	int length = 0;
1461 	long string = 0;
1462 	if (GTK.GTK4) {
1463 		/* TODO: GTK4 no access to key event string */
1464 	} else {
1465 		GdkEventKey gdkEvent = new GdkEventKey ();
1466 		OS.memmove(gdkEvent, event, GdkEventKey.sizeof);
1467 		length = gdkEvent.length;
1468 		string = gdkEvent.string;
1469 	}
1470 
1471 	if (string == 0 || OS.g_utf16_strlen (string, length) <= 1) {
1472 		Event javaEvent = new Event ();
1473 		javaEvent.time = GDK.gdk_event_get_time(event);
1474 		if (!setKeyState (javaEvent, event)) return true;
1475 		sendEvent (type, javaEvent);
1476 		// widget could be disposed at this point
1477 
1478 		/*
1479 		* It is possible (but unlikely), that application
1480 		* code could have disposed the widget in the key
1481 		* events.  If this happens, end the processing of
1482 		* the key by returning false.
1483 		*/
1484 		if (isDisposed ()) return false;
1485 		return javaEvent.doit;
1486 	}
1487 	byte [] buffer = new byte [length];
1488 	C.memmove (buffer, string, length);
1489 	char [] chars = Converter.mbcsToWcs (buffer);
1490 	return sendIMKeyEvent (type, event, chars) != null;
1491 }
1492 
sendIMKeyEvent(int type, long event, char [] chars)1493 char [] sendIMKeyEvent (int type, long event, char [] chars) {
1494 	int index = 0, count = 0, state = 0;
1495 	long ptr = 0;
1496 	if (event == 0) {
1497 		ptr = GTK3.gtk_get_current_event ();
1498 		if (ptr != 0) {
1499 			int eventType = GDK.gdk_event_get_event_type(ptr);
1500 			eventType = Control.fixGdkEventTypeValues(eventType);
1501 			switch (eventType) {
1502 				case GDK.GDK_KEY_PRESS:
1503 				case GDK.GDK_KEY_RELEASE:
1504 					int [] eventState = new int[1];
1505 					if (GTK.GTK4) {
1506 						eventState[0] = GDK.gdk_event_get_modifier_state(event);
1507 					} else {
1508 						GDK.gdk_event_get_state(event, eventState);
1509 					}
1510 					state = eventState[0];
1511 					break;
1512 				default:
1513 					event = 0;
1514 					break;
1515 			}
1516 		} else {
1517 			int [] buffer = new int [1];
1518 			GTK3.gtk_get_current_event_state (buffer);
1519 			state = buffer [0];
1520 		}
1521 	} else {
1522 		ptr = event;
1523 	}
1524 	while (index < chars.length) {
1525 		Event javaEvent = new Event ();
1526 		if (ptr != 0 && chars.length <= 1) {
1527 			setKeyState (javaEvent, ptr);
1528 		} else {
1529 			setInputState (javaEvent, state);
1530 		}
1531 		javaEvent.character = chars [index];
1532 		sendEvent (type, javaEvent);
1533 
1534 		/*
1535 		* It is possible (but unlikely), that application
1536 		* code could have disposed the widget in the key
1537 		* events.  If this happens, end the processing of
1538 		* the key by returning null.
1539 		*/
1540 		if (isDisposed ()) {
1541 			if (ptr != 0 && ptr != event) gdk_event_free (ptr);
1542 			return null;
1543 		}
1544 		if (javaEvent.doit) chars [count++] = chars [index];
1545 		index++;
1546 	}
1547 	if (ptr != 0 && ptr != event) gdk_event_free (ptr);
1548 	if (count == 0) return null;
1549 	if (index != count) {
1550 		char [] result = new char [count];
1551 		System.arraycopy (chars, 0, result, 0, count);
1552 		return result;
1553 	}
1554 	return chars;
1555 }
1556 
sendSelectionEvent(int eventType)1557 void sendSelectionEvent (int eventType) {
1558 	sendSelectionEvent (eventType, null, false);
1559 }
1560 
sendSelectionEvent(int eventType, Event event, boolean send)1561 void sendSelectionEvent (int eventType, Event event, boolean send) {
1562 	if (eventTable == null && !display.filters (eventType)) {
1563 		return;
1564 	}
1565 	if (event == null) event = new Event ();
1566 	long ptr = GTK.GTK4 ? 0 : GTK3.gtk_get_current_event ();
1567 	if (ptr != 0) {
1568 		int currentEventType = GDK.gdk_event_get_event_type(ptr);
1569 		currentEventType = Control.fixGdkEventTypeValues(currentEventType);
1570 		switch (currentEventType) {
1571 			case GDK.GDK_BUTTON_PRESS:
1572 			case GDK.GDK_2BUTTON_PRESS:
1573 			case GDK.GDK_BUTTON_RELEASE: {
1574 				int [] eventButton = new int [1];
1575 				if (GTK.GTK4) {
1576 					eventButton[0] = GDK.gdk_button_event_get_button(ptr);
1577 				} else {
1578 					GDK.gdk_event_get_button(ptr, eventButton);
1579 				}
1580 
1581 				setButtonState(event, eventButton [0]);
1582 			}
1583 			//$FALL-THROUGH$
1584 			case GDK.GDK_KEY_PRESS:
1585 			case GDK.GDK_KEY_RELEASE: {
1586 				int [] state = new int[1];
1587 				if (GTK.GTK4) {
1588 					state[0] = GDK.gdk_event_get_modifier_state(ptr);
1589 				} else {
1590 					GDK.gdk_event_get_state(ptr, state);
1591 				}
1592 				setInputState (event, state [0]);
1593 				break;
1594 			}
1595 		}
1596 		gdk_event_free (ptr);
1597 	}
1598 	sendEvent (eventType, event, send);
1599 }
1600 
1601 /**
1602  * Sets the application defined widget data associated
1603  * with the receiver to be the argument. The <em>widget
1604  * data</em> is a single, unnamed field that is stored
1605  * with every widget.
1606  * <p>
1607  * Applications may put arbitrary objects in this field. If
1608  * the object stored in the widget data needs to be notified
1609  * when the widget is disposed of, it is the application's
1610  * responsibility to hook the Dispose event on the widget and
1611  * do so.
1612  * </p>
1613  *
1614  * @param data the widget data
1615  *
1616  * @exception SWTException <ul>
1617  *    <li>ERROR_WIDGET_DISPOSED - when the receiver has been disposed</li>
1618  *    <li>ERROR_THREAD_INVALID_ACCESS - when called from the wrong thread</li>
1619  * </ul>
1620  *
1621  * @see #getData()
1622  */
setData(Object data)1623 public void setData (Object data) {
1624 	checkWidget();
1625 	if ((state & KEYED_DATA) != 0) {
1626 		((Object []) this.data) [0] = data;
1627 	} else {
1628 		this.data = data;
1629 	}
1630 }
1631 
1632 /**
1633  * Sets the application defined property of the receiver
1634  * with the specified name to the given value.
1635  * <p>
1636  * Applications may associate arbitrary objects with the
1637  * receiver in this fashion. If the objects stored in the
1638  * properties need to be notified when the widget is disposed
1639  * of, it is the application's responsibility to hook the
1640  * Dispose event on the widget and do so.
1641  * </p>
1642  *
1643  * @param key the name of the property
1644  * @param value the new value for the property
1645  *
1646  * @exception IllegalArgumentException <ul>
1647  *    <li>ERROR_NULL_ARGUMENT - if the key is null</li>
1648  * </ul>
1649  * @exception SWTException <ul>
1650  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1651  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1652  * </ul>
1653  *
1654  * @see #getData(String)
1655  */
setData(String key, Object value)1656 public void setData (String key, Object value) {
1657 	checkWidget();
1658 	if (key == null) error (SWT.ERROR_NULL_ARGUMENT);
1659 
1660 	if (key.equals (KEY_CHECK_SUBWINDOW)) {
1661 		if (value != null && value instanceof Boolean) {
1662 			if (((Boolean)value).booleanValue ()) {
1663 				state |= CHECK_SUBWINDOW;
1664 			} else {
1665 				state &= ~CHECK_SUBWINDOW;
1666 			}
1667 		}
1668 		return;
1669 	}
1670 
1671 	int index = 1;
1672 	Object [] table = null;
1673 	if ((state & KEYED_DATA) != 0) {
1674 		table = (Object []) data;
1675 		while (index < table.length) {
1676 			if (key.equals (table [index])) break;
1677 			index += 2;
1678 		}
1679 	}
1680 	if (value != null) {
1681 		if ((state & KEYED_DATA) != 0) {
1682 			if (index == table.length) {
1683 				Object [] newTable = new Object [table.length + 2];
1684 				System.arraycopy (table, 0, newTable, 0, table.length);
1685 				data = table = newTable;
1686 			}
1687 		} else {
1688 			table = new Object [3];
1689 			table [0] = data;
1690 			data = table;
1691 			state |= KEYED_DATA;
1692 		}
1693 		table [index] = key;
1694 		table [index + 1] = value;
1695 	} else {
1696 		if ((state & KEYED_DATA) != 0) {
1697 			if (index != table.length) {
1698 				int length = table.length - 2;
1699 				if (length == 1) {
1700 					data = table [0];
1701 					state &= ~KEYED_DATA;
1702 				} else {
1703 					Object [] newTable = new Object [length];
1704 					System.arraycopy (table, 0, newTable, 0, index);
1705 					System.arraycopy (table, index + 2, newTable, index, length - index);
1706 					data = newTable;
1707 				}
1708 			}
1709 		}
1710 	}
1711 	if (key.equals(SWT.SKIN_CLASS) || key.equals(SWT.SKIN_ID)) this.reskin(SWT.ALL);
1712 	if (key.equals(KEY_GTK_CSS) && value instanceof String) {
1713 		long context = GTK.gtk_widget_get_style_context (cssHandle());
1714 		long provider = GTK.gtk_css_provider_new();
1715 		if (context != 0 && provider != 0) {
1716 			GTK.gtk_style_context_add_provider (context, provider, GTK.GTK_STYLE_PROVIDER_PRIORITY_USER);
1717 			if (GTK.GTK4) {
1718 				GTK4.gtk_css_provider_load_from_data (provider, Converter.wcsToMbcs ((String) value, true), -1);
1719 			} else {
1720 				GTK3.gtk_css_provider_load_from_data (provider, Converter.wcsToMbcs ((String) value, true), -1, null);
1721 			}
1722 			OS.g_object_unref (provider);
1723 		}
1724 	}
1725 }
1726 
1727 /**
1728  * @param fontDescription Font description in the form of
1729  *                        <code>PangoFontDescription*</code>. This pointer
1730  *                        will never be used by GTK after calling this
1731  *                        function, so it's safe to free it as soon as the
1732  *                        function completes.
1733  */
setFontDescription(long widget, long fontDescription)1734 void setFontDescription(long widget, long fontDescription) {
1735 	if (GTK.GTK4) {
1736 		long styleContext = GTK.gtk_widget_get_style_context(widget);
1737 		long provider = GTK.gtk_css_provider_new();
1738 		GTK.gtk_style_context_add_provider(styleContext, provider, GTK.GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1739 		OS.g_object_unref(provider);
1740 
1741 		String css = convertPangoFontDescriptionToCss(fontDescription);
1742 		GTK4.gtk_css_provider_load_from_data(provider, Converter.javaStringToCString(css), -1);
1743 	} else {
1744 		// gtk_widget_override_font() copies the fields from 'fontDescription'
1745 		// and does not remember the pointer passed to it.
1746 		GTK3.gtk_widget_override_font(widget, fontDescription);
1747 		long context = GTK.gtk_widget_get_style_context(widget);
1748 		GTK3.gtk_style_context_invalidate(context);
1749 	}
1750 }
1751 
convertPangoFontDescriptionToCss(long fontDescription)1752 String convertPangoFontDescriptionToCss(long fontDescription) {
1753 	String css = "* { ";
1754 	int fontMask = OS.pango_font_description_get_set_fields(fontDescription);
1755 
1756 	if ((fontMask & OS.PANGO_FONT_MASK_FAMILY) != 0) {
1757 		long fontFamily = OS.pango_font_description_get_family(fontDescription);
1758 		css += "font-family: \"" + Converter.cCharPtrToJavaString(fontFamily, false) + "\";";
1759 	}
1760 
1761 	if ((fontMask & OS.PANGO_FONT_MASK_WEIGHT) != 0) {
1762 		int fontWeight = OS.pango_font_description_get_weight(fontDescription);
1763 
1764 		String weightString = fontWeight < OS.PANGO_WEIGHT_BOLD ? "normal" : "bold";
1765 		css += "font-weight: " + weightString + ";";
1766 	}
1767 
1768 	if ((fontMask & OS.PANGO_FONT_MASK_STYLE) != 0) {
1769 		int fontStyle = OS.pango_font_description_get_style(fontDescription);
1770 
1771 		String styleString;
1772 		switch (fontStyle) {
1773 			case OS.PANGO_STYLE_NORMAL:
1774 				styleString = "normal";
1775 				break;
1776 			case OS.PANGO_STYLE_ITALIC:
1777 				styleString = "italic";
1778 				break;
1779 			default:
1780 				styleString = "";
1781 				break;
1782 		}
1783 
1784 		css += "font-style: " + styleString + ";";
1785 	}
1786 
1787 	if ((fontMask & OS.PANGO_FONT_MASK_SIZE) != 0) {
1788 		int fontSize = OS.pango_font_description_get_size(fontDescription);
1789 		css += "font-size: " + fontSize / OS.PANGO_SCALE + "pt;";
1790 	}
1791 
1792 	css += " } ";
1793 
1794 	return css;
1795 }
1796 
1797 void setButtonState (Event event, int eventButton) {
1798 	switch (eventButton) {
1799 	case 1: event.stateMask |= SWT.BUTTON1; break;
1800 	case 2: event.stateMask |= SWT.BUTTON2; break;
1801 	case 3: event.stateMask |= SWT.BUTTON3; break;
1802 	case 4: event.stateMask |= SWT.BUTTON4; break;
1803 	case 5: event.stateMask |= SWT.BUTTON5; break;
1804 	default:
1805 	}
1806 }
1807 
1808 boolean setInputState (Event event, int state) {
1809 	if ((state & GDK.GDK_MOD1_MASK) != 0) event.stateMask |= SWT.ALT;
1810 	if ((state & GDK.GDK_SHIFT_MASK) != 0) event.stateMask |= SWT.SHIFT;
1811 	if ((state & GDK.GDK_CONTROL_MASK) != 0) event.stateMask |= SWT.CONTROL;
1812 	if ((state & GDK.GDK_BUTTON1_MASK) != 0) event.stateMask |= SWT.BUTTON1;
1813 	if ((state & GDK.GDK_BUTTON2_MASK) != 0) event.stateMask |= SWT.BUTTON2;
1814 	if ((state & GDK.GDK_BUTTON3_MASK) != 0) event.stateMask |= SWT.BUTTON3;
1815 	return true;
1816 }
1817 
1818 boolean setKeyState (Event javaEvent, long event) {
1819 	long string = 0;
1820 	int length = 0;
1821 	int group;
1822 
1823 	int [] eventKeyval = new int [1];
1824 	int [] eventState = new int [1];
1825 	if (GTK.GTK4) {
1826 		eventKeyval[0] = GDK.gdk_key_event_get_keyval(event);
1827 		eventState[0] = GDK.gdk_event_get_modifier_state(event);
1828 	} else {
1829 		GDK.gdk_event_get_keyval(event, eventKeyval);
1830 		GDK.gdk_event_get_state(event, eventState);
1831 	}
1832 
1833 	if (GTK.GTK4) {
1834 		group = GDK.gdk_key_event_get_layout(event);
1835 	} else {
1836 		GdkEventKey gdkEvent = new GdkEventKey ();
1837 		OS.memmove(gdkEvent, event, GdkEventKey.sizeof);
1838 		length = gdkEvent.length;
1839 		string = gdkEvent.string;
1840 		group = gdkEvent.group;
1841 	}
1842 
1843 	if (string != 0 && OS.g_utf16_strlen (string, length) > 1) return false;
1844 	boolean isNull = false;
1845 	javaEvent.keyCode = Display.translateKey (eventKeyval[0]);
1846 	switch (eventKeyval[0]) {
1847 		case GDK.GDK_BackSpace:		javaEvent.character = SWT.BS; break;
1848 		case GDK.GDK_Linefeed:		javaEvent.character = SWT.LF; break;
1849 		case GDK.GDK_KP_Enter:
1850 		case GDK.GDK_Return: 		javaEvent.character = SWT.CR; break;
1851 		case GDK.GDK_KP_Delete:
1852 		case GDK.GDK_Delete:			javaEvent.character = SWT.DEL; break;
1853 		case GDK.GDK_Escape:			javaEvent.character = SWT.ESC; break;
1854 		case GDK.GDK_Tab:
1855 		case GDK.GDK_ISO_Left_Tab: 	javaEvent.character = SWT.TAB; break;
1856 		default: {
1857 			if (javaEvent.keyCode == 0) {
1858 				int [] keyval = new int [1];
1859 				int [] effective_group = new int [1], level = new int [1], consumed_modifiers = new int [1];
1860 				/* If current group is not a Latin layout, get the most Latin Layout group from input source. */
1861 				Map<Integer, Integer> groupLatinKeysCount = display.getGroupKeysCount();
1862 				if (!groupLatinKeysCount.containsKey(group)) {
1863 					group = display.getLatinKeyGroup();
1864 				}
1865 
1866 				long keymap = 0;
1867 				long display = GDK.gdk_display_get_default();
1868 				if (GTK.GTK4) {
1869 					//TODO: GTK4 Get keymap or find alternative for gdk_keymap_translate_keyboard_state (no longer exist in GTK4)
1870 				} else {
1871 					keymap = GDK.gdk_keymap_get_for_display(display);
1872 				}
1873 
1874 				short [] keyCode = new short [1];
1875 				if (GTK.GTK4) {
1876 					keyCode[0] = (short) GDK.gdk_key_event_get_keycode(event);
1877 					javaEvent.keyCode = keyCode[0];
1878 				} else {
1879 					GDK.gdk_event_get_keycode(event, keyCode);
1880 					if (GDK.gdk_keymap_translate_keyboard_state (keymap, keyCode[0],
1881 							0, group, keyval, effective_group, level, consumed_modifiers)) {
1882 						javaEvent.keyCode = (int) GDK.gdk_keyval_to_unicode (keyval [0]);
1883 					}
1884 				}
1885 			}
1886 			int key = eventKeyval[0];
1887 			if ((eventState[0] & GDK.GDK_CONTROL_MASK) != 0 && (0 <= key && key <= 0x7F)) {
1888 				if ('a'  <= key && key <= 'z') key -= 'a' - 'A';
1889 				if (64 <= key && key <= 95) key -= 64;
1890 				javaEvent.character = (char) key;
1891 				isNull = eventKeyval[0] == '@' && key == 0;
1892 			} else {
1893 				javaEvent.character = (char) GDK.gdk_keyval_to_unicode (key);
1894 			}
1895 		}
1896 	}
1897 	setLocationState (javaEvent, event);
1898 	if (javaEvent.keyCode == 0 && javaEvent.character == 0) {
1899 		if (!isNull) return false;
1900 	}
1901 	return setInputState (javaEvent, eventState[0]);
1902 }
1903 
setLocationState(Event event, long eventPtr)1904 void setLocationState (Event event, long eventPtr) {
1905 	int [] eventKeyval = new int[1];
1906 	if (GTK.GTK4) {
1907 		eventKeyval[0] = GDK.gdk_key_event_get_keyval(eventPtr);
1908 	} else {
1909 		GDK.gdk_event_get_keyval(eventPtr, eventKeyval);
1910 	}
1911 
1912 	switch (eventKeyval[0]) {
1913 		case GDK.GDK_Alt_L:
1914 		case GDK.GDK_Shift_L:
1915 		case GDK.GDK_Control_L:
1916 			event.keyLocation = SWT.LEFT;
1917 			break;
1918 		case GDK.GDK_Alt_R:
1919 		case GDK.GDK_Shift_R:
1920 		case GDK.GDK_Control_R:
1921 				event.keyLocation = SWT.RIGHT;
1922 			break;
1923 		case GDK.GDK_KP_0:
1924 		case GDK.GDK_KP_1:
1925 		case GDK.GDK_KP_2:
1926 		case GDK.GDK_KP_3:
1927 		case GDK.GDK_KP_4:
1928 		case GDK.GDK_KP_5:
1929 		case GDK.GDK_KP_6:
1930 		case GDK.GDK_KP_7:
1931 		case GDK.GDK_KP_8:
1932 		case GDK.GDK_KP_9:
1933 		case GDK.GDK_KP_Add:
1934 		case GDK.GDK_KP_Decimal:
1935 		case GDK.GDK_KP_Delete:
1936 		case GDK.GDK_KP_Divide:
1937 		case GDK.GDK_KP_Down:
1938 		case GDK.GDK_KP_End:
1939 		case GDK.GDK_KP_Enter:
1940 		case GDK.GDK_KP_Equal:
1941 		case GDK.GDK_KP_Home:
1942 		case GDK.GDK_KP_Insert:
1943 		case GDK.GDK_KP_Left:
1944 		case GDK.GDK_KP_Multiply:
1945 		case GDK.GDK_KP_Page_Down:
1946 		case GDK.GDK_KP_Page_Up:
1947 		case GDK.GDK_KP_Right:
1948 		case GDK.GDK_KP_Subtract:
1949 		case GDK.GDK_KP_Up:
1950 		case GDK.GDK_Num_Lock:
1951 			event.keyLocation = SWT.KEYPAD;
1952 			break;
1953 	}
1954 }
1955 
setOrientation(boolean create)1956 void setOrientation (boolean create) {
1957 }
1958 
setTabGroupFocus(boolean next)1959 boolean setTabGroupFocus (boolean next) {
1960 	return setTabItemFocus (next);
1961 }
1962 
setTabItemFocus(boolean next)1963 boolean setTabItemFocus (boolean next) {
1964 	return false;
1965 }
1966 
shellMapProc(long handle, long arg0, long user_data)1967 long shellMapProc (long handle, long arg0, long user_data) {
1968 	return 0;
1969 }
1970 
sizeAllocateProc(long handle, long arg0, long user_data)1971 long sizeAllocateProc (long handle, long arg0, long user_data) {
1972 	return 0;
1973 }
1974 
sizeRequestProc(long handle, long arg0, long user_data)1975 long sizeRequestProc (long handle, long arg0, long user_data) {
1976 	return 0;
1977 }
1978 
1979 /**
1980  * Converts an incoming snapshot into a gtk_draw() call, complete with
1981  * a Cairo context.
1982  *
1983  * @param handle the widget receiving the snapshot
1984  * @param snapshot the actual GtkSnapshot
1985  */
snapshotToDraw(long handle, long snapshot)1986 void snapshotToDraw (long handle, long snapshot) {
1987 	GtkAllocation allocation = new GtkAllocation ();
1988 	GTK.gtk_widget_get_allocation(handle, allocation);
1989 	long rect = Graphene.graphene_rect_alloc();
1990 	Graphene.graphene_rect_init(rect, 0, 0, allocation.width, allocation.height);
1991 	long cairo = GTK4.gtk_snapshot_append_cairo(snapshot, rect);
1992 	if (cairo != 0) gtk_draw(handle, cairo);
1993 	Graphene.graphene_rect_free(rect);
1994 	return;
1995 }
1996 
gtk_widget_get_window(long widget)1997 long gtk_widget_get_window (long widget){
1998 	GTK.gtk_widget_realize(widget);
1999 	return GTK3.gtk_widget_get_window (widget);
2000 }
2001 
gtk_widget_get_surface(long widget)2002 long gtk_widget_get_surface (long widget){
2003 	GTK.gtk_widget_realize(widget);
2004 	return GTK4.gtk_native_get_surface(GTK4.gtk_widget_get_native (widget));
2005 }
2006 
gdk_window_get_size(long drawable, int[] width, int[] height)2007 void gdk_window_get_size (long drawable, int[] width, int[] height) {
2008 	width[0] = GDK.gdk_window_get_width (drawable);
2009 	height[0] = GDK.gdk_window_get_height (drawable);
2010 }
2011 
gdk_surface_get_size(long surface, int[] width, int[] height)2012 void gdk_surface_get_size (long surface, int[] width, int[] height) {
2013 	width[0] = GDK.gdk_surface_get_width (surface);
2014 	height[0] = GDK.gdk_surface_get_height (surface);
2015 }
2016 
2017 /**
2018  * GTK4 does not hand out copies of events anymore, only references.
2019  * Call gdk_event_free() on GTK3 and g_object_unref() on GTK4.
2020  *
2021  * @param event the event to be freed
2022  */
gdk_event_free(long event)2023 void gdk_event_free (long event) {
2024 	if (event == 0) return;
2025 	if (GTK.GTK4) {
2026 		GDK.gdk_event_unref(event);
2027 	} else {
2028 		GDK.gdk_event_free(event);
2029 	}
2030 }
2031 
2032 /**
2033  * Wrapper function for gdk_event_get_surface() on GTK4,
2034  * and gdk_event_get_window() on GTK3.
2035  *
2036  * @param event the event whose window or surface to fetch
2037  * @return the GdkWindow or GdkSurface associated with the event
2038  */
gdk_event_get_surface_or_window(long event)2039 long gdk_event_get_surface_or_window(long event) {
2040 	if (event == 0) return 0;
2041 	if (GTK.GTK4) {
2042 		return GDK.gdk_event_get_surface(event);
2043 	} else {
2044 		return GDK.gdk_event_get_window(event);
2045 	}
2046 }
2047 
2048 /**
2049  * Wrapper function for gdk_event_get_state()
2050  * @param event   pointer to the GdkEvent.
2051  * @return the keymask to be used with constants like
2052  *        OS.GDK_SHIFT_MASK / OS.GDK_CONTROL_MASK / OS.GDK_MOD1_MASK etc..
2053  */
gdk_event_get_state(long event)2054 int gdk_event_get_state (long event) {
2055 	int [] state = new int[1];
2056 	if (GTK.GTK4) {
2057 		state[0] = GDK.gdk_event_get_modifier_state(event);
2058 	} else {
2059 		GDK.gdk_event_get_state(event, state);
2060 	}
2061 
2062 	return state[0];
2063 }
2064 
2065 
gtk_box_new(int orientation, boolean homogeneous, int spacing)2066 long gtk_box_new (int orientation, boolean homogeneous, int spacing) {
2067 	long box = GTK.gtk_box_new (orientation, spacing);
2068 	GTK.gtk_box_set_homogeneous (box, homogeneous);
2069 	return box;
2070 }
2071 
gtk_box_set_child_packing(long box, long child, boolean expand, boolean fill, int padding, int pack_type)2072 void gtk_box_set_child_packing (long box, long child, boolean expand, boolean fill, int padding, int pack_type) {
2073 	if (GTK.GTK4) {
2074 		GTK.gtk_widget_set_hexpand(child, expand);
2075 		GTK.gtk_widget_set_vexpand(child, expand);
2076 		if (fill) {
2077 			GTK.gtk_widget_set_halign(child, GTK.GTK_ALIGN_FILL);
2078 			GTK.gtk_widget_set_valign(child, GTK.GTK_ALIGN_FILL);
2079 		}
2080 	} else {
2081 		GTK3.gtk_box_set_child_packing(box, child, expand, fill, padding, pack_type);
2082 	}
2083 }
2084 
gtk_box_pack_end(long box, long child, boolean expand, boolean fill, int padding)2085 void gtk_box_pack_end (long box, long child, boolean expand, boolean fill, int padding) {
2086 	if (GTK.GTK4) {
2087 		GTK.gtk_widget_set_hexpand(child, expand);
2088 		GTK.gtk_widget_set_vexpand(child, expand);
2089 		if (fill) {
2090 			GTK.gtk_widget_set_halign(child, GTK.GTK_ALIGN_FILL);
2091 			GTK.gtk_widget_set_valign(child, GTK.GTK_ALIGN_FILL);
2092 		}
2093 		GTK4.gtk_box_append(box, child);
2094 	} else {
2095 		GTK3.gtk_box_pack_end(box, child, expand, fill, padding);
2096 	}
2097 }
2098 
gdk_pointer_grab(long gdkResource, int grab_ownership, boolean owner_events, int event_mask, long confine_to, long cursor, int time_)2099 int gdk_pointer_grab (long gdkResource, int grab_ownership, boolean owner_events, int event_mask, long confine_to, long cursor, int time_) {
2100 	long display = 0;
2101 	if (GTK.GTK4) {
2102 		if( gdkResource != 0) {
2103 			display = GDK.gdk_surface_get_display (gdkResource);
2104 		}
2105 	} else {
2106 		if( gdkResource != 0) {
2107 			display = GDK.gdk_window_get_display (gdkResource);
2108 		} else {
2109 			gdkResource = GDK.gdk_get_default_root_window ();
2110 			display = GDK.gdk_window_get_display (gdkResource);
2111 		}
2112 	}
2113 	long seat = GDK.gdk_display_get_default_seat(display);
2114 	if (gdkSeatGrabPrepareFunc == null) {
2115 		gdkSeatGrabPrepareFunc = new Callback(Widget.class, "GdkSeatGrabPrepareFunc", 3); //$NON-NLS-1$
2116 	}
2117 	return GDK.gdk_seat_grab(seat, gdkResource, GDK.GDK_SEAT_CAPABILITY_ALL_POINTING, owner_events, cursor, 0, gdkSeatGrabPrepareFunc.getAddress(), gdkResource);
2118 }
2119 
gdk_pointer_ungrab(long gdkResource, int time_)2120 void gdk_pointer_ungrab (long gdkResource, int time_) {
2121 	long display = GTK.GTK4? GDK.gdk_surface_get_display(gdkResource) : GDK.gdk_window_get_display (gdkResource);
2122 	long seat = GDK.gdk_display_get_default_seat(display);
2123 	GDK.gdk_seat_ungrab(seat);
2124 }
2125 
GdkSeatGrabPrepareFunc(long gdkSeat, long gdkResource, long userData_gdkResource)2126 static long GdkSeatGrabPrepareFunc (long gdkSeat, long gdkResource, long userData_gdkResource) {
2127 	if (userData_gdkResource != 0) {
2128 		if (GTK.GTK4) {
2129 			/* TODO: GTK does not provide a gdk_surface_show, probably will require use of the present api */
2130 		} else {
2131 			GDK.gdk_window_show(userData_gdkResource);
2132 		}
2133 	}
2134 	return 0;
2135 }
2136 
2137 /**
2138  * Returns a string containing a concise, human-readable
2139  * description of the receiver.
2140  *
2141  * @return a string representation of the receiver
2142  */
2143 @Override
toString()2144 public String toString () {
2145 	String string = "*Disposed*";
2146 	if (!isDisposed ()) {
2147 		string = "*Wrong Thread*";
2148 		if (isValidThread ()) string = getNameText ();
2149 	}
2150 	return getName () + " {" + string + "}";
2151 }
2152 
topHandle()2153 long topHandle () {
2154 	return handle;
2155 }
2156 
timerProc(long widget)2157 long timerProc (long widget) {
2158 	return 0;
2159 }
2160 
translateTraversal(int event)2161 boolean translateTraversal (int event) {
2162 	return false;
2163 }
2164 
enterMotionScrollProc(long controller, long handle, double x, double y, long user_data)2165 long enterMotionScrollProc(long controller, long handle, double x, double y, long user_data) {
2166 	long result = 0;
2167 	long event = GTK4.gtk_event_controller_get_current_event(controller);
2168 
2169 	switch ((int)user_data) {
2170 		case ENTER:
2171 			result = gtk_enter_notify_event(handle, event);
2172 			break;
2173 		case MOTION:
2174 			result = gtk_motion_notify_event(handle, event);
2175 			break;
2176 		case MOTION_INVERSE:
2177 			result = 1;
2178 			break;
2179 		case SCROLL:
2180 			result = gtk_scroll_event(handle, event);
2181 			break;
2182 	}
2183 
2184 	return result;
2185 }
2186 
focusProc(long controller, long handle, long user_data)2187 long focusProc(long controller, long handle, long user_data) {
2188 	long result = 0;
2189 	long event = GTK4.gtk_event_controller_get_current_event(controller);
2190 
2191 	switch ((int)user_data) {
2192 		case FOCUS_IN:
2193 			result = gtk_focus_in_event(handle, event);
2194 			break;
2195 		case FOCUS_OUT:
2196 			result = gtk_focus_out_event(handle, event);
2197 			break;
2198 	}
2199 
2200 	return result;
2201 }
2202 
keyPressReleaseProc(long controller, long handle, int keyval, int keycode, int state, long user_data)2203 long keyPressReleaseProc(long controller, long handle, int keyval, int keycode, int state, long user_data) {
2204 	long result = 0;
2205 	long event = GTK4.gtk_event_controller_get_current_event(controller);
2206 
2207 	switch ((int)user_data) {
2208 		case KEY_PRESSED:
2209 			result = gtk_key_press_event(handle, event);
2210 			break;
2211 		case KEY_RELEASED:
2212 			result = gtk_key_release_event(handle, event);
2213 			break;
2214 	}
2215 
2216 	return result;
2217 }
2218 
gesturePressReleaseProc(long gesture, int n_press, double x, double y, long user_data)2219 void gesturePressReleaseProc(long gesture, int n_press, double x, double y, long user_data) {
2220 	long event = GTK4.gtk_event_controller_get_current_event(gesture);
2221 
2222 	switch ((int)user_data) {
2223 		case GESTURE_PRESSED:
2224 			gtk_gesture_press_event(gesture, n_press, x, y, event);
2225 			break;
2226 		case GESTURE_RELEASED:
2227 			gtk_gesture_release_event(gesture, n_press, x, y, event);
2228 			break;
2229 	}
2230 }
2231 
leaveProc(long controller, long handle, long user_data)2232 long leaveProc(long controller, long handle, long user_data) {
2233 	long result = 0;
2234 	long event = GTK4.gtk_event_controller_get_current_event(controller);
2235 
2236 	switch ((int)user_data) {
2237 		case LEAVE:
2238 			result = gtk_leave_notify_event(handle, event);
2239 			break;
2240 	}
2241 
2242 	return result;
2243 }
2244 
notifyProc(long object, long arg0, long user_data)2245 long notifyProc (long object, long arg0, long user_data) {
2246 	switch ((int)user_data) {
2247 		case DPI_CHANGED: return dpiChanged(object, arg0);
2248 		case NOTIFY_STATE: return notifyState(object, arg0);
2249 	}
2250 	return 0;
2251 }
2252 
notifyState(long object, long argo0)2253 long notifyState (long object, long argo0) {
2254 	return 0;
2255 }
2256 
windowProc(long handle, long user_data)2257 long windowProc (long handle, long user_data) {
2258 	switch ((int)user_data) {
2259 		case ACTIVATE: return gtk_activate (handle);
2260 		case CHANGED: return gtk_changed (handle);
2261 		case CLICKED: return gtk_clicked (handle);
2262 		case CLOSE_REQUEST: return gtk_close_request (handle);
2263 		case CREATE_MENU_PROXY: return gtk_create_menu_proxy (handle);
2264 		case DAY_SELECTED: return gtk_day_selected (handle);
2265 		case DAY_SELECTED_DOUBLE_CLICK: return gtk_day_selected_double_click (handle);
2266 		case HIDE: return gtk_hide (handle);
2267 		case GRAB_FOCUS: return gtk_grab_focus (handle);
2268 		case MAP: return gtk_map (handle);
2269 		case MONTH_CHANGED: return gtk_month_changed (handle);
2270 		case OUTPUT: return gtk_output (handle);
2271 		case POPUP_MENU: return gtk_popup_menu (handle);
2272 		case PREEDIT_CHANGED: return gtk_preedit_changed (handle);
2273 		case REALIZE: return gtk_realize (handle);
2274 		case START_INTERACTIVE_SEARCH: return gtk_start_interactive_search (handle);
2275 		case STYLE_UPDATED: return gtk_style_updated (handle);
2276 		case SELECT: return gtk_select (handle);
2277 		case SELECTION_DONE: return gtk_selection_done (handle);
2278 		case SHOW: return gtk_show (handle);
2279 		case VALUE_CHANGED: return gtk_value_changed(handle);
2280 		case UNMAP: return gtk_unmap (handle);
2281 		case UNREALIZE: return gtk_unrealize (handle);
2282 		default: return 0;
2283 	}
2284 }
2285 
windowProc(long handle, long arg0, long user_data)2286 long windowProc (long handle, long arg0, long user_data) {
2287 	switch ((int)user_data) {
2288 		case EXPOSE_EVENT_INVERSE: {
2289 			if (GTK.GTK_IS_CONTAINER (handle)) {
2290 				return gtk_draw (handle, arg0);
2291 			}
2292 			return 0;
2293 		}
2294 		case BUTTON_PRESS_EVENT_INVERSE:
2295 		case BUTTON_RELEASE_EVENT_INVERSE:
2296 		case MOTION_NOTIFY_EVENT_INVERSE: {
2297 			return 1;
2298 		}
2299 		case BUTTON_PRESS_EVENT: return gtk_button_press_event (handle, arg0);
2300 		case BUTTON_RELEASE_EVENT: return gtk_button_release_event (handle, arg0);
2301 		case COMMIT: return gtk_commit (handle, arg0);
2302 		case CONFIGURE_EVENT: return gtk_configure_event (handle, arg0);
2303 		case DELETE_EVENT: return gtk_delete_event (handle, arg0);
2304 		case ENTER_NOTIFY_EVENT: return gtk_enter_notify_event (handle, arg0);
2305 		case EVENT_AFTER: return gtk_event_after (handle, arg0);
2306 		case EXPOSE_EVENT: {
2307 			if (!GTK.GTK_IS_CONTAINER (handle)) {
2308 				return gtk_draw (handle, arg0);
2309 			}
2310 			return 0;
2311 		}
2312 		case FOCUS: return gtk_focus (handle, arg0);
2313 		case FOCUS_IN_EVENT: return gtk_focus_in_event (handle, arg0);
2314 		case FOCUS_OUT_EVENT: return gtk_focus_out_event (handle, arg0);
2315 		case KEY_PRESS_EVENT: return gtk_key_press_event (handle, arg0);
2316 		case KEY_RELEASE_EVENT: return gtk_key_release_event (handle, arg0);
2317 		case INPUT: return gtk_input (handle, arg0);
2318 		case LEAVE_NOTIFY_EVENT: return gtk_leave_notify_event (handle, arg0);
2319 		case MAP_EVENT: return gtk_map_event (handle, arg0);
2320 		case MNEMONIC_ACTIVATE: return gtk_mnemonic_activate (handle, arg0);
2321 		case MOTION_NOTIFY_EVENT: return gtk_motion_notify_event (handle, arg0);
2322 		case MOVE_FOCUS: return gtk_move_focus (handle, arg0);
2323 		case POPULATE_POPUP: return gtk_populate_popup (handle, arg0);
2324 		case SCROLL_EVENT:	return gtk_scroll_event (handle, arg0);
2325 		case SHOW_HELP: return gtk_show_help (handle, arg0);
2326 		case SIZE_ALLOCATE: return gtk_size_allocate (handle, arg0);
2327 		case TOGGLED: return gtk_toggled (handle, arg0);
2328 		case UNMAP_EVENT: return gtk_unmap_event (handle, arg0);
2329 		case WINDOW_STATE_EVENT: return gtk_window_state_event (handle, arg0);
2330 		case ROW_DELETED: return gtk_row_deleted (handle, arg0);
2331 		default: return 0;
2332 	}
2333 }
2334 
windowProc(long handle, long arg0, long arg1, long user_data)2335 long windowProc (long handle, long arg0, long arg1, long user_data) {
2336 	switch ((int)user_data) {
2337 		case DELETE_RANGE: return gtk_delete_range (handle, arg0, arg1);
2338 		case DELETE_TEXT: return gtk_delete_text (handle, arg0, arg1);
2339 		case ICON_RELEASE: return gtk_icon_release (handle, arg0, arg1);
2340 		case ROW_ACTIVATED: return gtk_row_activated (handle, arg0, arg1);
2341 		case SCROLL_CHILD: return gtk_scroll_child (handle, arg0, arg1);
2342 		case STATUS_ICON_POPUP_MENU: return gtk_status_icon_popup_menu (handle, arg0, arg1);
2343 		case SWITCH_PAGE: return gtk_switch_page(handle, arg0, (int)arg1);
2344 		case TEST_COLLAPSE_ROW: return gtk_test_collapse_row (handle, arg0, arg1);
2345 		case TEST_EXPAND_ROW: return gtk_test_expand_row(handle, arg0, arg1);
2346 		case ROW_INSERTED: return gtk_row_inserted (handle, arg0, arg1);
2347 		case ROW_HAS_CHILD_TOGGLED: return gtk_row_has_child_toggled(handle, arg0, arg1);
2348 		default: return 0;
2349 	}
2350 }
2351 
windowProc(long handle, long arg0, long arg1, long arg2, long user_data)2352 long windowProc (long handle, long arg0, long arg1, long arg2, long user_data) {
2353 	switch ((int)user_data) {
2354 		case EXPAND_COLLAPSE_CURSOR_ROW: return gtk_expand_collapse_cursor_row (handle, arg0, arg1, arg2);
2355 		case INSERT_TEXT: return gtk_insert_text (handle, arg0, arg1, arg2);
2356 		case TEXT_BUFFER_INSERT_TEXT: return gtk_text_buffer_insert_text (handle, arg0, arg1, arg2);
2357 		default: return 0;
2358 	}
2359 }
2360 
windowProc(long handle, long arg0, long arg1, long arg2, long arg3, long user_data)2361 long windowProc (long handle, long arg0, long arg1, long arg2, long arg3, long user_data) {
2362 	switch ((int)user_data) {
2363 		case POPPED_UP: return gtk_menu_popped_up (handle, arg0, arg1, arg2, arg3);
2364 		default: return 0;
2365 	}
2366 }
2367 
gtk_cell_renderer_get_preferred_size(long cell, long widget, int[] width, int[] height)2368 void gtk_cell_renderer_get_preferred_size (long cell, long widget,  int[] width, int[] height) {
2369 	GtkRequisition minimum_size = new GtkRequisition ();
2370 	GTK.gtk_cell_renderer_get_preferred_size (cell, widget, minimum_size, null);
2371 	if (width != null) width [0] = minimum_size.width;
2372 	if (height != null) height[0] = minimum_size.height;
2373 }
2374 
gtk_widget_get_preferred_size(long widget, GtkRequisition requisition)2375 void gtk_widget_get_preferred_size (long widget, GtkRequisition requisition){
2376 	GTK.gtk_widget_get_preferred_size (widget, requisition, null);
2377 }
2378 
2379 /**
2380  * Retrieves the amount of space around the outside of the container.
2381  * On GTK3: this is done using gtk_container_get_border_width.
2382  * On GTK4: this is done by returning the max margin on any side.
2383  * @param handle
2384  * @return amount of space around the outside of the container.
2385  */
gtk_container_get_border_width_or_margin(long handle)2386 int gtk_container_get_border_width_or_margin (long handle) {
2387 	if (GTK.GTK4) {
2388 		int marginTop = GTK.gtk_widget_get_margin_top(handle);
2389 		int marginBottom = GTK.gtk_widget_get_margin_bottom(handle);
2390 		int marginStart = GTK.gtk_widget_get_margin_start(handle);
2391 		int marginEnd = GTK.gtk_widget_get_margin_end(handle);
2392 		return Math.max(Math.max(marginTop, marginBottom), Math.max(marginStart, marginEnd));
2393 	} else {
2394 		return GTK3.gtk_container_get_border_width(handle);
2395 	}
2396 }
2397 /**
2398  * Sets the border width of the container to all sides of the container.
2399  * @param handle
2400  * @param border_width
2401  */
gtk_container_set_border_width(long handle, int border_width)2402 void gtk_container_set_border_width (long handle, int border_width) {
2403 	if (GTK.GTK4) {
2404 		GTK.gtk_widget_set_margin_top(handle, border_width);
2405 		GTK.gtk_widget_set_margin_bottom(handle, border_width);
2406 		GTK.gtk_widget_set_margin_start(handle, border_width);
2407 		GTK.gtk_widget_set_margin_end(handle, border_width);
2408 	} else {
2409 		GTK3.gtk_container_set_border_width (handle, border_width);
2410 	}
2411 }
2412 
2413 }
2414