diff options
author | Silenio Quarti <silenio> | 2004-09-29 22:53:54 +0000 |
---|---|---|
committer | Silenio Quarti <silenio> | 2004-09-29 22:53:54 +0000 |
commit | e657e76e5131e900496ccd41899277450879646c (patch) | |
tree | cbc84ff2b1e678105038bc9de211727da5d0fd03 /bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Widget.java | |
parent | 28611873c812080da03092456ee7cc4c93ef80a3 (diff) | |
download | eclipse.platform.swt-e657e76e5131e900496ccd41899277450879646c.tar.gz eclipse.platform.swt-e657e76e5131e900496ccd41899277450879646c.tar.xz eclipse.platform.swt-e657e76e5131e900496ccd41899277450879646c.zip |
74736
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Widget.java')
-rwxr-xr-x | bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Widget.java | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Widget.java index 0fae8e6fea..5d0134ccbf 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Widget.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/Widget.java @@ -353,6 +353,9 @@ char fixMnemonic (char [] buffer) { int focusProc (int w, int client_data, int call_data, int continue_to_dispatch) { return 0; } +String getCodePage () { + return null; +} /** * Returns the application defined widget data associated * with the receiver, or null if it has not been set. The @@ -754,6 +757,106 @@ void sendEvent (int eventType, Event event, boolean send) { display.postEvent (event); } } +boolean sendIMKeyEvent (int type, XKeyEvent xEvent) { + return sendIMKeyEvent (type, xEvent, 0); +} +boolean sendIMKeyEvent (int type, XKeyEvent xEvent, int textHandle) { + /* + * Bug in Motif. On Linux only, XmImMbLookupString () does not return + * XBufferOverflow as the status if the buffer is too small. The fix + * is to pass a large buffer. + */ + byte [] buffer = new byte [512]; + int [] status = new int [1], unused = new int [1]; + int focusHandle = OS.XtWindowToWidget (xEvent.display, xEvent.window); + int length = OS.XmImMbLookupString (focusHandle, xEvent, buffer, buffer.length, unused, status); + if (status [0] == OS.XBufferOverflow) { + buffer = new byte [length]; + length = OS.XmImMbLookupString (focusHandle, xEvent, buffer, length, unused, status); + } + if (length == 0) return true; + + /* Convert from MBCS to UNICODE and send the event */ + /* Use the character encoding for the default locale */ + char [] chars = Converter.mbcsToWcs (null, buffer); + int index = 0, count = 0; + while (index < chars.length) { + if (chars [index] == 0) { + chars [count] = 0; + break; + } + Event event = new Event (); + event.time = xEvent.time; + event.character = chars [index]; + setInputState (event, xEvent.state); + sendEvent (type, event); + // widget could be disposed at this point + + /* + * It is possible (but unlikely), that application + * code could have disposed the widget in the key + * events. If this happens, end the processing of + * the key by returning false. + */ + if (isDisposed ()) return false; + if (event.doit) chars [count++] = chars [index]; + index++; + } + if (count == 0) return false; + if (textHandle != 0) { + /* + * Bug in Motif. On Solaris and Linux, XmImMbLookupString() clears + * the characters from the IME. This causes the characters to be + * stolen from the text widget. The fix is to detect that the IME + * has been cleared and use XmTextInsert() to insert the stolen + * characters. This problem does not happen on AIX. + */ + byte [] testBuffer = new byte [5]; + int testLength = OS.XmImMbLookupString (textHandle, xEvent, testBuffer, testBuffer.length, unused, unused); + if (testLength == 0 || index != count) { + int [] start = new int [1], end = new int [1]; + OS.XmTextGetSelectionPosition (textHandle, start, end); + if (start [0] == end [0]) { + start [0] = end [0] = OS.XmTextGetInsertionPosition (textHandle); + } + boolean warnings = display.getWarnings (); + display.setWarnings (false); + if (index != count) { + buffer = Converter.wcsToMbcs (getCodePage (), chars, true); + } + OS.XmTextReplace (textHandle, start [0], end [0], buffer); + int position = start [0] + count; + OS.XmTextSetInsertionPosition (textHandle, position); + display.setWarnings (warnings); + return false; + } + } + return true; +} +boolean sendKeyEvent (int type, XKeyEvent xEvent) { + Event event = new Event (); + event.time = xEvent.time; + if (!setKeyState (event, xEvent)) return true; + Widget control = this; + if ((state & CANVAS) != 0) { + if ((style & SWT.NO_FOCUS) != 0) { + control = display.getFocusControl (); + } + } + if (control != null) { + control.sendEvent (type, event); + // widget could be disposed at this point + + /* + * It is possible (but unlikely), that application + * code could have disposed the widget in the key + * events. If this happens, end the processing of + * the key by returning false. + */ + if (isDisposed ()) return false; + } + return event.doit; +} /** * Sets the application defined widget data associated * with the receiver to be the argument. The <em>widget @@ -961,9 +1064,27 @@ int XFocusChange (int w, int client_data, int call_data, int continue_to_dispatc return 0; } int XKeyPress (int w, int client_data, int call_data, int continue_to_dispatch) { + XKeyEvent xEvent = new XKeyEvent (); + OS.memmove (xEvent, call_data, XKeyEvent.sizeof); + boolean doit = true; + if (xEvent.keycode != 0) { + doit = sendKeyEvent (SWT.KeyDown, xEvent); + } else { + doit = sendIMKeyEvent (SWT.KeyDown, xEvent); + } + if (!doit) { + OS.memmove (continue_to_dispatch, new int [1], 4); + return 1; + } return 0; } int XKeyRelease (int w, int client_data, int call_data, int continue_to_dispatch) { + XKeyEvent xEvent = new XKeyEvent (); + OS.memmove (xEvent, call_data, XKeyEvent.sizeof); + if (!sendKeyEvent (SWT.KeyUp, xEvent)) { + OS.memmove (continue_to_dispatch, new int [1], 4); + return 1; + } return 0; } int XLeaveWindow (int w, int client_data, int call_data, int continue_to_dispatch) { |