Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/eclipse/swt/widgets/Control.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.Converter;
16  import org.eclipse.swt.internal.gtk.*;
17  import org.eclipse.swt.graphics.*;
18  import org.eclipse.swt.events.*;
19  import org.eclipse.swt.accessibility.*;
20  
21  /**
22   * Control is the abstract superclass of all windowed user interface classes.
23   * <p>
24   * <dl>
25   * <dt><b>Styles:</b>
26   * <dd>BORDER</dd>
27   * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd>
28   * <dt><b>Events:</b>
29   * <dd>FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick, MouseDown, MouseEnter,
30   *     MouseExit, MouseHover, MouseUp, MouseMove, Move, Paint, Resize, Traverse,
31   *     DragDetect, MenuDetect</dd>
32   * </dl>
33   * <p>
34   * Only one of LEFT_TO_RIGHT or RIGHT_TO_LEFT may be specified.
35   * </p><p>
36   * IMPORTANT: This class is intended to be subclassed <em>only</em>
37   * within the SWT implementation.
38   * </p>
39   */
40  public abstract class Control extends Widget implements Drawable {
41    long /*int*/ fixedHandle;
42    long /*int*/ redrawWindow, enableWindow;
43    int drawCount;
44    Composite parent;
45    Cursor cursor;
46    Menu menu;
47    Font font;
48    String toolTipText;
49    Object layoutData;
50    Accessible accessible;
51  
52  Control () {
53  }
54  
55  /**
56   * Constructs a new instance of this class given its parent
57   * and a style value describing its behavior and appearance.
58   * <p>
59   * The style value is either one of the style constants defined in
60   * class <code>SWT</code> which is applicable to instances of this
61   * class, or must be built by <em>bitwise OR</em>'ing together 
62   * (that is, using the <code>int</code> "|" operator) two or more
63   * of those <code>SWT</code> style constants. The class description
64   * lists the style constants that are applicable to the class.
65   * Style bits are also inherited from superclasses.
66   * </p>
67   *
68   * @param parent a composite control which will be the parent of the new instance (cannot be null)
69   * @param style the style of control to construct
70   *
71   * @exception IllegalArgumentException <ul>
72   *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
73   * </ul>
74   * @exception SWTException <ul>
75   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
76   *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
77   * </ul>
78   *
79   * @see SWT#BORDER
80   * @see Widget#checkSubclass
81   * @see Widget#getStyle
82   */
83  public Control (Composite parent, int style) {
84    super (parent, style);
85    this.parent = parent;
86    createWidget (0);
87  }
88  
89  long /*int*/ defaultFont () {
90    return display.defaultFont;
91  }
92  
93  void deregister () {
94    super.deregister ();
95    if (fixedHandle != 0) display.removeWidget (fixedHandle);
96    long /*int*/ imHandle = imHandle ();
97    if (imHandle != 0) display.removeWidget (imHandle);
98  }
99  
100 boolean drawGripper (int x, int y, int width, int height) {
101   long /*int*/ paintHandle = paintHandle ();
102   long /*int*/ window = OS.GTK_WIDGET_WINDOW (paintHandle);
103   if (window == 0) return false;
104   long /*int*/ style = OS.gtk_widget_get_style (paintHandle);
105   if (style == 0) return false;
106   byte[] detail = Converter.wcsToMbcs (null, "", true);
107   OS.gtk_paint_handle (style, window, OS.GTK_STATE_NORMAL, OS.GTK_SHADOW_OUT, null, paintHandle, detail, x, y, width, height, OS.GTK_ORIENTATION_VERTICAL);
108   return true;
109 }
110 
111 void enableWidget (boolean enabled) {
112   OS.gtk_widget_set_sensitive (handle, enabled);
113 }
114 
115 long /*int*/ eventHandle () {
116   return handle;
117 }
118 
119 void fixFocus (Control focusControl) {
120   Shell shell = getShell ();
121   Control control = this;
122   while ((control = control.parent) != null) {
123     if (control.setFocus ()) return;
124     if (control == shell) break;
125   }
126   shell.setSavedFocus (focusControl);
127   long /*int*/ focusHandle = shell.fixedHandle;
128   OS.GTK_WIDGET_SET_FLAGS (focusHandle, OS.GTK_CAN_FOCUS);
129   OS.gtk_widget_grab_focus (focusHandle);
130   OS.GTK_WIDGET_UNSET_FLAGS (focusHandle, OS.GTK_CAN_FOCUS);
131 }
132 
133 long /*int*/ focusHandle () {
134   return handle;
135 }
136 
137 long /*int*/ fontHandle () {
138   return handle;
139 }
140 
141 boolean hasFocus () {
142   return this == display.getFocusControl();
143 }
144 
145 void hookEvents () {
146   long /*int*/ windowProc2 = display.windowProc2;
147   long /*int*/ windowProc3 = display.windowProc3;
148   
149   /* Connect the keyboard signals */
150   long /*int*/ focusHandle = focusHandle ();
151   int focusMask = OS.GDK_KEY_PRESS_MASK | OS.GDK_KEY_RELEASE_MASK | OS.GDK_FOCUS_CHANGE_MASK;
152   OS.gtk_widget_add_events (focusHandle, focusMask);
153   OS.g_signal_connect (focusHandle, OS.popup_menu, windowProc2, POPUP_MENU);
154   OS.g_signal_connect (focusHandle, OS.show_help, windowProc3, SHOW_HELP);
155   OS.g_signal_connect (focusHandle, OS.key_press_event, windowProc3, KEY_PRESS_EVENT);
156   OS.g_signal_connect (focusHandle, OS.key_release_event, windowProc3, KEY_RELEASE_EVENT);
157   OS.g_signal_connect (focusHandle, OS.focus, windowProc3, FOCUS);
158   OS.g_signal_connect (focusHandle, OS.focus_in_event, windowProc3, FOCUS_IN_EVENT);
159   OS.g_signal_connect (focusHandle, OS.focus_out_event, windowProc3, FOCUS_OUT_EVENT);
160 
161   /* Connect the mouse signals */
162   long /*int*/ eventHandle = eventHandle ();
163   int eventMask = OS.GDK_POINTER_MOTION_MASK | OS.GDK_BUTTON_PRESS_MASK |
164     OS.GDK_BUTTON_RELEASE_MASK | OS.GDK_ENTER_NOTIFY_MASK |
165     OS.GDK_LEAVE_NOTIFY_MASK;
166   OS.gtk_widget_add_events (eventHandle, eventMask);
167   OS.g_signal_connect (eventHandle, OS.button_press_event, windowProc3, BUTTON_PRESS_EVENT);
168   OS.g_signal_connect (eventHandle, OS.button_release_event, windowProc3, BUTTON_RELEASE_EVENT);
169   OS.g_signal_connect (eventHandle, OS.motion_notify_event, windowProc3, MOTION_NOTIFY_EVENT);
170   OS.g_signal_connect (eventHandle, OS.enter_notify_event, windowProc3, ENTER_NOTIFY_EVENT);
171   OS.g_signal_connect (eventHandle, OS.leave_notify_event, windowProc3, LEAVE_NOTIFY_EVENT);
172   /*
173   * Feature in GTK.  Events such as mouse move are propagate up
174   * the widget hierarchy and are seen by the parent.  This is the
175   * correct GTK behavior but not correct for SWT.  The fix is to
176   * hook a signal after and stop the propagation using a negative
177   * event number to distinguish this case.
178   */
179   OS.g_signal_connect_after (eventHandle, OS.button_press_event, windowProc3, -BUTTON_PRESS_EVENT);
180   OS.g_signal_connect_after (eventHandle, OS.button_release_event, windowProc3, -BUTTON_RELEASE_EVENT);
181   OS.g_signal_connect_after (eventHandle, OS.motion_notify_event, windowProc3, -MOTION_NOTIFY_EVENT);
182 
183   /* Connect the event_after signal for both key and mouse */
184   OS.g_signal_connect (eventHandle, OS.event_after, windowProc3, EVENT_AFTER);
185   if (focusHandle != eventHandle) {
186     OS.g_signal_connect (focusHandle, OS.event_after, windowProc3, EVENT_AFTER);
187   }
188   
189   /* Connect the paint signal */
190   long /*int*/ paintHandle = paintHandle ();
191   int paintMask = OS.GDK_EXPOSURE_MASK | OS.GDK_VISIBILITY_NOTIFY_MASK;
192   OS.gtk_widget_add_events (paintHandle, paintMask);
193   OS.g_signal_connect (paintHandle, OS.expose_event, windowProc3, -EXPOSE_EVENT);
194   OS.g_signal_connect (paintHandle, OS.visibility_notify_event, windowProc3, VISIBILITY_NOTIFY_EVENT);
195   OS.g_signal_connect_after (paintHandle, OS.expose_event, windowProc3, EXPOSE_EVENT);
196 
197   /* Connect the Input Method signals */
198   OS.g_signal_connect_after (handle, OS.realize, windowProc2, REALIZE);
199   OS.g_signal_connect (handle, OS.unrealize, windowProc2, UNREALIZE);
200   long /*int*/ imHandle = imHandle ();
201   if (imHandle != 0) {
202     OS.g_signal_connect (imHandle, OS.commit, windowProc3, COMMIT);
203     OS.g_signal_connect (imHandle, OS.preedit_changed, windowProc2, PREEDIT_CHANGED);
204   }
205 }
206 
207 long /*int*/ hoverProc (long /*int*/ widget) {
208   Event event = new Event ();
209   int [] x = new int [1], y = new int [1], mask = new int [1];
210   OS.gdk_window_get_pointer (0, x, y, mask);
211   event.x = x [0];
212   event.y = y [0];
213   long /*int*/ eventHandle = eventHandle ();
214   long /*int*/ window = OS.GTK_WIDGET_WINDOW (eventHandle);
215   OS.gdk_window_get_origin (window, x, y);
216   event.x -= x [0];
217   event.y -= y [0];
218   setInputState (event, mask [0]);
219   postEvent (SWT.MouseHover, event);
220   return 0;
221 }
222 
223 long /*int*/ topHandle() {
224   if (fixedHandle != 0) return fixedHandle;
225   return super.topHandle ();
226 }
227 
228 long /*int*/ paintHandle () {
229   long /*int*/ topHandle = topHandle ();
230   long /*int*/ paintHandle = handle;
231   while (paintHandle != topHandle) {
232     if ((OS.GTK_WIDGET_FLAGS (paintHandle) & OS.GTK_NO_WINDOW) == 0) break;
233     paintHandle = OS.gtk_widget_get_parent (paintHandle);
234   }
235   return paintHandle;
236 }
237 
238 long /*int*/ paintWindow () {
239   long /*int*/ paintHandle = paintHandle ();
240   OS.gtk_widget_realize (paintHandle);
241   return OS.GTK_WIDGET_WINDOW (paintHandle);
242 }
243 
244 /**
245  * Returns the preferred size of the receiver.
246  * <p>
247  * The <em>preferred size</em> of a control is the size that it would
248  * best be displayed at. The width hint and height hint arguments
249  * allow the caller to ask a control questions such as "Given a particular
250  * width, how high does the control need to be to show all of the contents?"
251  * To indicate that the caller does not wish to constrain a particular 
252  * dimension, the constant <code>SWT.DEFAULT</code> is passed for the hint. 
253  * </p>
254  *
255  * @param wHint the width hint (can be <code>SWT.DEFAULT</code>)
256  * @param hHint the height hint (can be <code>SWT.DEFAULT</code>)
257  * @return the preferred size of the control
258  *
259  * @exception SWTException <ul>
260  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
261  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
262  * </ul>
263  *
264  * @see Layout
265  * @see #getBorderWidth
266  * @see #getBounds
267  * @see #getSize
268  * @see #pack
269  * @see "computeTrim, getClientArea for controls that implement them"
270  */
271 public Point computeSize (int wHint, int hHint) {
272   return computeSize (wHint, hHint, true);
273 }
274 
275 Control computeTabGroup () {
276   if (isTabGroup()) return this;
277   return parent.computeTabGroup ();
278 }
279 
280 Control[] computeTabList() {
281   if (isTabGroup()) {
282     if (getVisible() && getEnabled()) {
283       return new Control[] {this};
284     }
285   }
286   return new Control[0];
287 }
288 
289 Control computeTabRoot () {
290   Control[] tabList = parent._getTabList();
291   if (tabList != null) {
292     int index = 0;
293     while (index < tabList.length) {
294       if (tabList [index] == this) break;
295       index++;
296     }
297     if (index == tabList.length) {
298       if (isTabGroup ()) return this;
299     }
300   }
301   return parent.computeTabRoot ();
302 }
303 
304 void createWidget (int index) {
305   checkOrientation (parent);
306   super.createWidget (index);
307   setInitialSize ();
308   setZOrder (null, false);
309 }
310 
311 /**
312  * Returns the preferred size of the receiver.
313  * <p>
314  * The <em>preferred size</em> of a control is the size that it would
315  * best be displayed at. The width hint and height hint arguments
316  * allow the caller to ask a control questions such as "Given a particular
317  * width, how high does the control need to be to show all of the contents?"
318  * To indicate that the caller does not wish to constrain a particular 
319  * dimension, the constant <code>SWT.DEFAULT</code> is passed for the hint. 
320  * </p><p>
321  * If the changed flag is <code>true</code>, it indicates that the receiver's
322  * <em>contents</em> have changed, therefore any caches that a layout manager
323  * containing the control may have been keeping need to be flushed. When the
324  * control is resized, the changed flag will be <code>false</code>, so layout
325  * manager caches can be retained. 
326  * </p>
327  *
328  * @param wHint the width hint (can be <code>SWT.DEFAULT</code>)
329  * @param hHint the height hint (can be <code>SWT.DEFAULT</code>)
330  * @param changed <code>true</code> if the control's contents have changed, and <code>false</code> otherwise
331  * @return the preferred size of the control.
332  *
333  * @exception SWTException <ul>
334  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
335  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
336  * </ul>
337  *
338  * @see Layout
339  * @see #getBorderWidth
340  * @see #getBounds
341  * @see #getSize
342  * @see #pack
343  * @see "computeTrim, getClientArea for controls that implement them"
344  */
345 public Point computeSize (int wHint, int hHint, boolean changed) {
346   checkWidget();
347   if (wHint != SWT.DEFAULT && wHint < 0) wHint = 0;
348   if (hHint != SWT.DEFAULT && hHint < 0) hHint = 0;
349   return computeNativeSize (handle, wHint, hHint, changed);  
350 }
351 
352 Point computeNativeSize (long /*int*/ h, int wHint, int hHint, boolean changed) {
353   int width = OS.GTK_WIDGET_WIDTH (h);
354   int height = OS.GTK_WIDGET_HEIGHT (h);
355   OS.gtk_widget_set_size_request (h, -1, -1);
356   GtkRequisition requisition = new GtkRequisition ();
357   OS.gtk_widget_size_request (h, requisition);
358   OS.gtk_widget_set_size_request (h, width, height);
359   width = wHint == SWT.DEFAULT ? requisition.width : wHint;
360   height = hHint == SWT.DEFAULT ? requisition.height : hHint;
361   return new Point (width, height);  
362 }
363 
364 /**
365  * Returns the accessible object for the receiver.
366  * If this is the first time this object is requested,
367  * then the object is created and returned.
368  *
369  * @return the accessible object
370  *
371  * @exception SWTException <ul>
372  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
373  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
374  * </ul>
375  * 
376  * @see Accessible#addAccessibleListener
377  * @see Accessible#addAccessibleControlListener
378  * 
379  * @since 2.0
380  */
381 public Accessible getAccessible () {
382   checkWidget ();
383   if (accessible == null) {
384     accessible = Accessible.internal_new_Accessible (this);
385   }
386   return accessible;
387 }
388 
389 /**
390  * Returns a rectangle describing the receiver's size and location
391  * relative to its parent (or its display if its parent is null),
392  * unless the receiver is a shell. In this case, the location is
393  * relative to the display.
394  *
395  * @return the receiver's bounding rectangle
396  *
397  * @exception SWTException <ul>
398  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
399  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
400  * </ul>
401  */
402 public Rectangle getBounds () {
403   checkWidget();
404   long /*int*/ topHandle = topHandle ();
405   int x = OS.GTK_WIDGET_X (topHandle);
406   int y = OS.GTK_WIDGET_Y (topHandle);
407   int width = OS.GTK_WIDGET_WIDTH (topHandle);
408   int height = OS.GTK_WIDGET_HEIGHT (topHandle);
409   return new Rectangle (x, y, width, height);
410 }
411 
412 /**
413  * Sets the receiver's size and location to the rectangular
414  * area specified by the argument. The <code>x</code> and 
415  * <code>y</code> fields of the rectangle are relative to
416  * the receiver's parent (or its display if its parent is null).
417  * <p>
418  * Note: Attempting to set the width or height of the
419  * receiver to a negative number will cause that
420  * value to be set to zero instead.
421  * </p>
422  *
423  * @param rect the new bounds for the receiver
424  *
425  * @exception SWTException <ul>
426  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
427  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
428  * </ul>
429  */
430 public void setBounds (Rectangle rect) {
431   checkWidget ();
432   if (rect == null) error (SWT.ERROR_NULL_ARGUMENT);
433   setBounds (rect.x, rect.y, rect.width, rect.height);
434 }
435 
436 /**
437  * Sets the receiver's size and location to the rectangular
438  * area specified by the arguments. The <code>x</code> and 
439  * <code>y</code> arguments are relative to the receiver's
440  * parent (or its display if its parent is null), unless 
441  * the receiver is a shell. In this case, the <code>x</code>
442  * and <code>y</code> arguments are relative to the display.
443  * <p>
444  * Note: Attempting to set the width or height of the
445  * receiver to a negative number will cause that
446  * value to be set to zero instead.
447  * </p>
448  *
449  * @param x the new x coordinate for the receiver
450  * @param y the new y coordinate for the receiver
451  * @param width the new width for the receiver
452  * @param height the new height for the receiver
453  *
454  * @exception SWTException <ul>
455  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
456  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
457  * </ul>
458  */
459 public void setBounds (int x, int y, int width, int height) {
460   checkWidget();
461   setBounds (x, y, width, height, true, true);
462 }
463 
464 void moveHandle (int x, int y) {
465   long /*int*/ topHandle = topHandle ();
466   long /*int*/ parentHandle = parent.parentingHandle ();
467   OS.gtk_fixed_move (parentHandle, topHandle, x, y);
468 }
469 
470 void resizeHandle (int width, int height) {
471   long /*int*/ topHandle = topHandle ();
472   OS.gtk_widget_set_size_request (topHandle, width, height);
473   if (topHandle != handle) {
474     OS.gtk_widget_set_size_request (handle, width, height);
475   }
476 
477   /*
478   * Feature in GTK.  Some widgets do not allocate the size
479   * of their internal children in gtk_widget_size_allocate().
480   * Instead this is done in gtk_widget_size_request().  This
481   * means that the client area of the widget is not correct.
482   * The fix is to call gtk_widget_size_request() (and throw
483   * the results away).
484   *
485   * Note: The following widgets rely on this feature:
486   *   GtkScrolledWindow
487   *   GtkNotebook
488   *   GtkFrame
489   *   GtkCombo
490   */
491   GtkRequisition requisition = new GtkRequisition ();
492   OS.gtk_widget_size_request (handle, requisition);
493 }
494 
495 boolean setBounds (int x, int y, int width, int height, boolean move, boolean resize) {
496   long /*int*/ topHandle = topHandle ();
497   int flags = OS.GTK_WIDGET_FLAGS (topHandle);
498   OS.GTK_WIDGET_SET_FLAGS (topHandle, OS.GTK_VISIBLE);
499   boolean sameOrigin = true, sameExtent = true;
500   if (move) {
501     int oldX = OS.GTK_WIDGET_X (topHandle);
502     int oldY = OS.GTK_WIDGET_Y (topHandle);
503     sameOrigin = x == oldX && y == oldY;
504     if (!sameOrigin) {
505       if (enableWindow != 0) {
506         OS.gdk_window_move (enableWindow, x, y);
507       }
508       moveHandle (x, y);
509     }
510   }
511   if (resize) {
512     width = Math.max (1, width);
513     height = Math.max (1, height);
514     int oldWidth = OS.GTK_WIDGET_WIDTH (topHandle);
515     int oldHeight = OS.GTK_WIDGET_HEIGHT (topHandle);
516     sameExtent = width == oldWidth && height == oldHeight;
517     if (!sameExtent) {
518       if (redrawWindow != 0) {
519         OS.gdk_window_resize (redrawWindow, width, height);
520       }
521       if (enableWindow != 0) {
522         OS.gdk_window_resize (enableWindow, width, height);
523       }
524       resizeHandle (width, height);
525     }
526   }
527   if (!sameOrigin || !sameExtent) {
528     /*
529     * Force the container to allocate the size of its children.
530     */
531     long /*int*/ parentHandle = parent.parentingHandle ();
532     OS.gtk_container_resize_children (parentHandle);
533   }
534   if ((flags & OS.GTK_VISIBLE) == 0) {
535     OS.GTK_WIDGET_UNSET_FLAGS (topHandle, OS.GTK_VISIBLE);  
536   }
537   if (!sameOrigin) sendEvent (SWT.Move);
538   if (!sameExtent) sendEvent (SWT.Resize);
539   return !sameOrigin || !sameExtent;
540 }
541 
542 /**
543  * Returns a point describing the receiver's location relative
544  * to its parent (or its display if its parent is null), unless
545  * the receiver is a shell. In this case, the point is 
546  * relative to the display. 
547  *
548  * @return the receiver's location
549  *
550  * @exception SWTException <ul>
551  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
552  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
553  * </ul>
554  */
555 public Point getLocation () {
556   checkWidget();
557   long /*int*/ topHandle = topHandle ();
558   int x = OS.GTK_WIDGET_X (topHandle);
559   int y = OS.GTK_WIDGET_Y (topHandle);
560   return new Point (x, y);
561 }
562 
563 /**
564  * Sets the receiver's location to the point specified by
565  * the arguments which are relative to the receiver's
566  * parent (or its display if its parent is null), unless 
567  * the receiver is a shell. In this case, the point is 
568  * relative to the display. 
569  *
570  * @param location the new location for the receiver
571  *
572  * @exception SWTException <ul>
573  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
574  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
575  * </ul>
576  */
577 public void setLocation (Point location) {
578   checkWidget ();
579   if (location == null) error (SWT.ERROR_NULL_ARGUMENT);
580   setLocation (location.x, location.y);
581 }
582 
583 /**
584  * Sets the receiver's location to the point specified by
585  * the arguments which are relative to the receiver's
586  * parent (or its display if its parent is null), unless 
587  * the receiver is a shell. In this case, the point is 
588  * relative to the display. 
589  *
590  * @param x the new x coordinate for the receiver
591  * @param y the new y coordinate for the receiver
592  *
593  * @exception SWTException <ul>
594  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
595  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
596  * </ul>
597  */
598 public void setLocation(int x, int y) {
599   checkWidget();
600   setBounds (x, y, 0, 0, true, false);
601 }
602 
603 /**
604  * Returns a point describing the receiver's size. The
605  * x coordinate of the result is the width of the receiver.
606  * The y coordinate of the result is the height of the
607  * receiver.
608  *
609  * @return the receiver's size
610  *
611  * @exception SWTException <ul>
612  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
613  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
614  * </ul>
615  */
616 public Point getSize () {
617   checkWidget();
618   long /*int*/ topHandle = topHandle ();
619   int width = OS.GTK_WIDGET_WIDTH (topHandle);
620   int height = OS.GTK_WIDGET_HEIGHT (topHandle);
621   return new Point (width, height);
622 }
623 
624 /**
625  * Sets the receiver's size to the point specified by the argument.
626  * <p>
627  * Note: Attempting to set the width or height of the
628  * receiver to a negative number will cause them to be
629  * set to zero instead.
630  * </p>
631  *
632  * @param size the new size for the receiver
633  *
634  * @exception IllegalArgumentException <ul>
635  *    <li>ERROR_NULL_ARGUMENT - if the point is null</li>
636  * </ul>
637  * @exception SWTException <ul>
638  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
639  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
640  * </ul>
641  */
642 public void setSize (Point size) {
643   checkWidget ();
644   if (size == null) error (SWT.ERROR_NULL_ARGUMENT);
645   setSize (size.x, size.y);
646 }
647 
648 /**
649  * Sets the receiver's size to the point specified by the arguments.
650  * <p>
651  * Note: Attempting to set the width or height of the
652  * receiver to a negative number will cause that
653  * value to be set to zero instead.
654  * </p>
655  *
656  * @param width the new width for the receiver
657  * @param height the new height for the receiver
658  *
659  * @exception SWTException <ul>
660  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
661  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
662  * </ul>
663  */
664 public void setSize (int width, int height) {
665   checkWidget();
666   setBounds (0, 0, width, height, false, true);
667 }
668 
669 /**
670  * Moves the receiver above the specified control in the
671  * drawing order. If the argument is null, then the receiver
672  * is moved to the top of the drawing order. The control at
673  * the top of the drawing order will not be covered by other
674  * controls even if they occupy intersecting areas.
675  *
676  * @param control the sibling control (or null)
677  *
678  * @exception IllegalArgumentException <ul>
679  *    <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li> 
680  * </ul>
681  * @exception SWTException <ul>
682  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
683  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
684  * </ul>
685  * 
686  * @see #moveBelow
687  */
688 public void moveAbove (Control control) {
689   checkWidget();
690   if (control != null) {
691     if (control.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
692     if (parent != control.parent) return;
693   }
694   setZOrder (control, true);
695 }
696 
697 /**
698  * Moves the receiver below the specified control in the
699  * drawing order. If the argument is null, then the receiver
700  * is moved to the bottom of the drawing order. The control at
701  * the bottom of the drawing order will be covered by all other
702  * controls which occupy intersecting areas.
703  *
704  * @param control the sibling control (or null)
705  *
706  * @exception IllegalArgumentException <ul>
707  *    <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li> 
708  * </ul>
709  * @exception SWTException <ul>
710  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
711  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
712  * </ul>
713  * 
714  * @see #moveAbove
715  */
716 public void moveBelow (Control control) {
717   checkWidget();
718   if (control != null) {
719     if (control.isDisposed ()) error(SWT.ERROR_INVALID_ARGUMENT);
720     if (parent != control.parent) return;
721   }
722   setZOrder (control, false);
723 }
724 
725 /**
726  * Causes the receiver to be resized to its preferred size.
727  * For a composite, this involves computing the preferred size
728  * from its layout, if there is one.
729  *
730  * @exception SWTException <ul>
731  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
732  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
733  * </ul>
734  *
735  * @see #computeSize
736  */
737 public void pack () {
738   pack (true);
739 }
740 
741 /**
742  * Causes the receiver to be resized to its preferred size.
743  * For a composite, this involves computing the preferred size
744  * from its layout, if there is one.
745  * <p>
746  * If the changed flag is <code>true</code>, it indicates that the receiver's
747  * <em>contents</em> have changed, therefore any caches that a layout manager
748  * containing the control may have been keeping need to be flushed. When the
749  * control is resized, the changed flag will be <code>false</code>, so layout
750  * manager caches can be retained. 
751  * </p>
752  *
753  * @param changed whether or not the receiver's contents have changed
754  * 
755  * @exception SWTException <ul>
756  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
757  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
758  * </ul>
759  *
760  * @see #computeSize
761  */
762 public void pack (boolean changed) {
763   setSize (computeSize (SWT.DEFAULT, SWT.DEFAULT, changed));
764 }
765 
766 /**
767  * Sets the layout data associated with the receiver to the argument.
768  * 
769  * @param layoutData the new layout data for the receiver.
770  * 
771  * @exception SWTException <ul>
772  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
773  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
774  * </ul>
775  */
776 public void setLayoutData (Object layoutData) {
777   checkWidget();
778   this.layoutData = layoutData;
779 }
780 
781 /**
782  * Returns a point which is the result of converting the
783  * argument, which is specified in display relative coordinates,
784  * to coordinates relative to the receiver.
785  * <p>
786  * @param x the x coordinate to be translated
787  * @param y the y coordinate to be translated
788  * @return the translated coordinates
789  *
790  * @exception SWTException <ul>
791  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
792  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
793  * </ul>
794  * 
795  * @since 2.1
796  */
797 public Point toControl (int x, int y) {
798   checkWidget ();
799   long /*int*/ eventHandle = eventHandle ();
800   OS.gtk_widget_realize (eventHandle);
801   long /*int*/ window = OS.GTK_WIDGET_WINDOW (eventHandle);
802   int [] origin_x = new int [1], origin_y = new int [1];
803   OS.gdk_window_get_origin (window, origin_x, origin_y);
804   return new Point (x - origin_x [0], y - origin_y [0]);
805 }
806 
807 /**
808  * Returns a point which is the result of converting the
809  * argument, which is specified in display relative coordinates,
810  * to coordinates relative to the receiver.
811  * <p>
812  * @param point the point to be translated (must not be null)
813  * @return the translated coordinates
814  *
815  * @exception IllegalArgumentException <ul>
816  *    <li>ERROR_NULL_ARGUMENT - if the point is null</li>
817  * </ul>
818  * @exception SWTException <ul>
819  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
820  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
821  * </ul>
822  */
823 public Point toControl (Point point) {
824   checkWidget ();
825   if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
826   return toControl (point.x, point.y);
827 }
828 
829 /**
830  * Returns a point which is the result of converting the
831  * argument, which is specified in coordinates relative to
832  * the receiver, to display relative coordinates.
833  * <p>
834  * @param x the x coordinate to be translated
835  * @param y the y coordinate to be translated
836  * @return the translated coordinates
837  *
838  * @exception SWTException <ul>
839  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
840  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
841  * </ul>
842  * 
843  * @since 2.1
844  */
845 public Point toDisplay (int x, int y) {
846   checkWidget();
847   long /*int*/ eventHandle = eventHandle ();
848   OS.gtk_widget_realize (eventHandle);
849   long /*int*/ window = OS.GTK_WIDGET_WINDOW (eventHandle);
850   int [] origin_x = new int [1], origin_y = new int [1];
851   OS.gdk_window_get_origin (window, origin_x, origin_y);
852   return new Point (origin_x [0] + x, origin_y [0] + y);
853 }
854 
855 /**
856  * Returns a point which is the result of converting the
857  * argument, which is specified in coordinates relative to
858  * the receiver, to display relative coordinates.
859  * <p>
860  * @param point the point to be translated (must not be null)
861  * @return the translated coordinates
862  *
863  * @exception IllegalArgumentException <ul>
864  *    <li>ERROR_NULL_ARGUMENT - if the point is null</li>
865  * </ul>
866  * @exception SWTException <ul>
867  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
868  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
869  * </ul>
870  */
871 public Point toDisplay (Point point) {
872   checkWidget();
873   if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
874   return toDisplay (point.x, point.y);
875 }
876  
877 /**
878  * Adds the listener to the collection of listeners who will
879  * be notified when the control is moved or resized, by sending
880  * it one of the messages defined in the <code>ControlListener</code>
881  * interface.
882  *
883  * @param listener the listener which should be notified
884  *
885  * @exception IllegalArgumentException <ul>
886  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
887  * </ul>
888  * @exception SWTException <ul>
889  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
890  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
891  * </ul>
892  *
893  * @see ControlListener
894  * @see #removeControlListener
895  */
896 public void addControlListener(ControlListener listener) {
897   checkWidget();
898   if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
899   TypedListener typedListener = new TypedListener (listener);
900   addListener (SWT.Resize,typedListener);
901   addListener (SWT.Move,typedListener);
902 }
903 
904 /**
905  * Adds the listener to the collection of listeners who will
906  * be notified when the control gains or loses focus, by sending
907  * it one of the messages defined in the <code>FocusListener</code>
908  * interface.
909  *
910  * @param listener the listener which should be notified
911  *
912  * @exception IllegalArgumentException <ul>
913  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
914  * </ul>
915  * @exception SWTException <ul>
916  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
917  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
918  * </ul>
919  *
920  * @see FocusListener
921  * @see #removeFocusListener
922  */
923 public void addFocusListener(FocusListener listener) {
924   checkWidget();
925   if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
926   TypedListener typedListener = new TypedListener (listener);
927   addListener(SWT.FocusIn,typedListener);
928   addListener(SWT.FocusOut,typedListener);
929 }
930 
931 /**
932  * Adds the listener to the collection of listeners who will
933  * be notified when help events are generated for the control,
934  * by sending it one of the messages defined in the
935  * <code>HelpListener</code> interface.
936  *
937  * @param listener the listener which should be notified
938  *
939  * @exception IllegalArgumentException <ul>
940  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
941  * </ul>
942  * @exception SWTException <ul>
943  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
944  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
945  * </ul>
946  *
947  * @see HelpListener
948  * @see #removeHelpListener
949  */
950 public void addHelpListener (HelpListener listener) {
951   checkWidget();
952   if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
953   TypedListener typedListener = new TypedListener (listener);
954   addListener (SWT.Help, typedListener);
955 }
956 
957 /**
958  * Adds the listener to the collection of listeners who will
959  * be notified when keys are pressed and released on the system keyboard, by sending
960  * it one of the messages defined in the <code>KeyListener</code>
961  * interface.
962  *
963  * @param listener the listener which should be notified
964  *
965  * @exception IllegalArgumentException <ul>
966  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
967  * </ul>
968  * @exception SWTException <ul>
969  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
970  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
971  * </ul>
972  *
973  * @see KeyListener
974  * @see #removeKeyListener
975  */
976 public void addKeyListener(KeyListener listener) {
977   checkWidget();
978   if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
979   TypedListener typedListener = new TypedListener (listener);
980   addListener(SWT.KeyUp,typedListener);
981   addListener(SWT.KeyDown,typedListener);
982 }
983 
984 /**
985  * Adds the listener to the collection of listeners who will
986  * be notified when mouse buttons are pressed and released, by sending
987  * it one of the messages defined in the <code>MouseListener</code>
988  * interface.
989  *
990  * @param listener the listener which should be notified
991  *
992  * @exception IllegalArgumentException <ul>
993  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
994  * </ul>
995  * @exception SWTException <ul>
996  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
997  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
998  * </ul>
999  *
1000 * @see MouseListener
1001 * @see #removeMouseListener
1002 */
1003public void addMouseListener(MouseListener listener) {
1004  checkWidget();
1005  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1006  TypedListener typedListener = new TypedListener (listener);
1007  addListener(SWT.MouseDown,typedListener);
1008  addListener(SWT.MouseUp,typedListener);
1009  addListener(SWT.MouseDoubleClick,typedListener);
1010}
1011
1012/**
1013 * Adds the listener to the collection of listeners who will
1014 * be notified when the mouse moves, by sending it one of the
1015 * messages defined in the <code>MouseMoveListener</code>
1016 * interface.
1017 *
1018 * @param listener the listener which should be notified
1019 *
1020 * @exception IllegalArgumentException <ul>
1021 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1022 * </ul>
1023 * @exception SWTException <ul>
1024 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1025 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1026 * </ul>
1027 *
1028 * @see MouseMoveListener
1029 * @see #removeMouseMoveListener
1030 */
1031public void addMouseMoveListener(MouseMoveListener listener) {
1032  checkWidget();
1033  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1034  TypedListener typedListener = new TypedListener (listener);
1035  addListener(SWT.MouseMove,typedListener);
1036}
1037
1038/**
1039 * Adds the listener to the collection of listeners who will
1040 * be notified when the mouse passes or hovers over controls, by sending
1041 * it one of the messages defined in the <code>MouseTrackListener</code>
1042 * interface.
1043 *
1044 * @param listener the listener which should be notified
1045 *
1046 * @exception IllegalArgumentException <ul>
1047 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1048 * </ul>
1049 * @exception SWTException <ul>
1050 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1051 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1052 * </ul>
1053 *
1054 * @see MouseTrackListener
1055 * @see #removeMouseTrackListener
1056 */
1057public void addMouseTrackListener (MouseTrackListener listener) {
1058  checkWidget();
1059  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1060  TypedListener typedListener = new TypedListener (listener);
1061  addListener (SWT.MouseEnter,typedListener);
1062  addListener (SWT.MouseExit,typedListener);
1063  addListener (SWT.MouseHover,typedListener);
1064}
1065
1066/**
1067 * Adds the listener to the collection of listeners who will
1068 * be notified when the receiver needs to be painted, by sending it
1069 * one of the messages defined in the <code>PaintListener</code>
1070 * interface.
1071 *
1072 * @param listener the listener which should be notified
1073 *
1074 * @exception IllegalArgumentException <ul>
1075 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1076 * </ul>
1077 * @exception SWTException <ul>
1078 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1079 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1080 * </ul>
1081 *
1082 * @see PaintListener
1083 * @see #removePaintListener
1084 */
1085public void addPaintListener(PaintListener listener) {
1086  checkWidget();
1087  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1088  TypedListener typedListener = new TypedListener (listener);
1089  addListener(SWT.Paint,typedListener);
1090}
1091
1092/**
1093 * Adds the listener to the collection of listeners who will
1094 * be notified when traversal events occur, by sending it
1095 * one of the messages defined in the <code>TraverseListener</code>
1096 * interface.
1097 *
1098 * @param listener the listener which should be notified
1099 *
1100 * @exception IllegalArgumentException <ul>
1101 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1102 * </ul>
1103 * @exception SWTException <ul>
1104 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1105 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1106 * </ul>
1107 *
1108 * @see TraverseListener
1109 * @see #removeTraverseListener
1110 */
1111public void addTraverseListener (TraverseListener listener) {
1112  checkWidget();
1113  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1114  TypedListener typedListener = new TypedListener (listener);
1115  addListener (SWT.Traverse,typedListener);
1116}
1117
1118/**
1119 * Removes the listener from the collection of listeners who will
1120 * be notified when the control is moved or resized.
1121 *
1122 * @param listener the listener which should be notified
1123 *
1124 * @exception IllegalArgumentException <ul>
1125 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1126 * </ul>
1127 * @exception SWTException <ul>
1128 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1129 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1130 * </ul>
1131 *
1132 * @see ControlListener
1133 * @see #addControlListener
1134 */
1135public void removeControlListener (ControlListener listener) {
1136  checkWidget();
1137  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1138  if (eventTable == null) return;
1139  eventTable.unhook (SWT.Move, listener);
1140  eventTable.unhook (SWT.Resize, listener);
1141}
1142/**
1143 * Removes the listener from the collection of listeners who will
1144 * be notified when the control gains or loses focus.
1145 *
1146 * @param listener the listener which should be notified
1147 *
1148 * @exception IllegalArgumentException <ul>
1149 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1150 * </ul>
1151 * @exception SWTException <ul>
1152 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1153 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1154 * </ul>
1155 *
1156 * @see FocusListener
1157 * @see #addFocusListener
1158 */
1159public void removeFocusListener(FocusListener listener) {
1160  checkWidget();
1161  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1162  if (eventTable == null) return;
1163  eventTable.unhook (SWT.FocusIn, listener);
1164  eventTable.unhook (SWT.FocusOut, listener);
1165}
1166/**
1167 * Removes the listener from the collection of listeners who will
1168 * be notified when the help events are generated for the control.
1169 *
1170 * @param listener the listener which should be notified
1171 *
1172 * @exception IllegalArgumentException <ul>
1173 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1174 * </ul>
1175 * @exception SWTException <ul>
1176 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1177 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1178 * </ul>
1179 *
1180 * @see HelpListener
1181 * @see #addHelpListener
1182 */
1183public void removeHelpListener (HelpListener listener) {
1184  checkWidget();
1185  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1186  if (eventTable == null) return;
1187  eventTable.unhook (SWT.Help, listener);
1188}
1189/**
1190 * Removes the listener from the collection of listeners who will
1191 * be notified when keys are pressed and released on the system keyboard.
1192 *
1193 * @param listener the listener which should be notified
1194 *
1195 * @exception IllegalArgumentException <ul>
1196 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1197 * </ul>
1198 * @exception SWTException <ul>
1199 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1200 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1201 * </ul>
1202 *
1203 * @see KeyListener
1204 * @see #addKeyListener
1205 */
1206public void removeKeyListener(KeyListener listener) {
1207  checkWidget();
1208  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1209  if (eventTable == null) return;
1210  eventTable.unhook (SWT.KeyUp, listener);
1211  eventTable.unhook (SWT.KeyDown, listener);
1212}
1213/**
1214 * Removes the listener from the collection of listeners who will
1215 * be notified when mouse buttons are pressed and released.
1216 *
1217 * @param listener the listener which should be notified
1218 *
1219 * @exception IllegalArgumentException <ul>
1220 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1221 * </ul>
1222 * @exception SWTException <ul>
1223 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1224 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1225 * </ul>
1226 *
1227 * @see MouseListener
1228 * @see #addMouseListener
1229 */
1230public void removeMouseListener (MouseListener listener) {
1231  checkWidget();
1232  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1233  if (eventTable == null) return;
1234  eventTable.unhook (SWT.MouseDown, listener);
1235  eventTable.unhook (SWT.MouseUp, listener);
1236  eventTable.unhook (SWT.MouseDoubleClick, listener);
1237}
1238/**
1239 * Removes the listener from the collection of listeners who will
1240 * be notified when the mouse moves.
1241 *
1242 * @param listener the listener which should be notified
1243 *
1244 * @exception IllegalArgumentException <ul>
1245 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1246 * </ul>
1247 * @exception SWTException <ul>
1248 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1249 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1250 * </ul>
1251 *
1252 * @see MouseMoveListener
1253 * @see #addMouseMoveListener
1254 */
1255public void removeMouseMoveListener(MouseMoveListener listener) {
1256  checkWidget();
1257  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1258  if (eventTable == null) return;
1259  eventTable.unhook (SWT.MouseMove, listener);
1260}
1261
1262/**
1263 * Removes the listener from the collection of listeners who will
1264 * be notified when the mouse passes or hovers over controls.
1265 *
1266 * @param listener the listener which should be notified
1267 *
1268 * @exception IllegalArgumentException <ul>
1269 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1270 * </ul>
1271 * @exception SWTException <ul>
1272 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1273 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1274 * </ul>
1275 *
1276 * @see MouseTrackListener
1277 * @see #addMouseTrackListener
1278 */
1279public void removeMouseTrackListener(MouseTrackListener listener) {
1280  checkWidget();
1281  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1282  if (eventTable == null) return;
1283  eventTable.unhook (SWT.MouseEnter, listener);
1284  eventTable.unhook (SWT.MouseExit, listener);
1285  eventTable.unhook (SWT.MouseHover, listener);
1286}
1287
1288/**
1289 * Removes the listener from the collection of listeners who will
1290 * be notified when the receiver needs to be painted.
1291 *
1292 * @param listener the listener which should be notified
1293 *
1294 * @exception IllegalArgumentException <ul>
1295 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1296 * </ul>
1297 * @exception SWTException <ul>
1298 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1299 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1300 * </ul>
1301 *
1302 * @see PaintListener
1303 * @see #addPaintListener
1304 */
1305public void removePaintListener(PaintListener listener) {
1306  checkWidget();
1307  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1308  if (eventTable == null) return;
1309  eventTable.unhook(SWT.Paint, listener);
1310}
1311
1312/**
1313 * Removes the listener from the collection of listeners who will
1314 * be notified when traversal events occur.
1315 *
1316 * @param listener the listener which should be notified
1317 *
1318 * @exception IllegalArgumentException <ul>
1319 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1320 * </ul>
1321 * @exception SWTException <ul>
1322 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1323 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1324 * </ul>
1325 *
1326 * @see TraverseListener
1327 * @see #addTraverseListener
1328 */
1329public void removeTraverseListener(TraverseListener listener) {
1330  checkWidget ();
1331  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1332  if (eventTable == null) return;
1333  eventTable.unhook (SWT.Traverse, listener);
1334}
1335
1336boolean filterKey (int keyval, long /*int*/ event) {
1337  long /*int*/ imHandle = imHandle ();
1338  if (imHandle != 0) {
1339    return OS.gtk_im_context_filter_keypress (imHandle, event);
1340  }
1341  return false;
1342}
1343
1344Menu [] findMenus (Control control) {
1345  if (menu != null && this != control) return new Menu [] {menu};
1346  return new Menu [0];
1347}
1348
1349void fixChildren (Shell newShell, Shell oldShell, Decorations newDecorations, Decorations oldDecorations, Menu [] menus) {
1350  oldShell.fixShell (newShell, this);
1351  oldDecorations.fixDecorations (newDecorations, this, menus);
1352}
1353
1354/**
1355 * Forces the receiver to have the <em>keyboard focus</em>, causing
1356 * all keyboard events to be delivered to it.
1357 *
1358 * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to.
1359 *
1360 * @exception SWTException <ul>
1361 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1362 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1363 * </ul>
1364 *
1365 * @see #setFocus
1366 */
1367public boolean forceFocus () {
1368  checkWidget();
1369  Shell shell = getShell ();
1370  shell.setSavedFocus (this);
1371  if (!isEnabled () || !isVisible ()) return false;
1372  shell.bringToTop (false);
1373  return forceFocus (focusHandle ());
1374}
1375
1376boolean forceFocus (long /*int*/ focusHandle) {
1377  OS.gtk_widget_grab_focus (focusHandle);
1378  return this == display.getFocusControl();
1379}
1380
1381/**
1382 * Returns the receiver's background color.
1383 *
1384 * @return the background color
1385 *
1386 * @exception SWTException <ul>
1387 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1388 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1389 * </ul>
1390 */
1391public Color getBackground () {
1392  checkWidget();
1393  return Color.gtk_new (display, getBackgroundColor ());
1394}
1395
1396GdkColor getBackgroundColor () {
1397  return getBgColor ();
1398}
1399
1400GdkColor getBgColor () {
1401  long /*int*/ fontHandle = fontHandle ();
1402  OS.gtk_widget_realize (fontHandle);
1403  GdkColor color = new GdkColor ();
1404  OS.gtk_style_get_bg (OS.gtk_widget_get_style (fontHandle), OS.GTK_STATE_NORMAL, color);
1405  return color;
1406}
1407
1408GdkColor getBaseColor () {
1409  long /*int*/ fontHandle = fontHandle ();
1410  OS.gtk_widget_realize (fontHandle);
1411  GdkColor color = new GdkColor ();
1412  OS.gtk_style_get_base (OS.gtk_widget_get_style (fontHandle), OS.GTK_STATE_NORMAL, color);
1413  return color;
1414}
1415
1416/**
1417 * Returns the receiver's border width.
1418 *
1419 * @return the border width
1420 *
1421 * @exception SWTException <ul>
1422 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1423 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1424 * </ul>
1425 */
1426public int getBorderWidth () {
1427  checkWidget();
1428  return 0;
1429}
1430
1431/**
1432 * Returns <code>true</code> if the receiver is enabled, and
1433 * <code>false</code> otherwise. A disabled control is typically
1434 * not selectable from the user interface and draws with an
1435 * inactive or "grayed" look.
1436 *
1437 * @return the receiver's enabled state
1438 *
1439 * @exception SWTException <ul>
1440 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1441 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1442 * </ul>
1443 * 
1444 * @see #isEnabled
1445 */
1446public boolean getEnabled () {
1447  checkWidget ();
1448  return (state & DISABLED) == 0;
1449}
1450
1451/**
1452 * Returns the font that the receiver will use to paint textual information.
1453 *
1454 * @return the receiver's font
1455 *
1456 * @exception SWTException <ul>
1457 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1458 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1459 * </ul>
1460 */
1461public Font getFont () {
1462  checkWidget();
1463  if (font != null) return font;
1464  return Font.gtk_new (display, defaultFont ());
1465}
1466  
1467long /*int*/ getFontDescription () {
1468  long /*int*/ fontHandle = fontHandle ();
1469  return OS.gtk_style_get_font_desc (OS.gtk_widget_get_style (fontHandle));
1470}
1471
1472/**
1473 * Returns the foreground color that the receiver will use to draw.
1474 *
1475 * @return the receiver's foreground color
1476 *
1477 * @exception SWTException <ul>
1478 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1479 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1480 * </ul>
1481 */
1482public Color getForeground () {
1483  checkWidget();
1484  return Color.gtk_new (display, getForegroundColor ());
1485}
1486
1487GdkColor getForegroundColor () {
1488  return getFgColor ();
1489}
1490
1491GdkColor getFgColor () {
1492  long /*int*/ fontHandle = fontHandle ();
1493  OS.gtk_widget_realize (fontHandle);
1494  GdkColor color = new GdkColor ();
1495  OS.gtk_style_get_fg (OS.gtk_widget_get_style (fontHandle), OS.GTK_STATE_NORMAL, color);
1496  return color;
1497}
1498
1499Point getIMCaretPos () {
1500  return new Point (0, 0);
1501}
1502
1503GdkColor getTextColor () {
1504  long /*int*/ fontHandle = fontHandle ();
1505  OS.gtk_widget_realize (fontHandle);
1506  GdkColor color = new GdkColor ();
1507  OS.gtk_style_get_text (OS.gtk_widget_get_style (fontHandle), OS.GTK_STATE_NORMAL, color);
1508  return color;
1509}
1510
1511/**
1512 * Returns layout data which is associated with the receiver.
1513 *
1514 * @return the receiver's layout data
1515 *
1516 * @exception SWTException <ul>
1517 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1518 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1519 * </ul>
1520 */
1521public Object getLayoutData () {
1522  checkWidget();
1523  return layoutData;
1524}
1525
1526/**
1527 * Returns the receiver's pop up menu if it has one, or null
1528 * if it does not. All controls may optionally have a pop up
1529 * menu that is displayed when the user requests one for
1530 * the control. The sequence of key strokes, button presses
1531 * and/or button releases that are used to request a pop up
1532 * menu is platform specific.
1533 *
1534 * @return the receiver's menu
1535 *
1536 * @exception SWTException <ul>
1537 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1538 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1539 * </ul>
1540 */
1541public Menu getMenu () {
1542  checkWidget();
1543  return menu;
1544}
1545
1546/**
1547 * Returns the receiver's monitor.
1548 * 
1549 * @return the receiver's monitor
1550 * 
1551 * @since 3.0
1552 */
1553public Monitor getMonitor () {
1554  checkWidget();
1555  Monitor monitor = null;
1556  long /*int*/ screen = OS.gdk_screen_get_default ();
1557  if (screen != 0) {
1558    int monitorNumber = OS.gdk_screen_get_monitor_at_window (screen, paintWindow ());
1559    GdkRectangle dest = new GdkRectangle ();
1560    OS.gdk_screen_get_monitor_geometry (screen, monitorNumber, dest);
1561    monitor = new Monitor ();
1562    monitor.handle = monitorNumber;
1563    monitor.x = dest.x;
1564    monitor.y = dest.y;
1565    monitor.width = dest.width;
1566    monitor.height = dest.height;
1567    monitor.clientX = monitor.x;
1568    monitor.clientY = monitor.y;
1569    monitor.clientWidth = monitor.width;
1570    monitor.clientHeight = monitor.height;
1571  } else {
1572    monitor = display.getPrimaryMonitor ();
1573  }
1574  return monitor;
1575}
1576
1577/**
1578 * Returns the receiver's parent, which must be a <code>Composite</code>
1579 * or null when the receiver is a shell that was created with null or
1580 * a display for a parent.
1581 *
1582 * @return the receiver's parent
1583 *
1584 * @exception SWTException <ul>
1585 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1586 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1587 * </ul>
1588 */
1589public Composite getParent () {
1590  checkWidget();
1591  return parent;
1592}
1593
1594Control [] getPath () {
1595  int count = 0;
1596  Shell shell = getShell ();
1597  Control control = this;
1598  while (control != shell) {
1599    count++;
1600    control = control.parent;
1601  }
1602  control = this;
1603  Control [] result = new Control [count];
1604  while (control != shell) {
1605    result [--count] = control;
1606    control = control.parent;
1607  }
1608  return result;
1609}
1610
1611/**
1612 * Returns the receiver's shell. For all controls other than
1613 * shells, this simply returns the control's nearest ancestor
1614 * shell. Shells return themselves, even if they are children
1615 * of other shells.
1616 *
1617 * @return the receiver's shell
1618 *
1619 * @exception SWTException <ul>
1620 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1621 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1622 * </ul>
1623 *
1624 * @see #getParent
1625 */
1626public Shell getShell() {
1627  checkWidget();
1628  return _getShell();
1629}
1630Shell _getShell() {
1631  return parent._getShell();
1632}
1633
1634/**
1635 * Returns the receiver's tool tip text, or null if it has
1636 * not been set.
1637 *
1638 * @return the receiver's tool tip text
1639 *
1640 * @exception SWTException <ul>
1641 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1642 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1643 * </ul>
1644 */
1645public String getToolTipText () {
1646  checkWidget();
1647  return toolTipText;
1648}
1649/**
1650 * Returns <code>true</code> if the receiver is visible, and
1651 * <code>false</code> otherwise.
1652 * <p>
1653 * If one of the receiver's ancestors is not visible or some
1654 * other condition makes the receiver not visible, this method
1655 * may still indicate that it is considered visible even though
1656 * it may not actually be showing.
1657 * </p>
1658 *
1659 * @return the receiver's visibility state
1660 *
1661 * @exception SWTException <ul>
1662 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1663 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1664 * </ul>
1665 */
1666public boolean getVisible () {
1667  checkWidget();
1668  return OS.GTK_WIDGET_VISIBLE (topHandle ()); 
1669}
1670
1671long /*int*/ gtk_button_press_event (long /*int*/ widget, long /*int*/ event) {
1672  Shell shell = _getShell ();
1673  GdkEventButton gdkEvent = new GdkEventButton ();
1674  OS.memmove (gdkEvent, event, GdkEventButton.sizeof);
1675  if (gdkEvent.type == OS.GDK_3BUTTON_PRESS) return 0;
1676  display.dragStartX = (int) gdkEvent.x;
1677  display.dragStartY = (int) gdkEvent.y;
1678  display.dragging = false;
1679  int button = gdkEvent.button;
1680  int type = gdkEvent.type != OS.GDK_2BUTTON_PRESS ? SWT.MouseDown : SWT.MouseDoubleClick;
1681  sendMouseEvent (type, button, event);
1682  int result = 0;
1683  if ((state & MENU) != 0) {
1684    if (gdkEvent.button == 3 && gdkEvent.type == OS.GDK_BUTTON_PRESS) {
1685      if (showMenu ((int)gdkEvent.x_root, (int)gdkEvent.y_root)) {
1686        result = 1;
1687      }
1688    }
1689  }  
1690  
1691  /*
1692  * It is possible that the shell may be
1693  * disposed at this point.  If this happens
1694  * don't send the activate and deactivate
1695  * events.
1696  */  
1697  if (!shell.isDisposed ()) {
1698    shell.setActiveControl (this);
1699  }
1700  return result;
1701}
1702
1703long /*int*/ gtk_button_release_event (long /*int*/ widget, long /*int*/ event) {
1704  GdkEventButton gdkEvent = new GdkEventButton ();
1705  OS.memmove (gdkEvent, event, GdkEventButton.sizeof);
1706  sendMouseEvent (SWT.MouseUp, gdkEvent.button, event);
1707  return 0;
1708}
1709
1710long /*int*/ gtk_commit (long /*int*/ imcontext, long /*int*/ text) {
1711  if (text == 0) return 0;
1712  int length = OS.strlen (text);
1713  if (length == 0) return 0;
1714  byte [] buffer = new byte [length];
1715  OS.memmove (buffer, text, length);
1716  char [] chars = Converter.mbcsToWcs (null, buffer);
1717  sendIMKeyEvent (SWT.KeyDown, null, chars);
1718  return 0;
1719}
1720
1721long /*int*/ gtk_enter_notify_event (long /*int*/ widget, long /*int*/ event) {
1722  GdkEventCrossing gdkEvent = new GdkEventCrossing ();
1723  OS.memmove (gdkEvent, event, GdkEventCrossing.sizeof);
1724  if (gdkEvent.mode != OS.GDK_CROSSING_NORMAL) return 0;
1725  if (gdkEvent.subwindow != 0) return 0;
1726  sendMouseEvent (SWT.MouseEnter, 0, event);
1727  return 0;
1728}
1729
1730long /*int*/ gtk_event_after (long /*int*/ widget, long /*int*/ gdkEvent) {
1731  GdkEvent event = new GdkEvent ();
1732  OS.memmove (event, gdkEvent, GdkEvent.sizeof);
1733  switch (event.type) {
1734    case OS.GDK_BUTTON_PRESS: {
1735      if ((state & MENU) == 0) {
1736        GdkEventButton gdkEventButton = new GdkEventButton ();
1737        OS.memmove (gdkEventButton, gdkEvent, GdkEventButton.sizeof);
1738        if (gdkEventButton.button == 3) {
1739          showMenu ((int) gdkEventButton.x_root, (int) gdkEventButton.y_root);
1740        }
1741      }
1742      break;
1743    }
1744    case OS.GDK_FOCUS_CHANGE: {
1745      GdkEventFocus gdkEventFocus = new GdkEventFocus ();
1746      OS.memmove (gdkEventFocus, gdkEvent, GdkEventFocus.sizeof);
1747      sendFocusEvent (gdkEventFocus.in != 0 ? SWT.FocusIn : SWT.FocusOut);
1748      break;
1749    }
1750  }
1751  return 0;
1752}
1753  
1754long /*int*/ gtk_expose_event (long /*int*/ widget, long /*int*/ eventPtr) {
1755  if ((state & OBSCURED) != 0) return 0;
1756  if (!hooks (SWT.Paint) && !filters (SWT.Paint)) return 0;
1757  GdkEventExpose gdkEvent = new GdkEventExpose ();
1758  OS.memmove(gdkEvent, eventPtr, GdkEventExpose.sizeof);
1759  Event event = new Event ();
1760  event.count = gdkEvent.count;
1761  event.x = gdkEvent.area_x;
1762  event.y = gdkEvent.area_y;
1763  event.width = gdkEvent.area_width;
1764  event.height = gdkEvent.area_height;
1765  GC gc = event.gc = new GC (this);
1766  Region region = Region.gtk_new (display, gdkEvent.region);
1767  gc.setClipping (region);
1768  sendEvent (SWT.Paint, event);
1769  gc.dispose ();
1770  event.gc = null;
1771  return 0;
1772}
1773
1774long /*int*/ gtk_focus (long /*int*/ widget, long /*int*/ directionType) {
1775  /* Stop GTK traversal for every widget */
1776  return 1;
1777}
1778
1779long /*int*/ gtk_focus_in_event (long /*int*/ widget, long /*int*/ event) {
1780  // widget could be disposed at this point
1781  if (handle != 0) {
1782    Control oldControl = display.imControl;
1783    if (oldControl != this)  {
1784      if (oldControl != null && !oldControl.isDisposed ()) {
1785        long /*int*/ oldIMHandle = oldControl.imHandle ();
1786        if (oldIMHandle != 0) OS.gtk_im_context_reset (oldIMHandle);
1787      }
1788    }
1789    if (hooks (SWT.KeyDown) || hooks (SWT.KeyUp)) {
1790      long /*int*/ imHandle = imHandle ();
1791      if (imHandle != 0) OS.gtk_im_context_focus_in (imHandle);
1792    }
1793  }
1794  return 0;
1795}
1796
1797long /*int*/ gtk_focus_out_event (long /*int*/ widget, long /*int*/ event) {
1798  // widget could be disposed at this point
1799  if (handle != 0) {
1800    if (hooks (SWT.KeyDown) || hooks (SWT.KeyUp)) {
1801      long /*int*/ imHandle = imHandle ();
1802      if (imHandle != 0) {
1803        OS.gtk_im_context_focus_out (imHandle);
1804      }
1805    }
1806  }
1807  return 0;
1808}
1809
1810long /*int*/ gtk_key_press_event (long /*int*/ widget, long /*int*/ event) {
1811  if (!hasFocus ()) return 0;
1812  GdkEventKey gdkEvent = new GdkEventKey ();
1813  OS.memmove (gdkEvent, event, GdkEventKey.sizeof);
1814  
1815  if (translateMnemonic (gdkEvent.keyval, gdkEvent)) return 1;
1816  // widget could be disposed at this point
1817  if (isDisposed ()) return 0;
1818  
1819  if (filterKey (gdkEvent.keyval, event)) return 1;
1820  // widget could be disposed at this point
1821  if (isDisposed ()) return 0;  
1822  
1823  if (translateTraversal (gdkEvent)) return 1;
1824  // widget could be disposed at this point
1825  if (isDisposed ()) return 0;
1826  return sendKeyEvent (SWT.KeyDown, gdkEvent) ? 0 : 1;
1827}
1828
1829long /*int*/ gtk_key_release_event (long /*int*/ widget, long /*int*/ event) {
1830  if (!hasFocus ()) return 0;
1831  long /*int*/ imHandle = imHandle ();
1832  if (imHandle != 0) {
1833    if (OS.gtk_im_context_filter_keypress (imHandle, event)) return 1;
1834  }
1835  GdkEventKey gdkEvent = new GdkEventKey ();
1836  OS.memmove (gdkEvent, event, GdkEventKey.sizeof);
1837  return sendKeyEvent (SWT.KeyUp, gdkEvent) ? 0 : 1;
1838}
1839
1840long /*int*/ gtk_leave_notify_event (long /*int*/ widget, long /*int*/ event) {
1841  display.removeMouseHoverTimeout (handle);
1842  GdkEventCrossing gdkEvent = new GdkEventCrossing ();
1843  OS.memmove (gdkEvent, event, GdkEventCrossing.sizeof);
1844  if (gdkEvent.mode != OS.GDK_CROSSING_NORMAL) return 0;
1845  if (gdkEvent.subwindow != 0) return 0;
1846  sendMouseEvent (SWT.MouseExit, 0, event);
1847  return 0;
1848}
1849
1850long /*int*/ gtk_mnemonic_activate (long /*int*/ widget, long /*int*/ arg1) {
1851  int result = 0;
1852  long /*int*/ eventPtr = OS.gtk_get_current_event ();
1853  if (eventPtr != 0) {
1854    GdkEventKey keyEvent = new GdkEventKey ();
1855    OS.memmove (keyEvent, eventPtr, GdkEventKey.sizeof);
1856    if (keyEvent.type == OS.GDK_KEY_PRESS) {
1857      Control focusControl = display.getFocusControl ();
1858      long /*int*/ focusHandle = focusControl != null ? focusControl.focusHandle () : 0;
1859      if (focusHandle != 0) {
1860        display.mnemonicControl = this;
1861        OS.gtk_widget_event (focusHandle, eventPtr);
1862        display.mnemonicControl = null;
1863      }
1864      result = 1;
1865    }
1866    OS.gdk_event_free (eventPtr);
1867  }
1868  return result;
1869}
1870
1871long /*int*/ gtk_motion_notify_event (long /*int*/ widget, long /*int*/ event) {
1872  if (hooks (SWT.DragDetect)) {
1873    if (!display.dragging) {
1874      int []  state = new int [1];
1875      OS.gdk_event_get_state (event, state);
1876      if ((state [0] & OS.GDK_BUTTON1_MASK) != 0) {
1877        double [] px = new double [1], py = new double [1];
1878        OS.gdk_event_get_coords (event, px, py);
1879        if (OS.gtk_drag_check_threshold (handle, display.dragStartX, display.dragStartY, (int) px [0], (int) py [0])){
1880          display.dragging = true;
1881          Event e = new Event ();
1882          e.x = display.dragStartX;
1883          e.y = display.dragStartY;
1884          postEvent (SWT.DragDetect, e);
1885        }
1886      }
1887    }
1888  }
1889  if (hooks (SWT.MouseHover) || filters (SWT.MouseHover)) {
1890    display.addMouseHoverTimeout (handle);
1891  }
1892  sendMouseEvent (SWT.MouseMove, 0, event);
1893  return 0;
1894}
1895
1896long /*int*/ gtk_popup_menu (long /*int*/ widget) {
1897  if (!hasFocus()) return 0;
1898  int [] x = new int [1], y = new int [1];
1899  OS.gdk_window_get_pointer (0, x, y, null);
1900  showMenu (x [0], y [0]);
1901  return 0;
1902}
1903
1904long /*int*/ gtk_preedit_changed (long /*int*/ imcontext) {
1905  display.showIMWindow (this);
1906  return 0;
1907}
1908
1909long /*int*/ gtk_realize (long /*int*/ widget) {
1910  long /*int*/ imHandle = imHandle ();
1911  if (imHandle != 0) {
1912    long /*int*/ window = OS.GTK_WIDGET_WINDOW (paintHandle ());
1913    OS.gtk_im_context_set_client_window (imHandle, window);
1914  }
1915  return 0;
1916}
1917
1918long /*int*/ gtk_show_help (long /*int*/ widget, long /*int*/ helpType) {
1919  if (!hasFocus ()) return 0;
1920  return sendHelpEvent (helpType) ? 1 : 0;
1921}
1922
1923long /*int*/ gtk_unrealize (long /*int*/ widget) {
1924  long /*int*/ imHandle = imHandle ();
1925  if (imHandle != 0) OS.gtk_im_context_set_client_window (imHandle, 0);
1926  return 0;  
1927}
1928
1929long /*int*/ gtk_visibility_notify_event (long /*int*/ widget, long /*int*/ event) {
1930  GdkEventVisibility gdkEvent = new GdkEventVisibility ();
1931  OS.memmove (gdkEvent, event, GdkEventVisibility.sizeof);
1932  if (gdkEvent.state == OS.GDK_VISIBILITY_FULLY_OBSCURED) {
1933    state |= OBSCURED;
1934  } else {
1935    if ((state & OBSCURED) != 0) {
1936      long /*int*/ paintHandle = paintHandle ();
1937      int width = OS.GTK_WIDGET_WIDTH (paintHandle);
1938      int height = OS.GTK_WIDGET_HEIGHT (paintHandle);
1939      redrawWidget (0, 0, width, height, false);
1940    }
1941    state &= ~OBSCURED;
1942  }
1943  return 0;
1944}
1945
1946/**   
1947 * Invokes platform specific functionality to allocate a new GC handle.
1948 * <p>
1949 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
1950 * API for <code>Control</code>. It is marked public only so that it
1951 * can be shared within the packages provided by SWT. It is not
1952 * available on all platforms, and should never be called from
1953 * application code.
1954 * </p>
1955 *
1956 * @param data the platform specific GC data 
1957 * @return the platform specific GC handle
1958 */
1959public long /*int*/ internal_new_GC (GCData data) {
1960  checkWidget ();
1961  long /*int*/ window = paintWindow ();
1962  if (window == 0) SWT.error (SWT.ERROR_NO_HANDLES);
1963  long /*int*/ gdkGC = OS.gdk_gc_new (window);
1964  if (gdkGC == 0) error (SWT.ERROR_NO_HANDLES);  
1965  if (data != null) {
1966    int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
1967    if ((data.style & mask) == 0) {
1968      data.style |= style & (mask | SWT.MIRRORED);
1969    }
1970    data.drawable = window;
1971    data.device = display;
1972    data.background = getBackgroundColor ();
1973    data.foreground = getForegroundColor ();
1974    data.font = font != null ? font.handle : defaultFont (); 
1975  }  
1976  return gdkGC;
1977}
1978
1979long /*int*/ imHandle () {
1980  return 0;
1981}
1982
1983/**   
1984 * Invokes platform specific functionality to dispose a GC handle.
1985 * <p>
1986 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
1987 * API for <code>Control</code>. It is marked public only so that it
1988 * can be shared within the packages provided by SWT. It is not
1989 * available on all platforms, and should never be called from
1990 * application code.
1991 * </p>
1992 *
1993 * @param hDC the platform specific GC handle
1994 * @param data the platform specific GC data 
1995 */
1996public void internal_dispose_GC (long /*int*/ gdkGC, GCData data) {
1997  checkWidget ();
1998  OS.g_object_unref (gdkGC);
1999}
2000
2001/**
2002 * Returns <code>true</code> if the underlying operating
2003 * system supports this reparenting, otherwise <code>false</code>
2004 *
2005 * @return <code>true</code> if the widget can be reparented, otherwise <code>false</code>
2006 *
2007 * @exception SWTException <ul>
2008 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2009 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2010 * </ul>
2011 */
2012public boolean isReparentable () {
2013  checkWidget();
2014  return true;
2015}
2016boolean isShowing () {
2017  /*
2018  * This is not complete.  Need to check if the
2019  * widget is obscurred by a parent or sibling.
2020  */
2021  if (!isVisible ()) return false;
2022  Control control = this;
2023  while (control != null) {
2024    Point size = control.getSize ();
2025    if (size.x == 1 || size.y == 1) {
2026      return false;
2027    }
2028    control = control.parent;
2029  }
2030  return true;
2031}
2032boolean isTabGroup () {
2033  Control [] tabList = parent._getTabList ();
2034  if (tabList != null) {
2035    for (int i=0; i<tabList.length; i++) {
2036      if (tabList [i] == this) return true;
2037    }
2038  }
2039  int code = traversalCode (0, null);
2040  if ((code & (SWT.TRAVERSE_ARROW_PREVIOUS | SWT.TRAVERSE_ARROW_NEXT)) != 0) return false;
2041  return (code & (SWT.TRAVERSE_TAB_PREVIOUS | SWT.TRAVERSE_TAB_NEXT)) != 0;
2042}
2043boolean isTabItem () {
2044  Control [] tabList = parent._getTabList ();
2045  if (tabList != null) {
2046    for (int i=0; i<tabList.length; i++) {
2047      if (tabList [i] == this) return false;
2048    }
2049  }
2050  int code = traversalCode (0, null);
2051  return (code & (SWT.TRAVERSE_ARROW_PREVIOUS | SWT.TRAVERSE_ARROW_NEXT)) != 0;
2052}
2053
2054/**
2055 * Returns <code>true</code> if the receiver is enabled and all
2056 * of the receiver's ancestors are enabled, and <code>false</code>
2057 * otherwise. A disabled control is typically not selectable from the
2058 * user interface and draws with an inactive or "grayed" look.
2059 *
2060 * @return the receiver's enabled state
2061 *
2062 * @exception SWTException <ul>
2063 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2064 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2065 * </ul>
2066 * 
2067 * @see #getEnabled
2068 */
2069public boolean isEnabled () {
2070  checkWidget ();
2071  return getEnabled () && parent.isEnabled ();
2072}
2073
2074boolean isFocusAncestor (Control control) {
2075  while (control != null && control != this) {
2076    control = control.parent;
2077  }
2078  return control == this;
2079}
2080
2081/**
2082 * Returns <code>true</code> if the receiver has the user-interface
2083 * focus, and <code>false</code> otherwise.
2084 *
2085 * @return the receiver's focus state
2086 *
2087 * @exception SWTException <ul>
2088 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2089 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2090 * </ul>
2091 */
2092public boolean isFocusControl () {
2093  checkWidget();
2094  return hasFocus ();
2095}
2096
2097/**
2098 * Returns <code>true</code> if the receiver is visible and all
2099 * of the receiver's ancestors are visible and <code>false</code>
2100 * otherwise.
2101 *
2102 * @return the receiver's visibility state
2103 *
2104 * @exception SWTException <ul>
2105 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2106 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2107 * </ul>
2108 *
2109 * @see #getVisible
2110 */
2111public boolean isVisible () {
2112  checkWidget();
2113  return getVisible () && parent.isVisible ();
2114}
2115
2116Decorations menuShell () {
2117  return parent.menuShell ();
2118}
2119
2120boolean mnemonicHit (char key) {
2121  return false;
2122}
2123
2124boolean mnemonicMatch (char key) {
2125  return false;
2126}
2127
2128void register () {
2129  super.register ();
2130  if (fixedHandle != 0) display.addWidget (fixedHandle, this);
2131  long /*int*/ imHandle = imHandle ();
2132  if (imHandle != 0) display.addWidget (imHandle, this);
2133}
2134
2135/**
2136 * Causes the entire bounds of the receiver to be marked
2137 * as needing to be redrawn. The next time a paint request
2138 * is processed, the control will be completely painted,
2139 * including the background.
2140 *
2141 * @exception SWTException <ul>
2142 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2143 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2144 * </ul>
2145 *
2146 * @see #update
2147 * @see PaintListener
2148 * @see SWT#Paint
2149 * @see SWT#NO_BACKGROUND
2150 * @see SWT#NO_REDRAW_RESIZE
2151 * @see SWT#NO_MERGE_PAINTS
2152 */
2153public void redraw () {
2154  checkWidget();
2155  long /*int*/ paintHandle = paintHandle ();
2156  int width = OS.GTK_WIDGET_WIDTH (paintHandle);
2157  int height = OS.GTK_WIDGET_HEIGHT (paintHandle);
2158  redrawWidget (0, 0, width, height, true);
2159}
2160/**
2161 * Causes the rectangular area of the receiver specified by
2162 * the arguments to be marked as needing to be redrawn. 
2163 * The next time a paint request is processed, that area of
2164 * the receiver will be painted, including the background.
2165 * If the <code>all</code> flag is <code>true</code>, any
2166 * children of the receiver which intersect with the specified
2167 * area will also paint their intersecting areas. If the
2168 * <code>all</code> flag is <code>false</code>, the children
2169 * will not be painted.
2170 *
2171 * @param x the x coordinate of the area to draw
2172 * @param y the y coordinate of the area to draw
2173 * @param width the width of the area to draw
2174 * @param height the height of the area to draw
2175 * @param all <code>true</code> if children should redraw, and <code>false</code> otherwise
2176 *
2177 * @exception SWTException <ul>
2178 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2179 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2180 * </ul>
2181 *
2182 * @see #update
2183 * @see PaintListener
2184 * @see SWT#Paint
2185 * @see SWT#NO_BACKGROUND
2186 * @see SWT#NO_REDRAW_RESIZE
2187 * @see SWT#NO_MERGE_PAINTS
2188 */
2189public void redraw (int x, int y, int width, int height, boolean all) {
2190  checkWidget();
2191  redrawWidget (x, y, width, height, all);
2192}
2193
2194void redrawWidget (int x, int y, int width, int height, boolean all) {
2195  if ((OS.GTK_WIDGET_FLAGS (handle) & OS.GTK_REALIZED) == 0) return;
2196  long /*int*/ window = paintWindow ();
2197  GdkRectangle rect = new GdkRectangle ();
2198  rect.x = x;
2199  rect.y = y;
2200  rect.width = width;
2201  rect.height = height;
2202  OS.gdk_window_invalidate_rect (window, rect, all);
2203}
2204
2205void releaseChild () {
2206  parent.removeControl (this);
2207}
2208
2209void releaseHandle () {
2210  super.releaseHandle ();
2211  fixedHandle = 0;
2212}
2213
2214void releaseWidget () {
2215  display.removeMouseHoverTimeout (handle);
2216  super.releaseWidget ();
2217  long /*int*/ imHandle = imHandle ();
2218  if (imHandle != 0) {
2219    OS.gtk_im_context_reset (imHandle);
2220    OS.gtk_im_context_set_client_window (imHandle, 0);
2221  }
2222  if (enableWindow != 0) {
2223    OS.gdk_window_set_user_data (enableWindow, 0);
2224    OS.gdk_window_destroy (enableWindow);
2225    enableWindow = 0;
2226  }
2227  if (menu != null && !menu.isDisposed ()) {
2228    menu.dispose ();
2229  }
2230  menu = null;
2231  cursor = null;
2232  toolTipText = null;
2233  parent = null;
2234  layoutData = null;
2235  accessible = null;
2236}
2237
2238void sendFocusEvent (int type) {
2239  Shell shell = _getShell ();
2240  sendEvent (type);
2241  switch (type) {
2242    case SWT.FocusIn: {
2243      /*
2244      * It is possible that the shell may be
2245      * disposed at this point.  If this happens
2246      * don't send the activate and deactivate
2247      * events.
2248      */
2249      if (!shell.isDisposed ()) {
2250        shell.setActiveControl (this);
2251      }      
2252      break;
2253    }
2254    case SWT.FocusOut: {
2255      /*
2256      * It is possible that the shell may be
2257      * disposed at this point.  If this happens
2258      * don't send the activate and deactivate
2259      * events.
2260      */
2261      if (!shell.isDisposed ()) {
2262        Display display = shell.display;
2263        Control control = display.getFocusControl ();
2264        if (control == null || shell != control.getShell () ) {
2265          shell.setActiveControl (null);
2266        }
2267      }
2268      break;
2269    }
2270  }
2271}
2272
2273boolean sendHelpEvent (long /*int*/ helpType) {
2274  Control control = this;
2275  while (control != null) {
2276    if (control.hooks (SWT.Help)) {
2277      control.postEvent (SWT.Help);
2278      return true;
2279    }
2280    control = control.parent;
2281  }
2282  return false;
2283}
2284
2285char [] sendIMKeyEvent (int type, GdkEventKey keyEvent, char  [] chars) {
2286  int index = 0, count = 0, state = 0, time = 0;
2287  if (keyEvent == null) {
2288    long /*int*/ ptr = OS.gtk_get_current_event ();
2289    if (ptr != 0) {
2290      keyEvent = new GdkEventKey ();
2291      OS.memmove (keyEvent, ptr, GdkEventKey.sizeof);
2292      OS.gdk_event_free (ptr);
2293      switch (keyEvent.type) {
2294        case OS.GDK_KEY_PRESS:
2295        case OS.GDK_KEY_RELEASE:
2296          state = keyEvent.state;
2297          time =  keyEvent.time;
2298          break;
2299        default:
2300          keyEvent = null;
2301          break;
2302      }
2303    }
2304  }
2305  if (keyEvent == null) {
2306    int [] buffer = new int [1];
2307    OS.gtk_get_current_event_state (buffer);
2308    state = buffer [0];
2309    time = OS.gtk_get_current_event_time();
2310  }
2311  while (index < chars.length) {
2312    Event event = new Event ();
2313    event.time = time;
2314    if (keyEvent != null && keyEvent.length <= 1) {
2315      setKeyState (event, keyEvent);
2316    } else {
2317      setInputState (event, state);
2318    }
2319    event.character = chars [index];
2320    sendEvent (type, event);
2321  
2322    /*
2323    * It is possible (but unlikely), that application
2324    * code could have disposed the widget in the key
2325    * events.  If this happens, end the processing of
2326    * the key by returning null.
2327    */
2328    if (isDisposed ()) return null;
2329    if (event.doit) chars [count++] = chars [index];
2330    index++;
2331  }
2332  if (count == 0) return null;
2333  if (index != count) {
2334    char [] result = new char [count];
2335    System.arraycopy (chars, 0, result, 0, count);
2336    return result;
2337  }
2338  return chars;
2339}
2340
2341boolean sendKeyEvent (int type, GdkEventKey keyEvent) {
2342  int length = keyEvent.length;
2343  if (length <= 1) {
2344    Event event = new Event ();
2345    event.time = keyEvent.time;
2346    if (!setKeyState (event, keyEvent)) return true;
2347    sendEvent (type, event);
2348    // widget could be disposed at this point
2349  
2350    /*
2351    * It is possible (but unlikely), that application
2352    * code could have disposed the widget in the key
2353    * events.  If this happens, end the processing of
2354    * the key by returning false.
2355    */
2356    if (isDisposed ()) return false;
2357    return event.doit;
2358  }
2359  byte [] buffer = new byte [length];
2360  OS.memmove (buffer, keyEvent.string, length);
2361  char [] chars = Converter.mbcsToWcs (null, buffer);
2362  return sendIMKeyEvent (type, keyEvent, chars) != null;
2363}
2364
2365void sendMouseEvent (int type, int button, long /*int*/ eventPtr) {
2366  Event event = new Event ();
2367  event.time = OS.gdk_event_get_time (eventPtr);
2368  event.button = button;
2369  if (type == SWT.MouseMove) {
2370    GdkEventMotion gdkEvent = new GdkEventMotion ();
2371    OS.memmove (gdkEvent, eventPtr, GdkEventMotion.sizeof);
2372    if (gdkEvent.is_hint != 0) {
2373      int [] pointer_x = new int [1], pointer_y = new int [1];
2374      OS.gdk_window_get_pointer (gdkEvent.window, pointer_x, pointer_y, null);
2375      event.x = pointer_x [0];
2376      event.y = pointer_y [0];
2377    } else {
2378      int [] origin_x = new int [1], origin_y = new int [1];
2379      OS.gdk_window_get_origin (gdkEvent.window, origin_x, origin_y);  
2380      event.x = (int) (gdkEvent.x_root - origin_x [0]);
2381      event.y = (int) (gdkEvent.y_root - origin_y [0]);
2382    }
2383  } else {
2384    double [] root_x = new double [1], root_y = new double [1];
2385    OS.gdk_event_get_root_coords (eventPtr, root_x, root_y);  
2386    long /*int*/ window = OS.GTK_WIDGET_WINDOW (eventHandle ());
2387    int [] origin_x = new int [1], origin_y = new int [1];
2388    OS.gdk_window_get_origin (window, origin_x, origin_y);
2389    event.x = (int)(root_x [0] - origin_x [0]);
2390    event.y = (int)(root_y [0] - origin_y [0]);
2391  }
2392  int [] state = new int [1];
2393  OS.gdk_event_get_state (eventPtr, state);
2394  setInputState (event, state [0]);
2395  postEvent (type, event);
2396}
2397
2398/**
2399 * Sets the receiver's background color to the color specified
2400 * by the argument, or to the default system color for the control
2401 * if the argument is null.
2402 *
2403 * @param color the new color (or null)
2404 *
2405 * @exception IllegalArgumentException <ul>
2406 *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 
2407 * </ul>
2408 * @exception SWTException <ul>
2409 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2410 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2411 * </ul>
2412 */
2413public void setBackground (Color color) {
2414  checkWidget();
2415  GdkColor gdkColor = null;
2416  if (color != null) {
2417    if (color.isDisposed ()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
2418    gdkColor = color.handle;
2419  }
2420  boolean set = false;
2421  if (gdkColor == null) {
2422    long /*int*/ style = OS.gtk_widget_get_modifier_style (handle);
2423    set = (OS.gtk_rc_style_get_color_flags (style, OS.GTK_STATE_NORMAL) & OS.GTK_RC_BG) != 0;
2424  } else {
2425    GdkColor oldColor = getBackgroundColor ();
2426    set = oldColor.pixel != gdkColor.pixel;
2427  }
2428  if (set) setBackgroundColor (gdkColor);
2429}
2430
2431void setBackgroundColor (long /*int*/ handle, GdkColor color) {
2432  int index = OS.GTK_STATE_NORMAL;
2433  long /*int*/ style = OS.gtk_widget_get_modifier_style (handle);
2434  long /*int*/ ptr = OS.gtk_rc_style_get_bg_pixmap_name (style, index);
2435  if (ptr != 0) OS.g_free (ptr);
2436  String name = color == null ? "<parent>" : "<none>";
2437  byte[] buffer = Converter.wcsToMbcs (null, name, true);
2438  ptr = OS.g_malloc (buffer.length);
2439  OS.memmove (ptr, buffer, buffer.length);
2440  OS.gtk_rc_style_set_bg_pixmap_name (style, index, ptr);
2441  OS.gtk_rc_style_set_bg (style, index, color);
2442  int flags = OS.gtk_rc_style_get_color_flags (style, index);
2443  flags = (color == null) ? flags & ~OS.GTK_RC_BG : flags | OS.GTK_RC_BG;
2444  OS.gtk_rc_style_set_color_flags (style, index, flags);
2445  OS.gtk_widget_modify_style (handle, style);
2446}
2447void setBackgroundColor (GdkColor color) {
2448  setBackgroundColor(handle, color);
2449}
2450
2451/**
2452 * If the argument is <code>true</code>, causes the receiver to have
2453 * all mouse events delivered to it until the method is called with
2454 * <code>false</code> as the argument.
2455 *
2456 * @param capture <code>true</code> to capture the mouse, and <code>false</code> to release it
2457 *
2458 * @exception SWTException <ul>
2459 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2460 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2461 * </ul>
2462 */
2463public void setCapture (boolean capture) {
2464  checkWidget();
2465  /* FIXME !!!!! */
2466  /*
2467  if (capture) {
2468    OS.gtk_widget_grab_focus (handle);
2469  } else {
2470    OS.gtk_widget_grab_default (handle);
2471  }
2472  */
2473}
2474/**
2475 * Sets the receiver's cursor to the cursor specified by the
2476 * argument, or to the default cursor for that kind of control
2477 * if the argument is null.
2478 * <p>
2479 * When the mouse pointer passes over a control its appearance
2480 * is changed to match the control's cursor.
2481 * </p>
2482 *
2483 * @param cursor the new cursor (or null)
2484 *
2485 * @exception IllegalArgumentException <ul>
2486 *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 
2487 * </ul>
2488 * @exception SWTException <ul>
2489 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2490 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2491 * </ul>
2492 */
2493public void setCursor (Cursor cursor) {
2494  checkWidget();
2495  if (cursor != null && cursor.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
2496  this.cursor = cursor;
2497  setCursor (cursor != null ? cursor.handle : 0);
2498}
2499
2500void setCursor (long /*int*/ cursor) {
2501  long /*int*/ window = paintWindow ();
2502  if (window != 0) {
2503    OS.gdk_window_set_cursor (window, cursor);
2504    OS.gdk_flush ();
2505  }
2506}
2507
2508/**
2509 * Enables the receiver if the argument is <code>true</code>,
2510 * and disables it otherwise. A disabled control is typically
2511 * not selectable from the user interface and draws with an
2512 * inactive or "grayed" look.
2513 *
2514 * @param enabled the new enabled state
2515 *
2516 * @exception SWTException <ul>
2517 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2518 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2519 * </ul>
2520 */
2521public void setEnabled (boolean enabled) {
2522  checkWidget();
2523  if (((state & DISABLED) == 0) == enabled) return;
2524  Control control = null;
2525  boolean fixFocus = false;
2526  if (!enabled) {
2527    control = display.getFocusControl ();
2528    fixFocus = isFocusAncestor (control);
2529  }
2530  if (enabled) {
2531    state &= ~DISABLED;
2532  } else {
2533    state |= DISABLED;
2534  }
2535  enableWidget (enabled);
2536  if (enabled) {
2537    if (enableWindow != 0) {
2538      OS.gdk_window_set_user_data (enableWindow, 0);
2539      OS.gdk_window_destroy (enableWindow);
2540      enableWindow = 0;
2541    }
2542  } else {
2543    OS.gtk_widget_realize (handle);
2544    long /*int*/ parentHandle = parent.parentingHandle ();
2545    long /*int*/ window = OS.GTK_WIDGET_WINDOW (parentHandle);
2546    Rectangle rect = getBounds ();
2547    GdkWindowAttr attributes = new GdkWindowAttr ();
2548    attributes.x = rect.x;
2549    attributes.y = rect.y;
2550    attributes.width = rect.width;
2551    attributes.height = rect.height;
2552    attributes.event_mask = (0xFFFFFFFF & ~OS.ExposureMask);
2553    attributes.wclass = OS.GDK_INPUT_ONLY;
2554    attributes.window_type = OS.GDK_WINDOW_CHILD;
2555    enableWindow = OS.gdk_window_new (window, attributes, OS.GDK_WA_X | OS.GDK_WA_Y);
2556    if (enableWindow != 0) {
2557      long /*int*/ topHandle = topHandle ();
2558      OS.gdk_window_set_user_data (enableWindow, parentHandle);
2559      if (!OS.GDK_WINDOWING_X11 ()) {
2560        OS.gdk_window_raise (enableWindow);
2561      } else {
2562        long /*int*/ topWindow = OS.GTK_WIDGET_WINDOW (topHandle);      
2563        long /*int*/ xDisplay = OS.gdk_x11_drawable_get_xdisplay (topWindow);
2564        long /*int*/ xWindow = OS.gdk_x11_drawable_get_xid (enableWindow);
2565        int xScreen = OS.XDefaultScreen (xDisplay);
2566        int flags = OS.CWStackMode | OS.CWSibling;      
2567        XWindowChanges changes = new XWindowChanges ();
2568        changes.sibling = OS.gdk_x11_drawable_get_xid (topWindow);
2569        changes.stack_mode = OS.Above;
2570        OS.XReconfigureWMWindow (xDisplay, xWindow, xScreen, flags, changes);
2571      }
2572      if (OS.GTK_WIDGET_VISIBLE (topHandle)) OS.gdk_window_show (enableWindow);
2573    }
2574  }
2575  if (fixFocus) fixFocus (control);
2576}
2577
2578/**
2579 * Causes the receiver to have the <em>keyboard focus</em>, 
2580 * such that all keyboard events will be delivered to it.  Focus
2581 * reassignment will respect applicable platform constraints.
2582 *
2583 * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to.
2584 *
2585 * @exception SWTException <ul>
2586 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2587 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2588 * </ul>
2589 *
2590 * @see #forceFocus
2591 */
2592public boolean setFocus () {
2593  checkWidget();
2594  if ((style & SWT.NO_FOCUS) != 0) return false;
2595  return forceFocus ();
2596}
2597
2598/**
2599 * Sets the font that the receiver will use to paint textual information
2600 * to the font specified by the argument, or to the default font for that
2601 * kind of control if the argument is null.
2602 *
2603 * @param font the new font (or null)
2604 *
2605 * @exception IllegalArgumentException <ul>
2606 *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 
2607 * </ul>
2608 * @exception SWTException <ul>
2609 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2610 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2611 * </ul>
2612 */
2613public void setFont (Font font) {
2614  checkWidget();
2615  this.font = font;
2616  long /*int*/ fontDesc;
2617  if (font == null) {
2618    fontDesc = defaultFont ();
2619  } else {
2620    if (font.isDisposed ()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
2621    fontDesc = font.handle;
2622  }
2623  setFontDescription (fontDesc);
2624}
2625  
2626void setFontDescription (long /*int*/ font) {
2627  OS.gtk_widget_modify_font (handle, font);
2628}
2629
2630/**
2631 * Sets the receiver's foreground color to the color specified
2632 * by the argument, or to the default system color for the control
2633 * if the argument is null.
2634 *
2635 * @param color the new color (or null)
2636 *
2637 * @exception IllegalArgumentException <ul>
2638 *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 
2639 * </ul>
2640 * @exception SWTException <ul>
2641 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2642 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2643 * </ul>
2644 */
2645public void setForeground (Color color) {
2646  checkWidget();
2647  GdkColor gdkColor = null;
2648  if (color != null) {
2649    if (color.isDisposed ()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
2650    gdkColor = color.handle;
2651  }
2652  boolean set = false;
2653  if (gdkColor == null) {
2654    long /*int*/ style = OS.gtk_widget_get_modifier_style (handle);
2655    set = (OS.gtk_rc_style_get_color_flags (style, OS.GTK_STATE_NORMAL) & OS.GTK_RC_FG) != 0;
2656  } else {
2657    GdkColor oldColor = getForegroundColor ();
2658    set = oldColor.pixel != gdkColor.pixel;
2659  }
2660  if (set) setForegroundColor (gdkColor);
2661}
2662
2663void setForegroundColor (GdkColor color) {
2664  OS.gtk_widget_modify_fg (handle, OS.GTK_STATE_NORMAL, color);
2665}
2666
2667void setInitialSize () {
2668  resizeHandle (1, 1);
2669  /*
2670  * Force the container to allocate the size of its children.
2671  */
2672  long /*int*/ parentHandle = parent.parentingHandle ();
2673  OS.gtk_container_resize_children (parentHandle);
2674}
2675
2676/**
2677 * Sets the receiver's pop up menu to the argument.
2678 * All controls may optionally have a pop up
2679 * menu that is displayed when the user requests one for
2680 * the control. The sequence of key strokes, button presses
2681 * and/or button releases that are used to request a pop up
2682 * menu is platform specific.
2683 *
2684 * @param menu the new pop up menu
2685 *
2686 * @exception IllegalArgumentException <ul>
2687 *    <li>ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu</li>
2688 *    <li>ERROR_INVALID_PARENT - if the menu is not in the same widget tree</li>
2689 *    <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed</li> 
2690 * </ul>
2691 * @exception SWTException <ul>
2692 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2693 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2694 * </ul>
2695 */
2696public void setMenu (Menu menu) {
2697  checkWidget();
2698  if (menu != null) {
2699    if ((menu.style & SWT.POP_UP) == 0) {
2700      error (SWT.ERROR_MENU_NOT_POP_UP);
2701    }
2702    if (menu.parent != menuShell ()) {
2703      error (SWT.ERROR_INVALID_PARENT);
2704    }
2705  }
2706  this.menu = menu;
2707}
2708
2709/**
2710 * Changes the parent of the widget to be the one provided if
2711 * the underlying operating system supports this feature.
2712 * Answers <code>true</code> if the parent is successfully changed.
2713 *
2714 * @param parent the new parent for the control.
2715 * @return <code>true</code> if the parent is changed and <code>false</code> otherwise.
2716 *
2717 * @exception IllegalArgumentException <ul>
2718 *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> 
2719 * </ul>
2720 * @exception SWTError <ul>
2721 *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
2722 *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
2723 *  </ul>
2724 */
2725public boolean setParent (Composite parent) {
2726  checkWidget ();
2727  if (parent == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
2728  if (parent.isDisposed()) SWT.error (SWT.ERROR_INVALID_ARGUMENT);
2729  if (this.parent == parent) return true;
2730  if (!isReparentable ()) return false;
2731  releaseChild ();
2732  Shell newShell = parent.getShell (), oldShell = getShell ();
2733  Decorations newDecorations = parent.menuShell (), oldDecorations = menuShell ();
2734  Menu [] menus = oldShell.findMenus (this);
2735  if (oldShell != newShell || oldDecorations != newDecorations) {
2736    fixChildren (newShell, oldShell, newDecorations, oldDecorations, menus);
2737    newDecorations.fixAccelGroup ();
2738    oldDecorations.fixAccelGroup ();
2739  }
2740  long /*int*/ topHandle = topHandle ();
2741  long /*int*/ newParent = parent.parentingHandle();
2742  int x = OS.GTK_WIDGET_X (topHandle);
2743  int y = OS.GTK_WIDGET_Y (topHandle);
2744  OS.gtk_widget_reparent (topHandle, newParent);
2745  OS.gtk_fixed_move (newParent, topHandle, x, y);
2746  this.parent = parent;
2747  setZOrder (null, false);
2748  return true;
2749}
2750
2751boolean setRadioSelection (boolean value) {
2752  return false;
2753}
2754
2755/**
2756 * If the argument is <code>false</code>, causes subsequent drawing
2757 * operations in the receiver to be ignored. No drawing of any kind
2758 * can occur in the receiver until the flag is set to true.
2759 * Graphics operations that occurred while the flag was
2760 * <code>false</code> are lost. When the flag is set to <code>true</code>,
2761 * the entire widget is marked as needing to be redrawn.
2762 * <p>
2763 * Note: This operation is a hint and may not be supported on some
2764 * platforms or for some widgets.
2765 * </p>
2766 *
2767 * @param redraw the new redraw state
2768 *
2769 * @exception SWTException <ul>
2770 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2771 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2772 * </ul>
2773 * 
2774 * @see #redraw
2775 * @see #update
2776 */
2777public void setRedraw (boolean redraw) {
2778  checkWidget();
2779  if (redraw) {
2780    if (--drawCount == 0) {
2781      if (redrawWindow != 0) {
2782        long /*int*/ window = paintWindow ();
2783        OS.gdk_window_destroy (redrawWindow);
2784        OS.gdk_window_set_events (window, OS.gtk_widget_get_events (paintHandle ()));
2785        redrawWindow = 0;
2786      }
2787    }
2788  } else {
2789    if (drawCount++ == 0) {
2790      if ((OS.GTK_WIDGET_FLAGS (handle) & OS.GTK_REALIZED) != 0) {
2791        long /*int*/ window = paintWindow ();
2792        Rectangle rect = getBounds ();
2793        GdkWindowAttr attributes = new GdkWindowAttr ();
2794        attributes.width = rect.width;
2795        attributes.height = rect.height;
2796        attributes.event_mask = OS.GDK_EXPOSURE_MASK;
2797        attributes.window_type = OS.GDK_WINDOW_CHILD;
2798        redrawWindow = OS.gdk_window_new (window, attributes, 0);
2799        if (redrawWindow != 0) {
2800          int mouseMask = OS.GDK_BUTTON_PRESS_MASK | OS.GDK_BUTTON_RELEASE_MASK |
2801            OS.GDK_ENTER_NOTIFY_MASK | OS.GDK_LEAVE_NOTIFY_MASK |
2802            OS.GDK_POINTER_MOTION_MASK | OS.GDK_POINTER_MOTION_HINT_MASK |
2803            OS.GDK_BUTTON_MOTION_MASK | OS.GDK_BUTTON1_MOTION_MASK | 
2804            OS.GDK_BUTTON2_MOTION_MASK | OS.GDK_BUTTON3_MOTION_MASK;
2805          OS.gdk_window_set_events (window, OS.gdk_window_get_events (window) & ~mouseMask);
2806          OS.gdk_window_set_back_pixmap (redrawWindow, 0, false);
2807          OS.gdk_window_raise (redrawWindow);
2808          OS.gdk_window_show (redrawWindow);
2809        }
2810      }
2811    }
2812  }
2813}
2814
2815boolean setTabGroupFocus (boolean next) {
2816  return setTabItemFocus (next);
2817}
2818boolean setTabItemFocus (boolean next) {
2819  if (!isShowing ()) return false;
2820  return forceFocus ();
2821}
2822
2823/**
2824 * Sets the receiver's tool tip text to the argument, which
2825 * may be null indicating that no tool tip text should be shown.
2826 *
2827 * @param string the new tool tip text (or null)
2828 *
2829 * @exception SWTException <ul>
2830 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2831 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2832 * </ul>
2833 */
2834public void setToolTipText (String string) {
2835  checkWidget();
2836  Shell shell = _getShell ();
2837  shell.setToolTipText (eventHandle (), toolTipText = string);
2838}
2839
2840/**
2841 * Marks the receiver as visible if the argument is <code>true</code>,
2842 * and marks it invisible otherwise. 
2843 * <p>
2844 * If one of the receiver's ancestors is not visible or some
2845 * other condition makes the receiver not visible, marking
2846 * it visible may not actually cause it to be displayed.
2847 * </p>
2848 *
2849 * @param visible the new visibility state
2850 *
2851 * @exception SWTException <ul>
2852 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2853 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2854 * </ul>
2855 */
2856public void setVisible (boolean visible) {
2857  checkWidget();
2858  long /*int*/ topHandle = topHandle();
2859  if ((OS.GTK_WIDGET_VISIBLE (topHandle) == visible)) return;
2860  if (visible) {
2861    /*
2862    * It is possible (but unlikely), that application
2863    * code could have disposed the widget in the show
2864    * event.  If this happens, just return.
2865    */
2866    sendEvent (SWT.Show);
2867    if (isDisposed ()) return;
2868    if (enableWindow != 0) OS.gdk_window_show (enableWindow);
2869    OS.gtk_widget_show (topHandle);
2870  } else {
2871    /*
2872    * Bug in GTK.  Invoking gtk_widget_hide() on a widget that has
2873    * focus causes a focus_out_event to be sent. If the client disposes
2874    * the widget inside the event, GTK GP's.  The fix is to reassign focus
2875    * before hiding the widget.
2876    * 
2877    * NOTE: In order to stop the same widget from taking focus,
2878    * temporarily clear and set the GTK_VISIBLE flag.
2879    */    
2880    Control control = null;
2881    boolean fixFocus = false;
2882    if (!visible) {
2883      control = display.getFocusControl ();
2884      fixFocus = isFocusAncestor (control);
2885    }
2886    if (fixFocus) {
2887      int flags = OS.GTK_WIDGET_FLAGS (topHandle);
2888      OS.GTK_WIDGET_UNSET_FLAGS (topHandle, OS.GTK_VISIBLE);
2889      fixFocus (control);
2890      if (isDisposed ()) return;
2891      if ((flags & OS.GTK_VISIBLE) != 0) {
2892        OS.GTK_WIDGET_SET_FLAGS (topHandle, OS.GTK_VISIBLE);
2893      }
2894    }
2895    OS.gtk_widget_hide (topHandle);
2896    if (enableWindow != 0) OS.gdk_window_hide (enableWindow);
2897    sendEvent (SWT.Hide);
2898  }
2899}
2900
2901void setZOrder (Control sibling, boolean above) {
2902   setZOrder (sibling, above, true);
2903}
2904
2905void setZOrder (Control sibling, boolean above, boolean fixChildren) {
2906  long /*int*/ topHandle = topHandle ();
2907  long /*int*/ siblingHandle = sibling != null ? sibling.topHandle () : 0;
2908  long /*int*/ window = OS.GTK_WIDGET_WINDOW (topHandle);
2909  if (window != 0) {
2910    long /*int*/ siblingWindow = 0;
2911    if (sibling != null) {
2912      if (above && sibling.enableWindow != 0) {
2913        siblingWindow = enableWindow;
2914      } else {
2915        siblingWindow = OS.GTK_WIDGET_WINDOW (siblingHandle);
2916      }
2917    }
2918    long /*int*/ redrawWindow = fixChildren ? parent.redrawWindow : 0;
2919    if (!OS.GDK_WINDOWING_X11 () || (siblingWindow == 0 && redrawWindow == 0)) {
2920      if (above) {
2921        OS.gdk_window_raise (window);
2922        if (redrawWindow != 0) OS.gdk_window_raise (redrawWindow);
2923        if (enableWindow != 0) OS.gdk_window_raise (enableWindow);
2924      } else {
2925        if (enableWindow != 0) OS.gdk_window_lower (enableWindow);
2926        OS.gdk_window_lower (window);
2927      }
2928    } else {
2929      XWindowChanges changes = new XWindowChanges ();
2930      changes.sibling = OS.gdk_x11_drawable_get_xid (siblingWindow != 0 ? siblingWindow : redrawWindow);
2931      changes.stack_mode = above ? OS.Above : OS.Below;
2932      if (redrawWindow != 0 && siblingWindow == 0) changes.stack_mode = OS.Below;
2933      long /*int*/ xDisplay = OS.gdk_x11_drawable_get_xdisplay (window);
2934      long /*int*/ xWindow = OS.gdk_x11_drawable_get_xid (window);
2935      int xScreen = OS.XDefaultScreen (xDisplay);
2936      int flags = OS.CWStackMode | OS.CWSibling;
2937      /*
2938      * Feature in X. If the receiver is a top level, XConfigureWindow ()
2939      * will fail (with a BadMatch error) for top level shells because top
2940      * level shells are reparented by the window manager and do not share
2941      * the same X window parent.  This is the correct behavior but it is
2942      * unexpected.  The fix is to use XReconfigureWMWindow () instead.
2943      * When the receiver is not a top level shell, XReconfigureWMWindow ()
2944      * behaves the same as XConfigureWindow ().
2945      */
2946      OS.XReconfigureWMWindow (xDisplay, xWindow, xScreen, flags, changes);      
2947      if (enableWindow != 0) {
2948        changes.sibling = OS.gdk_x11_drawable_get_xid (window);
2949        changes.stack_mode = OS.Above;
2950        xWindow = OS.gdk_x11_drawable_get_xid (enableWindow);
2951        OS.XReconfigureWMWindow (xDisplay, xWindow, xScreen, flags, changes);
2952      }
2953    }
2954  }
2955  if (fixChildren) {
2956    if (above) {
2957      parent.moveAbove (topHandle, siblingHandle);
2958    } else {
2959      parent.moveBelow (topHandle, siblingHandle);
2960    }
2961  }
2962  /*
2963  * Make sure that the parent handle is on the bottom of the stack
2964  * when the parent children are siblings of the parent handle.
2965  */
2966  if (!above && fixChildren && parent.parentingHandle () == parent.fixedHandle) {
2967    window = OS.GTK_WIDGET_WINDOW (parent.handle);
2968    if (window != 0) OS.gdk_window_lower (window);
2969  }
2970}
2971
2972boolean showMenu (int x, int y) {
2973  Event event = new Event ();
2974  event.x = x;
2975  event.y = y;
2976  sendEvent (SWT.MenuDetect, event);
2977  if (event.doit) {
2978    if (menu != null && !menu.isDisposed ()) {
2979      menu.createIMMenu (imHandle());
2980      if (event.x != x || event.y != y) {
2981        menu.setLocation (event.x, event.y);
2982      }
2983      menu.setVisible (true);
2984      return true;
2985    }
2986  }
2987  return false;
2988}
2989
2990void sort (int [] items) {
2991  /* Shell Sort from K&R, pg 108 */
2992  int length = items.length;
2993  for (int gap=length/2; gap>0; gap/=2) {
2994    for (int i=gap; i<length; i++) {
2995      for (int j=i-gap; j>=0; j-=gap) {
2996           if (items [j] <= items [j + gap]) {
2997          int swap = items [j];
2998          items [j] = items [j + gap];
2999          items [j + gap] = swap;
3000           }
3001        }
3002      }
3003  }
3004}
3005
3006/**
3007 * Based on the argument, perform one of the expected platform
3008 * traversal action. The argument should be one of the constants:
3009 * <code>SWT.TRAVERSE_ESCAPE</code>, <code>SWT.TRAVERSE_RETURN</code>, 
3010 * <code>SWT.TRAVERSE_TAB_NEXT</code>, <code>SWT.TRAVERSE_TAB_PREVIOUS</code>, 
3011 * <code>SWT.TRAVERSE_ARROW_NEXT</code> and <code>SWT.TRAVERSE_ARROW_PREVIOUS</code>.
3012 *
3013 * @param traversal the type of traversal
3014 * @return true if the traversal succeeded
3015 *
3016 * @exception SWTException <ul>
3017 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3018 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3019 * </ul>
3020 */
3021public boolean traverse (int traversal) {
3022  checkWidget ();
3023  Event event = new Event ();
3024  event.doit = true;
3025  event.detail = traversal;
3026  return traverse (event);
3027}
3028
3029boolean translateMnemonic (Event event, Control control) {
3030  if (control == this) return false;
3031  if (!isVisible () || !isEnabled ()) return false;
3032  event.doit = this == display.mnemonicControl || mnemonicMatch (event.character);
3033  return traverse (event);
3034}
3035
3036boolean translateMnemonic (int keyval, GdkEventKey gdkEvent) {
3037  int key = OS.gdk_keyval_to_unicode (keyval);
3038  if (key < 0x20) return false;
3039  if (gdkEvent.state == 0) {
3040    int code = traversalCode (keyval, gdkEvent);
3041    if ((code & SWT.TRAVERSE_MNEMONIC) == 0) return false;
3042  } else {
3043    Shell shell = _getShell ();
3044    int mask = OS.GDK_CONTROL_MASK | OS.GDK_SHIFT_MASK | OS.GDK_MOD1_MASK;
3045    if ((gdkEvent.state & mask) != OS.gtk_window_get_mnemonic_modifier (shell.shellHandle)) return false;
3046  }
3047  Decorations shell = menuShell ();
3048  if (shell.isVisible () && shell.isEnabled ()) {
3049    Event event = new Event ();
3050    event.detail = SWT.TRAVERSE_MNEMONIC;
3051    if (setKeyState (event, gdkEvent)) {
3052      return translateMnemonic (event, null) || shell.translateMnemonic (event, this);
3053    }
3054  }
3055  return false;
3056}
3057
3058boolean translateTraversal (GdkEventKey keyEvent) {
3059  int detail = SWT.TRAVERSE_NONE;
3060  int key = keyEvent.keyval;
3061  int code = traversalCode (key, keyEvent);
3062  boolean all = false;
3063  switch (key) {
3064    case OS.GDK_Escape: {
3065      all = true;
3066      detail = SWT.TRAVERSE_ESCAPE;
3067      break;
3068    }
3069    case OS.GDK_KP_Enter:
3070    case OS.GDK_Return: {
3071      all = true;
3072      detail = SWT.TRAVERSE_RETURN;
3073      break;
3074    }
3075    case OS.GDK_ISO_Left_Tab: 
3076    case OS.GDK_Tab: {
3077      boolean next = (keyEvent.state & OS.GDK_SHIFT_MASK) == 0;
3078      detail = next ? SWT.TRAVERSE_TAB_NEXT : SWT.TRAVERSE_TAB_PREVIOUS;
3079      break;
3080    }
3081    case OS.GDK_Up:
3082    case OS.GDK_Left: 
3083    case OS.GDK_Down:
3084    case OS.GDK_Right: {
3085      boolean next = key == OS.GDK_Down || key == OS.GDK_Right;
3086      detail = next ? SWT.TRAVERSE_ARROW_NEXT : SWT.TRAVERSE_ARROW_PREVIOUS;
3087      break;
3088    }
3089    case OS.GDK_Page_Up:
3090    case OS.GDK_Page_Down: {
3091      all = true;
3092      if ((keyEvent.state & OS.GDK_CONTROL_MASK) == 0) return false;
3093      detail = key == OS.GDK_Page_Down ? SWT.TRAVERSE_PAGE_NEXT : SWT.TRAVERSE_PAGE_PREVIOUS;
3094      break;
3095    }
3096    default:
3097      return false;
3098  }
3099  Event event = new Event ();
3100  event.doit = (code & detail) != 0;
3101  event.detail = detail;
3102  event.time = keyEvent.time;
3103  if (!setKeyState (event, keyEvent)) return false;
3104  Shell shell = getShell ();
3105  Control control = this;
3106  do {
3107    if (control.traverse (event)) return true;
3108    if (!event.doit && control.hooks (SWT.Traverse)) return false;
3109    if (control == shell) return false;
3110    control = control.parent;
3111  } while (all && control != null);
3112  return false;
3113}
3114
3115int traversalCode (int key, GdkEventKey event) {
3116  int code = SWT.TRAVERSE_RETURN | SWT.TRAVERSE_TAB_NEXT |  SWT.TRAVERSE_TAB_PREVIOUS | SWT.TRAVERSE_PAGE_NEXT | SWT.TRAVERSE_PAGE_PREVIOUS;
3117  Shell shell = getShell ();
3118  if (shell.parent != null) code |= SWT.TRAVERSE_ESCAPE;
3119  return code;
3120}
3121
3122boolean traverse (Event event) {
3123  /*
3124  * It is possible (but unlikely), that application
3125  * code could have disposed the widget in the traverse
3126  * event.  If this happens, return true to stop further
3127  * event processing.
3128  */  
3129  sendEvent (SWT.Traverse, event);
3130  if (isDisposed ()) return true;
3131  if (!event.doit) return false;
3132  switch (event.detail) {
3133    case SWT.TRAVERSE_NONE:      return true;
3134    case SWT.TRAVERSE_ESCAPE:      return traverseEscape ();
3135    case SWT.TRAVERSE_RETURN:      return traverseReturn ();
3136    case SWT.TRAVERSE_TAB_NEXT:    return traverseGroup (true);
3137    case SWT.TRAVERSE_TAB_PREVIOUS:  return traverseGroup (false);
3138    case SWT.TRAVERSE_ARROW_NEXT:    return traverseItem (true);
3139    case SWT.TRAVERSE_ARROW_PREVIOUS:  return traverseItem (false);
3140    case SWT.TRAVERSE_MNEMONIC:    return traverseMnemonic (event.character);  
3141    case SWT.TRAVERSE_PAGE_NEXT:    return traversePage (true);
3142    case SWT.TRAVERSE_PAGE_PREVIOUS:  return traversePage (false);
3143  }
3144  return false;
3145}
3146
3147boolean traverseEscape () {
3148  return false;
3149}
3150
3151boolean traverseGroup (boolean next) {
3152  Control root = computeTabRoot ();
3153  Control group = computeTabGroup ();
3154  Control [] list = root.computeTabList ();
3155  int length = list.length;
3156  int index = 0;
3157  while (index < length) {
3158    if (list [index] == group) break;
3159    index++;
3160  }
3161  /*
3162  * It is possible (but unlikely), that application
3163  * code could have disposed the widget in focus in
3164  * or out events.  Ensure that a disposed widget is
3165  * not accessed.
3166  */
3167  if (index == length) return false;
3168  int start = index, offset = (next) ? 1 : -1;
3169  while ((index = ((index + offset + length) % length)) != start) {
3170    Control control = list [index];
3171    if (!control.isDisposed () && control.setTabGroupFocus (next)) {
3172      return true;
3173    }
3174  }
3175  if (group.isDisposed ()) return false;
3176  return group.setTabGroupFocus (next);
3177}
3178
3179boolean traverseItem (boolean next) {
3180  Control [] children = parent._getChildren ();
3181  int length = children.length;
3182  int index = 0;
3183  while (index < length) {
3184    if (children [index] == this) break;
3185    index++;
3186  }
3187  /*
3188  * It is possible (but unlikely), that application
3189  * code could have disposed the widget in focus in
3190  * or out events.  Ensure that a disposed widget is
3191  * not accessed.
3192  */
3193  if (index == length) return false;
3194  int start = index, offset = (next) ? 1 : -1;
3195  while ((index = (index + offset + length) % length) != start) {
3196    Control child = children [index];
3197    if (!child.isDisposed () && child.isTabItem ()) {
3198      if (child.setTabItemFocus (next)) return true;
3199    }
3200  }
3201  return false;
3202}
3203
3204boolean traverseReturn () {
3205  return false;
3206}
3207
3208boolean traversePage (boolean next) {
3209  return false;
3210}
3211
3212boolean traverseMnemonic (char key) {
3213  return mnemonicHit (key);
3214}
3215
3216/**
3217 * Forces all outstanding paint requests for the widget
3218 * to be processed before this method returns.
3219 *
3220 * @exception SWTException <ul>
3221 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3222 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3223 * </ul>
3224 *
3225 * @see #redraw
3226 * @see PaintListener
3227 * @see SWT#Paint
3228 */
3229public void update () {
3230  checkWidget ();
3231  update (false);
3232}
3233
3234void update (boolean all) {
3235//  checkWidget();
3236  if ((OS.GTK_WIDGET_FLAGS (handle) & OS.GTK_REALIZED) == 0) return;
3237  long /*int*/ window = paintWindow ();
3238  display.flushExposes (window, all);
3239  OS.gdk_window_process_updates (window, all);
3240}
3241}