1/*
2 Copyright (C) 1997-2021 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
28int done;
29
30/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
31static void
32quit(int rc)
33{
34 SDL_Quit();
35 exit(rc);
36}
37
38static void
39print_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
57static void
58print_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
91static void
92PrintModifierState()
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
105static void
106PrintKey(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
137static void
138PrintText(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
151void
152loop()
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
198int
199main(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: */
249