From b940da411bff04af2bed713b730546ef4378e457 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 15 Feb 2015 02:45:51 -0500 Subject: UTF-8 support on OSX. --- pugl/pugl_internal.h | 34 ++++++++++++++++++++++++++++++++++ pugl/pugl_osx.m | 26 +++++++++++++++++++++----- pugl/pugl_x11.c | 39 +-------------------------------------- 3 files changed, 56 insertions(+), 43 deletions(-) diff --git a/pugl/pugl_internal.h b/pugl/pugl_internal.h index 5b2b1c7..993f319 100644 --- a/pugl/pugl_internal.h +++ b/pugl/pugl_internal.h @@ -213,6 +213,40 @@ puglEnterContext(PuglView* view); void puglLeaveContext(PuglView* view, bool flush); +/** Return the code point for buf, or the replacement character on error. */ +static uint32_t +puglDecodeUTF8(const uint8_t* buf) +{ +#define FAIL_IF(cond) { if (cond) return 0xFFFD; } + + /* http://en.wikipedia.org/wiki/UTF-8 */ + + if (buf[0] < 0x80) { + return buf[0]; + } else if (buf[0] < 0xC2) { + return 0xFFFD; + } else if (buf[0] < 0xE0) { + FAIL_IF((buf[1] & 0xC0) != 0x80); + return (buf[0] << 6) + buf[1] - 0x3080; + } else if (buf[0] < 0xF0) { + FAIL_IF((buf[1] & 0xC0) != 0x80); + FAIL_IF(buf[0] == 0xE0 && buf[1] < 0xA0); + FAIL_IF((buf[2] & 0xC0) != 0x80); + return (buf[0] << 12) + (buf[1] << 6) + buf[2] - 0xE2080; + } else if (buf[0] < 0xF5) { + FAIL_IF((buf[1] & 0xC0) != 0x80); + FAIL_IF(buf[0] == 0xF0 && buf[1] < 0x90); + FAIL_IF(buf[0] == 0xF4 && buf[1] >= 0x90); + FAIL_IF((buf[2] & 0xC0) != 0x80); + FAIL_IF((buf[3] & 0xC0) != 0x80); + return ((buf[0] << 18) + + (buf[1] << 12) + + (buf[2] << 6) + + buf[3] - 0x3C82080); + } + return 0xFFFD; +} + static void puglDispatchEvent(PuglView* view, const PuglEvent* event) { diff --git a/pugl/pugl_osx.m b/pugl/pugl_osx.m index c7dbf5e..85e71a8 100644 --- a/pugl/pugl_osx.m +++ b/pugl/pugl_osx.m @@ -348,7 +348,8 @@ getModifiers(PuglView* view, NSEvent* ev) const NSPoint wloc = [self eventLocation:event]; const NSPoint rloc = [NSEvent mouseLocation]; const NSString* chars = [event characters]; - const PuglEventKey ev = { + const char* str = [chars UTF8String]; + PuglEventKey ev = { PUGL_KEY_PRESS, puglview, false, @@ -358,9 +359,13 @@ getModifiers(PuglView* view, NSEvent* ev) rloc.x, [[NSScreen mainScreen] frame].size.height - rloc.y, getModifiers(puglview, event), - [chars characterAtIndex:0], - 0 // TODO: Special keys? + [event keyCode], + puglDecodeUTF8((const uint8_t*)str), + 0, // TODO: Special keys? + { 0, 0, 0, 0, 0, 0, 0, 0 }, + false }; + strncpy((char*)ev.utf8, str, 8); puglDispatchEvent(puglview, (PuglEvent*)&ev); } @@ -369,6 +374,7 @@ getModifiers(PuglView* view, NSEvent* ev) const NSPoint wloc = [self eventLocation:event]; const NSPoint rloc = [NSEvent mouseLocation]; const NSString* chars = [event characters]; + const char* str = [chars UTF8String]; const PuglEventKey ev = { PUGL_KEY_RELEASE, puglview, @@ -379,9 +385,13 @@ getModifiers(PuglView* view, NSEvent* ev) rloc.x, [[NSScreen mainScreen] frame].size.height - rloc.y, getModifiers(puglview, event), - [chars characterAtIndex:0], - 0 // TODO: Special keys? + [event keyCode], + puglDecodeUTF8((const uint8_t*)str), + 0, // TODO: Special keys? + { 0, 0, 0, 0, 0, 0, 0, 0 }, + false, }; + strncpy((char*)ev.utf8, str, 8); puglDispatchEvent(puglview, (PuglEvent*)&ev); } @@ -535,3 +545,9 @@ puglGetNativeWindow(PuglView* view) { return (PuglNativeWindow)view->impl->glview; } + +void* +puglGetContext(PuglView* view) +{ + return NULL; +} diff --git a/pugl/pugl_x11.c b/pugl/pugl_x11.c index 532ff40..9262404 100644 --- a/pugl/pugl_x11.c +++ b/pugl/pugl_x11.c @@ -317,43 +317,6 @@ keySymToSpecial(KeySym sym) return (PuglKey)0; } -/** Return the code point for buf, or the replacement character on error. */ -static uint32_t -utf8Decode(const uint8_t* buf, size_t len) -{ -#define FAIL_IF(cond) { if (cond) return 0xFFFD; } - - /* http://en.wikipedia.org/wiki/UTF-8 */ - - if (buf[0] < 0x80) { - return buf[0]; - } else if (buf[0] < 0xC2) { - return 0xFFFD; - } else if (buf[0] < 0xE0) { - FAIL_IF(len != 2); - FAIL_IF((buf[1] & 0xC0) != 0x80); - return (buf[0] << 6) + buf[1] - 0x3080; - } else if (buf[0] < 0xF0) { - FAIL_IF(len != 3); - FAIL_IF((buf[1] & 0xC0) != 0x80); - FAIL_IF(buf[0] == 0xE0 && buf[1] < 0xA0); - FAIL_IF((buf[2] & 0xC0) != 0x80); - return (buf[0] << 12) + (buf[1] << 6) + buf[2] - 0xE2080; - } else if (buf[0] < 0xF5) { - FAIL_IF(len != 4); - FAIL_IF((buf[1] & 0xC0) != 0x80); - FAIL_IF(buf[0] == 0xF0 && buf[1] < 0x90); - FAIL_IF(buf[0] == 0xF4 && buf[1] >= 0x90); - FAIL_IF((buf[2] & 0xC0) != 0x80); - FAIL_IF((buf[3] & 0xC0) != 0x80); - return ((buf[0] << 18) + - (buf[1] << 12) + - (buf[2] << 6) + - buf[3] - 0x3C82080); - } - return 0xFFFD; -} - static void translateKey(PuglView* view, XEvent* xevent, PuglEvent* event) { @@ -370,7 +333,7 @@ translateKey(PuglView* view, XEvent* xevent, PuglEvent* event) const int n = XmbLookupString( view->impl->xic, &xevent->xkey, str, 7, &sym, &status); if (n > 0) { - event->key.character = utf8Decode((const uint8_t*)str, n); + event->key.character = puglDecodeUTF8((const uint8_t*)str); } } event->key.special = keySymToSpecial(sym); -- cgit v1.2.3