https://bugzilla.novell.com/show_bug.cgi?id=386528
Summary: Character input with the Carbon backend has endian (and other) problems Product: Mono: Class Libraries Version: 1.9.0 Platform: Macintosh OS/Version: Mac OS X 10.4 Status: NEW Severity: Major Priority: P5 - None Component: Windows.Forms AssignedTo: mono-bugs@lists.ximian.com ReportedBy: [EMAIL PROTECTED] QAContact: mono-bugs@lists.ximian.com Found By: --- KeyboardHandler::ProcessText has the following problems: 1) kEventParamTextInputSendText returns a Unicode string using the native endian. This means bdata[0] may return either the low or high byte of the code-point depending on if you are running on an Intel or a PowerPC mac. 2) The key_filter_table is only checked using a single byte from the code-point. It should instead check to see if the high byte is zero and then use the low byte. 3) wParam is only assigned a byte from the code point instead of the entire code point. Here's a fix for these issues (tested on a PowerPC mac). Note that with these fixes stuff like option-p can be used to enter the pi character even on Intel. internal const uint typeUTF16ExternalRepresentation = 0x75743136; /* 'ut16' big-endian 16 bit unicode with optional byte-order-mark, or little-endian 16 bit unicode with required byte-order-mark. */ public void ProcessText (IntPtr eventref, ref MSG msg) { // Get the size of the unicode buffer. Note that unlike typeUnicodeText typeUTF16ExternalRepresentation // provides enough information to determine the endian of the text we get back. TODO: we should really be checking the results of all Carbon calls for errors... UInt32 size = 0; GetEventParameter (eventref, kEventParamTextInputSendText, typeUTF16ExternalRepresentation, IntPtr.Zero, 0, ref size, IntPtr.Zero); // get the actual text buffer IntPtr buffer = Marshal.AllocHGlobal ((int) size); GetEventParameter (eventref, kEventParamTextInputSendText, typeUTF16ExternalRepresentation, IntPtr.Zero, size, IntPtr.Zero, buffer); byte[] bdata = new byte [size]; Marshal.Copy (buffer, bdata, 0, (int) size); Marshal.FreeHGlobal (buffer); int cp = GetCodePoint(bdata); int high = cp >> 8; int low = cp & 0xFF; if (high != 0 || key_filter_table [low] == 0x00) { msg.message = Msg.WM_CHAR; msg.wParam = (IntPtr) cp; msg.lParam = IntPtr.Zero; msg.hwnd = XplatUICarbon.FocusWindow; } } private static int GetCodePoint(byte[] data) { int index = 0; // Check for a byte-order-mark (if the BOM is missing the text // will be big endian). bool bigEndian = true; if (data.Length >= 2) { if (data[0] == 0xFE && data[1] == 0xFF) { index = 2; } else if (data[0] == 0xFF && data[1] == 0xFE) { bigEndian = false; index = 2; } } // We should now have at least two bytes of data. int cp; int bytes = data.Length - index; if (bytes == 2) { if (bigEndian) cp = (data[index] << 8) | data[index + 1]; else cp = (data[index + 1] << 8) | data[index]; } else if (bytes > 2) { // TODO: This can definitely happen and we should handle it. For now // we'll replace whatever the user typed with an ellipsis so they know // something bad happened. cp = 0x2027; } else { // This should not happen. throw new Exception(string.Format("Got {0} bytes of data from kEventParamTextInputSendText", bytes)); } return cp; } -- Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the QA contact for the bug. You are the assignee for the bug. _______________________________________________ mono-bugs maillist - mono-bugs@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-bugs