Mercurial > sdl-ios-xcode
annotate test/graywin.c @ 563:04dcaf3da918
Massive Quartz input enhancements from Darrell Walisser. His email:
Enclosed is a patch that addresses the following:
--Various minor cleanups.
Removed dead/obsolete code, made some style cleanups
--Mouse Events
Now keep track of what button(s) were pressed so we know when to send
the mouse up event. This fixes the case where the mouse is dragged
outside of the game window and released (in which case we want to send
the mouse up event even though the mouse is outside the game window).
--Input Grabbing
Here is my take on the grabbing situation, which is the basis for the
new implementation.
There are 3 grab states, ungrabbed (UG), visible (VG), and invisible
(IG). Both VG and IG keep the mouse constrained to the window and
produce relative motion events. In VG the cursor is visible (duh), in
IG it is not. In VG, absolute motion events also work.
There are 6 actions that can affect grabbing:
1. Set Fullscreen/Window (F/W). In fullscreen, a visible grab should do
nothing. However, a fullscreen visible grab can be treated just like a
windowed visible grab, which is what I have done to help simplify
things.
2. Cursor hide/show (H/S). If the cursor is hidden when grabbing, the
grab is an invisible grab. If the cursor is visible, the grab should
just constrain the mouse to the window.
3. Input grab/ungrab(G/U). If grabbed, the cursor should be confined to
the window as should the keyboard input. On Mac OS X, the keyboard
input is implicitly grabbed by confining the cursor, except for
command-tab which can switch away from the application. Should the
window come to the foreground if the application is deactivated and
grab input is called? This isn't necessary in this implementation
because the grab state will be asserted upon activation.
Using my notation, these are all the cases that need to be handled
(state + action = new state).
UG+U = UG
UG+G = VG or IG, if cursor is visible or not
UG+H = UG
UG+S = UG
VG+U = UG
VG+G = VG
VG+H = IG
VG+S = VG
IG+U = UG
IG+G = IG
IG+H = IG
IG+S = VG
The cases that result in the same state can be ignored in the code,
which cuts it down to just 5 cases.
Another issue is what happens when the app loses/gains input focus from
deactivate/activate or iconify/deiconify. I think that if input focus
is ever lost (outside of SDL's control), the grab state should be
suspended and the cursor should become visible and active again. When
regained, the cursor should reappear in its original location and/or
grab state. This way, when reactivating the cursor is still in the same
position as before so apps shouldn't get confused when the next motion
event comes in. This is what I've done in this patch.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Fri, 27 Dec 2002 20:52:41 +0000 |
parents | d3abe873e3f7 |
children | 609543e2b3a1 |
rev | line source |
---|---|
0 | 1 |
2 /* Simple program: Fill a colormap with gray and stripe it down the screen */ | |
3 | |
4 #include <stdio.h> | |
5 #include <stdlib.h> | |
6 #include <string.h> | |
7 #include <time.h> | |
8 | |
9 #include "SDL.h" | |
10 | |
11 #ifdef TEST_VGA16 /* Define this if you want to test VGA 16-color video modes */ | |
12 #define NUM_COLORS 16 | |
13 #else | |
14 #define NUM_COLORS 256 | |
15 #endif | |
16 | |
17 /* Draw a randomly sized and colored box centered about (X,Y) */ | |
380
bce7171e7a85
Date: Wed, 22 May 2002 22:30:58 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
18 void DrawBox(SDL_Surface *screen, int X, int Y, int width, int height) |
0 | 19 { |
20 static unsigned int seeded = 0; | |
21 SDL_Rect area; | |
22 Uint32 color; | |
23 | |
24 /* Seed the random number generator */ | |
25 if ( seeded == 0 ) { | |
26 srand(time(NULL)); | |
27 seeded = 1; | |
28 } | |
29 | |
30 /* Get the bounds of the rectangle */ | |
380
bce7171e7a85
Date: Wed, 22 May 2002 22:30:58 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
31 area.w = (rand()%width); |
bce7171e7a85
Date: Wed, 22 May 2002 22:30:58 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
32 area.h = (rand()%height); |
0 | 33 area.x = X-(area.w/2); |
34 area.y = Y-(area.h/2); | |
35 color = (rand()%NUM_COLORS); | |
36 | |
37 /* Do it! */ | |
38 SDL_FillRect(screen, &area, color); | |
538
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
39 if ( screen->flags & SDL_DOUBLEBUF ) { |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
40 SDL_Flip(screen); |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
41 } else { |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
42 SDL_UpdateRects(screen, 1, &area); |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
43 } |
0 | 44 } |
45 | |
46 SDL_Surface *CreateScreen(Uint16 w, Uint16 h, Uint8 bpp, Uint32 flags) | |
47 { | |
48 SDL_Surface *screen; | |
49 int i; | |
50 SDL_Color palette[NUM_COLORS]; | |
51 Uint8 *buffer; | |
52 | |
53 /* Set the video mode */ | |
54 screen = SDL_SetVideoMode(w, h, bpp, flags); | |
55 if ( screen == NULL ) { | |
56 fprintf(stderr, "Couldn't set display mode: %s\n", | |
57 SDL_GetError()); | |
58 return(NULL); | |
59 } | |
60 fprintf(stderr, "Screen is in %s mode\n", | |
61 (screen->flags & SDL_FULLSCREEN) ? "fullscreen" : "windowed"); | |
62 | |
63 /* Set a gray colormap, reverse order from white to black */ | |
64 for ( i=0; i<NUM_COLORS; ++i ) { | |
65 palette[i].r = (NUM_COLORS-1)-i * (256 / NUM_COLORS); | |
66 palette[i].g = (NUM_COLORS-1)-i * (256 / NUM_COLORS); | |
67 palette[i].b = (NUM_COLORS-1)-i * (256 / NUM_COLORS); | |
68 } | |
69 SDL_SetColors(screen, palette, 0, NUM_COLORS); | |
70 | |
71 /* Set the surface pixels and refresh! */ | |
538
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
72 /* Use two loops in case the surface is double-buffered (both sides) */ |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
73 for ( i=0; i<2; ++i ) { |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
74 if ( SDL_LockSurface(screen) < 0 ) { |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
75 fprintf(stderr, "Couldn't lock display surface: %s\n", |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
76 SDL_GetError()); |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
77 return(NULL); |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
78 } |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
79 buffer = (Uint8 *)screen->pixels; |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
80 for ( i=0; i<screen->h; ++i ) { |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
81 memset(buffer,(i*(NUM_COLORS-1))/screen->h, screen->w * screen->format->BytesPerPixel); |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
82 buffer += screen->pitch; |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
83 } |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
84 SDL_UnlockSurface(screen); |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
85 if ( screen->flags & SDL_DOUBLEBUF ) { |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
86 SDL_Flip(screen); |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
87 } else { |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
88 SDL_UpdateRect(screen, 0, 0, 0, 0); |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
89 } |
0 | 90 } |
91 | |
92 return(screen); | |
93 } | |
94 | |
95 int main(int argc, char *argv[]) | |
96 { | |
97 SDL_Surface *screen; | |
98 Uint32 videoflags; | |
99 int done; | |
100 SDL_Event event; | |
101 int width, height, bpp; | |
102 | |
103 /* Initialize SDL */ | |
104 if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { | |
105 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); | |
106 exit(1); | |
107 } | |
108 | |
109 /* See if we try to get a hardware colormap */ | |
110 width = 640; | |
111 height = 480; | |
112 bpp = 8; | |
113 videoflags = SDL_SWSURFACE; | |
114 while ( argc > 1 ) { | |
115 --argc; | |
116 if ( argv[argc-1] && (strcmp(argv[argc-1], "-width") == 0) ) { | |
117 width = atoi(argv[argc]); | |
118 --argc; | |
119 } else | |
120 if ( argv[argc-1] && (strcmp(argv[argc-1], "-height") == 0) ) { | |
121 height = atoi(argv[argc]); | |
122 --argc; | |
123 } else | |
124 if ( argv[argc-1] && (strcmp(argv[argc-1], "-bpp") == 0) ) { | |
125 bpp = atoi(argv[argc]); | |
126 --argc; | |
127 } else | |
128 if ( argv[argc] && (strcmp(argv[argc], "-hw") == 0) ) { | |
129 videoflags |= SDL_HWSURFACE; | |
130 } else | |
131 if ( argv[argc] && (strcmp(argv[argc], "-hwpalette") == 0) ) { | |
132 videoflags |= SDL_HWPALETTE; | |
133 } else | |
538
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
134 if ( argv[argc] && (strcmp(argv[argc], "-flip") == 0) ) { |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
135 videoflags |= SDL_DOUBLEBUF; |
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
136 } else |
0 | 137 if ( argv[argc] && (strcmp(argv[argc], "-noframe") == 0) ) { |
138 videoflags |= SDL_NOFRAME; | |
139 } else | |
140 if ( argv[argc] && (strcmp(argv[argc], "-fullscreen") == 0) ) { | |
141 videoflags |= SDL_FULLSCREEN; | |
142 } else { | |
538
d3abe873e3f7
Added support for testing video flipping with graywin.c
Sam Lantinga <slouken@libsdl.org>
parents:
380
diff
changeset
|
143 fprintf(stderr, "Usage: %s [-width] [-height] [-bpp] [-hw] [-hwpalette] [-flip] [-noframe] [-fullscreen]\n", |
0 | 144 argv[0]); |
145 exit(1); | |
146 } | |
147 } | |
148 | |
149 /* Set a video mode */ | |
150 screen = CreateScreen(width, height, bpp, videoflags); | |
151 if ( screen == NULL ) { | |
152 exit(2); | |
153 } | |
154 | |
155 /* Wait for a keystroke */ | |
156 done = 0; | |
157 while ( !done && SDL_WaitEvent(&event) ) { | |
158 switch (event.type) { | |
159 case SDL_MOUSEBUTTONDOWN: | |
380
bce7171e7a85
Date: Wed, 22 May 2002 22:30:58 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
160 DrawBox(screen, event.button.x, event.button.y, width, height); |
0 | 161 break; |
162 case SDL_KEYDOWN: | |
163 /* Ignore ALT-TAB for windows */ | |
164 if ( (event.key.keysym.sym == SDLK_LALT) || | |
165 (event.key.keysym.sym == SDLK_TAB) ) { | |
166 break; | |
167 } | |
168 /* Center the mouse on <SPACE> */ | |
169 if ( event.key.keysym.sym == SDLK_SPACE ) { | |
380
bce7171e7a85
Date: Wed, 22 May 2002 22:30:58 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
170 SDL_WarpMouse(width/2, height/2); |
0 | 171 break; |
172 } | |
173 /* Toggle fullscreen mode on <RETURN> */ | |
174 if ( event.key.keysym.sym == SDLK_RETURN ) { | |
175 videoflags ^= SDL_FULLSCREEN; | |
176 screen = CreateScreen( | |
177 screen->w, screen->h, | |
178 screen->format->BitsPerPixel, | |
179 videoflags); | |
180 if ( screen == NULL ) { | |
181 fprintf(stderr, | |
182 "Couldn't toggle fullscreen mode\n"); | |
183 done = 1; | |
184 } | |
185 break; | |
186 } | |
187 /* Any other key quits the application... */ | |
188 case SDL_QUIT: | |
189 done = 1; | |
190 break; | |
191 default: | |
192 break; | |
193 } | |
194 } | |
195 SDL_Quit(); | |
196 return(0); | |
197 } |