checkkeys.c (6370B)
1 /* 2 Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org> 3 4 This software is provided 'as-is', without any express or implied 5 warranty. In no event will the authors be held liable for any damages 6 arising from the use of this software. 7 8 Permission is granted to anyone to use this software for any purpose, 9 including commercial applications, and to alter it and redistribute it 10 freely. 11 */ 12 13 /* Simple program: Loop, watching keystrokes 14 Note that you need to call SDL_PollEvent() or SDL_WaitEvent() to 15 pump the event loop and catch keystrokes. 16 */ 17 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 22 #ifdef __EMSCRIPTEN__ 23 #include <emscripten/emscripten.h> 24 #endif 25 26 #include "SDL.h" 27 28 int done; 29 30 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ 31 static void 32 quit(int rc) 33 { 34 SDL_Quit(); 35 exit(rc); 36 } 37 38 static void 39 print_string(char **text, size_t *maxlen, const char *fmt, ...) 40 { 41 int len; 42 va_list ap; 43 44 va_start(ap, fmt); 45 len = SDL_vsnprintf(*text, *maxlen, fmt, ap); 46 if (len > 0) { 47 *text += len; 48 if ( ((size_t) len) < *maxlen ) { 49 *maxlen -= (size_t) len; 50 } else { 51 *maxlen = 0; 52 } 53 } 54 va_end(ap); 55 } 56 57 static void 58 print_modifiers(char **text, size_t *maxlen) 59 { 60 int mod; 61 print_string(text, maxlen, " modifiers:"); 62 mod = SDL_GetModState(); 63 if (!mod) { 64 print_string(text, maxlen, " (none)"); 65 return; 66 } 67 if (mod & KMOD_LSHIFT) 68 print_string(text, maxlen, " LSHIFT"); 69 if (mod & KMOD_RSHIFT) 70 print_string(text, maxlen, " RSHIFT"); 71 if (mod & KMOD_LCTRL) 72 print_string(text, maxlen, " LCTRL"); 73 if (mod & KMOD_RCTRL) 74 print_string(text, maxlen, " RCTRL"); 75 if (mod & KMOD_LALT) 76 print_string(text, maxlen, " LALT"); 77 if (mod & KMOD_RALT) 78 print_string(text, maxlen, " RALT"); 79 if (mod & KMOD_LGUI) 80 print_string(text, maxlen, " LGUI"); 81 if (mod & KMOD_RGUI) 82 print_string(text, maxlen, " RGUI"); 83 if (mod & KMOD_NUM) 84 print_string(text, maxlen, " NUM"); 85 if (mod & KMOD_CAPS) 86 print_string(text, maxlen, " CAPS"); 87 if (mod & KMOD_MODE) 88 print_string(text, maxlen, " MODE"); 89 } 90 91 static void 92 PrintModifierState() 93 { 94 char message[512]; 95 char *spot; 96 size_t left; 97 98 spot = message; 99 left = sizeof(message); 100 101 print_modifiers(&spot, &left); 102 SDL_Log("Initial state:%s\n", message); 103 } 104 105 static void 106 PrintKey(SDL_Keysym * sym, SDL_bool pressed, SDL_bool repeat) 107 { 108 char message[512]; 109 char *spot; 110 size_t left; 111 112 spot = message; 113 left = sizeof(message); 114 115 /* Print the keycode, name and state */ 116 if (sym->sym) { 117 print_string(&spot, &left, 118 "Key %s: scancode %d = %s, keycode 0x%08X = %s ", 119 pressed ? "pressed " : "released", 120 sym->scancode, 121 SDL_GetScancodeName(sym->scancode), 122 sym->sym, SDL_GetKeyName(sym->sym)); 123 } else { 124 print_string(&spot, &left, 125 "Unknown Key (scancode %d = %s) %s ", 126 sym->scancode, 127 SDL_GetScancodeName(sym->scancode), 128 pressed ? "pressed " : "released"); 129 } 130 print_modifiers(&spot, &left); 131 if (repeat) { 132 print_string(&spot, &left, " (repeat)"); 133 } 134 SDL_Log("%s\n", message); 135 } 136 137 static void 138 PrintText(char *eventtype, char *text) 139 { 140 char *spot, expanded[1024]; 141 142 expanded[0] = '\0'; 143 for ( spot = text; *spot; ++spot ) 144 { 145 size_t length = SDL_strlen(expanded); 146 SDL_snprintf(expanded + length, sizeof(expanded) - length, "\\x%.2x", (unsigned char)*spot); 147 } 148 SDL_Log("%s Text (%s): \"%s%s\"\n", eventtype, expanded, *text == '"' ? "\\" : "", text); 149 } 150 151 void 152 loop() 153 { 154 SDL_Event event; 155 /* Check for events */ 156 /*SDL_WaitEvent(&event); emscripten does not like waiting*/ 157 158 while (SDL_PollEvent(&event)) { 159 switch (event.type) { 160 case SDL_KEYDOWN: 161 case SDL_KEYUP: 162 PrintKey(&event.key.keysym, (event.key.state == SDL_PRESSED) ? SDL_TRUE : SDL_FALSE, (event.key.repeat) ? SDL_TRUE : SDL_FALSE); 163 break; 164 case SDL_TEXTEDITING: 165 PrintText("EDIT", event.text.text); 166 break; 167 case SDL_TEXTINPUT: 168 PrintText("INPUT", event.text.text); 169 break; 170 case SDL_MOUSEBUTTONDOWN: 171 /* Left button quits the app, other buttons toggles text input */ 172 if (event.button.button == SDL_BUTTON_LEFT) { 173 done = 1; 174 } else { 175 if (SDL_IsTextInputActive()) { 176 SDL_Log("Stopping text input\n"); 177 SDL_StopTextInput(); 178 } else { 179 SDL_Log("Starting text input\n"); 180 SDL_StartTextInput(); 181 } 182 } 183 break; 184 case SDL_QUIT: 185 done = 1; 186 break; 187 default: 188 break; 189 } 190 } 191 #ifdef __EMSCRIPTEN__ 192 if (done) { 193 emscripten_cancel_main_loop(); 194 } 195 #endif 196 } 197 198 int 199 main(int argc, char *argv[]) 200 { 201 SDL_Window *window; 202 203 /* Enable standard application logging */ 204 SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); 205 206 /* Initialize SDL */ 207 if (SDL_Init(SDL_INIT_VIDEO) < 0) { 208 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); 209 return (1); 210 } 211 212 /* Set 640x480 video mode */ 213 window = SDL_CreateWindow("CheckKeys Test", 214 SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 215 640, 480, 0); 216 if (!window) { 217 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create 640x480 window: %s\n", 218 SDL_GetError()); 219 quit(2); 220 } 221 222 #if __IPHONEOS__ 223 /* Creating the context creates the view, which we need to show keyboard */ 224 SDL_GL_CreateContext(window); 225 #endif 226 227 SDL_StartTextInput(); 228 229 /* Print initial modifier state */ 230 SDL_PumpEvents(); 231 PrintModifierState(); 232 233 /* Watch keystrokes */ 234 done = 0; 235 236 #ifdef __EMSCRIPTEN__ 237 emscripten_set_main_loop(loop, 0, 1); 238 #else 239 while (!done) { 240 loop(); 241 } 242 #endif 243 244 SDL_Quit(); 245 return (0); 246 } 247 248 /* vi: set ts=4 sw=4 expandtab: */