Mercurial > sdl-ios-xcode
comparison src/video/x11/SDL_x11image.c @ 1662:782fd950bd46 SDL-1.3
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.
WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.
The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce
The headers are being converted to automatically generate doxygen documentation.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 28 May 2006 13:04:16 +0000 |
parents | e49147870aac |
children | 4da1ee79c9af |
comparison
equal
deleted
inserted
replaced
1661:281d3f4870e5 | 1662:782fd950bd46 |
---|---|
30 | 30 |
31 #ifndef NO_SHARED_MEMORY | 31 #ifndef NO_SHARED_MEMORY |
32 | 32 |
33 /* Shared memory error handler routine */ | 33 /* Shared memory error handler routine */ |
34 static int shm_error; | 34 static int shm_error; |
35 static int (*X_handler)(Display *, XErrorEvent *) = NULL; | 35 static int (*X_handler) (Display *, XErrorEvent *) = NULL; |
36 static int shm_errhandler(Display *d, XErrorEvent *e) | 36 static int |
37 { | 37 shm_errhandler (Display * d, XErrorEvent * e) |
38 if ( e->error_code == BadAccess ) { | 38 { |
39 shm_error = True; | 39 if (e->error_code == BadAccess) { |
40 return(0); | 40 shm_error = True; |
41 } else | 41 return (0); |
42 return(X_handler(d,e)); | 42 } else |
43 } | 43 return (X_handler (d, e)); |
44 | 44 } |
45 static void try_mitshm(_THIS, SDL_Surface *screen) | 45 |
46 { | 46 static void |
47 /* Dynamic X11 may not have SHM entry points on this box. */ | 47 try_mitshm (_THIS, SDL_Surface * screen) |
48 if ((use_mitshm) && (!SDL_X11_HAVE_SHM)) | 48 { |
49 use_mitshm = 0; | 49 /* Dynamic X11 may not have SHM entry points on this box. */ |
50 | 50 if ((use_mitshm) && (!SDL_X11_HAVE_SHM)) |
51 if(!use_mitshm) | 51 use_mitshm = 0; |
52 return; | 52 |
53 shminfo.shmid = shmget(IPC_PRIVATE, screen->h*screen->pitch, | 53 if (!use_mitshm) |
54 IPC_CREAT | 0777); | 54 return; |
55 if ( shminfo.shmid >= 0 ) { | 55 shminfo.shmid = shmget (IPC_PRIVATE, screen->h * screen->pitch, |
56 shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0); | 56 IPC_CREAT | 0777); |
57 shminfo.readOnly = False; | 57 if (shminfo.shmid >= 0) { |
58 if ( shminfo.shmaddr != (char *)-1 ) { | 58 shminfo.shmaddr = (char *) shmat (shminfo.shmid, 0, 0); |
59 shm_error = False; | 59 shminfo.readOnly = False; |
60 X_handler = XSetErrorHandler(shm_errhandler); | 60 if (shminfo.shmaddr != (char *) -1) { |
61 XShmAttach(SDL_Display, &shminfo); | 61 shm_error = False; |
62 XSync(SDL_Display, True); | 62 X_handler = XSetErrorHandler (shm_errhandler); |
63 XSetErrorHandler(X_handler); | 63 XShmAttach (SDL_Display, &shminfo); |
64 if ( shm_error ) | 64 XSync (SDL_Display, True); |
65 shmdt(shminfo.shmaddr); | 65 XSetErrorHandler (X_handler); |
66 } else { | 66 if (shm_error) |
67 shm_error = True; | 67 shmdt (shminfo.shmaddr); |
68 } | 68 } else { |
69 shmctl(shminfo.shmid, IPC_RMID, NULL); | 69 shm_error = True; |
70 } else { | 70 } |
71 shm_error = True; | 71 shmctl (shminfo.shmid, IPC_RMID, NULL); |
72 } | 72 } else { |
73 if ( shm_error ) | 73 shm_error = True; |
74 use_mitshm = 0; | 74 } |
75 if ( use_mitshm ) | 75 if (shm_error) |
76 screen->pixels = shminfo.shmaddr; | 76 use_mitshm = 0; |
77 if (use_mitshm) | |
78 screen->pixels = shminfo.shmaddr; | |
77 } | 79 } |
78 #endif /* ! NO_SHARED_MEMORY */ | 80 #endif /* ! NO_SHARED_MEMORY */ |
79 | 81 |
80 /* Various screen update functions available */ | 82 /* Various screen update functions available */ |
81 static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); | 83 static void X11_NormalUpdate (_THIS, int numrects, SDL_Rect * rects); |
82 static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects); | 84 static void X11_MITSHMUpdate (_THIS, int numrects, SDL_Rect * rects); |
83 | 85 |
84 int X11_SetupImage(_THIS, SDL_Surface *screen) | 86 int |
85 { | 87 X11_SetupImage (_THIS, SDL_Surface * screen) |
86 #ifndef NO_SHARED_MEMORY | 88 { |
87 try_mitshm(this, screen); | 89 #ifndef NO_SHARED_MEMORY |
88 if(use_mitshm) { | 90 try_mitshm (this, screen); |
89 SDL_Ximage = XShmCreateImage(SDL_Display, SDL_Visual, | 91 if (use_mitshm) { |
90 this->hidden->depth, ZPixmap, | 92 SDL_Ximage = XShmCreateImage (SDL_Display, SDL_Visual, |
91 shminfo.shmaddr, &shminfo, | 93 this->hidden->depth, ZPixmap, |
92 screen->w, screen->h); | 94 shminfo.shmaddr, &shminfo, |
93 if(!SDL_Ximage) { | 95 screen->w, screen->h); |
94 XShmDetach(SDL_Display, &shminfo); | 96 if (!SDL_Ximage) { |
95 XSync(SDL_Display, False); | 97 XShmDetach (SDL_Display, &shminfo); |
96 shmdt(shminfo.shmaddr); | 98 XSync (SDL_Display, False); |
97 screen->pixels = NULL; | 99 shmdt (shminfo.shmaddr); |
98 goto error; | 100 screen->pixels = NULL; |
99 } | 101 goto error; |
100 this->UpdateRects = X11_MITSHMUpdate; | 102 } |
101 } | 103 this->UpdateRects = X11_MITSHMUpdate; |
102 if(!use_mitshm) | 104 } |
105 if (!use_mitshm) | |
103 #endif /* not NO_SHARED_MEMORY */ | 106 #endif /* not NO_SHARED_MEMORY */ |
104 { | 107 { |
105 int bpp; | 108 int bpp; |
106 screen->pixels = SDL_malloc(screen->h*screen->pitch); | 109 screen->pixels = SDL_malloc (screen->h * screen->pitch); |
107 if ( screen->pixels == NULL ) { | 110 if (screen->pixels == NULL) { |
108 SDL_OutOfMemory(); | 111 SDL_OutOfMemory (); |
109 return -1; | 112 return -1; |
110 } | 113 } |
111 bpp = screen->format->BytesPerPixel; | 114 bpp = screen->format->BytesPerPixel; |
112 SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual, | 115 SDL_Ximage = XCreateImage (SDL_Display, SDL_Visual, |
113 this->hidden->depth, ZPixmap, 0, | 116 this->hidden->depth, ZPixmap, 0, |
114 (char *)screen->pixels, | 117 (char *) screen->pixels, |
115 screen->w, screen->h, | 118 screen->w, screen->h, 32, 0); |
116 32, 0); | 119 if (SDL_Ximage == NULL) |
117 if ( SDL_Ximage == NULL ) | 120 goto error; |
118 goto error; | 121 /* XPutImage will convert byte sex automatically */ |
119 /* XPutImage will convert byte sex automatically */ | 122 SDL_Ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN) |
120 SDL_Ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN) | 123 ? MSBFirst : LSBFirst; |
121 ? MSBFirst : LSBFirst; | 124 this->UpdateRects = X11_NormalUpdate; |
122 this->UpdateRects = X11_NormalUpdate; | 125 } |
123 } | 126 screen->pitch = SDL_Ximage->bytes_per_line; |
124 screen->pitch = SDL_Ximage->bytes_per_line; | 127 return (0); |
125 return(0); | 128 |
126 | 129 error: |
127 error: | 130 SDL_SetError ("Couldn't create XImage"); |
128 SDL_SetError("Couldn't create XImage"); | 131 return 1; |
129 return 1; | 132 } |
130 } | 133 |
131 | 134 void |
132 void X11_DestroyImage(_THIS, SDL_Surface *screen) | 135 X11_DestroyImage (_THIS, SDL_Surface * screen) |
133 { | 136 { |
134 if ( SDL_Ximage ) { | 137 if (SDL_Ximage) { |
135 XDestroyImage(SDL_Ximage); | 138 XDestroyImage (SDL_Ximage); |
136 #ifndef NO_SHARED_MEMORY | 139 #ifndef NO_SHARED_MEMORY |
137 if ( use_mitshm ) { | 140 if (use_mitshm) { |
138 XShmDetach(SDL_Display, &shminfo); | 141 XShmDetach (SDL_Display, &shminfo); |
139 XSync(SDL_Display, False); | 142 XSync (SDL_Display, False); |
140 shmdt(shminfo.shmaddr); | 143 shmdt (shminfo.shmaddr); |
141 } | 144 } |
142 #endif /* ! NO_SHARED_MEMORY */ | 145 #endif /* ! NO_SHARED_MEMORY */ |
143 SDL_Ximage = NULL; | 146 SDL_Ximage = NULL; |
144 } | 147 } |
145 if ( screen ) { | 148 if (screen) { |
146 screen->pixels = NULL; | 149 screen->pixels = NULL; |
147 } | 150 } |
148 } | 151 } |
149 | 152 |
150 /* Determine the number of CPUs in the system */ | 153 /* Determine the number of CPUs in the system */ |
151 static int num_CPU(void) | 154 static int |
152 { | 155 num_CPU (void) |
153 static int num_cpus = 0; | 156 { |
154 | 157 static int num_cpus = 0; |
155 if(!num_cpus) { | 158 |
159 if (!num_cpus) { | |
156 #if defined(__LINUX__) | 160 #if defined(__LINUX__) |
157 char line[BUFSIZ]; | 161 char line[BUFSIZ]; |
158 FILE *pstat = fopen("/proc/stat", "r"); | 162 FILE *pstat = fopen ("/proc/stat", "r"); |
159 if ( pstat ) { | 163 if (pstat) { |
160 while ( fgets(line, sizeof(line), pstat) ) { | 164 while (fgets (line, sizeof (line), pstat)) { |
161 if (SDL_memcmp(line, "cpu", 3) == 0 && line[3] != ' ') { | 165 if (SDL_memcmp (line, "cpu", 3) == 0 && line[3] != ' ') { |
162 ++num_cpus; | 166 ++num_cpus; |
163 } | 167 } |
164 } | 168 } |
165 fclose(pstat); | 169 fclose (pstat); |
166 } | 170 } |
167 #elif defined(__IRIX__) | 171 #elif defined(__IRIX__) |
168 num_cpus = sysconf(_SC_NPROC_ONLN); | 172 num_cpus = sysconf (_SC_NPROC_ONLN); |
169 #elif defined(_SC_NPROCESSORS_ONLN) | 173 #elif defined(_SC_NPROCESSORS_ONLN) |
170 /* number of processors online (SVR4.0MP compliant machines) */ | 174 /* number of processors online (SVR4.0MP compliant machines) */ |
171 num_cpus = sysconf(_SC_NPROCESSORS_ONLN); | 175 num_cpus = sysconf (_SC_NPROCESSORS_ONLN); |
172 #elif defined(_SC_NPROCESSORS_CONF) | 176 #elif defined(_SC_NPROCESSORS_CONF) |
173 /* number of processors configured (SVR4.0MP compliant machines) */ | 177 /* number of processors configured (SVR4.0MP compliant machines) */ |
174 num_cpus = sysconf(_SC_NPROCESSORS_CONF); | 178 num_cpus = sysconf (_SC_NPROCESSORS_CONF); |
175 #endif | 179 #endif |
176 if ( num_cpus <= 0 ) { | 180 if (num_cpus <= 0) { |
177 num_cpus = 1; | 181 num_cpus = 1; |
178 } | 182 } |
179 } | 183 } |
180 return num_cpus; | 184 return num_cpus; |
181 } | 185 } |
182 | 186 |
183 int X11_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags) | 187 int |
184 { | 188 X11_ResizeImage (_THIS, SDL_Surface * screen, Uint32 flags) |
185 int retval; | 189 { |
186 | 190 int retval; |
187 X11_DestroyImage(this, screen); | 191 |
188 if ( flags & SDL_INTERNALOPENGL ) { /* No image when using GL */ | 192 X11_DestroyImage (this, screen); |
189 retval = 0; | 193 if (flags & SDL_INTERNALOPENGL) { /* No image when using GL */ |
190 } else { | 194 retval = 0; |
191 retval = X11_SetupImage(this, screen); | 195 } else { |
192 /* We support asynchronous blitting on the display */ | 196 retval = X11_SetupImage (this, screen); |
193 if ( flags & SDL_ASYNCBLIT ) { | 197 /* We support asynchronous blitting on the display */ |
194 /* This is actually slower on single-CPU systems, | 198 if (flags & SDL_ASYNCBLIT) { |
195 probably because of CPU contention between the | 199 /* This is actually slower on single-CPU systems, |
196 X server and the application. | 200 probably because of CPU contention between the |
197 Note: Is this still true with XFree86 4.0? | 201 X server and the application. |
198 */ | 202 Note: Is this still true with XFree86 4.0? |
199 if ( num_CPU() > 1 ) { | 203 */ |
200 screen->flags |= SDL_ASYNCBLIT; | 204 if (num_CPU () > 1) { |
201 } | 205 screen->flags |= SDL_ASYNCBLIT; |
202 } | 206 } |
203 } | 207 } |
204 return(retval); | 208 } |
209 return (retval); | |
205 } | 210 } |
206 | 211 |
207 /* We don't actually allow hardware surfaces other than the main one */ | 212 /* We don't actually allow hardware surfaces other than the main one */ |
208 int X11_AllocHWSurface(_THIS, SDL_Surface *surface) | 213 int |
209 { | 214 X11_AllocHWSurface (_THIS, SDL_Surface * surface) |
210 return(-1); | 215 { |
211 } | 216 return (-1); |
212 void X11_FreeHWSurface(_THIS, SDL_Surface *surface) | 217 } |
213 { | 218 |
214 return; | 219 void |
215 } | 220 X11_FreeHWSurface (_THIS, SDL_Surface * surface) |
216 | 221 { |
217 int X11_LockHWSurface(_THIS, SDL_Surface *surface) | 222 return; |
218 { | 223 } |
219 if ( (surface == SDL_VideoSurface) && blit_queued ) { | 224 |
220 XSync(GFX_Display, False); | 225 int |
221 blit_queued = 0; | 226 X11_LockHWSurface (_THIS, SDL_Surface * surface) |
222 } | 227 { |
223 return(0); | 228 if ((surface == SDL_VideoSurface) && blit_queued) { |
224 } | 229 XSync (GFX_Display, False); |
225 void X11_UnlockHWSurface(_THIS, SDL_Surface *surface) | 230 blit_queued = 0; |
226 { | 231 } |
227 return; | 232 return (0); |
228 } | 233 } |
229 | 234 |
230 int X11_FlipHWSurface(_THIS, SDL_Surface *surface) | 235 void |
231 { | 236 X11_UnlockHWSurface (_THIS, SDL_Surface * surface) |
232 return(0); | 237 { |
233 } | 238 return; |
234 | 239 } |
235 static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) | 240 |
236 { | 241 int |
237 int i; | 242 X11_FlipHWSurface (_THIS, SDL_Surface * surface) |
238 | 243 { |
239 for (i = 0; i < numrects; ++i) { | 244 return (0); |
240 if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */ | 245 } |
241 continue; | 246 |
242 } | 247 static void |
243 XPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, | 248 X11_NormalUpdate (_THIS, int numrects, SDL_Rect * rects) |
244 rects[i].x, rects[i].y, | 249 { |
245 rects[i].x, rects[i].y, rects[i].w, rects[i].h); | 250 int i; |
246 } | 251 |
247 if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) { | 252 for (i = 0; i < numrects; ++i) { |
248 XFlush(GFX_Display); | 253 if (rects[i].w == 0 || rects[i].h == 0) { /* Clipped? */ |
249 blit_queued = 1; | 254 continue; |
250 } else { | 255 } |
251 XSync(GFX_Display, False); | 256 XPutImage (GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, |
252 } | 257 rects[i].x, rects[i].y, |
253 } | 258 rects[i].x, rects[i].y, rects[i].w, rects[i].h); |
254 | 259 } |
255 static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects) | 260 if (SDL_VideoSurface->flags & SDL_ASYNCBLIT) { |
256 { | 261 XFlush (GFX_Display); |
257 #ifndef NO_SHARED_MEMORY | 262 blit_queued = 1; |
258 int i; | 263 } else { |
259 | 264 XSync (GFX_Display, False); |
260 for ( i=0; i<numrects; ++i ) { | 265 } |
261 if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */ | 266 } |
262 continue; | 267 |
263 } | 268 static void |
264 XShmPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, | 269 X11_MITSHMUpdate (_THIS, int numrects, SDL_Rect * rects) |
265 rects[i].x, rects[i].y, | 270 { |
266 rects[i].x, rects[i].y, rects[i].w, rects[i].h, | 271 #ifndef NO_SHARED_MEMORY |
267 False); | 272 int i; |
268 } | 273 |
269 if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) { | 274 for (i = 0; i < numrects; ++i) { |
270 XFlush(GFX_Display); | 275 if (rects[i].w == 0 || rects[i].h == 0) { /* Clipped? */ |
271 blit_queued = 1; | 276 continue; |
272 } else { | 277 } |
273 XSync(GFX_Display, False); | 278 XShmPutImage (GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, |
274 } | 279 rects[i].x, rects[i].y, |
280 rects[i].x, rects[i].y, rects[i].w, rects[i].h, False); | |
281 } | |
282 if (SDL_VideoSurface->flags & SDL_ASYNCBLIT) { | |
283 XFlush (GFX_Display); | |
284 blit_queued = 1; | |
285 } else { | |
286 XSync (GFX_Display, False); | |
287 } | |
275 #endif /* ! NO_SHARED_MEMORY */ | 288 #endif /* ! NO_SHARED_MEMORY */ |
276 } | 289 } |
277 | 290 |
278 /* There's a problem with the automatic refreshing of the display. | 291 /* There's a problem with the automatic refreshing of the display. |
279 Even though the XVideo code uses the GFX_Display to update the | 292 Even though the XVideo code uses the GFX_Display to update the |
281 from a different thread will cause "blackouts" of the window. | 294 from a different thread will cause "blackouts" of the window. |
282 This is a sort of a hacked workaround for the problem. | 295 This is a sort of a hacked workaround for the problem. |
283 */ | 296 */ |
284 static int enable_autorefresh = 1; | 297 static int enable_autorefresh = 1; |
285 | 298 |
286 void X11_DisableAutoRefresh(_THIS) | 299 void |
287 { | 300 X11_DisableAutoRefresh (_THIS) |
288 --enable_autorefresh; | 301 { |
289 } | 302 --enable_autorefresh; |
290 | 303 } |
291 void X11_EnableAutoRefresh(_THIS) | 304 |
292 { | 305 void |
293 ++enable_autorefresh; | 306 X11_EnableAutoRefresh (_THIS) |
294 } | 307 { |
295 | 308 ++enable_autorefresh; |
296 void X11_RefreshDisplay(_THIS) | 309 } |
297 { | 310 |
298 /* Don't refresh a display that doesn't have an image (like GL) | 311 void |
299 Instead, post an expose event so the application can refresh. | 312 X11_RefreshDisplay (_THIS) |
300 */ | 313 { |
301 if ( ! SDL_Ximage || (enable_autorefresh <= 0) ) { | 314 /* Don't refresh a display that doesn't have an image (like GL) |
302 SDL_PrivateExpose(); | 315 Instead, post an expose event so the application can refresh. |
303 return; | 316 */ |
304 } | 317 if (!SDL_Ximage || (enable_autorefresh <= 0)) { |
305 #ifndef NO_SHARED_MEMORY | 318 SDL_PrivateExpose (); |
306 if ( this->UpdateRects == X11_MITSHMUpdate ) { | 319 return; |
307 XShmPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, | 320 } |
308 0, 0, 0, 0, this->screen->w, this->screen->h, | 321 #ifndef NO_SHARED_MEMORY |
309 False); | 322 if (this->UpdateRects == X11_MITSHMUpdate) { |
310 } else | 323 XShmPutImage (SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, |
324 0, 0, SDL_CurrentWindow.offset_x, | |
325 SDL_CurrentWindow.offset_y, | |
326 SDL_CurrentDisplay.current_mode.w, | |
327 SDL_CurrentDisplay.current_mode.h, False); | |
328 } else | |
311 #endif /* ! NO_SHARED_MEMORY */ | 329 #endif /* ! NO_SHARED_MEMORY */ |
312 { | 330 { |
313 XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, | 331 XPutImage (SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, |
314 0, 0, 0, 0, this->screen->w, this->screen->h); | 332 0, 0, SDL_CurrentWindow.offset_x, |
315 } | 333 SDL_CurrentWindow.offset_y, |
316 XSync(SDL_Display, False); | 334 SDL_CurrentDisplay.current_mode.w, |
317 } | 335 SDL_CurrentDisplay.current_mode.h); |
318 | 336 } |
337 XSync (SDL_Display, False); | |
338 } | |
339 | |
340 /* vi: set ts=4 sw=4 expandtab: */ |