diff dwt/widgets/Widget.d @ 213:36f5cb12e1a2

Update to SWT 3.4M7
author Frank Benoit <benoit@tionex.de>
date Sat, 17 May 2008 17:34:28 +0200
parents ab60f3309436
children 387fe83aa839
line wrap: on
line diff
--- a/dwt/widgets/Widget.d	Mon May 05 00:12:38 2008 +0200
+++ b/dwt/widgets/Widget.d	Sat May 17 17:34:28 2008 +0200
@@ -101,6 +101,15 @@
     static const int FOREIGN_HANDLE = 1<<14;
     static const int DRAG_DETECT    = 1<<15;
 
+    /* Move and resize state flags */
+    static final int MOVE_OCCURRED      = 1<<16;
+    static final int MOVE_DEFERRED      = 1<<17;
+    static final int RESIZE_OCCURRED    = 1<<18;
+    static final int RESIZE_DEFERRED    = 1<<19;
+
+    /* Ignore WM_CHANGEUISTATE */
+    static final int IGNORE_WM_CHANGEUISTATE = 1<<20;
+
     /* Default size for widgets */
     static const int DEFAULT_WIDTH  = 64;
     static const int DEFAULT_HEIGHT = 64;
@@ -197,6 +206,7 @@
  *
  * @see Listener
  * @see DWT
+ * @see #getListeners(int)
  * @see #removeListener(int, Listener)
  * @see #notifyListeners
  */
@@ -357,7 +367,27 @@
 void checkWidget () {
     Display display = this.display;
     if (display is null) error (DWT.ERROR_WIDGET_DISPOSED);
-    if (display.thread !is Thread.getThis ()) error (DWT.ERROR_THREAD_INVALID_ACCESS);
+    if (display.thread !is Thread.getThis ()) {
+        /*
+        * Bug in IBM JVM 1.6.  For some reason, under
+        * conditions that are yet to be full understood,
+        * Thread.currentThread() is either returning null
+        * or a different instance from the one that was
+        * saved when the Display was created.  This is
+        * possibly a JIT problem because modifying this
+        * method to print logging information when the
+        * error happens seems to fix the problem.  The
+        * fix is to use operating system calls to verify
+        * that the current thread is not the Display thread.
+        *
+        * NOTE: Despite the fact that Thread.currentThread()
+        * is used in other places, the failure has only been
+        * observed here.
+        */
+        if (display.threadId !is OS.GetCurrentThreadId ()) {
+            error (DWT.ERROR_THREAD_INVALID_ACCESS);
+        }
+    }
     if ((state & DISPOSED) !is 0) error (DWT.ERROR_WIDGET_DISPOSED);
 }
 
