Source code: org/eclipse/swt/widgets/Widget.java
1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.swt.widgets;
12
13
14 import org.eclipse.swt.*;
15 import org.eclipse.swt.internal.*;
16 import org.eclipse.swt.internal.gtk.*;
17 import org.eclipse.swt.events.*;
18
19 /**
20 * This class is the abstract superclass of all user interface objects.
21 * Widgets are created, disposed and issue notification to listeners
22 * when events occur which affect them.
23 * <dl>
24 * <dt><b>Styles:</b></dt>
25 * <dd>(none)</dd>
26 * <dt><b>Events:</b></dt>
27 * <dd>Dispose</dd>
28 * </dl>
29 * <p>
30 * IMPORTANT: This class is intended to be subclassed <em>only</em>
31 * within the SWT implementation. However, it has not been marked
32 * final to allow those outside of the SWT development team to implement
33 * patched versions of the class in order to get around specific
34 * limitations in advance of when those limitations can be addressed
35 * by the team. Any class built using subclassing to access the internals
36 * of this class will likely fail to compile or run between releases and
37 * may be strongly platform specific. Subclassing should not be attempted
38 * without an intimate and detailed understanding of the workings of the
39 * hierarchy. No support is provided for user-written classes which are
40 * implemented as subclasses of this class.
41 * </p>
42 *
43 * @see #checkSubclass
44 */
45 public abstract class Widget {
46 /**
47 * the handle to the OS resource
48 * (Warning: This field is platform dependent)
49 */
50 public long /*int*/ handle;
51 int style, state;
52 Display display;
53 EventTable eventTable;
54 Object data;
55
56 /* Global state flags */
57 static final int DISPOSED = 1<<0;
58 static final int CANVAS = 1<<1;
59 static final int KEYED_DATA = 1<<2;
60 static final int HANDLE = 1<<3;
61 static final int DISABLED = 1<<4;
62 static final int MENU = 1<<5;
63 static final int OBSCURED = 1<<6;
64
65 /* Default widths for widgets */
66 static final int DEFAULT_WIDTH = 64;
67 static final int DEFAULT_HEIGHT = 64;
68
69 /* GTK signals data */
70 static final int ACTIVATE = 1;
71 static final int BUTTON_PRESS_EVENT = 2;
72 static final int BUTTON_RELEASE_EVENT = 3;
73 static final int CHANGED = 4;
74 static final int CLICKED = 5;
75 static final int COMMIT = 6;
76 static final int CONFIGURE_EVENT = 7;
77 static final int DELETE_EVENT = 8;
78 static final int DELETE_RANGE = 9;
79 static final int DELETE_TEXT = 10;
80 static final int ENTER_NOTIFY_EVENT = 11;
81 static final int EVENT = 12;
82 static final int EVENT_AFTER = 13;
83 static final int EXPOSE_EVENT = 14;
84 static final int FOCUS = 15;
85 static final int FOCUS_IN_EVENT = 16;
86 static final int FOCUS_OUT_EVENT = 17;
87 static final int HIDE = 18;
88 static final int INSERT_TEXT = 19;
89 static final int KEY_PRESS_EVENT = 20;
90 static final int KEY_RELEASE_EVENT = 21;
91 static final int LEAVE_NOTIFY_EVENT = 22;
92 static final int MAP_EVENT = 23;
93 static final int MNEMONIC_ACTIVATE = 24;
94 static final int MOTION_NOTIFY_EVENT = 25;
95 static final int POPUP_MENU = 26;
96 static final int PREEDIT_CHANGED = 27;
97 static final int REALIZE = 28;
98 static final int ROW_ACTIVATED = 29;
99 static final int SCROLL_CHILD = 30;
100 static final int SELECT = 31;
101 static final int SHOW = 32;
102 static final int SHOW_HELP = 33;
103 static final int SIZE_ALLOCATE = 34;
104 static final int STYLE_SET = 35;
105 static final int SWITCH_PAGE = 36;
106 static final int TEST_COLLAPSE_ROW = 37;
107 static final int TEST_EXPAND_ROW = 38;
108 static final int TOGGLED = 39;
109 static final int UNMAP_EVENT = 40;
110 static final int UNREALIZE = 41;
111 static final int VALUE_CHANGED = 42;
112 static final int VISIBILITY_NOTIFY_EVENT = 43;
113 static final int WINDOW_STATE_EVENT = 44;
114
115 /**
116 * Prevents uninitialized instances from being created outside the package.
117 */
118 Widget () {}
119
120 /**
121 * Constructs a new instance of this class given its parent
122 * and a style value describing its behavior and appearance.
123 * <p>
124 * The style value is either one of the style constants defined in
125 * class <code>SWT</code> which is applicable to instances of this
126 * class, or must be built by <em>bitwise OR</em>'ing together
127 * (that is, using the <code>int</code> "|" operator) two or more
128 * of those <code>SWT</code> style constants. The class description
129 * lists the style constants that are applicable to the class.
130 * Style bits are also inherited from superclasses.
131 * </p>
132 *
133 * @param parent a widget which will be the parent of the new instance (cannot be null)
134 * @param style the style of widget to construct
135 *
136 * @exception IllegalArgumentException <ul>
137 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
138 * </ul>
139 * @exception SWTException <ul>
140 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
141 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
142 * </ul>
143 *
144 * @see SWT
145 * @see #checkSubclass
146 * @see #getStyle
147 */
148 public Widget (Widget parent, int style) {
149 checkSubclass ();
150 checkParent (parent);
151 this.style = style;
152 display = parent.display;
153 }
154
155 /**
156 * Adds the listener to the collection of listeners who will
157 * be notifed when an event of the given type occurs. When the
158 * event does occur in the widget, the listener is notified by
159 * sending it the <code>handleEvent()</code> message.
160 *
161 * @param eventType the type of event to listen for
162 * @param listener the listener which should be notified when the event occurs
163 *
164 * @exception IllegalArgumentException <ul>
165 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
166 * </ul>
167 * @exception SWTException <ul>
168 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
169 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
170 * </ul>
171 *
172 * @see Listener
173 * @see #removeListener
174 */
175 public void addListener (int eventType, Listener handler) {
176 checkWidget ();
177 if (handler == null) error (SWT.ERROR_NULL_ARGUMENT);
178 if (eventTable == null) eventTable = new EventTable ();
179 eventTable.hook (eventType, handler);
180 }
181
182 /**
183 * Adds the listener to the collection of listeners who will
184 * be notifed when the widget is disposed. When the widget is
185 * disposed, the listener is notified by sending it the
186 * <code>widgetDisposed()</code> message.
187 *
188 * @param listener the listener which should be notified when the receiver is disposed
189 *
190 * @exception IllegalArgumentException <ul>
191 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
192 * </ul>
193 * @exception SWTException <ul>
194 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
195 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
196 * </ul>
197 *
198 * @see DisposeListener
199 * @see #removeDisposeListener
200 */
201 public void addDisposeListener (DisposeListener listener) {
202 checkWidget ();
203 if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
204 TypedListener typedListener = new TypedListener (listener);
205 addListener (SWT.Dispose, typedListener);
206 }
207
208 long /*int*/ textCellDataProc (long /*int*/ tree_column, long /*int*/ cell, long /*int*/ tree_model, long /*int*/ iter, long /*int*/ data) {
209 return 0;
210 }
211 long /*int*/ pixbufCellDataProc (long /*int*/ tree_column, long /*int*/ cell, long /*int*/ tree_model, long /*int*/ iter, long /*int*/ data) {
212 return 0;
213 }
214
215 static int checkBits (int style, int int0, int int1, int int2, int int3, int int4, int int5) {
216 int mask = int0 | int1 | int2 | int3 | int4 | int5;
217 if ((style & mask) == 0) style |= int0;
218 if ((style & int0) != 0) style = (style & ~mask) | int0;
219 if ((style & int1) != 0) style = (style & ~mask) | int1;
220 if ((style & int2) != 0) style = (style & ~mask) | int2;
221 if ((style & int3) != 0) style = (style & ~mask) | int3;
222 if ((style & int4) != 0) style = (style & ~mask) | int4;
223 if ((style & int5) != 0) style = (style & ~mask) | int5;
224 return style;
225 }
226
227 void checkOrientation (Widget parent) {
228 style &= ~SWT.MIRRORED;
229 if ((style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT)) == 0) {
230 if (parent != null) {
231 if ((parent.style & SWT.LEFT_TO_RIGHT) != 0) style |= SWT.LEFT_TO_RIGHT;
232 if ((parent.style & SWT.RIGHT_TO_LEFT) != 0) style |= SWT.RIGHT_TO_LEFT;
233 }
234 }
235 style = checkBits (style, SWT.LEFT_TO_RIGHT, SWT.RIGHT_TO_LEFT, 0, 0, 0, 0);
236 }
237
238 /**
239 * Throws an exception if the specified widget can not be
240 * used as a parent for the receiver.
241 *
242 * @exception IllegalArgumentException <ul>
243 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
244 * <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li>
245 * </ul>
246 * @exception SWTException <ul>
247 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
248 * </ul>
249 */
250 void checkParent (Widget parent) {
251 if (parent == null) error (SWT.ERROR_NULL_ARGUMENT);
252 parent.checkWidget ();
253 }
254
255 /**
256 * Checks that this class can be subclassed.
257 * <p>
258 * The SWT class library is intended to be subclassed
259 * only at specific, controlled points (most notably,
260 * <code>Composite</code> and <code>Canvas</code> when
261 * implementing new widgets). This method enforces this
262 * rule unless it is overridden.
263 * </p><p>
264 * <em>IMPORTANT:</em> By providing an implementation of this
265 * method that allows a subclass of a class which does not
266 * normally allow subclassing to be created, the implementer
267 * agrees to be fully responsible for the fact that any such
268 * subclass will likely fail between SWT releases and will be
269 * strongly platform specific. No support is provided for
270 * user-written classes which are implemented in this fashion.
271 * </p><p>
272 * The ability to subclass outside of the allowed SWT classes
273 * is intended purely to enable those not on the SWT development
274 * team to implement patches in order to get around specific
275 * limitations in advance of when those limitations can be
276 * addressed by the team. Subclassing should not be attempted
277 * without an intimate and detailed understanding of the hierarchy.
278 * </p>
279 *
280 * @exception SWTException <ul>
281 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
282 * </ul>
283 */
284 protected void checkSubclass () {
285 if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
286 }
287
288 /**
289 * Throws an <code>SWTException</code> if the receiver can not
290 * be accessed by the caller. This may include both checks on
291 * the state of the receiver and more generally on the entire
292 * execution context. This method <em>should</em> be called by
293 * widget implementors to enforce the standard SWT invariants.
294 * <p>
295 * Currently, it is an error to invoke any method (other than
296 * <code>isDisposed()</code>) on a widget that has had its
297 * <code>dispose()</code> method called. It is also an error
298 * to call widget methods from any thread that is different
299 * from the thread that created the widget.
300 * </p><p>
301 * In future releases of SWT, there may be more or fewer error
302 * checks and exceptions may be thrown for different reasons.
303 * </p>
304 *
305 * @exception SWTException <ul>
306 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
307 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
308 * </ul>
309 */
310 protected void checkWidget () {
311 Display display = this.display;
312 if (display == null) error (SWT.ERROR_WIDGET_DISPOSED);
313 if (display.thread != Thread.currentThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
314 if ((state & DISPOSED) != 0) error (SWT.ERROR_WIDGET_DISPOSED);
315 }
316
317 void createHandle (int index) {
318 }
319
320 void createWidget (int index) {
321 createHandle (index);
322 setOrientation ();
323 hookEvents ();
324 register ();
325 }
326
327 void deregister () {
328 if (handle == 0) return;
329 if ((state & HANDLE) != 0) display.removeWidget (handle);
330 }
331
332 void destroyWidget () {
333 long /*int*/ topHandle = topHandle ();
334 releaseHandle ();
335 if (topHandle != 0 && (state & HANDLE) != 0) {
336 OS.gtk_widget_destroy (topHandle);
337 }
338 }
339
340 /**
341 * Disposes of the operating system resources associated with
342 * the receiver and all its descendents. After this method has
343 * been invoked, the receiver and all descendents will answer
344 * <code>true</code> when sent the message <code>isDisposed()</code>.
345 * Any internal connections between the widgets in the tree will
346 * have been removed to facilitate garbage collection.
347 * <p>
348 * NOTE: This method is not called recursively on the descendents
349 * of the receiver. This means that, widget implementers can not
350 * detect when a widget is being disposed of by re-implementing
351 * this method, but should instead listen for the <code>Dispose</code>
352 * event.
353 * </p>
354 *
355 * @exception SWTException <ul>
356 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
357 * </ul>
358 *
359 * @see #addDisposeListener
360 * @see #removeDisposeListener
361 * @see #checkWidget
362 */
363 public void dispose () {
364 /*
365 * Note: It is valid to attempt to dispose a widget
366 * more than once. If this happens, fail silently.
367 */
368 if (isDisposed()) return;
369 if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
370 releaseChild ();
371 releaseWidget ();
372 destroyWidget ();
373 }
374
375 void error (int code) {
376 SWT.error (code);
377 }
378
379 /**
380 * Returns the application defined widget data associated
381 * with the receiver, or null if it has not been set. The
382 * <em>widget data</em> is a single, unnamed field that is
383 * stored with every widget.
384 * <p>
385 * Applications may put arbitrary objects in this field. If
386 * the object stored in the widget data needs to be notified
387 * when the widget is disposed of, it is the application's
388 * responsibility to hook the Dispose event on the widget and
389 * do so.
390 * </p>
391 *
392 * @return the widget data
393 *
394 * @exception SWTException <ul>
395 * <li>ERROR_WIDGET_DISPOSED - when the receiver has been disposed</li>
396 * <li>ERROR_THREAD_INVALID_ACCESS - when called from the wrong thread</li>
397 * </ul>
398 *
399 * @see #setData
400 */
401 public Object getData () {
402 checkWidget();
403 return (state & KEYED_DATA) != 0 ? ((Object []) data) [0] : data;
404 }
405 /**
406 * Returns the application defined property of the receiver
407 * with the specified name, or null if it has not been set.
408 * <p>
409 * Applications may have associated arbitrary objects with the
410 * receiver in this fashion. If the objects stored in the
411 * properties need to be notified when the widget is disposed
412 * of, it is the application's responsibility to hook the
413 * Dispose event on the widget and do so.
414 * </p>
415 *
416 * @param key the name of the property
417 * @return the value of the property or null if it has not been set
418 *
419 * @exception IllegalArgumentException <ul>
420 * <li>ERROR_NULL_ARGUMENT - if the key is null</li>
421 * </ul>
422 * @exception SWTException <ul>
423 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
424 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
425 * </ul>
426 *
427 * @see #setData
428 */
429 public Object getData (String key) {
430 checkWidget();
431 if (key == null) error (SWT.ERROR_NULL_ARGUMENT);
432 if ((state & KEYED_DATA) != 0) {
433 Object [] table = (Object []) data;
434 for (int i=1; i<table.length; i+=2) {
435 if (key.equals (table [i])) return table [i+1];
436 }
437 }
438 return null;
439 }
440
441 /**
442 * Returns the <code>Display</code> that is associated with
443 * the receiver.
444 * <p>
445 * A widget's display is either provided when it is created
446 * (for example, top level <code>Shell</code>s) or is the
447 * same as its parent's display.
448 * </p>
449 *
450 * @return the receiver's display
451 *
452 * @exception SWTException <ul>
453 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
454 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
455 * </ul>
456 */
457 public Display getDisplay () {
458 Display display = this.display;
459 if (display == null) error (SWT.ERROR_WIDGET_DISPOSED);
460 return display;
461 }
462
463 String getName () {
464 // String string = getClass ().getName ();
465 // int index = string.lastIndexOf ('.');
466 // if (index == -1) return string;
467 String string = getClass ().getName ();
468 int index = string.length ();
469 while ((--index > 0) && (string.charAt (index) != '.'));
470 return string.substring (index + 1, string.length ());
471 }
472
473 String getNameText () {
474 return "";
475 }
476
477 /**
478 * Returns the receiver's style information.
479 * <p>
480 * Note that the value which is returned by this method <em>may
481 * not match</em> the value which was provided to the constructor
482 * when the receiver was created. This can occur when the underlying
483 * operating system does not support a particular combination of
484 * requested styles. For example, if the platform widget used to
485 * implement a particular SWT widget always has scroll bars, the
486 * result of calling this method would always have the
487 * <code>SWT.H_SCROLL</code> and <code>SWT.V_SCROLL</code> bits set.
488 * </p>
489 *
490 * @return the style bits
491 *
492 * @exception SWTException <ul>
493 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
494 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
495 * </ul>
496 */
497 public int getStyle () {
498 checkWidget ();
499 return style;
500 }
501
502
503 long /*int*/ gtk_activate (long /*int*/ widget) {
504 return 0;
505 }
506
507 long /*int*/ gtk_button_press_event (long /*int*/ widget, long /*int*/ event) {
508 return 0;
509 }
510
511 long /*int*/ gtk_button_release_event (long /*int*/ widget, long /*int*/ event) {
512 return 0;
513 }
514
515 long /*int*/ gtk_changed (long /*int*/ widget) {
516 return 0;
517 }
518
519 long /*int*/ gtk_clicked (long /*int*/ widget) {
520 return 0;
521 }
522
523 long /*int*/ gtk_commit (long /*int*/ imcontext, long /*int*/ text) {
524 return 0;
525 }
526
527 long /*int*/ gtk_configure_event (long /*int*/ widget, long /*int*/ event) {
528 return 0;
529 }
530
531 long /*int*/ gtk_delete_event (long /*int*/ widget, long /*int*/ event) {
532 return 0;
533 }
534
535 long /*int*/ gtk_delete_range (long /*int*/ widget, long /*int*/ iter1, long /*int*/ iter2) {
536 return 0;
537 }
538
539 long /*int*/ gtk_delete_text (long /*int*/ widget, long /*int*/ start_pos, long /*int*/ end_pos) {
540 return 0;
541 }
542
543 long /*int*/ gtk_enter_notify_event (long /*int*/ widget, long /*int*/ event) {
544 return 0;
545 }
546
547 long /*int*/ gtk_event (long /*int*/ widget, long /*int*/ event) {
548 return 0;
549 }
550
551 long /*int*/ gtk_event_after (long /*int*/ widget, long /*int*/ event) {
552 return 0;
553 }
554
555 long /*int*/ gtk_expose_event (long /*int*/ widget, long /*int*/ event) {
556 return 0;
557 }
558
559 long /*int*/ gtk_focus (long /*int*/ widget, long /*int*/ event) {
560 return 0;
561 }
562
563 long /*int*/ gtk_focus_in_event (long /*int*/ widget, long /*int*/ event) {
564 return 0;
565 }
566
567 long /*int*/ gtk_focus_out_event (long /*int*/ widget, long /*int*/ event) {
568 return 0;
569 }
570
571 long /*int*/ gtk_hide (long /*int*/ widget) {
572 return 0;
573 }
574
575 long /*int*/ gtk_insert_text (long /*int*/ widget, long /*int*/ new_text, long /*int*/ new_text_length, long /*int*/ position) {
576 return 0;
577 }
578
579 long /*int*/ gtk_key_press_event (long /*int*/ widget, long /*int*/ event) {
580 return 0;
581 }
582
583 long /*int*/ gtk_key_release_event (long /*int*/ widget, long /*int*/ event) {
584 return 0;
585 }
586
587 long /*int*/ gtk_leave_notify_event (long /*int*/ widget, long /*int*/ event) {
588 return 0;
589 }
590
591 long /*int*/ gtk_map_event (long /*int*/ widget, long /*int*/ event) {
592 return 0;
593 }
594
595 long /*int*/ gtk_mnemonic_activate (long /*int*/ widget, long /*int*/ arg1) {
596 return 0;
597 }
598
599 long /*int*/ gtk_motion_notify_event (long /*int*/ widget, long /*int*/ event) {
600 return 0;
601 }
602
603 long /*int*/ gtk_popup_menu (long /*int*/ widget) {
604 return 0;
605 }
606
607 long /*int*/ gtk_preedit_changed (long /*int*/ imcontext) {
608 return 0;
609 }
610
611 long /*int*/ gtk_realize (long /*int*/ widget) {
612 return 0;
613 }
614
615 long /*int*/ gtk_row_activated (long /*int*/ tree, long /*int*/ path, long /*int*/ column) {
616 return 0;
617 }
618
619 long /*int*/ gtk_scroll_child (long /*int*/ widget, long /*int*/ scrollType, long /*int*/ horizontal) {
620 return 0;
621 }
622
623 long /*int*/ gtk_select (long /*int*/ item) {
624 return 0;
625 }
626
627 long /*int*/ gtk_show (long /*int*/ widget) {
628 return 0;
629 }
630
631 long /*int*/ gtk_show_help (long /*int*/ widget, long /*int*/ helpType) {
632 return 0;
633 }
634
635 long /*int*/ gtk_size_allocate (long /*int*/ widget, long /*int*/ allocation) {
636 return 0;
637 }
638
639 long /*int*/ gtk_style_set (long /*int*/ widget, long /*int*/ previousStyle) {
640 return 0;
641 }
642
643 long /*int*/ gtk_switch_page (long /*int*/ widget, long /*int*/ page, long /*int*/ page_num) {
644 return 0;
645 }
646
647 long /*int*/ gtk_test_collapse_row (long /*int*/ tree, long /*int*/ iter, long /*int*/ path) {
648 return 0;
649 }
650
651 long /*int*/ gtk_test_expand_row (long /*int*/ tree, long /*int*/ iter, long /*int*/ path) {
652 return 0;
653 }
654
655 long /*int*/ gtk_timer () {
656 return 0;
657 }
658
659 long /*int*/ gtk_toggled (long /*int*/ renderer, long /*int*/ pathStr) {
660 return 0;
661 }
662
663 long /*int*/ gtk_unmap_event (long /*int*/ widget, long /*int*/ event) {
664 return 0;
665 }
666
667 long /*int*/ gtk_unrealize (long /*int*/ widget) {
668 return 0;
669 }
670
671 long /*int*/ gtk_value_changed (long /*int*/ adjustment) {
672 return 0;
673 }
674
675 long /*int*/ gtk_visibility_notify_event (long /*int*/ widget, long /*int*/ event) {
676 return 0;
677 }
678
679 long /*int*/ gtk_window_state_event (long /*int*/ widget, long /*int*/ event) {
680 return 0;
681 }
682
683 int fontHeight (long /*int*/ font, long /*int*/ widgetHandle) {
684 long /*int*/ context = OS.gtk_widget_get_pango_context (widgetHandle);
685 long /*int*/ lang = OS.pango_context_get_language (context);
686 long /*int*/ metrics = OS.pango_context_get_metrics (context, font, lang);
687 int ascent = OS.pango_font_metrics_get_ascent (metrics);
688 int descent = OS.pango_font_metrics_get_descent (metrics);
689 OS.pango_font_metrics_unref (metrics);
690 return OS.PANGO_PIXELS (ascent + descent);
691 }
692
693 boolean filters (int eventType) {
694 return display.filters (eventType);
695 }
696
697 long /*int*/ filterProc (long /*int*/ xEvent, long /*int*/ gdkEvent, long /*int*/ data) {
698 return 0;
699 }
700
701 char [] fixMnemonic (String string) {
702 int length = string.length ();
703 char [] text = new char [length];
704 string.getChars (0, length, text, 0);
705 int i = 0, j = 0;
706 char [] result = new char [length * 2];
707 while (i < length) {
708 switch (text [i]) {
709 case '&':
710 if (i + 1 < length && text [i + 1] == '&') {
711 i++;
712 } else {
713 text [i] = '_';
714 }
715 break;
716 case '_':
717 result [j++] = '_';
718 break;
719 }
720 result [j++] = text [i++];
721 }
722 return result;
723 }
724
725 /**
726 * Returns <code>true</code> if the widget has been disposed,
727 * and <code>false</code> otherwise.
728 * <p>
729 * This method gets the dispose state for the widget.
730 * When a widget has been disposed, it is an error to
731 * invoke any other method using the widget.
732 * </p>
733 *
734 * @return <code>true</code> when the widget is disposed and <code>false</code> otherwise
735 */
736 public boolean isDisposed () {
737 if (handle != 0) return false;
738 if ((state & HANDLE) != 0) return true;
739 return (state & DISPOSED) != 0;
740 }
741
742 /**
743 * Returns <code>true</code> if there are any listeners
744 * for the specified event type associated with the receiver,
745 * and <code>false</code> otherwise.
746 *
747 * @param eventType the type of event
748 * @return true if the event is hooked
749 *
750 * @exception SWTException <ul>
751 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
752 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
753 * </ul>
754 */
755 protected boolean isListening (int eventType) {
756 checkWidget ();
757 return hooks (eventType);
758 }
759
760 boolean isValidThread () {
761 return getDisplay ().isValidThread ();
762 }
763
764 boolean isValidWidget () {
765 if (handle != 0) return true;
766 if ((state & HANDLE) != 0) return false;
767 return (state & DISPOSED) == 0;
768 }
769
770 boolean isValidSubclass() {
771 return Display.isValidClass(getClass());
772 }
773
774 void hookEvents () {
775 }
776
777 /*
778 * Returns <code>true</code> if the specified eventType is
779 * hooked, and <code>false</code> otherwise. Implementations
780 * of SWT can avoid creating objects and sending events
781 * when an event happens in the operating system but
782 * there are no listeners hooked for the event.
783 *
784 * @param eventType the event to be checked
785 *
786 * @return <code>true</code> when the eventType is hooked and <code>false</code> otherwise
787 *
788 * @see #isListening
789 */
790 boolean hooks (int eventType) {
791 if (eventTable == null) return false;
792 return eventTable.hooks (eventType);
793 }
794
795 long /*int*/ hoverProc (long /*int*/ widget) {
796 return 0;
797 }
798
799 long /*int*/ menuPositionProc (long /*int*/ menu, long /*int*/ x, long /*int*/ y, long /*int*/ push_in, long /*int*/ user_data) {
800 return 0;
801 }
802
803 boolean mnemonicHit (long /*int*/ mnemonicHandle, char key) {
804 if (!mnemonicMatch (mnemonicHandle, key)) return false;
805 OS.g_signal_handlers_block_matched (mnemonicHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, MNEMONIC_ACTIVATE);
806 boolean result = OS.gtk_widget_mnemonic_activate (mnemonicHandle, false);
807 OS.g_signal_handlers_unblock_matched (mnemonicHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, MNEMONIC_ACTIVATE);
808 return result;
809 }
810
811 boolean mnemonicMatch (long /*int*/ mnemonicHandle, char key) {
812 int keyval1 = OS.gdk_keyval_to_lower (OS.gdk_unicode_to_keyval (key));
813 int keyval2 = OS.gdk_keyval_to_lower (OS.gtk_label_get_mnemonic_keyval (mnemonicHandle));
814 return keyval1 == keyval2;
815 }
816
817 /**
818 * Notifies all of the receiver's listeners for events
819 * of the given type that one such event has occurred by
820 * invoking their <code>handleEvent()</code> method.
821 *
822 * @param eventType the type of event which has occurred
823 * @param event the event data
824 *
825 * @exception SWTException <ul>
826 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
827 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
828 * </ul>
829 */
830 public void notifyListeners (int eventType, Event event) {
831 checkWidget();
832 if (event == null) event = new Event ();
833 sendEvent (eventType, event);
834 }
835
836 void postEvent (int eventType) {
837 sendEvent (eventType, null, false);
838 }
839
840 void postEvent (int eventType, Event event) {
841 sendEvent (eventType, event, false);
842 }
843
844 void register () {
845 if (handle == 0) return;
846 if ((state & HANDLE) != 0) display.addWidget (handle, this);
847 }
848
849 void releaseChild () {
850 /* Do nothing */
851 }
852
853 void releaseHandle () {
854 handle = 0;
855 state |= DISPOSED;
856 display = null;
857 }
858
859 void releaseResources () {
860 releaseWidget ();
861 releaseHandle ();
862 }
863
864 void releaseWidget () {
865 sendEvent (SWT.Dispose);
866 deregister ();
867 eventTable = null;
868 data = null;
869 }
870
871 /**
872 * Removes the listener from the collection of listeners who will
873 * be notifed when an event of the given type occurs.
874 *
875 * @param eventType the type of event to listen for
876 * @param listener the listener which should no longer be notified when the event occurs
877 *
878 * @exception IllegalArgumentException <ul>
879 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
880 * </ul>
881 * @exception SWTException <ul>
882 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
883 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
884 * </ul>
885 *
886 * @see Listener
887 * @see #addListener
888 */
889 public void removeListener (int eventType, Listener handler) {
890 checkWidget ();
891 if (handler == null) error (SWT.ERROR_NULL_ARGUMENT);
892 if (eventTable == null) return;
893 eventTable.unhook (eventType, handler);
894 }
895
896 /**
897 * Removes the listener from the collection of listeners who will
898 * be notifed when an event of the given type occurs.
899 * <p>
900 * <b>IMPORTANT:</b> This method is <em>not</em> part of the SWT
901 * public API. It is marked public only so that it can be shared
902 * within the packages provided by SWT. It should never be
903 * referenced from application code.
904 * </p>
905 *
906 * @param eventType the type of event to listen for
907 * @param listener the listener which should no longer be notified when the event occurs
908 *
909 * @exception IllegalArgumentException <ul>
910 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
911 * </ul>
912 * @exception SWTException <ul>
913 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
914 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
915 * </ul>
916 *
917 * @see Listener
918 * @see #addListener
919 */
920 protected void removeListener (int eventType, SWTEventListener handler) {
921 checkWidget ();
922 if (handler == null) error (SWT.ERROR_NULL_ARGUMENT);
923 if (eventTable == null) return;
924 eventTable.unhook (eventType, handler);
925 }
926
927 /**
928 * Removes the listener from the collection of listeners who will
929 * be notifed when the widget is disposed.
930 *
931 * @param listener the listener which should no longer be notified when the receiver is disposed
932 *
933 * @exception IllegalArgumentException <ul>
934 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
935 * </ul>
936 * @exception SWTException <ul>
937 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
938 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
939 * </ul>
940 *
941 * @see DisposeListener
942 * @see #addDisposeListener
943 */
944 public void removeDisposeListener (DisposeListener listener) {
945 checkWidget ();
946 if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
947 if (eventTable == null) return;
948 eventTable.unhook (SWT.Dispose, listener);
949 }
950
951 void sendEvent (Event event) {
952 Display display = event.display;
953 if (!display.filterEvent (event)) {
954 if (eventTable != null) eventTable.sendEvent (event);
955 }
956 }
957
958 void sendEvent (int eventType) {
959 sendEvent (eventType, null, true);
960 }
961
962 void sendEvent (int eventType, Event event) {
963 sendEvent (eventType, event, true);
964 }
965
966 void sendEvent (int eventType, Event event, boolean send) {
967 if (eventTable == null && !display.filters (eventType)) {
968 return;
969 }
970 if (event == null) event = new Event ();
971 event.type = eventType;
972 event.display = display;
973 event.widget = this;
974 if (event.time == 0) {
975 event.time = display.getLastEventTime ();
976 }
977 if (send) {
978 sendEvent (event);
979 } else {
980 display.postEvent (event);
981 }
982 }
983
984 /**
985 * Sets the application defined widget data associated
986 * with the receiver to be the argument. The <em>widget
987 * data</em> is a single, unnamed field that is stored
988 * with every widget.
989 * <p>
990 * Applications may put arbitrary objects in this field. If
991 * the object stored in the widget data needs to be notified
992 * when the widget is disposed of, it is the application's
993 * responsibility to hook the Dispose event on the widget and
994 * do so.
995 * </p>
996 *
997 * @param data the widget data
998 *
999 * @exception SWTException <ul>
1000 * <li>ERROR_WIDGET_DISPOSED - when the receiver has been disposed</li>
1001 * <li>ERROR_THREAD_INVALID_ACCESS - when called from the wrong thread</li>
1002 * </ul>
1003 */
1004public void setData (Object data) {
1005 checkWidget();
1006 if ((state & KEYED_DATA) != 0) {
1007 ((Object []) this.data) [0] = data;
1008 } else {
1009 this.data = data;
1010 }
1011}
1012
1013/**
1014 * Sets the application defined property of the receiver
1015 * with the specified name to the given value.
1016 * <p>
1017 * Applications may associate arbitrary objects with the
1018 * receiver in this fashion. If the objects stored in the
1019 * properties need to be notified when the widget is disposed
1020 * of, it is the application's responsibility to hook the
1021 * Dispose event on the widget and do so.
1022 * </p>
1023 *
1024 * @param key the name of the property
1025 * @param value the new value for the property
1026 *
1027 * @exception IllegalArgumentException <ul>
1028 * <li>ERROR_NULL_ARGUMENT - if the key is null</li>
1029 * </ul>
1030 * @exception SWTException <ul>
1031 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1032 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1033 * </ul>
1034 *
1035 * @see #getData
1036 */
1037public void setData (String key, Object value) {
1038 checkWidget();
1039 if (key == null) error (SWT.ERROR_NULL_ARGUMENT);
1040 int index = 1;
1041 Object [] table = null;
1042 if ((state & KEYED_DATA) != 0) {
1043 table = (Object []) data;
1044 while (index < table.length) {
1045 if (key.equals (table [index])) break;
1046 index += 2;
1047 }
1048 }
1049 if (value != null) {
1050 if ((state & KEYED_DATA) != 0) {
1051 if (index == table.length) {
1052 Object [] newTable = new Object [table.length + 2];
1053 System.arraycopy (table, 0, newTable, 0, table.length);
1054 data = table = newTable;
1055 }
1056 } else {
1057 table = new Object [3];
1058 table [0] = data;
1059 data = table;
1060 state |= KEYED_DATA;
1061 }
1062 table [index] = key;
1063 table [index + 1] = value;
1064 } else {
1065 if ((state & KEYED_DATA) != 0) {
1066 if (index != table.length) {
1067 int length = table.length - 2;
1068 if (length == 1) {
1069 data = table [0];
1070 state &= ~KEYED_DATA;
1071 } else {
1072 Object [] newTable = new Object [length];
1073 System.arraycopy (table, 0, newTable, 0, index);
1074 System.arraycopy (table, index + 2, newTable, index, length - index);
1075 data = newTable;
1076 }
1077 }
1078 }
1079 }
1080}
1081
1082boolean setInputState (Event event, int state) {
1083 if ((state & OS.GDK_MOD1_MASK) != 0) event.stateMask |= SWT.ALT;
1084 if ((state & OS.GDK_SHIFT_MASK) != 0) event.stateMask |= SWT.SHIFT;
1085 if ((state & OS.GDK_CONTROL_MASK) != 0) event.stateMask |= SWT.CONTROL;
1086 if ((state & OS.GDK_BUTTON1_MASK) != 0) event.stateMask |= SWT.BUTTON1;
1087 if ((state & OS.GDK_BUTTON2_MASK) != 0) event.stateMask |= SWT.BUTTON2;
1088 if ((state & OS.GDK_BUTTON3_MASK) != 0) event.stateMask |= SWT.BUTTON3;
1089 return true;
1090}
1091
1092boolean setKeyState (Event event, GdkEventKey keyEvent) {
1093 if (keyEvent.length > 1) return false;
1094 boolean isNull = false;
1095 event.keyCode = Display.translateKey (keyEvent.keyval);
1096 switch (keyEvent.keyval) {
1097 case OS.GDK_BackSpace: event.character = '\b'; break;
1098 case OS.GDK_Linefeed: event.character = '\n'; break;
1099 case OS.GDK_KP_Enter:
1100 case OS.GDK_Return: event.character = '\r'; break;
1101 case OS.GDK_KP_Delete:
1102 case OS.GDK_Delete: event.character = 0x7F; break;
1103 case OS.GDK_Escape: event.character = 0x1B; break;
1104 case OS.GDK_Tab:
1105 case OS.GDK_ISO_Left_Tab: event.character = '\t'; break;
1106 default: {
1107 if (event.keyCode == 0) {
1108 int [] keyval = new int [1], effective_group= new int [1], level = new int [1], consumed_modifiers = new int [1];
1109 if (OS.gdk_keymap_translate_keyboard_state(OS.gdk_keymap_get_default (), keyEvent.hardware_keycode, 0, keyEvent.group, keyval, effective_group, level, consumed_modifiers)) {
1110 event.keyCode = OS.gdk_keyval_to_unicode (keyval [0]);
1111 }
1112 }
1113 int key = keyEvent.keyval;
1114 if ((keyEvent.state & OS.GDK_CONTROL_MASK) != 0 && (0 <= key && key <= 0x7F)) {
1115 if ('a' <= key && key <= 'z') key -= 'a' - 'A';
1116 if (64 <= key && key <= 95) key -= 64;
1117 event.character = (char) key;
1118 isNull = keyEvent.keyval == '@' && key == 0;
1119 } else {
1120 event.character = (char) OS.gdk_keyval_to_unicode (key);
1121 }
1122 }
1123 }
1124 if (event.keyCode == 0 && event.character == 0) {
1125 if (!isNull) return false;
1126 }
1127 return setInputState (event, keyEvent.state);
1128}
1129
1130void setOrientation () {
1131}
1132
1133long /*int*/ shellMapProc (long /*int*/ handle, long /*int*/ arg0, long /*int*/ user_data) {
1134 return 0;
1135}
1136
1137/**
1138 * Returns a string containing a concise, human-readable
1139 * description of the receiver.
1140 *
1141 * @return a string representation of the receiver
1142 */
1143public String toString () {
1144 String string = "*Disposed*";
1145 if (!isDisposed ()) {
1146 string = "*Wrong Thread*";
1147 if (isValidThread ()) string = getNameText ();
1148 }
1149 return getName () + " {" + string + "}";
1150}
1151
1152long /*int*/ topHandle () {
1153 return handle;
1154}
1155
1156long /*int*/ timerProc (long /*int*/ widget) {
1157 return 0;
1158}
1159
1160long /*int*/ treeSelectionProc (long /*int*/ model, long /*int*/ path, long /*int*/ iter, int [] selection, int length) {
1161 return 0;
1162}
1163
1164boolean translateTraversal (int event) {
1165 return false;
1166}
1167
1168long /*int*/ windowProc (long /*int*/ handle, long /*int*/ user_data) {
1169 switch ((int)/*64*/user_data) {
1170 case ACTIVATE: return gtk_activate (handle);
1171 case CHANGED: return gtk_changed (handle);
1172 case CLICKED: return gtk_clicked (handle);
1173 case HIDE: return gtk_hide (handle);
1174 case POPUP_MENU: return gtk_popup_menu (handle);
1175 case PREEDIT_CHANGED: return gtk_preedit_changed (handle);
1176 case REALIZE: return gtk_realize (handle);
1177 case SELECT: return gtk_select (handle);
1178 case SHOW: return gtk_show (handle);
1179 case VALUE_CHANGED: return gtk_value_changed (handle);
1180 case UNREALIZE: return gtk_unrealize (handle);
1181 default: return 0;
1182 }
1183}
1184
1185long /*int*/ windowProc (long /*int*/ handle, long /*int*/ arg0, long /*int*/ user_data) {
1186 switch ((int)/*64*/user_data) {
1187 case -EXPOSE_EVENT: {
1188 return (state & OBSCURED) != 0 ? 1 : 0;
1189 }
1190 case -BUTTON_PRESS_EVENT:
1191 case -BUTTON_RELEASE_EVENT:
1192 case -MOTION_NOTIFY_EVENT: {
1193 return 1;
1194 }
1195 case BUTTON_PRESS_EVENT: return gtk_button_press_event (handle, arg0);
1196 case BUTTON_RELEASE_EVENT: return gtk_button_release_event (handle, arg0);
1197 case COMMIT: return gtk_commit (handle, arg0);
1198 case CONFIGURE_EVENT: return gtk_configure_event (handle, arg0);
1199 case DELETE_EVENT: return gtk_delete_event (handle, arg0);
1200 case ENTER_NOTIFY_EVENT: return gtk_enter_notify_event (handle, arg0);
1201 case EVENT: return gtk_event (handle, arg0);
1202 case EVENT_AFTER: return gtk_event_after (handle, arg0);
1203 case EXPOSE_EVENT: return gtk_expose_event (handle, arg0);
1204 case FOCUS: return gtk_focus (handle, arg0);
1205 case FOCUS_IN_EVENT: return gtk_focus_in_event (handle, arg0);
1206 case FOCUS_OUT_EVENT: return gtk_focus_out_event (handle, arg0);
1207 case KEY_PRESS_EVENT: return gtk_key_press_event (handle, arg0);
1208 case KEY_RELEASE_EVENT: return gtk_key_release_event (handle, arg0);
1209 case LEAVE_NOTIFY_EVENT: return gtk_leave_notify_event (handle, arg0);
1210 case MAP_EVENT: return gtk_map_event (handle, arg0);
1211 case MNEMONIC_ACTIVATE: return gtk_mnemonic_activate (handle, arg0);
1212 case MOTION_NOTIFY_EVENT: return gtk_motion_notify_event (handle, arg0);
1213 case SHOW_HELP: return gtk_show_help (handle, arg0);
1214 case SIZE_ALLOCATE: return gtk_size_allocate (handle, arg0);
1215 case STYLE_SET: return gtk_style_set (handle, arg0);
1216 case TOGGLED: return gtk_toggled (handle, arg0);
1217 case UNMAP_EVENT: return gtk_unmap_event (handle, arg0);
1218 case VISIBILITY_NOTIFY_EVENT: return gtk_visibility_notify_event (handle, arg0);
1219 case WINDOW_STATE_EVENT: return gtk_window_state_event (handle, arg0);
1220 default: return 0;
1221 }
1222}
1223
1224long /*int*/ windowProc (long /*int*/ handle, long /*int*/ arg0, long /*int*/ arg1, long /*int*/ user_data) {
1225 switch ((int)/*64*/user_data) {
1226 case DELETE_RANGE: return gtk_delete_range (handle, arg0, arg1);
1227 case DELETE_TEXT: return gtk_delete_text (handle, arg0, arg1);
1228 case ROW_ACTIVATED: return gtk_row_activated (handle, arg0, arg1);
1229 case SCROLL_CHILD: return gtk_scroll_child (handle, arg0, arg1);
1230 case SWITCH_PAGE: return gtk_switch_page (handle, arg0, arg1);
1231 case TEST_COLLAPSE_ROW: return gtk_test_collapse_row (handle, arg0, arg1);
1232 case TEST_EXPAND_ROW: return gtk_test_expand_row(handle, arg0, arg1);
1233 default: return 0;
1234 }
1235}
1236
1237long /*int*/ windowProc (long /*int*/ handle, long /*int*/ arg0, long /*int*/ arg1, long /*int*/ arg2, long /*int*/ user_data) {
1238 switch ((int)/*64*/user_data) {
1239 case INSERT_TEXT: return gtk_insert_text (handle, arg0, arg1, arg2);
1240 default: return 0;
1241 }
1242}
1243
1244
1245}