Mercurial > sdl-ios-xcode
annotate src/video/SDL_gamma.c @ 816:428f688f2ad2
Date: Fri, 13 Feb 2004 17:03:16 +0100
From: Max Horn
Subject: Modifier key fix
The internal modifier state can get out of sync with reality. To
trigger this, do for example this:
1) Launch an SDL app
2) Alt-click on the desktop (this will hide the SDL app).
3) Bring the SDL app back to the front
4) SDL will still think alt is pressed (and as such will treat left
clicks like middle clicks). If you press and release alt, it'll be fine
again.
The attached patch cures this by rechecking the modifier state whenever
we process an event.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 13 Feb 2004 17:57:16 +0000 |
parents | b8d311d90021 |
children | c9b51268668f |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
669
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
152
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* Gamma correction support */ | |
29 | |
30 #define USE_MATH_H /* Used for calculating gamma ramps */ | |
31 | |
32 #ifdef USE_MATH_H | |
33 #include <math.h> | |
34 #endif | |
35 #include <stdlib.h> | |
152 | 36 #include <string.h> |
0 | 37 |
38 #include "SDL_error.h" | |
39 #include "SDL_sysvideo.h" | |
40 | |
41 #ifdef USE_MATH_H | |
42 static void CalculateGammaRamp(float gamma, Uint16 *ramp) | |
43 { | |
44 int i; | |
45 | |
46 /* 0.0 gamma is all black */ | |
47 if ( gamma <= 0.0 ) { | |
48 for ( i=0; i<256; ++i ) { | |
49 ramp[i] = 0; | |
50 } | |
51 return; | |
52 } else | |
53 /* 1.0 gamma is identity */ | |
54 if ( gamma == 1.0 ) { | |
55 for ( i=0; i<256; ++i ) { | |
56 ramp[i] = (i << 8) | i; | |
57 } | |
58 return; | |
59 } else | |
60 /* Calculate a real gamma ramp */ | |
61 { int value; | |
62 gamma = 1.0f / gamma; | |
63 for ( i=0; i<256; ++i ) { | |
64 value = (int)(pow((double)i/256.0, gamma)*65535.0+0.5); | |
65 if ( value > 65535 ) { | |
66 value = 65535; | |
67 } | |
68 ramp[i] = (Uint16)value; | |
69 } | |
70 } | |
71 } | |
72 static void CalculateGammaFromRamp(float *gamma, Uint16 *ramp) | |
73 { | |
74 /* The following is adapted from a post by Garrett Bass on OpenGL | |
75 Gamedev list, March 4, 2000. | |
76 */ | |
77 float sum = 0.0; | |
78 int i, count = 0; | |
79 | |
80 *gamma = 1.0; | |
81 for ( i = 1; i < 256; ++i ) { | |
82 if ( (ramp[i] != 0) && (ramp[i] != 65535) ) { | |
83 double B = (double)i / 256.0; | |
84 double A = ramp[i] / 65535.0; | |
85 sum += (float) ( log(A) / log(B) ); | |
86 count++; | |
87 } | |
88 } | |
89 if ( count && sum ) { | |
90 *gamma = 1.0f / (sum / count); | |
91 } | |
92 } | |
93 #endif /* USE_MATH_H */ | |
94 | |
95 int SDL_SetGamma(float red, float green, float blue) | |
96 { | |
97 int succeeded; | |
98 SDL_VideoDevice *video = current_video; | |
99 SDL_VideoDevice *this = current_video; | |
100 | |
101 succeeded = -1; | |
102 #ifdef USE_MATH_H | |
103 /* Prefer using SetGammaRamp(), as it's more flexible */ | |
104 { | |
105 Uint16 ramp[3][256]; | |
106 | |
107 CalculateGammaRamp(red, ramp[0]); | |
108 CalculateGammaRamp(green, ramp[1]); | |
109 CalculateGammaRamp(blue, ramp[2]); | |
110 succeeded = SDL_SetGammaRamp(ramp[0], ramp[1], ramp[2]); | |
111 } | |
112 #else | |
113 SDL_SetError("Gamma correction not supported"); | |
114 #endif | |
115 if ( (succeeded < 0) && video->SetGamma ) { | |
116 SDL_ClearError(); | |
117 succeeded = video->SetGamma(this, red, green, blue); | |
118 } | |
119 return succeeded; | |
120 } | |
121 | |
122 /* Calculating the gamma by integrating the gamma ramps isn't exact, | |
123 so this function isn't officially supported. | |
124 */ | |
125 int SDL_GetGamma(float *red, float *green, float *blue) | |
126 { | |
127 int succeeded; | |
128 SDL_VideoDevice *video = current_video; | |
129 SDL_VideoDevice *this = current_video; | |
130 | |
131 succeeded = -1; | |
132 #ifdef USE_MATH_H | |
133 /* Prefer using GetGammaRamp(), as it's more flexible */ | |
134 { | |
135 Uint16 ramp[3][256]; | |
136 | |
137 succeeded = SDL_GetGammaRamp(ramp[0], ramp[1], ramp[2]); | |
138 if ( succeeded >= 0 ) { | |
139 CalculateGammaFromRamp(red, ramp[0]); | |
140 CalculateGammaFromRamp(green, ramp[1]); | |
141 CalculateGammaFromRamp(blue, ramp[2]); | |
142 } | |
143 } | |
144 #else | |
145 SDL_SetError("Gamma correction not supported"); | |
146 #endif | |
147 if ( (succeeded < 0) && video->GetGamma ) { | |
148 SDL_ClearError(); | |
149 succeeded = video->GetGamma(this, red, green, blue); | |
150 } | |
151 return succeeded; | |
152 } | |
153 | |
669
37bb90b3d976
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
154 int SDL_SetGammaRamp(const Uint16 *red, const Uint16 *green, const Uint16 *blue) |
0 | 155 { |
156 int succeeded; | |
157 SDL_VideoDevice *video = current_video; | |
158 SDL_VideoDevice *this = current_video; | |
159 SDL_Surface *screen = SDL_PublicSurface; | |
160 | |
161 /* Verify the screen parameter */ | |
162 if ( !screen ) { | |
163 SDL_SetError("No video mode has been set"); | |
164 return -1; | |
165 } | |
166 | |
167 /* Lazily allocate the gamma tables */ | |
168 if ( ! video->gamma ) { | |
169 SDL_GetGammaRamp(0, 0, 0); | |
170 } | |
171 | |
172 /* Fill the gamma table with the new values */ | |
173 if ( red ) { | |
174 memcpy(&video->gamma[0*256], red, 256*sizeof(*video->gamma)); | |
175 } | |
176 if ( green ) { | |
177 memcpy(&video->gamma[1*256], green, 256*sizeof(*video->gamma)); | |
178 } | |
179 if ( blue ) { | |
180 memcpy(&video->gamma[2*256], blue, 256*sizeof(*video->gamma)); | |
181 } | |
182 | |
183 /* Gamma correction always possible on split palettes */ | |
184 if ( (screen->flags & SDL_HWPALETTE) == SDL_HWPALETTE ) { | |
185 SDL_Palette *pal = screen->format->palette; | |
186 | |
187 /* If physical palette has been set independently, use it */ | |
188 if(video->physpal) | |
189 pal = video->physpal; | |
190 | |
191 SDL_SetPalette(screen, SDL_PHYSPAL, | |
192 pal->colors, 0, pal->ncolors); | |
193 return 0; | |
194 } | |
195 | |
196 /* Try to set the gamma ramp in the driver */ | |
197 succeeded = -1; | |
198 if ( video->SetGammaRamp ) { | |
199 succeeded = video->SetGammaRamp(this, video->gamma); | |
200 } else { | |
201 SDL_SetError("Gamma ramp manipulation not supported"); | |
202 } | |
203 return succeeded; | |
204 } | |
205 | |
206 int SDL_GetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue) | |
207 { | |
208 SDL_VideoDevice *video = current_video; | |
209 SDL_VideoDevice *this = current_video; | |
210 | |
211 /* Lazily allocate the gamma table */ | |
212 if ( ! video->gamma ) { | |
213 video->gamma = malloc(3*256*sizeof(*video->gamma)); | |
214 if ( ! video->gamma ) { | |
215 SDL_OutOfMemory(); | |
216 return -1; | |
217 } | |
218 if ( video->GetGammaRamp ) { | |
219 /* Get the real hardware gamma */ | |
220 video->GetGammaRamp(this, video->gamma); | |
221 } else { | |
222 /* Assume an identity gamma */ | |
223 int i; | |
224 for ( i=0; i<256; ++i ) { | |
225 video->gamma[0*256+i] = (i << 8) | i; | |
226 video->gamma[1*256+i] = (i << 8) | i; | |
227 video->gamma[2*256+i] = (i << 8) | i; | |
228 } | |
229 } | |
230 } | |
231 | |
232 /* Just copy from our internal table */ | |
233 if ( red ) { | |
234 memcpy(red, &video->gamma[0*256], 256*sizeof(*red)); | |
235 } | |
236 if ( green ) { | |
237 memcpy(green, &video->gamma[1*256], 256*sizeof(*green)); | |
238 } | |
239 if ( blue ) { | |
240 memcpy(blue, &video->gamma[2*256], 256*sizeof(*blue)); | |
241 } | |
242 return 0; | |
243 } |