@@ -475,12 +505,17 @@
 }
 
 char [] fixMnemonic (String string) {
-    char [] buffer = string.dup;
+    return fixMnemonic (string, false);
+}
+
+char [] fixMnemonic (String string, bool spaces) {
+    char [] buffer = string ~ '\0';
     int i = 0, j = 0;
     while (i < buffer.length) {
         if (buffer [i] is '&') {
             if (i + 1 < buffer.length && buffer [i + 1] is '&') {
-                buffer [j++] = ' ';
+                if (spaces) buffer [j] = ' ';
+                j++;
                 i++;
             }
             i++;
@@ -577,6 +612,33 @@
     return display;
 }
 
+/**
+ * Returns an array of listeners who will be notified when an event
+ * of the given type occurs. The event type is one of the event constants
+ * defined in class <code>DWT</code>.
+ *
+ * @param eventType the type of event to listen for
+ * @return an array of listeners that will be notified when the event occurs
+ *
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see Listener
+ * @see DWT
+ * @see #addListener(int, Listener)
+ * @see #removeListener(int, Listener)
+ * @see #notifyListeners
+ *
+ * @since 3.4
+ */
+public Listener[] getListeners (int eventType) {
+    checkWidget();
+    if (eventTable is null) return new Listener[0];
+    return eventTable.getListeners(eventType);
+}
+
 Menu getMenu () {
     return null;
 }
@@ -732,6 +794,7 @@
  *
  * @see DWT
  * @see #addListener
+ * @see #getListeners(int)
  * @see #removeListener(int, Listener)
  */
 public void notifyListeners (int eventType, Event event) {
@@ -880,6 +943,7 @@
  * @see Listener
  * @see DWT
  * @see #addListener
+ * @see #getListeners(int)
  * @see #notifyListeners
  */
 public void removeListener (int eventType, Listener listener) {
@@ -999,13 +1063,13 @@
     }
 }
 
-bool sendKeyEvent (int type, int msg, int wParam, int lParam) {
+bool sendKeyEvent (int type, int msg, int /*long*/ wParam, int /*long*/ lParam) {
     Event event = new Event ();
     if (!setKeyState (event, type, wParam, lParam)) return true;
     return sendKeyEvent (type, msg, wParam, lParam, event);
 }
 
-bool sendKeyEvent (int type, int msg, int wParam, int lParam, Event event) {
+bool sendKeyEvent (int type, int msg, int /*long*/ wParam, int /*long*/ lParam, Event event) {
     sendEvent (type, event);
     if (isDisposed ()) return false;
     return event.doit;
@@ -1021,8 +1085,8 @@
     event.button = button;
     event.detail = detail;
     event.count = count;
-    event.x = cast(short) (lParam & 0xFFFF);
-    event.y = cast(short) (lParam >> 16);
+    event.x = OS.GET_X_LPARAM (lParam);
+    event.y = OS.GET_Y_LPARAM (lParam);
     setInputState (event, type);
     mapEvent (hwnd, event);
     if (send) {
@@ -1149,8 +1213,10 @@
     if (OS.GetKeyState (OS.VK_LBUTTON) < 0) event.stateMask |= DWT.BUTTON1;
     if (OS.GetKeyState (OS.VK_MBUTTON) < 0) event.stateMask |= DWT.BUTTON2;
     if (OS.GetKeyState (OS.VK_RBUTTON) < 0) event.stateMask |= DWT.BUTTON3;
-    if (OS.GetKeyState (OS.VK_XBUTTON1) < 0) event.stateMask |= DWT.BUTTON4;
-    if (OS.GetKeyState (OS.VK_XBUTTON2) < 0) event.stateMask |= DWT.BUTTON5;
+    if (display.xMouse) {
+        if (OS.GetKeyState (OS.VK_XBUTTON1) < 0) event.stateMask |= DWT.BUTTON4;
+        if (OS.GetKeyState (OS.VK_XBUTTON2) < 0) event.stateMask |= DWT.BUTTON5;
+    }
     switch (type) {
         case DWT.MouseDown:
         case DWT.MouseDoubleClick:
@@ -1183,7 +1249,7 @@
     return true;
 }
 
-bool setKeyState (Event event, int type, int wParam, int lParam) {
+bool setKeyState (Event event, int type, int /*long*/ wParam, int /*long*/ lParam) {
 
     /*
     * Feature in Windows.  When the user presses Ctrl+Backspace
@@ -1357,16 +1423,16 @@
     int x = 0, y = 0;
     if (lParam !is -1) {
         POINT pt;
-        x = pt.x = cast(short) (lParam & 0xFFFF);
-        y = pt.y = cast(short) (lParam >> 16);
-        OS.ScreenToClient (hwnd, &pt);
+        OS.POINTSTOPOINT (pt, lParam);
+        x = pt.x;
+        y = pt.y;
         RECT rect;
         OS.GetClientRect (hwnd, &rect);
         if (!OS.PtInRect (&rect, pt)) return null;
     } else {
         int pos = OS.GetMessagePos ();
-        x = cast(short) (pos & 0xFFFF);
-        y = cast(short) (pos >> 16);
+        x = OS.GET_X_LPARAM (pos);
+        y = OS.GET_Y_LPARAM (pos);
     }
 
     /* Show the menu */
@@ -1434,7 +1500,22 @@
             default:
         }
     } else {
-        mapKey = OS.MapVirtualKey (wParam, 2);
+        /*
+        * Feature in Windows.  For numbers in Marathi and Bengali,
+        * MapVirtualKey() returns the localized number instead of
+        * the ASCII equivalent.  For example, MapVirtualKey()
+        * maps VK_1 on the Marathi keyboard to \u2407, which is
+        * a valid Unicode Marathi '1' character, but not ASCII.
+        * The fix is to test for VK_0 to VK_9 and map these
+        * explicitly.
+        *
+        * NOTE: VK_0 to VK_9 are the same as ASCII.
+        */
+        if ('0' <= wParam && wParam <= '9') {
+            mapKey = wParam;
+        } else {
+            mapKey = OS.MapVirtualKey (wParam, 2);
+        }
     }
 
     /*
@@ -1718,6 +1799,7 @@
 }
 
 LRESULT wmKillFocus (HWND hwnd, int wParam, int lParam) {
+    display.scrollRemainder = 0;
     int code = callWindowProc (hwnd, OS.WM_KILLFOCUS, wParam, lParam);
     sendFocusEvent (DWT.FocusOut);
     // widget could be disposed at this point
@@ -1766,8 +1848,8 @@
 LRESULT wmLButtonDown (HWND hwnd, int wParam, int lParam) {
     Display display = this.display;
     LRESULT result = null;
-    int x = cast(short) (lParam & 0xFFFF);
-    int y = cast(short) (lParam >> 16);
+    int x = OS.GET_X_LPARAM (lParam);
+    int y = OS.GET_Y_LPARAM (lParam);
     bool [] consume = null, detect = null;
     bool dragging = false, mouseDown = true;
     int count = display.getClickCount (DWT.MouseDown, 1, hwnd, lParam);
@@ -1871,7 +1953,7 @@
     */
     int mask = OS.MK_LBUTTON | OS.MK_MBUTTON | OS.MK_RBUTTON;
     if (display.xMouse) mask |= OS.MK_XBUTTON1 | OS.MK_XBUTTON2;
-    if (((wParam & 0xFFFF) & mask) is 0) {
+    if ((wParam & mask) is 0) {
         if (OS.GetCapture () is hwnd) OS.ReleaseCapture ();
     }
     return result;
@@ -1937,7 +2019,7 @@
     */
     int mask = OS.MK_LBUTTON | OS.MK_MBUTTON | OS.MK_RBUTTON;
     if (display.xMouse) mask |= OS.MK_XBUTTON1 | OS.MK_XBUTTON2;
-    if (((wParam & 0xFFFF) & mask) is 0) {
+    if ((wParam & mask) is 0) {
         if (OS.GetCapture () is hwnd) OS.ReleaseCapture ();
     }
     return result;
@@ -1954,10 +2036,9 @@
     if (!hooks (DWT.MouseExit) && !filters (DWT.MouseExit)) return null;
     int pos = OS.GetMessagePos ();
     POINT pt;
-    pt.x = cast(short) (pos & 0xFFFF);
-    pt.y = cast(short) (pos >> 16);
+    OS.POINTSTOPOINT (pt, pos);
     OS.ScreenToClient (hwnd, &pt);
-    lParam = (pt.x & 0xFFFF) | ((pt.y << 16) & 0xFFFF0000);
+    lParam = OS.MAKELPARAM (pt.x, pt.y);
     if (!sendMouseEvent (DWT.MouseExit, 0, hwnd, OS.WM_MOUSELEAVE, wParam, lParam)) {
         return LRESULT.ZERO;
     }
@@ -2017,30 +2098,37 @@
 }
 
 LRESULT wmMouseWheel (HWND hwnd, int wParam, int lParam) {
-    if (!hooks (DWT.MouseWheel) && !filters (DWT.MouseWheel)) return null;
-    int delta = wParam >> 16;
-    int value;
-    int count, detail;
-    OS.SystemParametersInfo (OS.SPI_GETWHEELSCROLLLINES, 0, &value, 0);
-    if (value is OS.WHEEL_PAGESCROLL) {
+    int delta = OS.GET_WHEEL_DELTA_WPARAM (wParam);
+    int linesToScroll;
+    int detail;
+    OS.SystemParametersInfo (OS.SPI_GETWHEELSCROLLLINES, 0, &linesToScroll, 0);
+    if (linesToScroll is OS.WHEEL_PAGESCROLL) {
         detail = DWT.SCROLL_PAGE;
-        count = delta / OS.WHEEL_DELTA;
     } else {
         detail = DWT.SCROLL_LINE;
-        count = value * delta / OS.WHEEL_DELTA;
+        delta *= linesToScroll;
     }
+    /* Check if the delta and the remainder have the same direction (sign) */
+    if ((delta ^ display.scrollRemainder) >= 0) delta += display.scrollRemainder;
+    display.scrollRemainder = delta % OS.WHEEL_DELTA;
+
+    if (!hooks (DWT.MouseWheel) && !filters (DWT.MouseWheel)) return null;
+    int count = delta / OS.WHEEL_DELTA;
     POINT pt;
-    pt.x = cast(short) (lParam & 0xFFFF);
-    pt.y = cast(short) (lParam >> 16);
+    OS.POINTSTOPOINT (pt, lParam);
     OS.ScreenToClient (hwnd, &pt);
-    lParam = (pt.x & 0xFFFF) | ((pt.y << 16) & 0xFFFF0000);
+    lParam = OS.MAKELPARAM (pt.x, pt.y);
     if (!sendMouseEvent (DWT.MouseWheel, 0, count, detail, true, hwnd, OS.WM_MOUSEWHEEL, wParam, lParam)) {
         return LRESULT.ZERO;
     }
     return null;
 }
 
-LRESULT wmPaint (HWND hwnd, int wParam, int lParam) {
+LRESULT wmNCPaint (HWND hwnd, int /*long*/ wParam, int /*long*/ lParam) {
+    return null;
+}
+
+LRESULT wmPaint (HWND hwnd, int /*long*/ wParam, int /*long*/ lParam) {
 
     /* Exit early - don't draw the background */
     if (!hooks (DWT.Paint) && !filters (DWT.Paint)) {
@@ -2048,7 +2136,7 @@
     }
 
     /* Issue a paint event */
-    int result = 0;
+    int /*long*/ result = 0;
     static if (OS.IsWinCE) {
         RECT rect;
         OS.GetUpdateRect (hwnd, &rect, false);
@@ -2132,7 +2220,7 @@
         if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
             int bits = OS.GetWindowLong (hwnd, OS.GWL_EXSTYLE);
             if ((bits & OS.WS_EX_CLIENTEDGE) !is 0) {
-                int code = callWindowProc (hwnd, OS.WM_PRINT, wParam, lParam);
+                int /*long*/ code = callWindowProc (hwnd, OS.WM_PRINT, wParam, lParam);
                 RECT rect;
                 OS.GetWindowRect (hwnd, &rect);
                 rect.right -= rect.left;
@@ -2210,14 +2298,14 @@
     */
     int mask = OS.MK_LBUTTON | OS.MK_MBUTTON | OS.MK_RBUTTON;
     if (display.xMouse) mask |= OS.MK_XBUTTON1 | OS.MK_XBUTTON2;
-    if (((wParam & 0xFFFF) & mask) is 0) {
+    if ((wParam & mask) is 0) {
         if (OS.GetCapture () is hwnd) OS.ReleaseCapture ();
     }
     return result;
 }
 
 LRESULT wmSetFocus (HWND hwnd, int wParam, int lParam) {
-    int code = callWindowProc (hwnd, OS.WM_SETFOCUS, wParam, lParam);
+    int /*long*/ code = callWindowProc (hwnd, OS.WM_SETFOCUS, wParam, lParam);
     sendFocusEvent (DWT.FocusIn);
     // widget could be disposed at this point
 
@@ -2246,7 +2334,7 @@
     /* Call the window proc to determine whether it is a system key or mnemonic */
     bool oldKeyHit = display.mnemonicKeyHit;
     display.mnemonicKeyHit = true;
-    int result = callWindowProc (hwnd, OS.WM_SYSCHAR, wParam, lParam);
+    int /*long*/ result = callWindowProc (hwnd, OS.WM_SYSCHAR, wParam, lParam);
     bool consumed = false;
     if (!display.mnemonicKeyHit) {
         consumed = !sendKeyEvent (DWT.KeyDown, OS.WM_SYSCHAR, wParam, lParam);
@@ -2405,7 +2493,7 @@
     LRESULT result = null;
     Display display = this.display;
     display.captureChanged = false;
-    int button = (wParam >> 16 is OS.XBUTTON1) ? 4 : 5;
+    int button = OS.HIWORD (wParam) is OS.XBUTTON1 ? 4 : 5;
     sendMouseEvent (DWT.MouseDown, button, hwnd, OS.WM_XBUTTONDOWN, wParam, lParam);
     if (sendMouseEvent (DWT.MouseDoubleClick, button, hwnd, OS.WM_XBUTTONDBLCLK, wParam, lParam)) {
         result = new LRESULT (callWindowProc (hwnd, OS.WM_XBUTTONDBLCLK, wParam, lParam));
@@ -2423,7 +2511,7 @@
     Display display = this.display;
     display.captureChanged = false;
     display.xMouse = true;
-    int button = (wParam >> 16 is OS.XBUTTON1) ? 4 : 5;
+    int button = OS.HIWORD (wParam) is OS.XBUTTON1 ? 4 : 5;
     if (sendMouseEvent (DWT.MouseDown, button, hwnd, OS.WM_XBUTTONDOWN, wParam, lParam)) {
         result = new LRESULT (callWindowProc (hwnd, OS.WM_XBUTTONDOWN, wParam, lParam));
     } else {
@@ -2438,7 +2526,7 @@
 LRESULT wmXButtonUp (HWND hwnd, int wParam, int lParam) {
     Display display = this.display;
     LRESULT result = null;
-    int button = (wParam >> 16 is OS.XBUTTON1) ? 4 : 5;
+    int button = OS.HIWORD (wParam) is OS.XBUTTON1 ? 4 : 5;
     if (sendMouseEvent (DWT.MouseUp, button, hwnd, OS.WM_XBUTTONUP, wParam, lParam)) {
         result = new LRESULT (callWindowProc (hwnd, OS.WM_XBUTTONUP, wParam, lParam));
     } else {
@@ -2452,7 +2540,7 @@
     */
     int mask = OS.MK_LBUTTON | OS.MK_MBUTTON | OS.MK_RBUTTON;
     if (display.xMouse) mask |= OS.MK_XBUTTON1 | OS.MK_XBUTTON2;
-    if (((wParam & 0xFFFF) & mask) is 0) {
+    if ((wParam & mask) is 0) {
         if (OS.GetCapture () is hwnd) OS.ReleaseCapture ();
     }
     return result;