[Mono-bugs] [Bug 386528] New: Character input with the Carbon backend has endian ( and other) problems
bugzilla_noreply at novell.com
bugzilla_noreply at novell.com
Sun May 4 16:43:20 EDT 2008
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 at lists.ximian.com
ReportedBy: jesjones at mindspring.com
QAContact: mono-bugs at 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.
More information about the mono-bugs
mailing list