| /* |
| Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org> |
| |
| This software is provided 'as-is', without any express or implied |
| warranty. In no event will the authors be held liable for any damages |
| arising from the use of this software. |
| |
| Permission is granted to anyone to use this software for any purpose, |
| including commercial applications, and to alter it and redistribute it |
| freely. |
| */ |
| |
| /* Simple program: Loop, watching keystrokes |
| Note that you need to call SDL_PollEvent() or SDL_WaitEvent() to |
| pump the event loop and catch keystrokes. |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #ifdef __EMSCRIPTEN__ |
| #include <emscripten/emscripten.h> |
| #endif |
| |
| #include "SDL.h" |
| #include "SDL_test_font.h" |
| |
| static SDL_Window *window; |
| static SDL_Renderer *renderer; |
| static SDLTest_TextWindow *textwin; |
| static int done; |
| |
| /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ |
| static void |
| quit(int rc) |
| { |
| SDL_Quit(); |
| exit(rc); |
| } |
| |
| static void |
| print_string(char **text, size_t *maxlen, const char *fmt, ...) |
| { |
| int len; |
| va_list ap; |
| |
| va_start(ap, fmt); |
| len = SDL_vsnprintf(*text, *maxlen, fmt, ap); |
| if (len > 0) { |
| *text += len; |
| if ( ((size_t) len) < *maxlen ) { |
| *maxlen -= (size_t) len; |
| } else { |
| *maxlen = 0; |
| } |
| } |
| va_end(ap); |
| } |
| |
| static void |
| print_modifiers(char **text, size_t *maxlen) |
| { |
| int mod; |
| print_string(text, maxlen, " modifiers:"); |
| mod = SDL_GetModState(); |
| if (!mod) { |
| print_string(text, maxlen, " (none)"); |
| return; |
| } |
| if (mod & KMOD_LSHIFT) |
| print_string(text, maxlen, " LSHIFT"); |
| if (mod & KMOD_RSHIFT) |
| print_string(text, maxlen, " RSHIFT"); |
| if (mod & KMOD_LCTRL) |
| print_string(text, maxlen, " LCTRL"); |
| if (mod & KMOD_RCTRL) |
| print_string(text, maxlen, " RCTRL"); |
| if (mod & KMOD_LALT) |
| print_string(text, maxlen, " LALT"); |
| if (mod & KMOD_RALT) |
| print_string(text, maxlen, " RALT"); |
| if (mod & KMOD_LGUI) |
| print_string(text, maxlen, " LGUI"); |
| if (mod & KMOD_RGUI) |
| print_string(text, maxlen, " RGUI"); |
| if (mod & KMOD_NUM) |
| print_string(text, maxlen, " NUM"); |
| if (mod & KMOD_CAPS) |
| print_string(text, maxlen, " CAPS"); |
| if (mod & KMOD_MODE) |
| print_string(text, maxlen, " MODE"); |
| if (mod & KMOD_SCROLL) |
| print_string(text, maxlen, " SCROLL"); |
| } |
| |
| static void |
| PrintModifierState() |
| { |
| char message[512]; |
| char *spot; |
| size_t left; |
| |
| spot = message; |
| left = sizeof(message); |
| |
| print_modifiers(&spot, &left); |
| SDL_Log("Initial state:%s\n", message); |
| } |
| |
| static void |
| PrintKey(SDL_Keysym * sym, SDL_bool pressed, SDL_bool repeat) |
| { |
| char message[512]; |
| char *spot; |
| size_t left; |
| |
| spot = message; |
| left = sizeof(message); |
| |
| /* Print the keycode, name and state */ |
| if (sym->sym) { |
| print_string(&spot, &left, |
| "Key %s: scancode %d = %s, keycode 0x%08X = %s ", |
| pressed ? "pressed " : "released", |
| sym->scancode, |
| SDL_GetScancodeName(sym->scancode), |
| sym->sym, SDL_GetKeyName(sym->sym)); |
| } else { |
| print_string(&spot, &left, |
| "Unknown Key (scancode %d = %s) %s ", |
| sym->scancode, |
| SDL_GetScancodeName(sym->scancode), |
| pressed ? "pressed " : "released"); |
| } |
| print_modifiers(&spot, &left); |
| if (repeat) { |
| print_string(&spot, &left, " (repeat)"); |
| } |
| SDL_Log("%s\n", message); |
| } |
| |
| static void |
| PrintText(const char *eventtype, const char *text) |
| { |
| const char *spot; |
| char expanded[1024]; |
| |
| expanded[0] = '\0'; |
| for ( spot = text; *spot; ++spot ) |
| { |
| size_t length = SDL_strlen(expanded); |
| SDL_snprintf(expanded + length, sizeof(expanded) - length, "\\x%.2x", (unsigned char)*spot); |
| } |
| SDL_Log("%s Text (%s): \"%s%s\"\n", eventtype, expanded, *text == '"' ? "\\" : "", text); |
| } |
| |
| void |
| loop() |
| { |
| SDL_Event event; |
| /* Check for events */ |
| /*SDL_WaitEvent(&event); emscripten does not like waiting*/ |
| |
| while (SDL_PollEvent(&event)) { |
| switch (event.type) { |
| case SDL_KEYDOWN: |
| case SDL_KEYUP: |
| PrintKey(&event.key.keysym, (event.key.state == SDL_PRESSED) ? SDL_TRUE : SDL_FALSE, (event.key.repeat) ? SDL_TRUE : SDL_FALSE); |
| if (event.type == SDL_KEYDOWN) { |
| switch (event.key.keysym.sym) { |
| case SDLK_BACKSPACE: |
| SDLTest_TextWindowAddText(textwin, "\b"); |
| break; |
| case SDLK_RETURN: |
| SDLTest_TextWindowAddText(textwin, "\n"); |
| break; |
| default: |
| break; |
| } |
| } |
| break; |
| case SDL_TEXTEDITING: |
| PrintText("EDIT", event.edit.text); |
| break; |
| case SDL_TEXTEDITING_EXT: |
| PrintText("EDIT_EXT", event.editExt.text); |
| SDL_free(event.editExt.text); |
| break; |
| case SDL_TEXTINPUT: |
| PrintText("INPUT", event.text.text); |
| SDLTest_TextWindowAddText(textwin, "%s", event.text.text); |
| break; |
| case SDL_FINGERDOWN: |
| if (SDL_IsTextInputActive()) { |
| SDL_Log("Stopping text input\n"); |
| SDL_StopTextInput(); |
| } else { |
| SDL_Log("Starting text input\n"); |
| SDL_StartTextInput(); |
| } |
| break; |
| case SDL_MOUSEBUTTONDOWN: |
| /* Left button quits the app, other buttons toggles text input */ |
| if (event.button.button == SDL_BUTTON_LEFT) { |
| done = 1; |
| } else { |
| if (SDL_IsTextInputActive()) { |
| SDL_Log("Stopping text input\n"); |
| SDL_StopTextInput(); |
| } else { |
| SDL_Log("Starting text input\n"); |
| SDL_StartTextInput(); |
| } |
| } |
| break; |
| case SDL_QUIT: |
| done = 1; |
| break; |
| default: |
| break; |
| } |
| } |
| |
| SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); |
| SDL_RenderClear(renderer); |
| SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); |
| SDLTest_TextWindowDisplay(textwin, renderer); |
| SDL_RenderPresent(renderer); |
| |
| /* Slow down framerate */ |
| SDL_Delay(100); |
| |
| #ifdef __EMSCRIPTEN__ |
| if (done) { |
| emscripten_cancel_main_loop(); |
| } |
| #endif |
| } |
| |
| int |
| main(int argc, char *argv[]) |
| { |
| /* Enable standard application logging */ |
| SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); |
| |
| /* Disable mouse emulation */ |
| SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0"); |
| |
| /* Enable extended text editing events */ |
| SDL_SetHint(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, "1"); |
| |
| /* Initialize SDL */ |
| if (SDL_Init(SDL_INIT_VIDEO) < 0) { |
| SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); |
| return (1); |
| } |
| |
| /* Set 640x480 video mode */ |
| window = SDL_CreateWindow("CheckKeys Test", |
| SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, |
| 640, 480, 0); |
| if (!window) { |
| SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create 640x480 window: %s\n", |
| SDL_GetError()); |
| quit(2); |
| } |
| |
| renderer = SDL_CreateRenderer(window, -1, 0); |
| if (!renderer) { |
| SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", |
| SDL_GetError()); |
| quit(2); |
| } |
| |
| textwin = SDLTest_TextWindowCreate(0, 0, 640, 480); |
| |
| #if __IPHONEOS__ |
| /* Creating the context creates the view, which we need to show keyboard */ |
| SDL_GL_CreateContext(window); |
| #endif |
| |
| SDL_StartTextInput(); |
| |
| /* Print initial modifier state */ |
| SDL_PumpEvents(); |
| PrintModifierState(); |
| |
| /* Watch keystrokes */ |
| done = 0; |
| |
| #ifdef __EMSCRIPTEN__ |
| emscripten_set_main_loop(loop, 0, 1); |
| #else |
| while (!done) { |
| loop(); |
| } |
| #endif |
| |
| SDL_Quit(); |
| return (0); |
| } |
| |
| /* vi: set ts=4 sw=4 expandtab: */ |