Mercurial > sdl-ios-xcode
annotate docs/html/guideinputkeyboard.html @ 4139:568c9b3c0167 SDL-1.2
* Added configure option --enable-screensaver, to allow enabling the screensaver by default.
* Use XResetScreenSaver() instead of disabling screensaver entirely.
Full discussion summary from Erik on the SDL mailing list:
Current behaviour
=================
SDL changes the user's display power management settings without
permission from the user and without telling the user.
The interface that it uses to do so is DPMSDisable/DPMSEnable, which
should only ever be used by configuration utilities like KControl, never
by normal application programs, let alone by the libraries that they
use. Using an interface that is not at all intended for what SDL tries
to achieve means that it will not work as it should. Firstly, the power
management is completely disabled during the whole lifetime of the SDL
program, not only when it should be. Secondly, it makes SDL
non-reentrant, meaning that things will break when multiple SDL programs
are clients of the same X server simultaneously. Thirdly, no cleanup
mechanism ensures that the setting is restored if the client does not do
that (for example if it crashes).
In addition to that, this interface is broken on xorg,
[http://bugs.freedesktop.org/show_bug.cgi?id=13962], so what SDL tries
to do does not work at all on that implementation of the X Window
System. (The reason that the DPMSEnable works in KControl is that it
calls DPMSSetTimeout immediately after,
[http://websvn.kde.org/tags/KDE/3.5.9/kdebase/kcontrol/energy/energy.cpp?annotate=774532#l343]).
The problems that the current behaviour causes
==============================================
1. Information leak. When the user is away, someone might see what the
user has on the display when the user counts on the screensaver
preventing this. This does not even require physical access to the
workstation, it is enough to see it from a distance.
2. Draining battery. An SDL program that runs on a laptop will quickly
drain the battery while the user is away. The system will soon shut down
and require recharging before being usable again, while it should in
fact have consumed very little energy if the user's settings would have
been obeyed.
3. Wasting energy. Even if battery issues are not considered, energy as
such is wasted.
4. Display wear. The display may be worn out.
The problems that the current behaviour tries to solve
======================================================
1. Preventing screensaver while playing movies.
Many SDL applications are media players. They have reasons to prevent
screensavers from being activated while a movie is being played. When a
user clicks on the play button it can be interpreted as saying "play
this movie, but do not turn off the display while playing it, because I
will watch it even though I do not interact with the system".
2. Preventing screensaver when some input bypasses X.
Sometimes SDL uses input from another source than the X server, so
that the X server is bypassed. This obviously breaks the screensaver
handling. SDL tries to work around that.
3. Preventing screensaver when all input bypasses X.
There is something called Direct Graphics Access mode, where a
program takes control of both the display and the input devices from the
X server. This obviously means that the X server can not handle the
screensaver alone, since screensaver handling depends on input handling.
SDL does not do what it should to help the X server to handle the
screensaver. Nor does SDL take care of screeensaver handling itself. SDL
simply disables the screensaver completely.
How the problems should be solved
=================================
The correct way for an application program to prevent the screensaver
under X is to call XResetScreenSaver. This was recently discovered and
implemented by the mplayer developers,
[http://svn.mplayerhq.hu/mplayer?view=rev&revision=25637]. SDL needs to
wrap this in an API call (SDL_ResetScreenSaver) and implement it for the
other video targets (if they do not have a corresponding call, SDL
should do what it takes on that particular target, for example sending
fake key events).
1. When a movie is played, the player should reset the screensaver when
the animation is advanced to a new frame. The same applies to anything
similar, like slideshows.
2. When the X server is handling input, it must handle all input
(keyboards, mice, gamepads, ...). This is necessary, not only to be able
to handle the screensaver, but also so that it can send the events to
the correct (the currently active) client. If there is an input device
that the X server can not handle for some reason (such as lack of Plug
and Play capability), the program that handles the device as a
workaround must simulate what would happen if the X server would have
handled the device, by calling XResetScreenSaver when input is received
from the device.
3. When the X server is not handling the input, it depends on the
program that does to call XResetScreenSaver whenever an input event
occurs. Alternatively the program must handle the screensaver countdown
internally and call XActivateScreenSaver.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 29 Feb 2008 13:55:44 +0000 |
parents | 355632dca928 |
children |
rev | line source |
---|---|
0 | 1 <HTML |
2 ><HEAD | |
3 ><TITLE | |
4 >Handling the Keyboard</TITLE | |
5 ><META | |
6 NAME="GENERATOR" | |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
7 CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ |
0 | 8 "><LINK |
9 REL="HOME" | |
10 TITLE="SDL Library Documentation" | |
11 HREF="index.html"><LINK | |
12 REL="UP" | |
13 TITLE="Input handling" | |
14 HREF="guideinput.html"><LINK | |
15 REL="PREVIOUS" | |
16 TITLE="Input handling" | |
17 HREF="guideinput.html"><LINK | |
18 REL="NEXT" | |
19 TITLE="Examples" | |
20 HREF="guideexamples.html"></HEAD | |
21 ><BODY | |
22 CLASS="SECT1" | |
23 BGCOLOR="#FFF8DC" | |
24 TEXT="#000000" | |
25 LINK="#0000ee" | |
26 VLINK="#551a8b" | |
27 ALINK="#ff0000" | |
28 ><DIV | |
29 CLASS="NAVHEADER" | |
30 ><TABLE | |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
31 SUMMARY="Header navigation table" |
0 | 32 WIDTH="100%" |
33 BORDER="0" | |
34 CELLPADDING="0" | |
35 CELLSPACING="0" | |
36 ><TR | |
37 ><TH | |
38 COLSPAN="3" | |
39 ALIGN="center" | |
40 >SDL Library Documentation</TH | |
41 ></TR | |
42 ><TR | |
43 ><TD | |
44 WIDTH="10%" | |
45 ALIGN="left" | |
46 VALIGN="bottom" | |
47 ><A | |
48 HREF="guideinput.html" | |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
49 ACCESSKEY="P" |
0 | 50 >Prev</A |
51 ></TD | |
52 ><TD | |
53 WIDTH="80%" | |
54 ALIGN="center" | |
55 VALIGN="bottom" | |
56 >Chapter 3. Input handling</TD | |
57 ><TD | |
58 WIDTH="10%" | |
59 ALIGN="right" | |
60 VALIGN="bottom" | |
61 ><A | |
62 HREF="guideexamples.html" | |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
63 ACCESSKEY="N" |
0 | 64 >Next</A |
65 ></TD | |
66 ></TR | |
67 ></TABLE | |
68 ><HR | |
69 ALIGN="LEFT" | |
70 WIDTH="100%"></DIV | |
71 ><DIV | |
72 CLASS="SECT1" | |
73 ><H1 | |
74 CLASS="SECT1" | |
75 ><A | |
76 NAME="GUIDEINPUTKEYBOARD" | |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
77 ></A |
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
78 >Handling the Keyboard</H1 |
0 | 79 ><DIV |
80 CLASS="SECT2" | |
81 ><H2 | |
82 CLASS="SECT2" | |
83 ><A | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
84 NAME="AEN271" |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
85 ></A |
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
86 >Keyboard Related Structures</H2 |
0 | 87 ><P |
88 >It should make it a lot easier to understand this tutorial is you are familiar with the data types involved in keyboard access, so I'll explain them first.</P | |
89 ><DIV | |
90 CLASS="SECT3" | |
91 ><H3 | |
92 CLASS="SECT3" | |
93 ><A | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
94 NAME="AEN274" |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
95 ></A |
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
96 >SDLKey</H3 |
0 | 97 ><P |
98 ><SPAN | |
99 CLASS="STRUCTNAME" | |
100 >SDLKey</SPAN | |
101 > is an enumerated type defined in SDL/include/SDL_keysym.h and detailed <A | |
102 HREF="sdlkey.html" | |
103 >here</A | |
104 >. Each <SPAN | |
105 CLASS="STRUCTNAME" | |
106 >SDLKey</SPAN | |
107 > symbol represents a key, <TT | |
108 CLASS="LITERAL" | |
109 >SDLK_a</TT | |
110 > corresponds to the 'a' key on a keyboard, <TT | |
111 CLASS="LITERAL" | |
112 >SDLK_SPACE</TT | |
113 > corresponds to the space bar, and so on.</P | |
114 ></DIV | |
115 ><DIV | |
116 CLASS="SECT3" | |
117 ><H3 | |
118 CLASS="SECT3" | |
119 ><A | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
120 NAME="AEN282" |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
121 ></A |
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
122 >SDLMod</H3 |
0 | 123 ><P |
124 >SDLMod is an enumerated type, similar to <SPAN | |
125 CLASS="STRUCTNAME" | |
126 >SDLKey</SPAN | |
127 >, however it enumerates keyboard modifiers (Control, Alt, Shift). The full list of modifier symbols is <A | |
128 HREF="sdlkey.html#SDLMOD" | |
129 >here</A | |
130 >. <SPAN | |
131 CLASS="STRUCTNAME" | |
132 >SDLMod</SPAN | |
133 > values can be AND'd together to represent several modifiers.</P | |
134 ></DIV | |
135 ><DIV | |
136 CLASS="SECT3" | |
137 ><H3 | |
138 CLASS="SECT3" | |
139 ><A | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
140 NAME="AEN288" |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
141 ></A |
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
142 >SDL_keysym</H3 |
0 | 143 ><PRE |
144 CLASS="PROGRAMLISTING" | |
145 >typedef struct{ | |
146 Uint8 scancode; | |
147 SDLKey sym; | |
148 SDLMod mod; | |
149 Uint16 unicode; | |
150 } SDL_keysym;</PRE | |
151 ><P | |
152 >The <SPAN | |
153 CLASS="STRUCTNAME" | |
154 >SDL_keysym</SPAN | |
155 > structure describes a key press or a key release. The <TT | |
156 CLASS="STRUCTFIELD" | |
157 ><I | |
158 >scancode</I | |
159 ></TT | |
160 > field is hardware specific and should be ignored unless you know what your doing. The <TT | |
161 CLASS="STRUCTFIELD" | |
162 ><I | |
163 >sym</I | |
164 ></TT | |
165 > field is the <SPAN | |
166 CLASS="STRUCTNAME" | |
167 >SDLKey</SPAN | |
168 > value of the key being pressed or released. The <TT | |
169 CLASS="STRUCTFIELD" | |
170 ><I | |
171 >mod</I | |
172 ></TT | |
173 > field describes the state of the keyboard modifiers at the time the key press or release occurred. So a value of <TT | |
174 CLASS="LITERAL" | |
175 >KMOD_NUM | KMOD_CAPS | KMOD_LSHIFT</TT | |
176 > would mean that Numlock, Capslock and the left shift key were all press (or enabled in the case of the lock keys). Finally, the <TT | |
177 CLASS="STRUCTFIELD" | |
178 ><I | |
179 >unicode</I | |
180 ></TT | |
181 > field stores the 16-bit unicode value of the key.</P | |
182 ><DIV | |
183 CLASS="NOTE" | |
184 ><BLOCKQUOTE | |
185 CLASS="NOTE" | |
186 ><P | |
187 ><B | |
188 >Note: </B | |
189 >It should be noted and understood that this field is only valid when the <SPAN | |
190 CLASS="STRUCTNAME" | |
191 >SDL_keysym</SPAN | |
192 > is describing a key press, not a key release. Unicode values only make sense on a key press because the unicode value describes an international character and only key presses produce characters. More information on Unicode can be found at <A | |
193 HREF="http://www.unicode.org" | |
194 TARGET="_top" | |
195 >www.unicode.org</A | |
196 ></P | |
197 ></BLOCKQUOTE | |
198 ></DIV | |
199 ><DIV | |
200 CLASS="NOTE" | |
201 ><BLOCKQUOTE | |
202 CLASS="NOTE" | |
203 ><P | |
204 ><B | |
205 >Note: </B | |
206 >Unicode translation must be enabled using the <A | |
207 HREF="sdlenableunicode.html" | |
208 ><TT | |
209 CLASS="FUNCTION" | |
210 >SDL_EnableUNICODE</TT | |
211 ></A | |
212 > function.</P | |
213 ></BLOCKQUOTE | |
214 ></DIV | |
215 ></DIV | |
216 ><DIV | |
217 CLASS="SECT3" | |
218 ><H3 | |
219 CLASS="SECT3" | |
220 ><A | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
221 NAME="AEN307" |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
222 ></A |
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
223 >SDL_KeyboardEvent</H3 |
0 | 224 ><PRE |
225 CLASS="PROGRAMLISTING" | |
226 >typedef struct{ | |
227 Uint8 type; | |
228 Uint8 state; | |
229 SDL_keysym keysym; | |
230 } SDL_KeyboardEvent;</PRE | |
231 ><P | |
232 >The <SPAN | |
233 CLASS="STRUCTNAME" | |
234 >SDL_KeyboardEvent</SPAN | |
235 > describes a keyboard event (obviously). The <TT | |
236 CLASS="STRUCTFIELD" | |
237 ><I | |
238 >key</I | |
239 ></TT | |
240 > member of the <A | |
241 HREF="sdlevent.html" | |
242 ><SPAN | |
243 CLASS="STRUCTNAME" | |
244 >SDL_Event</SPAN | |
245 ></A | |
246 > union is a <SPAN | |
247 CLASS="STRUCTNAME" | |
248 >SDL_KeyboardEvent</SPAN | |
249 > structure. The <TT | |
250 CLASS="STRUCTFIELD" | |
251 ><I | |
252 >type</I | |
253 ></TT | |
254 > field specifies whether the event is a key release (<TT | |
255 CLASS="LITERAL" | |
256 >SDL_KEYUP</TT | |
257 >) or a key press (<TT | |
258 CLASS="LITERAL" | |
259 >SDL_KEYDOWN</TT | |
260 >) event. The <TT | |
261 CLASS="STRUCTFIELD" | |
262 ><I | |
263 >state</I | |
264 ></TT | |
265 > is largely redundant, it reports the same information as the <TT | |
266 CLASS="STRUCTFIELD" | |
267 ><I | |
268 >type</I | |
269 ></TT | |
270 > field but uses different values (<TT | |
271 CLASS="LITERAL" | |
272 >SDL_RELEASED</TT | |
273 > and <TT | |
274 CLASS="LITERAL" | |
275 >SDL_PRESSED</TT | |
276 >). The <TT | |
277 CLASS="STRUCTFIELD" | |
278 ><I | |
279 >keysym</I | |
280 ></TT | |
281 > contains information of the key press or release that this event represents (see above).</P | |
282 ></DIV | |
283 ></DIV | |
284 ><DIV | |
285 CLASS="SECT2" | |
286 ><H2 | |
287 CLASS="SECT2" | |
288 ><A | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
289 NAME="AEN324" |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
290 ></A |
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
291 >Reading Keyboard Events</H2 |
0 | 292 ><P |
293 >Reading keybaord events from the event queue is quite simple (the event queue and using it is described <A | |
294 HREF="sdlevent.html" | |
295 >here</A | |
296 >). We read events using <A | |
297 HREF="sdlpollevent.html" | |
298 ><TT | |
299 CLASS="FUNCTION" | |
300 >SDL_PollEvent</TT | |
301 ></A | |
302 > in a <TT | |
303 CLASS="LITERAL" | |
304 >while()</TT | |
305 > loop and check for <TT | |
306 CLASS="LITERAL" | |
307 >SDL_KEYUP</TT | |
308 > and <TT | |
309 CLASS="LITERAL" | |
310 >SDL_KEYDOWN</TT | |
311 > events using a <TT | |
312 CLASS="LITERAL" | |
313 >switch</TT | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
314 > statement, like so:</P |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
315 ><DIV |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
316 CLASS="EXAMPLE" |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
317 ><A |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
318 NAME="AEN334" |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
319 ></A |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
320 ><P |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
321 ><B |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
322 >Example 3-10. Reading Keyboard Events</B |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
323 ></P |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
324 ><PRE |
0 | 325 CLASS="PROGRAMLISTING" |
326 > SDL_Event event; | |
327 . | |
328 . | |
329 /* Poll for events. SDL_PollEvent() returns 0 when there are no */ | |
330 /* more events on the event queue, our while loop will exit when */ | |
331 /* that occurs. */ | |
332 while( SDL_PollEvent( &event ) ){ | |
333 /* We are only worried about SDL_KEYDOWN and SDL_KEYUP events */ | |
334 switch( event.type ){ | |
335 case SDL_KEYDOWN: | |
336 printf( "Key press detected\n" ); | |
337 break; | |
338 | |
339 case SDL_KEYUP: | |
340 printf( "Key release detected\n" ); | |
341 break; | |
342 | |
343 default: | |
344 break; | |
345 } | |
346 } | |
347 . | |
348 .</PRE | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
349 ></DIV |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
350 ><P |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
351 >This is a very basic example. No information about the key press or release is interpreted. We will explore the other extreme out our first full example below - reporting all available information about a keyboard event.</P |
0 | 352 ></DIV |
353 ><DIV | |
354 CLASS="SECT2" | |
355 ><H2 | |
356 CLASS="SECT2" | |
357 ><A | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
358 NAME="AEN338" |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
359 ></A |
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
360 >A More Detailed Look</H2 |
0 | 361 ><P |
362 >Before we can read events SDL must be initialised with <A | |
363 HREF="sdlinit.html" | |
364 ><TT | |
365 CLASS="FUNCTION" | |
366 >SDL_Init</TT | |
367 ></A | |
368 > and a video mode must be set using <A | |
369 HREF="sdlsetvideomode.html" | |
370 ><TT | |
371 CLASS="FUNCTION" | |
372 >SDL_SetVideoMode</TT | |
373 ></A | |
374 >. There are, however, two other functions we must use to obtain all the information required. We must enable unicode translation by calling <TT | |
375 CLASS="FUNCTION" | |
376 >SDL_EnableUNICODE(1)</TT | |
377 > and we must convert <SPAN | |
378 CLASS="STRUCTNAME" | |
379 >SDLKey</SPAN | |
380 > values into something printable, using <A | |
381 HREF="sdlgetkeyname.html" | |
382 ><TT | |
383 CLASS="FUNCTION" | |
384 >SDL_GetKeyName</TT | |
385 ></A | |
386 ></P | |
387 ><DIV | |
388 CLASS="NOTE" | |
389 ><BLOCKQUOTE | |
390 CLASS="NOTE" | |
391 ><P | |
392 ><B | |
393 >Note: </B | |
394 >It is useful to note that unicode values < 0x80 translate directly a characters ASCII value. THis is used in the example below</P | |
395 ></BLOCKQUOTE | |
396 ></DIV | |
397 ><DIV | |
398 CLASS="EXAMPLE" | |
399 ><A | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
400 NAME="AEN351" |
0 | 401 ></A |
402 ><P | |
403 ><B | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
404 >Example 3-11. Interpreting Key Event Information</B |
0 | 405 ></P |
406 ><PRE | |
407 CLASS="PROGRAMLISTING" | |
408 > #include "SDL.h" | |
409 | |
410 /* Function Prototypes */ | |
411 void PrintKeyInfo( SDL_KeyboardEvent *key ); | |
412 void PrintModifiers( SDLMod mod ); | |
413 | |
414 /* main */ | |
415 int main( int argc, char *argv[] ){ | |
416 | |
417 SDL_Event event; | |
418 int quit = 0; | |
419 | |
420 /* Initialise SDL */ | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
421 if( SDL_Init( SDL_INIT_VIDEO ) < 0){ |
0 | 422 fprintf( stderr, "Could not initialise SDL: %s\n", SDL_GetError() ); |
423 exit( -1 ); | |
424 } | |
425 | |
426 /* Set a video mode */ | |
427 if( !SDL_SetVideoMode( 320, 200, 0, 0 ) ){ | |
428 fprintf( stderr, "Could not set video mode: %s\n", SDL_GetError() ); | |
429 SDL_Quit(); | |
430 exit( -1 ); | |
431 } | |
432 | |
433 /* Enable Unicode translation */ | |
434 SDL_EnableUNICODE( 1 ); | |
435 | |
436 /* Loop until an SDL_QUIT event is found */ | |
437 while( !quit ){ | |
438 | |
439 /* Poll for events */ | |
440 while( SDL_PollEvent( &event ) ){ | |
441 | |
442 switch( event.type ){ | |
443 /* Keyboard event */ | |
444 /* Pass the event data onto PrintKeyInfo() */ | |
445 case SDL_KEYDOWN: | |
446 case SDL_KEYUP: | |
447 PrintKeyInfo( &event.key ); | |
448 break; | |
449 | |
450 /* SDL_QUIT event (window close) */ | |
451 case SDL_QUIT: | |
452 quit = 1; | |
453 break; | |
454 | |
455 default: | |
456 break; | |
457 } | |
458 | |
459 } | |
460 | |
461 } | |
462 | |
463 /* Clean up */ | |
464 SDL_Quit(); | |
465 exit( 0 ); | |
466 } | |
467 | |
468 /* Print all information about a key event */ | |
469 void PrintKeyInfo( SDL_KeyboardEvent *key ){ | |
470 /* Is it a release or a press? */ | |
471 if( key->type == SDL_KEYUP ) | |
472 printf( "Release:- " ); | |
473 else | |
474 printf( "Press:- " ); | |
475 | |
476 /* Print the hardware scancode first */ | |
477 printf( "Scancode: 0x%02X", key->keysym.scancode ); | |
478 /* Print the name of the key */ | |
479 printf( ", Name: %s", SDL_GetKeyName( key->keysym.sym ) ); | |
480 /* We want to print the unicode info, but we need to make */ | |
481 /* sure its a press event first (remember, release events */ | |
482 /* don't have unicode info */ | |
483 if( key->type == SDL_KEYDOWN ){ | |
484 /* If the Unicode value is less than 0x80 then the */ | |
485 /* unicode value can be used to get a printable */ | |
486 /* representation of the key, using (char)unicode. */ | |
487 printf(", Unicode: " ); | |
488 if( key->keysym.unicode < 0x80 && key->keysym.unicode > 0 ){ | |
489 printf( "%c (0x%04X)", (char)key->keysym.unicode, | |
490 key->keysym.unicode ); | |
491 } | |
492 else{ | |
493 printf( "? (0x%04X)", key->keysym.unicode ); | |
494 } | |
495 } | |
496 printf( "\n" ); | |
497 /* Print modifier info */ | |
498 PrintModifiers( key->keysym.mod ); | |
499 } | |
500 | |
501 /* Print modifier info */ | |
502 void PrintModifiers( SDLMod mod ){ | |
503 printf( "Modifers: " ); | |
504 | |
505 /* If there are none then say so and return */ | |
506 if( mod == KMOD_NONE ){ | |
507 printf( "None\n" ); | |
508 return; | |
509 } | |
510 | |
511 /* Check for the presence of each SDLMod value */ | |
512 /* This looks messy, but there really isn't */ | |
513 /* a clearer way. */ | |
514 if( mod & KMOD_NUM ) printf( "NUMLOCK " ); | |
515 if( mod & KMOD_CAPS ) printf( "CAPSLOCK " ); | |
516 if( mod & KMOD_LCTRL ) printf( "LCTRL " ); | |
517 if( mod & KMOD_RCTRL ) printf( "RCTRL " ); | |
518 if( mod & KMOD_RSHIFT ) printf( "RSHIFT " ); | |
519 if( mod & KMOD_LSHIFT ) printf( "LSHIFT " ); | |
520 if( mod & KMOD_RALT ) printf( "RALT " ); | |
521 if( mod & KMOD_LALT ) printf( "LALT " ); | |
522 if( mod & KMOD_CTRL ) printf( "CTRL " ); | |
523 if( mod & KMOD_SHIFT ) printf( "SHIFT " ); | |
524 if( mod & KMOD_ALT ) printf( "ALT " ); | |
525 printf( "\n" ); | |
526 }</PRE | |
527 ></DIV | |
528 ></DIV | |
529 ><DIV | |
530 CLASS="SECT2" | |
531 ><H2 | |
532 CLASS="SECT2" | |
533 ><A | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
534 NAME="AEN354" |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
535 ></A |
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
536 >Game-type Input</H2 |
0 | 537 ><P |
538 >I have found that people using keyboard events for games and other interactive applications don't always understand one fundemental point.</P | |
539 ><A | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
540 NAME="AEN357" |
0 | 541 ></A |
542 ><BLOCKQUOTE | |
543 CLASS="BLOCKQUOTE" | |
544 ><P | |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
545 >Keyboard events <SPAN |
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
546 CLASS="emphasis" |
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
547 ><I |
0 | 548 CLASS="EMPHASIS" |
549 >only</I | |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
550 ></SPAN |
0 | 551 > take place when a keys state changes from being unpressed to pressed, and vice versa.</P |
552 ></BLOCKQUOTE | |
553 ><P | |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
554 >Imagine you have an image of an alien that you wish to move around using the cursor keys: when you pressed the left arrow key you want him to slide over to the left, and when you press the down key you want him to slide down the screen. Examine the following code; it highlights an error that many people have made. |
0 | 555 <PRE |
556 CLASS="PROGRAMLISTING" | |
557 > /* Alien screen coordinates */ | |
558 int alien_x=0, alien_y=0; | |
559 . | |
560 . | |
561 /* Initialise SDL and video modes and all that */ | |
562 . | |
563 /* Main game loop */ | |
564 /* Check for events */ | |
565 while( SDL_PollEvent( &event ) ){ | |
566 switch( event.type ){ | |
567 /* Look for a keypress */ | |
568 case SDL_KEYDOWN: | |
569 /* Check the SDLKey values and move change the coords */ | |
570 switch( event.key.keysym.sym ){ | |
571 case SDLK_LEFT: | |
572 alien_x -= 1; | |
573 break; | |
574 case SDLK_RIGHT: | |
575 alien_x += 1; | |
576 break; | |
577 case SDLK_UP: | |
578 alien_y -= 1; | |
579 break; | |
580 case SDLK_DOWN: | |
581 alien_y += 1; | |
582 break; | |
583 default: | |
584 break; | |
585 } | |
586 } | |
587 } | |
588 } | |
589 . | |
590 .</PRE | |
591 > | |
592 At first glance you may think this is a perfectly reasonable piece of code for the task, but it isn't. Like I said keyboard events only occur when a key changes state, so the user would have to press and release the left cursor key 100 times to move the alien 100 pixels to the left.</P | |
593 ><P | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
594 >To get around this problem we must not use the events to change the position of the alien, we use the events to set flags which are then used in a seperate section of code to move the alien. Something like this:</P |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
595 ><DIV |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
596 CLASS="EXAMPLE" |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
597 ><A |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
598 NAME="AEN363" |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
599 ></A |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
600 ><P |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
601 ><B |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
602 >Example 3-12. Proper Game Movement</B |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
603 ></P |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
604 ><PRE |
0 | 605 CLASS="PROGRAMLISTING" |
606 > /* Alien screen coordinates */ | |
607 int alien_x=0, alien_y=0; | |
608 int alien_xvel=0, alien_yvel=0; | |
609 . | |
610 . | |
611 /* Initialise SDL and video modes and all that */ | |
612 . | |
613 /* Main game loop */ | |
614 /* Check for events */ | |
615 while( SDL_PollEvent( &event ) ){ | |
616 switch( event.type ){ | |
617 /* Look for a keypress */ | |
618 case SDL_KEYDOWN: | |
619 /* Check the SDLKey values and move change the coords */ | |
620 switch( event.key.keysym.sym ){ | |
621 case SDLK_LEFT: | |
622 alien_xvel = -1; | |
623 break; | |
624 case SDLK_RIGHT: | |
625 alien_xvel = 1; | |
626 break; | |
627 case SDLK_UP: | |
628 alien_yvel = -1; | |
629 break; | |
630 case SDLK_DOWN: | |
631 alien_yvel = 1; | |
632 break; | |
633 default: | |
634 break; | |
635 } | |
636 break; | |
637 /* We must also use the SDL_KEYUP events to zero the x */ | |
638 /* and y velocity variables. But we must also be */ | |
639 /* careful not to zero the velocities when we shouldn't*/ | |
640 case SDL_KEYUP: | |
641 switch( event.key.keysym.sym ){ | |
642 case SDLK_LEFT: | |
643 /* We check to make sure the alien is moving */ | |
644 /* to the left. If it is then we zero the */ | |
645 /* velocity. If the alien is moving to the */ | |
646 /* right then the right key is still press */ | |
647 /* so we don't tocuh the velocity */ | |
648 if( alien_xvel < 0 ) | |
649 alien_xvel = 0; | |
650 break; | |
651 case SDLK_RIGHT: | |
652 if( alien_xvel > 0 ) | |
653 alien_xvel = 0; | |
654 break; | |
655 case SDLK_UP: | |
656 if( alien_yvel < 0 ) | |
657 alien_yvel = 0; | |
658 break; | |
659 case SDLK_DOWN: | |
660 if( alien_yvel > 0 ) | |
661 alien_yvel = 0; | |
662 break; | |
663 default: | |
664 break; | |
665 } | |
666 break; | |
667 | |
668 default: | |
669 break; | |
670 } | |
671 } | |
672 . | |
673 . | |
674 /* Update the alien position */ | |
675 alien_x += alien_xvel; | |
676 alien_y += alien_yvel;</PRE | |
55
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
677 ></DIV |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
678 ><P |
55f1f1b3e27d
Added new docs for SDL 1.2.1
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
679 >As can be seen, we use two extra variables, alien_xvel and alien_yvel, which represent the motion of the ship, it is these variables that we update when we detect keypresses and releases.</P |
0 | 680 ></DIV |
681 ></DIV | |
682 ><DIV | |
683 CLASS="NAVFOOTER" | |
684 ><HR | |
685 ALIGN="LEFT" | |
686 WIDTH="100%"><TABLE | |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
687 SUMMARY="Footer navigation table" |
0 | 688 WIDTH="100%" |
689 BORDER="0" | |
690 CELLPADDING="0" | |
691 CELLSPACING="0" | |
692 ><TR | |
693 ><TD | |
694 WIDTH="33%" | |
695 ALIGN="left" | |
696 VALIGN="top" | |
697 ><A | |
698 HREF="guideinput.html" | |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
699 ACCESSKEY="P" |
0 | 700 >Prev</A |
701 ></TD | |
702 ><TD | |
703 WIDTH="34%" | |
704 ALIGN="center" | |
705 VALIGN="top" | |
706 ><A | |
707 HREF="index.html" | |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
708 ACCESSKEY="H" |
0 | 709 >Home</A |
710 ></TD | |
711 ><TD | |
712 WIDTH="33%" | |
713 ALIGN="right" | |
714 VALIGN="top" | |
715 ><A | |
716 HREF="guideexamples.html" | |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
717 ACCESSKEY="N" |
0 | 718 >Next</A |
719 ></TD | |
720 ></TR | |
721 ><TR | |
722 ><TD | |
723 WIDTH="33%" | |
724 ALIGN="left" | |
725 VALIGN="top" | |
726 >Input handling</TD | |
727 ><TD | |
728 WIDTH="34%" | |
729 ALIGN="center" | |
730 VALIGN="top" | |
731 ><A | |
732 HREF="guideinput.html" | |
803
355632dca928
Updated SDL HTML documentation
Sam Lantinga <slouken@libsdl.org>
parents:
55
diff
changeset
|
733 ACCESSKEY="U" |
0 | 734 >Up</A |
735 ></TD | |
736 ><TD | |
737 WIDTH="33%" | |
738 ALIGN="right" | |
739 VALIGN="top" | |
740 >Examples</TD | |
741 ></TR | |
742 ></TABLE | |
743 ></DIV | |
744 ></BODY | |
745 ></HTML | |
746 > |