unsigned GetCharacter(size_t characterIdx) const { assert(characterIdx < GetCharacterCount()); std::pair<unsigned, const char *> next = NextUTF8(event.text.text); for (size_t i = 0; i < characterIdx; ++i) next = NextUTF8(next.second); return next.first; }
gcc_pure static std::pair<unsigned, const TCHAR *> NextChar(const TCHAR *p) { #ifdef _UNICODE return std::make_pair(unsigned(*p), p + 1); #else return NextUTF8(p); #endif }
int main(int argc, char **argv) { plan_tests(2 * ARRAY_SIZE(valid) + 2 * ARRAY_SIZE(invalid) + 2 * ARRAY_SIZE(length) + 4 * ARRAY_SIZE(crop) + ARRAY_SIZE(latin1_chars) + #ifndef _UNICODE ARRAY_SIZE(truncate_string_tests) + #endif 9 + 27); for (auto i : valid) { ok1(ValidateUTF8(i)); ok1(LengthUTF8(i) == MyLengthUTF8(i)); } for (auto i : invalid) { ok1(!ValidateUTF8(i)); ok1(!MyValidateUTF8(i)); } for (auto &l : length) { ok1(l.length == LengthUTF8(l.value)); ok1(l.length == MyLengthUTF8(l.value)); } char buffer[64]; for (auto &l : latin1_chars) { *Latin1ToUTF8(l.ch, buffer) = 0; ok1(strcmp(l.utf8, buffer) == 0); } for (auto &c : crop) { strcpy(buffer, c.input); auto *end = CropIncompleteUTF8(buffer); ok1(strcmp(c.output, buffer) == 0); ok1(end != nullptr); ok1(*end == '\0'); ok1(end == buffer + strlen(buffer)); } #ifndef _UNICODE TestTruncateString(); #endif { const char *p = "foo\xe7\x9b\xae"; auto n = NextUTF8(p); ok1(n.first == 'f'); ok1(n.second == p + 1); n = NextUTF8(p + 1); ok1(n.first == 'o'); ok1(n.second == p + 2); n = NextUTF8(p + 2); ok1(n.first == 'o'); ok1(n.second == p + 3); n = NextUTF8(p + 3); ok1(n.first == 30446); ok1(n.second == p + 6); n = NextUTF8(p + 6); ok1(n.first == 0); } /* test UnicodeToUTF8() */ buffer[0] = 1; ok1(UnicodeToUTF8(0, buffer) == buffer + 1); ok1(buffer[0] == 0); ok1(UnicodeToUTF8(' ', buffer) == buffer + 1); ok1(buffer[0] == ' '); ok1(UnicodeToUTF8(0x7f, buffer) == buffer + 1); ok1(buffer[0] == 0x7f); ok1(UnicodeToUTF8(0xa2, buffer) == buffer + 2); ok1(buffer[0] == char(0xc2)); ok1(buffer[1] == char(0xa2)); ok1(UnicodeToUTF8(0x6fb3, buffer) == buffer + 3); ok1(buffer[0] == char(0xe6)); ok1(buffer[1] == char(0xbe)); ok1(buffer[2] == char(0xb3)); ok1(UnicodeToUTF8(0xffff, buffer) == buffer + 3); ok1(buffer[0] == char(0xef)); ok1(buffer[1] == char(0xbf)); ok1(buffer[2] == char(0xbf)); ok1(UnicodeToUTF8(0x10000, buffer) == buffer + 4); ok1(buffer[0] == char(0xf0)); ok1(buffer[1] == char(0x90)); ok1(buffer[2] == char(0x80)); ok1(buffer[3] == char(0x80)); ok1(UnicodeToUTF8(0x10ffff, buffer) == buffer + 4); ok1(buffer[0] == char(0xf4)); ok1(buffer[1] == char(0x8f)); ok1(buffer[2] == char(0xbf)); ok1(buffer[3] == char(0xbf)); return exit_status(); }
bool TopWindow::OnEvent(const SDL_Event &event) { switch (event.type) { Window *w; #if SDL_MAJOR_VERSION < 2 case SDL_VIDEOEXPOSE: invalidated = false; Expose(); return true; #endif case SDL_KEYDOWN: w = GetFocusedWindow(); if (w == nullptr) w = this; if (!w->IsEnabled()) return false; #if SDL_MAJOR_VERSION >= 2 return w->OnKeyDown(event.key.keysym.sym); #else return w->OnKeyDown(event.key.keysym.sym) || (event.key.keysym.unicode != 0 && w->OnCharacter(event.key.keysym.unicode)); #endif #if SDL_MAJOR_VERSION >= 2 case SDL_TEXTINPUT: w = GetFocusedWindow(); if (w == nullptr) w = this; if (!w->IsEnabled()) return false; if (event.text.text && *event.text.text) { std::pair<unsigned, const char *> next = NextUTF8(event.text.text); bool handled = w->OnCharacter(next.first); while (next.second) { next = NextUTF8(next.second); handled = w->OnCharacter(next.first) || handled; } return handled; } else return false; #endif case SDL_KEYUP: w = GetFocusedWindow(); if (w == nullptr) w = this; if (!w->IsEnabled()) return false; return w->OnKeyUp(event.key.keysym.sym); #ifdef HAVE_MULTI_TOUCH case SDL_FINGERDOWN: if (SDL_GetNumTouchFingers(event.tfinger.touchId) == 2) return OnMultiTouchDown(); else return false; case SDL_FINGERUP: if (SDL_GetNumTouchFingers(event.tfinger.touchId) == 1) return OnMultiTouchUp(); else return false; #endif case SDL_MOUSEMOTION: // XXX keys return OnMouseMove(event.motion.x, event.motion.y, 0); case SDL_MOUSEBUTTONDOWN: #if SDL_MAJOR_VERSION < 2 if (event.button.button == SDL_BUTTON_WHEELUP) return OnMouseWheel(event.button.x, event.button.y, 1); else if (event.button.button == SDL_BUTTON_WHEELDOWN) return OnMouseWheel(event.button.x, event.button.y, -1); #endif return double_click.Check(RasterPoint(event.button.x, event.button.y)) ? OnMouseDouble(event.button.x, event.button.y) : OnMouseDown(event.button.x, event.button.y); case SDL_MOUSEBUTTONUP: #if SDL_MAJOR_VERSION < 2 if (event.button.button == SDL_BUTTON_WHEELUP || event.button.button == SDL_BUTTON_WHEELDOWN) /* the wheel has already been handled in SDL_MOUSEBUTTONDOWN */ return false; #endif double_click.Moved(RasterPoint(event.button.x, event.button.y)); return OnMouseUp(event.button.x, event.button.y); case SDL_QUIT: return OnClose(); #if SDL_MAJOR_VERSION < 2 case SDL_VIDEORESIZE: Resize(event.resize.w, event.resize.h); return true; #endif #if SDL_MAJOR_VERSION >= 2 case SDL_MOUSEWHEEL: int x, y; SDL_GetMouseState(&x, &y); return OnMouseWheel(x, y, event.wheel.y); case SDL_WINDOWEVENT: switch (event.window.event) { case SDL_WINDOWEVENT_RESIZED: Resize(event.window.data1, event.window.data2); return true; case SDL_WINDOWEVENT_RESTORED: case SDL_WINDOWEVENT_MOVED: case SDL_WINDOWEVENT_SHOWN: case SDL_WINDOWEVENT_MAXIMIZED: { SDL_Window* event_window = SDL_GetWindowFromID(event.window.windowID); if (event_window) { int w, h; SDL_GetWindowSize(event_window, &w, &h); if ((w >= 0) && (h >= 0)) { Resize(w, h); } } } return true; case SDL_WINDOWEVENT_EXPOSED: invalidated = false; Expose(); return true; } #endif } return false; }
int main(int argc, char **argv) { plan_tests(ARRAY_SIZE(valid) + ARRAY_SIZE(invalid) + ARRAY_SIZE(length) + ARRAY_SIZE(crop) + ARRAY_SIZE(latin1_chars) + 9 + 27); for (auto i : valid) ok1(ValidateUTF8(i)); for (auto i : invalid) ok1(!ValidateUTF8(i)); for (auto &l : length) ok1(l.length == LengthUTF8(l.value)); char buffer[64]; for (auto &l : latin1_chars) { *Latin1ToUTF8(l.ch, buffer) = 0; ok1(strcmp(l.utf8, buffer) == 0); } for (auto &c : crop) { strcpy(buffer, c.input); CropIncompleteUTF8(buffer); ok1(strcmp(c.output, buffer) == 0); } { const char *p = "foo\xe7\x9b\xae"; auto n = NextUTF8(p); ok1(n.first == 'f'); ok1(n.second == p + 1); n = NextUTF8(p + 1); ok1(n.first == 'o'); ok1(n.second == p + 2); n = NextUTF8(p + 2); ok1(n.first == 'o'); ok1(n.second == p + 3); n = NextUTF8(p + 3); ok1(n.first == 30446); ok1(n.second == p + 6); n = NextUTF8(p + 6); ok1(n.first == 0); } /* test UnicodeToUTF8() */ buffer[0] = 1; ok1(UnicodeToUTF8(0, buffer) == buffer + 1); ok1(buffer[0] == 0); ok1(UnicodeToUTF8(' ', buffer) == buffer + 1); ok1(buffer[0] == ' '); ok1(UnicodeToUTF8(0x7f, buffer) == buffer + 1); ok1(buffer[0] == 0x7f); ok1(UnicodeToUTF8(0xa2, buffer) == buffer + 2); ok1(buffer[0] == char(0xc2)); ok1(buffer[1] == char(0xa2)); ok1(UnicodeToUTF8(0x6fb3, buffer) == buffer + 3); ok1(buffer[0] == char(0xe6)); ok1(buffer[1] == char(0xbe)); ok1(buffer[2] == char(0xb3)); ok1(UnicodeToUTF8(0xffff, buffer) == buffer + 3); ok1(buffer[0] == char(0xef)); ok1(buffer[1] == char(0xbf)); ok1(buffer[2] == char(0xbf)); ok1(UnicodeToUTF8(0x10000, buffer) == buffer + 4); ok1(buffer[0] == char(0xf0)); ok1(buffer[1] == char(0x90)); ok1(buffer[2] == char(0x80)); ok1(buffer[3] == char(0x80)); ok1(UnicodeToUTF8(0x10ffff, buffer) == buffer + 4); ok1(buffer[0] == char(0xf4)); ok1(buffer[1] == char(0x8f)); ok1(buffer[2] == char(0xbf)); ok1(buffer[3] == char(0xbf)); return exit_status(); }
bool TopWindow::OnEvent(const SDL_Event &event) { switch (event.type) { Window *w; #if SDL_MAJOR_VERSION < 2 case SDL_VIDEOEXPOSE: invalidated = false; Expose(); return true; #endif case SDL_KEYDOWN: w = GetFocusedWindow(); if (w == NULL) w = this; if (!w->IsEnabled()) return false; #if SDL_MAJOR_VERSION >= 2 return w->OnKeyDown(event.key.keysym.sym); #else return w->OnKeyDown(event.key.keysym.sym) || (event.key.keysym.unicode != 0 && w->OnCharacter(event.key.keysym.unicode)); #endif #if SDL_MAJOR_VERSION >= 2 case SDL_TEXTINPUT: w = GetFocusedWindow(); if (w == NULL) w = this; if (!w->IsEnabled()) return false; if (event.text.text && *event.text.text) { std::pair<unsigned, const char *> next = NextUTF8(event.text.text); bool handled = w->OnCharacter(next.first); while (next.second) { next = NextUTF8(next.second); handled = w->OnCharacter(next.first) || handled; } return handled; } else return false; #endif case SDL_KEYUP: w = GetFocusedWindow(); if (w == NULL) w = this; if (!w->IsEnabled()) return false; return w->OnKeyUp(event.key.keysym.sym); case SDL_MOUSEMOTION: // XXX keys return OnMouseMove(event.motion.x, event.motion.y, 0); case SDL_MOUSEBUTTONDOWN: #if SDL_MAJOR_VERSION < 2 if (event.button.button == SDL_BUTTON_WHEELUP) return OnMouseWheel(event.button.x, event.button.y, 1); else if (event.button.button == SDL_BUTTON_WHEELDOWN) return OnMouseWheel(event.button.x, event.button.y, -1); #endif return double_click.Check(RasterPoint(event.button.x, event.button.y)) ? OnMouseDouble(event.button.x, event.button.y) : OnMouseDown(event.button.x, event.button.y); case SDL_MOUSEBUTTONUP: #if SDL_MAJOR_VERSION < 2 if (event.button.button == SDL_BUTTON_WHEELUP || event.button.button == SDL_BUTTON_WHEELDOWN) /* the wheel has already been handled in SDL_MOUSEBUTTONDOWN */ return false; #endif double_click.Moved(RasterPoint(event.button.x, event.button.y)); return OnMouseUp(event.button.x, event.button.y); case SDL_QUIT: return OnClose(); #if SDL_MAJOR_VERSION < 2 case SDL_VIDEORESIZE: Resize(event.resize.w, event.resize.h); return true; #endif #if SDL_MAJOR_VERSION >= 2 case SDL_MOUSEWHEEL: int x, y; SDL_GetMouseState(&x, &y); return OnMouseWheel(x, y, event.wheel.y); case SDL_WINDOWEVENT: switch (event.window.event) { case SDL_WINDOWEVENT_RESIZED: Resize(event.window.data1, event.window.data2); return true; case SDL_WINDOWEVENT_EXPOSED: invalidated = false; Expose(); return true; } #endif } return false; }
bool TopWindow::OnEvent(const SDL_Event &event) { switch (event.type) { Window *w; #if SDL_MAJOR_VERSION < 2 case SDL_VIDEOEXPOSE: invalidated = false; Expose(); return true; #endif case SDL_KEYDOWN: w = GetFocusedWindow(); if (w == nullptr) w = this; if (!w->IsEnabled()) return false; #if SDL_MAJOR_VERSION >= 2 return w->OnKeyDown(event.key.keysym.sym); #else return w->OnKeyDown(event.key.keysym.sym) || (event.key.keysym.unicode != 0 && w->OnCharacter(event.key.keysym.unicode)); #endif #if SDL_MAJOR_VERSION >= 2 case SDL_TEXTINPUT: w = GetFocusedWindow(); if (w == nullptr) w = this; if (!w->IsEnabled()) return false; if (*event.text.text) { std::pair<unsigned, const char *> next = NextUTF8(event.text.text); bool handled = w->OnCharacter(next.first); while (next.second) { next = NextUTF8(next.second); handled = w->OnCharacter(next.first) || handled; } return handled; } else return false; #endif case SDL_KEYUP: w = GetFocusedWindow(); if (w == nullptr) w = this; if (!w->IsEnabled()) return false; return w->OnKeyUp(event.key.keysym.sym); #ifdef HAVE_MULTI_TOUCH case SDL_FINGERDOWN: if (SDL_GetNumTouchFingers(event.tfinger.touchId) == 2) return OnMultiTouchDown(); else return false; case SDL_FINGERUP: if (SDL_GetNumTouchFingers(event.tfinger.touchId) == 1) return OnMultiTouchUp(); else return false; #endif case SDL_MOUSEMOTION: // XXX keys #ifdef HAVE_HIGHDPI_SUPPORT { auto x = event.motion.x; auto y = event.motion.y; PointToReal(x, y); return OnMouseMove(x, y, 0); } #else return OnMouseMove(event.motion.x, event.motion.y, 0); #endif case SDL_MOUSEBUTTONDOWN: { #if SDL_MAJOR_VERSION < 2 if (event.button.button == SDL_BUTTON_WHEELUP) return OnMouseWheel(event.button.x, event.button.y, 1); else if (event.button.button == SDL_BUTTON_WHEELDOWN) return OnMouseWheel(event.button.x, event.button.y, -1); #endif #ifdef HAVE_HIGHDPI_SUPPORT auto x = event.button.x; auto y = event.button.y; PointToReal(x, y); return double_click.Check(RasterPoint(x, y)) ? OnMouseDouble(x, y) : OnMouseDown(x, y); #else return double_click.Check(RasterPoint(event.button.x, event.button.y)) ? OnMouseDouble(event.button.x, event.button.y) : OnMouseDown(event.button.x, event.button.y); #endif } case SDL_MOUSEBUTTONUP: { #if SDL_MAJOR_VERSION < 2 if (event.button.button == SDL_BUTTON_WHEELUP || event.button.button == SDL_BUTTON_WHEELDOWN) /* the wheel has already been handled in SDL_MOUSEBUTTONDOWN */ return false; #endif #ifdef HAVE_HIGHDPI_SUPPORT auto x = event.button.x; auto y = event.button.y; PointToReal(x, y); double_click.Moved(RasterPoint(x, y)); return OnMouseUp(x, y); #else double_click.Moved(RasterPoint(event.button.x, event.button.y)); return OnMouseUp(event.button.x, event.button.y); #endif } case SDL_QUIT: return OnClose(); #if SDL_MAJOR_VERSION < 2 case SDL_VIDEORESIZE: Resize(event.resize.w, event.resize.h); return true; #endif #if SDL_MAJOR_VERSION >= 2 case SDL_MOUSEWHEEL: { int x, y; SDL_GetMouseState(&x, &y); #ifdef HAVE_HIGHDPI_SUPPORT PointToReal(x, y); #endif return OnMouseWheel(x, y, event.wheel.y); } case SDL_WINDOWEVENT: switch (event.window.event) { case SDL_WINDOWEVENT_RESIZED: #ifndef HAVE_HIGHDPI_SUPPORT Resize(event.window.data1, event.window.data2); return true; #endif case SDL_WINDOWEVENT_RESTORED: case SDL_WINDOWEVENT_MOVED: case SDL_WINDOWEVENT_SHOWN: case SDL_WINDOWEVENT_MAXIMIZED: { SDL_Window* event_window = SDL_GetWindowFromID(event.window.windowID); if (event_window) { int w, h; SDL_GetWindowSize(event_window, &w, &h); if ((w >= 0) && (h >= 0)) { #ifdef HAVE_HIGHDPI_SUPPORT int real_w, real_h; SDL_GL_GetDrawableSize(event_window, &real_w, &real_h); point_to_real_x = static_cast<float>(real_w) / static_cast<float>(w); point_to_real_y = static_cast<float>(real_h) / static_cast<float>(h); Resize(real_w, real_h); #else Resize(w, h); #endif } #if defined(__MACOSX__) && __MACOSX__ SDL_SysWMinfo *wm_info = reinterpret_cast<SDL_SysWMinfo *>(alloca(sizeof(SDL_SysWMinfo))); SDL_VERSION(&wm_info->version); if ((SDL_GetWindowWMInfo(event_window, wm_info)) && (wm_info->subsystem == SDL_SYSWM_COCOA)) { [wm_info->info.cocoa.window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary]; } Invalidate(); #endif } } return true; case SDL_WINDOWEVENT_EXPOSED: invalidated = false; Expose(); return true; } #endif }