comparison src/video/photon/SDL_ph_video.c @ 0:74212992fb08

Initial revision
author Sam Lantinga <slouken@lokigames.com>
date Thu, 26 Apr 2001 16:45:43 +0000
parents
children 8cc4dbfab9ab
comparison
equal deleted inserted replaced
-1:000000000000 0:74212992fb08
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
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
20 slouken@devolution.com
21 */
22
23 #ifdef SAVE_RCSID
24 static char rcsid =
25 "@(#) $Id$";
26 #endif
27
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <sys/ioctl.h>
33
34 #include "SDL.h"
35 #include "SDL_error.h"
36 #include "SDL_timer.h"
37 #include "SDL_thread.h"
38 #include "SDL_video.h"
39 #include "SDL_mouse.h"
40 #include "SDL_endian.h"
41 #include "SDL_sysvideo.h"
42 #include "SDL_pixels_c.h"
43 #include "SDL_events_c.h"
44 #include "SDL_ph_video.h"
45 #include "SDL_ph_modes_c.h"
46 #include "SDL_ph_image_c.h"
47 #include "SDL_ph_events_c.h"
48 #include "SDL_ph_mouse_c.h"
49 #include "SDL_phyuv_c.h"
50 #include "blank_cursor.h"
51
52 static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat);
53 static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current,
54 int width, int height, int bpp, Uint32 flags);
55 static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
56 static void ph_VideoQuit(_THIS);
57 static void ph_DeleteDevice(SDL_VideoDevice *device);
58
59 static int ph_Available(void)
60 {
61
62 return 1;
63 }
64
65 static SDL_VideoDevice *ph_CreateDevice(int devindex)
66 {
67 SDL_VideoDevice *device;
68
69 /* Initialize all variables that we clean on shutdown */
70 device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
71 if ( device ) {
72 memset(device, 0, (sizeof *device));
73 device->hidden = (struct SDL_PrivateVideoData *)
74 malloc((sizeof *device->hidden));
75 device->gl_data = NULL;
76 }
77 if ( (device == NULL) || (device->hidden == NULL) ) {
78 SDL_OutOfMemory();
79 ph_DeleteDevice(device);
80 return(0);
81 }
82 memset(device->hidden, 0, (sizeof *device->hidden));
83
84 /* Set the driver flags */
85 device->handles_any_size = 1; //JB not true for fullscreen
86
87 /* Set the function pointers */
88 device->CreateYUVOverlay = ph_CreateYUVOverlay;
89 device->VideoInit = ph_VideoInit;
90 device->ListModes = ph_ListModes;
91 device->SetVideoMode = ph_SetVideoMode;
92 device->ToggleFullScreen = ph_ToggleFullScreen;
93 device->UpdateMouse = NULL;
94 device->SetColors = ph_SetColors;
95 device->UpdateRects = NULL; //set in ph_ResizeImage
96 device->VideoQuit = ph_VideoQuit;
97 device->AllocHWSurface = ph_AllocHWSurface;
98 device->CheckHWBlit = NULL;
99 device->FillHWRect = NULL;
100 device->SetHWColorKey = NULL;
101 device->SetHWAlpha = NULL;
102 device->LockHWSurface = ph_LockHWSurface;
103 device->UnlockHWSurface = ph_UnlockHWSurface;
104 device->FlipHWSurface = ph_FlipHWSurface;
105 device->FreeHWSurface = ph_FreeHWSurface;
106 device->SetCaption = NULL;
107 device->SetIcon = NULL;
108 device->IconifyWindow = NULL;
109 device->GrabInput = NULL;
110 device->GetWMInfo = NULL;
111 device->FreeWMCursor = ph_FreeWMCursor;
112 device->CreateWMCursor = ph_CreateWMCursor;
113 device->ShowWMCursor = ph_ShowWMCursor;
114 device->WarpWMCursor = ph_WarpWMCursor;
115 device->CheckMouseMode = ph_CheckMouseMode;
116 device->InitOSKeymap = ph_InitOSKeymap;
117 device->PumpEvents = ph_PumpEvents;
118
119 device->free = ph_DeleteDevice;
120
121 return device;
122 }
123
124 VideoBootStrap X11_bootstrap = {
125 "photon", "QNX Photon video output",
126 ph_Available, ph_CreateDevice
127 };
128
129 static void ph_DeleteDevice(SDL_VideoDevice *device)
130 {
131
132 if ( device ) {
133 if ( device->hidden ) {
134 free(device->hidden);
135 device->hidden = NULL;
136 }
137 if ( device->gl_data ) {
138 free(device->gl_data);
139 device->gl_data = NULL;
140 }
141 free(device);
142 device = NULL;
143 }
144 }
145
146 static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat)
147 {
148 PtArg_t arg[1];
149 PhDim_t dim;
150 PgColor_t ph_palette[_Pg_MAX_PALETTE];
151 int i;
152 unsigned long *tempptr;
153 int rtnval;
154 PgDisplaySettings_t mysettings;
155 PgVideoModeInfo_t my_mode_info;
156
157 if( NULL == ( event = malloc( EVENT_SIZE ) ) )
158 exit( EXIT_FAILURE );
159
160 /* Create a widget 'window' to capture events */
161 dim.w=0; //JB test320;
162 dim.h=0; //JB test240;
163 //We need to return BytesPerPixel as it in used by CreateRGBsurface
164
165 PtSetArg(&arg[0], Pt_ARG_DIM, &dim,0);
166
167 /*
168 PtSetArg(&arg[1], Pt_ARG_RESIZE_FLAGS, Pt_TRUE, Pt_RESIZE_XY_AS_REQUIRED);
169 PtSetArg(&arg[2], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFRONT |
170 Ph_WM_STATE_ISMAX |
171 Ph_WM_STATE_ISFOCUS);
172
173 PtSetArg(&arg[3], Pt_ARG_WINDOW_RENDER_FLAGS,Pt_FALSE,~0);
174 PtSetArg(&arg[4], Pt_ARG_WINDOW_MANAGED_FLAGS,Pt_TRUE,
175 Ph_WM_FFRONT |
176 Ph_WM_CLOSE |
177 Ph_WM_TOFRONT |
178 Ph_WM_CONSWITCH);
179 */
180
181
182 window=PtAppInit(NULL, NULL, NULL, 1, arg);
183
184 if(window == NULL)
185 {
186 printf("PtAppInit failed\n");
187 PtExit(EXIT_FAILURE);
188 }
189
190 //PgSetDrawBufferSize(16 *1024);
191 PgSetRegion(PtWidgetRid(window));
192 PgSetClipping(0,NULL);
193 PtRealizeWidget(window);
194
195
196 /* Get the available video modes */
197 // if(ph_GetVideoModes(this) < 0)
198 // return -1;
199
200 /* Create the blank cursor */
201 SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask,
202 (int)BLANK_CWIDTH, (int)BLANK_CHEIGHT,
203 (int)BLANK_CHOTX, (int)BLANK_CHOTY);
204
205 if(SDL_BlankCursor == NULL)
206 printf("could not create blank cursor\n");
207 /* Get the video mode */
208 if (PgGetVideoMode( &mysettings ) < 0)
209 {
210 fprintf(stderr,"ph_VideoInit: PgGetVideoMode failed\n");
211 //QNX6/Patch A always fails return code even though call succeeds. fixed Patch B
212 }
213
214 if (PgGetVideoModeInfo(mysettings.mode, &my_mode_info) < 0)
215 {
216 fprintf(stderr,"ph_VideoInit: PgGetVideoModeInfo failed\n");
217 }
218 //We need to return BytesPerPixel as it in used by CreateRGBsurface
219 vformat->BitsPerPixel = my_mode_info.bits_per_pixel;
220 vformat->BytesPerPixel = vformat->BitsPerPixel/8;
221
222 //return a palette if we are in 256 color mode
223 if(vformat->BitsPerPixel == 8)
224 {
225 vformat->palette = malloc(sizeof(SDL_Palette));
226 memset(vformat->palette, 0, sizeof(SDL_Palette));
227 vformat->palette->ncolors = 256;
228 vformat->palette->colors = (SDL_Color *)malloc(256 *sizeof(SDL_Color));
229
230 //fill the palette
231 rtnval = PgGetPalette(ph_palette);
232 if(rtnval < 0)
233 printf("ph_VideoInit: PgGetPalette failed\n");
234
235 tempptr = (unsigned long *)vformat->palette->colors;
236
237 for(i=0;i<256; i++)
238 {
239 *tempptr = (((unsigned long)ph_palette[i]) << 8);
240 tempptr++;
241
242 }
243
244 }
245
246
247 currently_fullscreen = 0;
248 return 0;
249 }
250
251 static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current,
252 int width, int height, int bpp, Uint32 flags)
253 {
254 PhRegion_t region_info;
255 PgDisplaySettings_t settings;
256 PgVideoModeInfo_t mode_info;
257 int mode, actual_width, actual_height;
258 PtArg_t arg[5];
259 PhDim_t dim;
260 int rtnval;
261 SDL_Rect ** mymodelist;
262 SDL_PixelFormat myformat;
263 PgColor_t ph_palette[_Pg_MAX_PALETTE];
264 int i;
265 unsigned long *tempptr;
266
267 actual_width = width;
268 actual_height = height;
269
270
271 /* Lock the event thread, in multi-threading environments */
272 SDL_Lock_EventThread();
273
274
275 /* Initialize the window */
276 if (flags & SDL_FULLSCREEN) //Direct Context , assume SDL_HWSURFACE also set
277 {
278
279 /*
280 if (old_video_mode==-1)
281 {
282 PgGetGraphicsHWCaps(&graphics_card_caps);
283 old_video_mode=graphics_card_caps.current_video_mode;
284 old_refresh_rate=graphics_card_caps.current_rrate;
285 }
286 */
287
288
289
290 /* Get the video mode and set it */
291 if (bpp == 0)
292 {
293 if (PgGetVideoMode( &settings ) < 0)
294 {
295 fprintf(stderr,"error: PgGetVideoMode failed\n");
296 }
297 if (PgGetVideoModeInfo(settings.mode, &mode_info) < 0)
298 {
299 fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
300 }
301 bpp = mode_info.bits_per_pixel;
302 }
303 if (flags & SDL_ANYFORMAT)
304 {
305 if ((mode = get_mode_any_format(width, height, bpp)) == 0)
306 {
307 fprintf(stderr,"error: get_mode_any_format failed\n");
308 exit(1);
309 }
310 }
311 else
312 {
313 if ((mode = get_mode(width, height, bpp)) == 0)
314 {
315 fprintf(stderr,"error: get_mode failed\n");
316 exit(1);
317 }
318
319
320 }
321 settings.mode = mode;
322 settings.refresh = 0;
323 settings.flags = 0;
324
325
326 if (PgSetVideoMode( &settings ) < 0)
327 {
328 fprintf(stderr,"error: PgSetVideoMode failed\n");
329 }
330
331 /* Get the true height and width */
332
333 current->flags = (flags|(~SDL_RESIZABLE)); //no resize for Direct Context
334
335 /* Begin direct mode */
336 ph_EnterFullScreen(this);
337
338
339
340 } //end fullscreen flag
341 else if (flags & SDL_HWSURFACE) /* Use offscreen memory iff SDL_HWSURFACE flag is set */
342 {
343 // Hardware surface is Offsceen Context. ph_ResizeImage handles the switch
344 current->flags = (flags|(~SDL_RESIZABLE)); //no stretch blit in offscreen context
345 }
346 else // must be SDL_SWSURFACE
347 {
348 current->flags = (flags|SDL_RESIZABLE); //yes we can resize as this is a software surface
349 }
350
351
352 //If we are setting video to use the palette make sure we have allocated memory for it
353 if(bpp == 8)
354 {
355 current->format->palette = malloc(sizeof(SDL_Palette));
356 memset(current->format->palette, 0, sizeof(SDL_Palette));
357 current->format->palette->ncolors = 256;
358 current->format->palette->colors = (SDL_Color *)malloc(256 *sizeof(SDL_Color));
359 //fill the palette
360 rtnval = PgGetPalette(ph_palette);
361
362 tempptr = (unsigned long *)current->format->palette->colors;
363
364 for(i=0;i<256; i++)
365 {
366 *tempptr = (((unsigned long)ph_palette[i]) << 8);
367 tempptr++;
368
369 }
370 }
371
372
373 //Current window dimensions
374 PtGetResource( window, Pt_ARG_DIM, &dim, 0 );
375
376 //If we need to resize the window
377 if((dim.w != width)||(dim.h != height))
378 {
379 dim.w=width;
380 dim.h=height;
381 PtSetArg(&arg[0], Pt_ARG_DIM, &dim,0);
382 PtSetResources( window, 1, arg );
383 current->w = width;
384 current->h = height;
385 current->format->BitsPerPixel = bpp;
386 current->format->BytesPerPixel = bpp/8;
387 current->pitch = SDL_CalculatePitch(current);
388 //Must call at least once it setup image planes
389 ph_ResizeImage(this, current, flags);
390 }
391
392
393 SDL_Unlock_EventThread();
394
395 /* We're done! */
396 return(current);
397 }
398
399 static void ph_VideoQuit(_THIS)
400 {
401
402 if(SDL_Image != NULL)
403 {
404 ph_DestroyImage(this, SDL_VideoSurface);
405
406 }
407
408 if (currently_fullscreen)
409 {
410 PdDirectStop( directContext );
411 PdReleaseDirectContext( directContext );
412 directContext=0;
413 currently_fullscreen = 0;
414 }
415
416 }
417
418
419 static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
420 {
421 PgColor_t *in, *out;
422 int i, j;
423 int alloct_all = 1;
424
425 colors = this->screen->format->palette->colors;
426
427 in = alloca( ncolors*sizeof(PgColor_t) );
428 if ( in == NULL ) {
429 return 0;
430 }
431 memset(in,0,ncolors*sizeof(PgColor_t));
432
433 out = alloca( ncolors*sizeof(PgColor_t) );
434 if ( out == NULL ) {
435 return 0;
436 }
437
438 for (i=0,j=firstcolor;i<ncolors;i++,j++)
439 {
440 in[i] |= colors[j].r<<16 ;
441 in[i] |= colors[j].g<<8 ;
442 in[i] |= colors[j].b ;
443 }
444
445 if ( (this->screen->flags & SDL_HWPALETTE) == SDL_HWPALETTE )
446 {
447 if( PgSetPalette( in, 0, 0, ncolors, Pg_PALSET_HARD, 0) < 0 )
448 {
449 fprintf(stderr,"error: PgSetPalette(..,Pg_PALSET_HARD) failed\n");
450 return 0;
451 }
452 }
453 else
454 {
455 if ( PgColorMatch(ncolors, in, out) < 0 )
456 {
457 fprintf(stderr,"error: PgColorMatch failed\n");
458 return 0;
459 }
460 for (i=0;i<ncolors;i++)
461 {
462 if (memcmp(&in[i],&out[i],sizeof(PgColor_t)))
463 {
464 alloct_all = 0;
465 break;
466 }
467 }
468 if( PgSetPalette( out, 0, 0, ncolors, Pg_PALSET_SOFT, 0) < 0 )
469 {
470 fprintf(stderr,"error: PgSetPalette(..,Pg_PALSET_SOFT) failed\n");
471 return 0;
472 }
473 }
474 return alloct_all;
475 }
476
477 static int ph_ResizeWindow(_THIS,
478 SDL_Surface *screen, int w, int h, Uint32 flags)
479 {
480 PhWindowEvent_t winevent;
481
482 memset( &winevent, 0, sizeof(winevent) );
483 winevent.event_f = Ph_WM_RESIZE;
484 winevent.size.w = w;
485 winevent.size.h = h;
486 winevent.rid = PtWidgetRid( window );
487 if (PtForwardWindowEvent( &winevent ) < 0)
488 {
489 fprintf(stderr,"error: PtForwardWindowEvent failed.\n");
490 }
491 current_w = w;
492 current_h = h;
493 return(0);
494 }
495
496