Mercurial > sdl-ios-xcode
comparison src/video/photon/SDL_photon.c @ 3108:aa1897bee1e9
Continue working on QNX Photon with OpenGL ES support
author | Mike Gorchak <lestat@i.com.ua> |
---|---|
date | Tue, 28 Apr 2009 04:30:52 +0000 |
parents | cad1aefa2ed9 |
children | 1102a3305928 |
comparison
equal
deleted
inserted
replaced
3107:3cf236d3cd81 | 3108:aa1897bee1e9 |
---|---|
22 QNX Photon GUI SDL driver | 22 QNX Photon GUI SDL driver |
23 Copyright (C) 2009 Mike Gorchak | 23 Copyright (C) 2009 Mike Gorchak |
24 (mike@malva.ua, lestat@i.com.ua) | 24 (mike@malva.ua, lestat@i.com.ua) |
25 */ | 25 */ |
26 | 26 |
27 /* SDL internals */ | |
27 #include "SDL_config.h" | 28 #include "SDL_config.h" |
28 | |
29 #include "../SDL_sysvideo.h" | 29 #include "../SDL_sysvideo.h" |
30 #include "SDL_version.h" | 30 #include "SDL_version.h" |
31 #include "SDL_syswm.h" | 31 #include "SDL_syswm.h" |
32 | 32 #include "SDL_loadso.h" |
33 #include "../SDL_sysvideo.h" | 33 #include "SDL_events.h" |
34 | 34 #include "../../events/SDL_mouse_c.h" |
35 #include "../../events/SDL_keyboard_c.h" | |
36 | |
37 /* Photon declarations */ | |
35 #include "SDL_photon.h" | 38 #include "SDL_photon.h" |
39 | |
40 /* Pixel format conversion routines */ | |
41 #include "SDL_photon_pixelfmt.h" | |
42 | |
43 /* Use GF's pixel format functions for OpenGL ES context creation */ | |
44 #if defined(SDL_VIDEO_OPENGL_ES) | |
45 #include "../qnxgf/SDL_gf_pixelfmt.h" | |
46 | |
47 /* If GF driver is not compiled in, include some of usefull functions */ | |
48 #if !defined(SDL_VIDEO_DRIVER_QNXGF) | |
49 #include "../qnxgf/SDL_gf_pixelfmt.c" | |
50 #endif /* SDL_VIDEO_DRIVER_QNXGF */ | |
51 #endif /* SDL_VIDEO_OPENGL_ES */ | |
52 | |
53 /* Use GF's OpenGL ES 1.1 functions emulation */ | |
54 #if defined(SDL_VIDEO_OPENGL_ES) | |
55 #include "../qnxgf/SDL_gf_opengles.h" | |
56 | |
57 /* If GF driver is not compiled in, include some of usefull functions */ | |
58 #if !defined(SDL_VIDEO_DRIVER_QNXGF) | |
59 #include "../qnxgf/SDL_gf_opengles.c" | |
60 #endif /* SDL_VIDEO_DRIVER_QNXGF */ | |
61 #endif /* SDL_VIDEO_OPENGL_ES */ | |
62 | |
63 /* Low level device graphics driver names, which they are reporting */ | |
64 Photon_DeviceCaps photon_devicename[]= | |
65 { | |
66 /* ATI Rage 128 graphics driver (devg-ati_rage128) */ | |
67 {"ati_rage128", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
68 /* Fujitsu Carmine graphics driver (devg-carmine.so) */ | |
69 {"carmine", SDL_PHOTON_ACCELERATED | SDL_PHOTON_ACCELERATED_3D}, | |
70 /* C&T graphics driver (devg-chips.so) */ | |
71 {"chips", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
72 /* Fujitsu Coral graphics driver (devg-coral.so) */ | |
73 {"coral", SDL_PHOTON_ACCELERATED | SDL_PHOTON_ACCELERATED_3D}, | |
74 /* Intel integrated graphics driver (devg-extreme2.so) */ | |
75 {"extreme2", SDL_PHOTON_ACCELERATED | SDL_PHOTON_ACCELERATED_3D}, | |
76 /* Unaccelerated FB driver (devg-flat.so) */ | |
77 {"flat", SDL_PHOTON_UNACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
78 /* NS Geode graphics driver (devg-geode.so) */ | |
79 {"geode", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
80 /* Geode LX graphics driver (devg-geodelx.so) */ | |
81 {"geodelx", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
82 /* Intel integrated graphics driver (devg-gma9xx.so) */ | |
83 {"gma", SDL_PHOTON_ACCELERATED | SDL_PHOTON_ACCELERATED_3D}, | |
84 /* Intel integrated graphics driver (devg-i810.so) */ | |
85 {"i810", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
86 /* Intel integrated graphics driver (devg-i830.so) */ | |
87 {"i830", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
88 /* Geode LX graphics driver (devg-lx800.so) */ | |
89 {"lx800", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
90 /* Matrox Gxx graphics driver (devg-matroxg.so) */ | |
91 {"matroxg", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
92 /* Intel Poulsbo graphics driver (devg-poulsbo.so) */ | |
93 {"poulsbo", SDL_PHOTON_ACCELERATED | SDL_PHOTON_ACCELERATED_3D}, | |
94 /* ATI Radeon driver (devg-radeon.so) */ | |
95 {"radeon", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
96 /* ATI Rage driver (devg-rage.so) */ | |
97 {"rage", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
98 /* S3 Savage graphics driver (devg-s3_savage.so) */ | |
99 {"s3_savage", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
100 /* SiS630 integrated graphics driver (devg-sis630.so) */ | |
101 {"sis630", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
102 /* PowerVR SGX 535 graphics driver (devg-poulsbo.so) */ | |
103 {"sgx", SDL_PHOTON_ACCELERATED | SDL_PHOTON_ACCELERATED_3D}, | |
104 /* SM Voyager GX graphics driver (devg-smi5xx.so) */ | |
105 {"smi5xx", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
106 /* Silicon Motion graphics driver (devg-smi7xx.so) */ | |
107 {"smi7xx", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
108 /* SVGA unaccelerated gfx driver (devg-svga.so) */ | |
109 {"svga", SDL_PHOTON_UNACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
110 /* nVidia TNT graphics driver (devg-tnt.so) */ | |
111 {"tnt", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
112 /* VIA integrated graphics driver (devg-tvia.so) */ | |
113 {"tvia", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
114 /* VIA UniChrome graphics driver (devg-unichrome.so) */ | |
115 {"unichrome", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
116 /* VESA unaccelerated gfx driver (devg-vesa.so) */ | |
117 {"vesa", SDL_PHOTON_UNACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
118 /* VmWare graphics driver (devg-volari.so) */ | |
119 {"vmware", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
120 /* XGI XP10 graphics driver (devg-volari.so), OpenGL 1.5*/ | |
121 {"volari", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}, | |
122 /* End of list */ | |
123 {NULL, 0x00000000} | |
124 }; | |
36 | 125 |
37 static SDL_bool photon_initialized=SDL_FALSE; | 126 static SDL_bool photon_initialized=SDL_FALSE; |
38 | 127 |
39 static int photon_available(void) | 128 static int photon_available(void) |
40 { | 129 { |
60 return 1; | 149 return 1; |
61 } | 150 } |
62 | 151 |
63 static void photon_destroy(SDL_VideoDevice* device) | 152 static void photon_destroy(SDL_VideoDevice* device) |
64 { | 153 { |
154 SDL_VideoData* phdata=(SDL_VideoData*) device->driverdata; | |
155 | |
156 #if defined(SDL_VIDEO_OPENGL_ES) | |
157 if (phdata->gfinitialized!=SDL_FALSE) | |
158 { | |
159 gf_dev_detach(phdata->gfdev); | |
160 } | |
161 #endif /* SDL_VIDEO_OPENGL_ES */ | |
162 | |
163 if (device->driverdata!=NULL) | |
164 { | |
165 device->driverdata=NULL; | |
166 } | |
65 } | 167 } |
66 | 168 |
67 static SDL_VideoDevice* photon_create(int devindex) | 169 static SDL_VideoDevice* photon_create(int devindex) |
68 { | 170 { |
69 SDL_VideoDevice* device; | 171 SDL_VideoDevice* device; |
70 SDL_VideoData* phdata; | 172 SDL_VideoData* phdata; |
71 int status; | 173 int status; |
72 | 174 |
73 /* Check if photon could be initialized */ | 175 /* Check if photon could be initialized */ |
74 status=photon_available(); | 176 status=photon_available(); |
75 if (status==0) | 177 if (status==0) |
76 { | 178 { |
77 /* Photon could not be used */ | 179 /* Photon could not be used */ |
78 return NULL; | 180 return NULL; |
79 } | 181 } |
80 | 182 |
183 /* Photon agregates all video devices to one with multiple heads */ | |
184 if (devindex!=0) | |
185 { | |
186 /* devindex could be zero only in Photon SDL driver */ | |
187 return NULL; | |
188 } | |
189 | |
81 /* Initialize SDL_VideoDevice structure */ | 190 /* Initialize SDL_VideoDevice structure */ |
82 device=(SDL_VideoDevice*)SDL_calloc(1, sizeof(SDL_VideoDevice)); | 191 device=(SDL_VideoDevice*)SDL_calloc(1, sizeof(SDL_VideoDevice)); |
83 if (device==NULL) | 192 if (device==NULL) |
84 { | 193 { |
85 SDL_OutOfMemory(); | 194 SDL_OutOfMemory(); |
94 SDL_free(device); | 203 SDL_free(device); |
95 return NULL; | 204 return NULL; |
96 } | 205 } |
97 device->driverdata=phdata; | 206 device->driverdata=phdata; |
98 | 207 |
208 /* Get all photon display devices */ | |
209 phdata->avail_rids=PdGetDevices(&phdata->rid[0], SDL_VIDEO_PHOTON_MAX_RIDS); | |
210 if (phdata->avail_rids>SDL_VIDEO_PHOTON_MAX_RIDS) | |
211 { | |
212 phdata->avail_rids=SDL_VIDEO_PHOTON_MAX_RIDS; | |
213 } | |
214 | |
215 #if defined(SDL_VIDEO_OPENGL_ES) | |
216 /* TODO: add real device detection versus multiple heads */ | |
217 status=gf_dev_attach(&phdata->gfdev, GF_DEVICE_INDEX(0), &phdata->gfdev_info); | |
218 if (status!=GF_ERR_OK) | |
219 { | |
220 /* Do not fail right now, if GF can't be attached */ | |
221 phdata->gfinitialized=SDL_FALSE; | |
222 } | |
223 else | |
224 { | |
225 phdata->gfinitialized=SDL_TRUE; | |
226 } | |
227 #endif /* SDL_VIDEO_OPENGL_ES */ | |
228 | |
229 /* Set default target device */ | |
230 status=PdSetTargetDevice(NULL, phdata->rid[0]); | |
231 if (status==-1) | |
232 { | |
233 SDL_SetError("Photon: Can't set default target device"); | |
234 #if defined(SDL_VIDEO_OPENGL_ES) | |
235 gf_dev_detach(phdata->gfdev); | |
236 #endif /* SDL_VIDEO_OPENGL_ES */ | |
237 SDL_free(phdata); | |
238 SDL_free(device); | |
239 return NULL; | |
240 } | |
241 phdata->current_device_id=0; | |
242 | |
99 /* Setup amount of available displays and current display */ | 243 /* Setup amount of available displays and current display */ |
100 device->num_displays=0; | 244 device->num_displays=0; |
101 device->current_display=0; | 245 device->current_display=0; |
246 | |
247 /* Set device free function */ | |
248 device->free=photon_destroy; | |
249 | |
250 /* Setup all functions which we can handle */ | |
251 device->VideoInit=photon_videoinit; | |
252 device->VideoQuit=photon_videoquit; | |
253 device->GetDisplayModes=photon_getdisplaymodes; | |
254 device->SetDisplayMode=photon_setdisplaymode; | |
255 device->SetDisplayPalette=photon_setdisplaypalette; | |
256 device->GetDisplayPalette=photon_getdisplaypalette; | |
257 device->SetDisplayGammaRamp=photon_setdisplaygammaramp; | |
258 device->GetDisplayGammaRamp=photon_getdisplaygammaramp; | |
259 device->CreateWindow=photon_createwindow; | |
260 device->CreateWindowFrom=photon_createwindowfrom; | |
261 device->SetWindowTitle=photon_setwindowtitle; | |
262 device->SetWindowIcon=photon_setwindowicon; | |
263 device->SetWindowPosition=photon_setwindowposition; | |
264 device->SetWindowSize=photon_setwindowsize; | |
265 device->ShowWindow=photon_showwindow; | |
266 device->HideWindow=photon_hidewindow; | |
267 device->RaiseWindow=photon_raisewindow; | |
268 device->MaximizeWindow=photon_maximizewindow; | |
269 device->MinimizeWindow=photon_minimizewindow; | |
270 device->RestoreWindow=photon_restorewindow; | |
271 device->SetWindowGrab=photon_setwindowgrab; | |
272 device->DestroyWindow=photon_destroywindow; | |
273 device->GetWindowWMInfo=photon_getwindowwminfo; | |
274 device->GL_LoadLibrary=photon_gl_loadlibrary; | |
275 device->GL_GetProcAddress=photon_gl_getprocaddres; | |
276 device->GL_UnloadLibrary=photon_gl_unloadlibrary; | |
277 device->GL_CreateContext=photon_gl_createcontext; | |
278 device->GL_MakeCurrent=photon_gl_makecurrent; | |
279 device->GL_SetSwapInterval=photon_gl_setswapinterval; | |
280 device->GL_GetSwapInterval=photon_gl_getswapinterval; | |
281 device->GL_SwapWindow=photon_gl_swapwindow; | |
282 device->GL_DeleteContext=photon_gl_deletecontext; | |
283 device->PumpEvents=photon_pumpevents; | |
284 device->SuspendScreenSaver=photon_suspendscreensaver; | |
285 | |
286 return device; | |
102 } | 287 } |
103 | 288 |
104 VideoBootStrap photon_bootstrap= | 289 VideoBootStrap photon_bootstrap= |
105 { | 290 { |
106 "photon", | 291 "photon", |
112 /*****************************************************************************/ | 297 /*****************************************************************************/ |
113 /* SDL Video and Display initialization/handling functions */ | 298 /* SDL Video and Display initialization/handling functions */ |
114 /*****************************************************************************/ | 299 /*****************************************************************************/ |
115 int photon_videoinit(_THIS) | 300 int photon_videoinit(_THIS) |
116 { | 301 { |
117 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; | 302 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; |
118 | 303 PgHWCaps_t hwcaps; |
119 /* Check for environment variables which could override some SDL settings */ | 304 PgVideoModeInfo_t modeinfo; |
120 // didata->custom_refresh=0; | 305 int32_t status; |
121 // override = SDL_getenv("SDL_VIDEO_PHOTON_REFRESH_RATE"); | 306 SDL_VideoDisplay display; |
122 // if (override!=NULL) | 307 SDL_DisplayMode current_mode; |
123 // { | 308 SDL_DisplayData* didata; |
124 // if (SDL_sscanf(override, "%u", &didata->custom_refresh)!=1) | 309 uint32_t it; |
125 // { | 310 uint32_t jt; |
126 // didata->custom_refresh=0; | 311 char* override; |
127 // } | 312 |
128 // } | 313 /* By default Photon do not uses swap on VSYNC */ |
314 phdata->swapinterval=0; | |
315 | |
316 for (it=0; it<phdata->avail_rids; it++) | |
317 { | |
318 didata=(SDL_DisplayData*)SDL_calloc(1, sizeof(SDL_DisplayData)); | |
319 if (didata==NULL) | |
320 { | |
321 /* memory allocation error */ | |
322 SDL_OutOfMemory(); | |
323 return -1; | |
324 } | |
325 | |
326 /* Allocate two cursors with SDL_VIDEO_PHOTON_MAX_CURSOR_SIZE size */ | |
327 /* and 128 bytes of spare place */ | |
328 didata->cursor_size=((SDL_VIDEO_PHOTON_MAX_CURSOR_SIZE*4)>>3)+128; | |
329 didata->cursor=(PhCursorDef_t*)SDL_calloc(1, didata->cursor_size); | |
330 if (didata->cursor==NULL) | |
331 { | |
332 /* memory allocation error */ | |
333 SDL_OutOfMemory(); | |
334 SDL_free(didata); | |
335 return -1; | |
336 } | |
337 | |
338 /* Initialize GF in case of OpenGL ES support is compiled in */ | |
339 #if defined(SDL_VIDEO_OPENGL_ES) | |
340 /* TODO: add real device detection versus multiple heads */ | |
341 if (phdata->gfinitialized==SDL_TRUE) | |
342 { | |
343 status=gf_display_attach(&didata->display, phdata->gfdev, it, &didata->display_info); | |
344 if (status!=GF_ERR_OK) | |
345 { | |
346 /* Just shutdown GF, do not fail */ | |
347 gf_dev_detach(phdata->gfdev); | |
348 phdata->gfinitialized=SDL_FALSE; | |
349 } | |
350 } | |
351 #endif /* SDL_VIDEO_OPENGL_ES */ | |
352 | |
353 /* Check if current device is not the same as target */ | |
354 if (phdata->current_device_id!=it) | |
355 { | |
356 /* Set target device as default for Pd and Pg functions */ | |
357 status=PdSetTargetDevice(NULL, phdata->rid[it]); | |
358 if (status!=0) | |
359 { | |
360 SDL_SetError("Photon: Can't set default target device\n"); | |
361 SDL_free(didata->cursor); | |
362 SDL_free(didata); | |
363 return -1; | |
364 } | |
365 phdata->current_device_id=it; | |
366 } | |
367 | |
368 /* Store device id */ | |
369 didata->device_id=it; | |
370 | |
371 /* Query photon about graphics hardware caps and current video mode */ | |
372 status=PgGetGraphicsHWCaps(&hwcaps); | |
373 if (status!=0) | |
374 { | |
375 SDL_SetError("Photon: Can't get graphics capabilities"); | |
376 SDL_free(didata->cursor); | |
377 SDL_free(didata); | |
378 return -1; | |
379 } | |
380 | |
381 /* Get current video mode details */ | |
382 status=PgGetVideoModeInfo(hwcaps.current_video_mode, &modeinfo); | |
383 if (status!=0) | |
384 { | |
385 SDL_SetError("Photon: Can't get current video mode information"); | |
386 SDL_free(didata->cursor); | |
387 SDL_free(didata); | |
388 return -1; | |
389 } | |
390 | |
391 /* Setup current desktop mode for SDL */ | |
392 SDL_zero(current_mode); | |
393 current_mode.w=modeinfo.width; | |
394 current_mode.h=modeinfo.height; | |
395 current_mode.refresh_rate=hwcaps.current_rrate; | |
396 current_mode.format=photon_image_to_sdl_pixelformat(modeinfo.type); | |
397 current_mode.driverdata=NULL; | |
398 | |
399 /* Copy device name */ | |
400 SDL_strlcpy(didata->description, hwcaps.chip_name, SDL_VIDEO_PHOTON_DEVICENAME_MAX-1); | |
401 | |
402 /* Search device capabilities and possible workarounds */ | |
403 jt=0; | |
404 do { | |
405 if (photon_devicename[jt].name==NULL) | |
406 { | |
407 break; | |
408 } | |
409 if (SDL_strncmp(photon_devicename[jt].name, didata->description, SDL_strlen(photon_devicename[jt].name))==0) | |
410 { | |
411 didata->caps=photon_devicename[jt].caps; | |
412 } | |
413 jt++; | |
414 } while(1); | |
415 | |
416 /* Initialize display structure */ | |
417 SDL_zero(display); | |
418 display.desktop_mode=current_mode; | |
419 display.current_mode=current_mode; | |
420 display.driverdata=didata; | |
421 didata->current_mode=current_mode; | |
422 SDL_AddVideoDisplay(&display); | |
423 | |
424 /* Check for environment variables which could override some SDL settings */ | |
425 didata->custom_refresh=0; | |
426 override=SDL_getenv("SDL_VIDEO_PHOTON_REFRESH_RATE"); | |
427 if (override!=NULL) | |
428 { | |
429 if (SDL_sscanf(override, "%u", &didata->custom_refresh)!=1) | |
430 { | |
431 didata->custom_refresh=0; | |
432 } | |
433 } | |
434 } | |
435 | |
436 /* Add photon input devices */ | |
437 status=photon_addinputdevices(_this); | |
438 if (status!=0) | |
439 { | |
440 /* SDL error is set by photon_addinputdevices() function */ | |
441 return -1; | |
442 } | |
129 | 443 |
130 /* Add photon renderer to SDL */ | 444 /* Add photon renderer to SDL */ |
131 photon_addrenderdriver(_this); | 445 photon_addrenderdriver(_this); |
132 | 446 |
133 /* video has been initialized successfully */ | 447 /* video has been initialized successfully */ |
134 return 1; | 448 return 1; |
135 } | 449 } |
136 | 450 |
137 void photon_videoquit(_THIS) | 451 void photon_videoquit(_THIS) |
138 { | 452 { |
453 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; | |
139 SDL_DisplayData* didata; | 454 SDL_DisplayData* didata; |
140 uint32_t it; | 455 uint32_t it; |
141 | 456 |
142 /* SDL will restore our desktop mode on exit */ | 457 /* SDL will restore our desktop mode on exit */ |
143 for(it=0; it<_this->num_displays; it++) | 458 for(it=0; it<_this->num_displays; it++) |
144 { | 459 { |
145 didata=_this->displays[it].driverdata; | 460 didata=_this->displays[it].driverdata; |
461 | |
462 if (didata->cursor!=NULL) | |
463 { | |
464 SDL_free(didata->cursor); | |
465 } | |
466 | |
467 #if defined(SDL_VIDEO_OPENGL_ES) | |
468 if (phdata->gfinitialized==SDL_TRUE) | |
469 { | |
470 /* Detach GF display */ | |
471 gf_display_detach(didata->display); | |
472 } | |
473 #endif /* SDL_VIDEO_OPENGL_ES */ | |
146 } | 474 } |
147 } | 475 } |
148 | 476 |
149 void photon_getdisplaymodes(_THIS) | 477 void photon_getdisplaymodes(_THIS) |
150 { | 478 { |
151 SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata; | 479 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; |
152 SDL_DisplayMode mode; | 480 SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata; |
153 | 481 SDL_DisplayMode mode; |
482 PgVideoModes_t modes; | |
483 PgVideoModeInfo_t modeinfo; | |
484 int32_t status; | |
485 uint32_t it; | |
486 uint32_t jt; | |
487 | |
488 /* Check if current device is not the same as target */ | |
489 if (phdata->current_device_id!=didata->device_id) | |
490 { | |
491 /* Set target device as default for Pd and Pg functions */ | |
492 status=PdSetTargetDevice(NULL, phdata->rid[didata->device_id]); | |
493 if (status!=0) | |
494 { | |
495 SDL_SetError("Photon: Can't set default target device\n"); | |
496 return; | |
497 } | |
498 phdata->current_device_id=didata->device_id; | |
499 } | |
500 | |
501 /* Get array of available video modes */ | |
502 status=PgGetVideoModeList(&modes); | |
503 if (status!=0) | |
504 { | |
505 SDL_SetError("Photon: Can't get video mode list"); | |
506 return; | |
507 } | |
508 | |
509 for (it=0; it<modes.num_modes; it++) | |
510 { | |
511 status=PgGetVideoModeInfo(modes.modes[it], &modeinfo); | |
512 if (status!=0) | |
513 { | |
514 /* Maybe something wrong with this particular mode, skip it */ | |
515 continue; | |
516 } | |
517 | |
518 jt=0; | |
519 do { | |
520 if (modeinfo.refresh_rates[jt]!=0) | |
521 { | |
522 mode.w=modeinfo.width; | |
523 mode.h=modeinfo.height; | |
524 mode.refresh_rate=modeinfo.refresh_rates[jt]; | |
525 mode.format=photon_image_to_sdl_pixelformat(modeinfo.type); | |
526 mode.driverdata=NULL; | |
527 SDL_AddDisplayMode(_this->current_display, &mode); | |
528 jt++; | |
529 } | |
530 else | |
531 { | |
532 break; | |
533 } | |
534 } while(1); | |
535 } | |
154 } | 536 } |
155 | 537 |
156 int photon_setdisplaymode(_THIS, SDL_DisplayMode* mode) | 538 int photon_setdisplaymode(_THIS, SDL_DisplayMode* mode) |
157 { | 539 { |
158 SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata; | 540 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; |
541 SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata; | |
542 PgVideoModes_t modes; | |
543 PgVideoModeInfo_t modeinfo; | |
544 PgDisplaySettings_t modesettings; | |
545 uint32_t refresh_rate=0; | |
546 int32_t status; | |
547 uint32_t it; | |
548 | |
549 /* Check if current device is not the same as target */ | |
550 if (phdata->current_device_id!=didata->device_id) | |
551 { | |
552 /* Set target device as default for Pd and Pg functions */ | |
553 status=PdSetTargetDevice(NULL, phdata->rid[didata->device_id]); | |
554 if (status!=0) | |
555 { | |
556 SDL_SetError("Photon: Can't set default target device\n"); | |
557 return; | |
558 } | |
559 phdata->current_device_id=didata->device_id; | |
560 } | |
561 | |
562 /* Get array of available video modes */ | |
563 status=PgGetVideoModeList(&modes); | |
564 if (status!=0) | |
565 { | |
566 SDL_SetError("Photon: Can't get video mode list"); | |
567 return; | |
568 } | |
569 | |
570 /* Current display dimensions and bpp are no more valid */ | |
571 didata->current_mode.format=SDL_PIXELFORMAT_UNKNOWN; | |
572 didata->current_mode.w=0; | |
573 didata->current_mode.h=0; | |
574 | |
575 /* Check if custom refresh rate requested */ | |
576 if (didata->custom_refresh!=0) | |
577 { | |
578 refresh_rate=didata->custom_refresh; | |
579 } | |
580 else | |
581 { | |
582 refresh_rate=mode->refresh_rate; | |
583 } | |
584 | |
585 /* Check if SDL GF driver needs to find appropriate refresh rate itself */ | |
586 if (refresh_rate==0) | |
587 { | |
588 SDL_DisplayMode tempmode; | |
589 | |
590 /* Clear display mode structure */ | |
591 SDL_memset(&tempmode, 0x00, sizeof(SDL_DisplayMode)); | |
592 tempmode.refresh_rate=0x0000FFFF; | |
593 | |
594 /* Check if window width and height matches one of our modes */ | |
595 for (it=0; it<SDL_CurrentDisplay.num_display_modes; it++) | |
596 { | |
597 if ((SDL_CurrentDisplay.display_modes[it].w==mode->w) && | |
598 (SDL_CurrentDisplay.display_modes[it].h==mode->h) && | |
599 (SDL_CurrentDisplay.display_modes[it].format==mode->format)) | |
600 { | |
601 /* Find the lowest refresh rate available */ | |
602 if (tempmode.refresh_rate>SDL_CurrentDisplay.display_modes[it].refresh_rate) | |
603 { | |
604 tempmode=SDL_CurrentDisplay.display_modes[it]; | |
605 } | |
606 } | |
607 } | |
608 if (tempmode.refresh_rate!=0x0000FFFF) | |
609 { | |
610 refresh_rate=tempmode.refresh_rate; | |
611 } | |
612 else | |
613 { | |
614 /* Let video driver decide what to do with this */ | |
615 refresh_rate=0; | |
616 } | |
617 } | |
618 | |
619 /* Check if SDL GF driver needs to check custom refresh rate */ | |
620 if (didata->custom_refresh!=0) | |
621 { | |
622 SDL_DisplayMode tempmode; | |
623 | |
624 /* Clear display mode structure */ | |
625 SDL_memset(&tempmode, 0x00, sizeof(SDL_DisplayMode)); | |
626 tempmode.refresh_rate=0x0000FFFF; | |
627 | |
628 /* Check if window width and height matches one of our modes */ | |
629 for (it=0; it<SDL_CurrentDisplay.num_display_modes; it++) | |
630 { | |
631 if ((SDL_CurrentDisplay.display_modes[it].w==mode->w) && | |
632 (SDL_CurrentDisplay.display_modes[it].h==mode->h) && | |
633 (SDL_CurrentDisplay.display_modes[it].format==mode->format)) | |
634 { | |
635 /* Find the lowest refresh rate available */ | |
636 if (tempmode.refresh_rate>SDL_CurrentDisplay.display_modes[it].refresh_rate) | |
637 { | |
638 tempmode=SDL_CurrentDisplay.display_modes[it]; | |
639 } | |
640 | |
641 /* Check if requested refresh rate found */ | |
642 if (refresh_rate==SDL_CurrentDisplay.display_modes[it].refresh_rate) | |
643 { | |
644 tempmode=SDL_CurrentDisplay.display_modes[it]; | |
645 break; | |
646 } | |
647 } | |
648 } | |
649 if (tempmode.refresh_rate!=0x0000FFFF) | |
650 { | |
651 refresh_rate=tempmode.refresh_rate; | |
652 } | |
653 else | |
654 { | |
655 /* Let video driver decide what to do with this */ | |
656 refresh_rate=0; | |
657 } | |
658 } | |
659 | |
660 /* Find photon's video mode number */ | |
661 for (it=0; it<modes.num_modes; it++) | |
662 { | |
663 uint32_t jt; | |
664 uint32_t foundrefresh; | |
665 | |
666 /* Get current video mode details */ | |
667 status=PgGetVideoModeInfo(modes.modes[it], &modeinfo); | |
668 if (status!=0) | |
669 { | |
670 /* Maybe something wrong with this particular mode, skip it */ | |
671 continue; | |
672 } | |
673 if ((modeinfo.width==mode->w) && (modeinfo.height==mode->h) && | |
674 (modeinfo.type==photon_sdl_to_image_pixelformat(mode->format))) | |
675 { | |
676 /* Mode is found, find requested refresh rate, this case is for */ | |
677 /* video drivers, which provide non-generic video modes. */ | |
678 jt=0; | |
679 foundrefresh=0; | |
680 do { | |
681 if (modeinfo.refresh_rates[jt]!=0) | |
682 { | |
683 if (modeinfo.refresh_rates[jt]==refresh_rate) | |
684 { | |
685 foundrefresh=1; | |
686 break; | |
687 } | |
688 jt++; | |
689 } | |
690 else | |
691 { | |
692 break; | |
693 } | |
694 } while(1); | |
695 if (foundrefresh!=0) | |
696 { | |
697 break; | |
698 } | |
699 } | |
700 } | |
701 | |
702 /* Check if video mode has not been found */ | |
703 if (it==modes.num_modes) | |
704 { | |
705 SDL_SetError("Photon: Can't find appropriate video mode"); | |
706 return -1; | |
707 } | |
708 | |
709 /* Fill mode settings */ | |
710 modesettings.flags=0x00000000; | |
711 modesettings.mode=modes.modes[it]; | |
712 modesettings.refresh=refresh_rate; | |
713 | |
714 /* Finally set new video mode */ | |
715 status=PgSetVideoMode(&modesettings); | |
716 if (status!=0) | |
717 { | |
718 SDL_SetError("Photon: Can't set new video mode"); | |
719 return -1; | |
720 } | |
721 | |
722 /* Store new video mode parameters */ | |
723 didata->current_mode=*mode; | |
724 didata->current_mode.refresh_rate=refresh_rate; | |
159 | 725 |
160 return 0; | 726 return 0; |
161 } | 727 } |
162 | 728 |
163 int photon_setdisplaypalette(_THIS, SDL_Palette* palette) | 729 int photon_setdisplaypalette(_THIS, SDL_Palette* palette) |
190 return -1; | 756 return -1; |
191 } | 757 } |
192 | 758 |
193 int photon_createwindow(_THIS, SDL_Window* window) | 759 int photon_createwindow(_THIS, SDL_Window* window) |
194 { | 760 { |
761 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; | |
195 SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata; | 762 SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata; |
196 SDL_WindowData* wdata; | 763 SDL_WindowData* wdata; |
764 PhDim_t winsize; | |
765 PhPoint_t winpos; | |
766 PtArg_t winargs[32]; | |
767 uint32_t winargc=0; | |
768 int32_t status; | |
769 PhRegion_t wregion; | |
197 | 770 |
198 /* Allocate window internal data */ | 771 /* Allocate window internal data */ |
199 wdata=(SDL_WindowData*)SDL_calloc(1, sizeof(SDL_WindowData)); | 772 wdata=(SDL_WindowData*)SDL_calloc(1, sizeof(SDL_WindowData)); |
200 if (wdata==NULL) | 773 if (wdata==NULL) |
201 { | 774 { |
204 } | 777 } |
205 | 778 |
206 /* Setup driver data for this window */ | 779 /* Setup driver data for this window */ |
207 window->driverdata=wdata; | 780 window->driverdata=wdata; |
208 | 781 |
782 /* Set initial window title */ | |
783 if (window->title!=NULL) | |
784 { | |
785 PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_TITLE, window->title, 0); | |
786 } | |
787 else | |
788 { | |
789 PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_TITLE, "", 0); | |
790 } | |
791 | |
792 /* TODO: handle SDL_WINDOW_INPUT_GRABBED */ | |
793 | |
794 /* Disable default window filling on redraw */ | |
795 PtSetArg(&winargs[winargc++], Pt_ARG_BASIC_FLAGS, Pt_TRUE, Pt_BASIC_PREVENT_FILL); | |
796 | |
797 /* Set default maximum and minimum window sizes */ | |
798 winsize.w=0; | |
799 winsize.h=0; | |
800 PtSetArg(&winargs[winargc++], Pt_ARG_MAX_HEIGHT, 0, 0); | |
801 PtSetArg(&winargs[winargc++], Pt_ARG_MAX_WIDTH, 0, 0); | |
802 PtSetArg(&winargs[winargc++], Pt_ARG_MIN_HEIGHT, 0, 0); | |
803 PtSetArg(&winargs[winargc++], Pt_ARG_MIN_WIDTH, 0, 0); | |
804 PtSetArg(&winargs[winargc++], Pt_ARG_MAXIMUM_DIM, &winsize, 0); | |
805 PtSetArg(&winargs[winargc++], Pt_ARG_MINIMUM_DIM, &winsize, 0); | |
806 | |
807 /* Reset default managed events to disable */ | |
808 PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, | |
809 Ph_WM_APP_DEF_MANAGED); | |
810 /* Set which events we will not handle, let WM to handle them */ | |
811 PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, | |
812 Ph_WM_BACKDROP | Ph_WM_TOFRONT | Ph_WM_COLLAPSE | Ph_WM_FFRONT | | |
813 Ph_WM_FOCUS | Ph_WM_HELP | Ph_WM_HIDE | Ph_WM_MAX | | |
814 Ph_WM_MENU | Ph_WM_MOVE | Ph_WM_RESIZE | Ph_WM_RESTORE | | |
815 Ph_WM_TASKBAR | Ph_WM_TOBACK); | |
816 | |
817 /* Reset default notify events to disable */ | |
818 PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_FALSE, | |
819 Ph_WM_RESIZE | Ph_WM_CLOSE | Ph_WM_HELP); | |
820 /* Set which events we will handle */ | |
821 PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, | |
822 Ph_WM_CLOSE | Ph_WM_COLLAPSE | Ph_WM_FOCUS | Ph_WM_MAX | | |
823 Ph_WM_MOVE | Ph_WM_RESIZE | Ph_WM_RESTORE | Ph_WM_HIDE); | |
824 | |
825 /* Borderless window can't be resizeable */ | |
826 if ((window->flags & SDL_WINDOW_BORDERLESS)==SDL_WINDOW_BORDERLESS) | |
827 { | |
828 window->flags&=~(SDL_WINDOW_RESIZABLE); | |
829 } | |
830 | |
831 /* Reset all default decorations */ | |
832 PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Ph_WM_APP_DEF_RENDER); | |
833 | |
834 /* Fullscreen window has its own decorations */ | |
835 if ((window->flags & SDL_WINDOW_FULLSCREEN)==SDL_WINDOW_FULLSCREEN) | |
836 { | |
837 window->flags|=SDL_WINDOW_BORDERLESS; | |
838 window->flags&=~(SDL_WINDOW_RESIZABLE); | |
839 PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, | |
840 Ph_WM_RENDER_CLOSE | Ph_WM_RENDER_TITLE); | |
841 } | |
842 else | |
843 { | |
844 uint32_t decorations=Ph_WM_RENDER_CLOSE | Ph_WM_RENDER_MENU | Ph_WM_RENDER_MIN | | |
845 Ph_WM_RENDER_TITLE | Ph_WM_RENDER_MOVE; | |
846 | |
847 if ((window->flags & SDL_WINDOW_RESIZABLE)==SDL_WINDOW_RESIZABLE) | |
848 { | |
849 decorations|=Ph_WM_RENDER_BORDER | Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX; | |
850 } | |
851 if ((window->flags & SDL_WINDOW_BORDERLESS)!=SDL_WINDOW_BORDERLESS) | |
852 { | |
853 decorations|=Ph_WM_RENDER_BORDER; | |
854 } | |
855 PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, decorations); | |
856 } | |
857 | |
858 /* Set initial window state */ | |
859 PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISFOCUS); | |
860 PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISALTKEY); | |
861 | |
862 /* Set window dimensions */ | |
863 winsize.w=window->w; | |
864 winsize.h=window->h; | |
865 PtSetArg(&winargs[winargc++], Pt_ARG_DIM, &winsize, 0); | |
866 | |
867 /* Check if upper level requests WM to position window */ | |
868 if ((window->x==SDL_WINDOWPOS_UNDEFINED) && (window->y==SDL_WINDOWPOS_UNDEFINED)) | |
869 { | |
870 /* Do not set widget position, let WM to set it */ | |
871 } | |
872 else | |
873 { | |
874 if (window->x==SDL_WINDOWPOS_UNDEFINED) | |
875 { | |
876 window->x=0; | |
877 } | |
878 if (window->y==SDL_WINDOWPOS_UNDEFINED) | |
879 { | |
880 window->y=0; | |
881 } | |
882 if (window->x==SDL_WINDOWPOS_CENTERED) | |
883 { | |
884 window->x=(didata->current_mode.w-window->w)/2; | |
885 } | |
886 if (window->y==SDL_WINDOWPOS_CENTERED) | |
887 { | |
888 window->y=(didata->current_mode.h-window->h)/2; | |
889 } | |
890 | |
891 /* Now set window position */ | |
892 winpos.x=window->x; | |
893 winpos.y=window->y; | |
894 PtSetArg(&winargs[winargc++], Pt_ARG_POS, &winpos, 0); | |
895 } | |
896 | |
897 /* Add SDL window id as user data */ | |
898 PtSetArg(&winargs[winargc++], Pt_ARG_POINTER, (void*)window->id, 0); | |
899 | |
209 /* Check if window must support OpenGL ES rendering */ | 900 /* Check if window must support OpenGL ES rendering */ |
210 if ((window->flags & SDL_WINDOW_OPENGL)==SDL_WINDOW_OPENGL) | 901 if ((window->flags & SDL_WINDOW_OPENGL)==SDL_WINDOW_OPENGL) |
211 { | 902 { |
212 /* Mark this window as OpenGL ES compatible */ | 903 #if defined(SDL_VIDEO_OPENGL_ES) |
213 wdata->uses_gles=SDL_TRUE; | 904 EGLBoolean initstatus; |
214 } | 905 |
906 /* Check if GF was initialized correctly */ | |
907 if (phdata->gfinitialized==SDL_FALSE) | |
908 { | |
909 SDL_SetError("Photon: GF initialization failed, no OpenGL ES support"); | |
910 return -1; | |
911 } | |
912 | |
913 /* Mark this window as OpenGL ES compatible */ | |
914 wdata->uses_gles=SDL_TRUE; | |
915 | |
916 /* Create connection to OpenGL ES */ | |
917 if (phdata->egldisplay==EGL_NO_DISPLAY) | |
918 { | |
919 phdata->egldisplay=eglGetDisplay(phdata->gfdev); | |
920 if (phdata->egldisplay==EGL_NO_DISPLAY) | |
921 { | |
922 SDL_SetError("Photon: Can't get connection to OpenGL ES"); | |
923 return -1; | |
924 } | |
925 | |
926 /* Initialize OpenGL ES library, ignore EGL version */ | |
927 initstatus=eglInitialize(phdata->egldisplay, NULL, NULL); | |
928 if (initstatus!=EGL_TRUE) | |
929 { | |
930 SDL_SetError("Photon: Can't init OpenGL ES library"); | |
931 return -1; | |
932 } | |
933 } | |
934 | |
935 /* Increment GL ES reference count usage */ | |
936 phdata->egl_refcount++; | |
937 #else | |
938 SDL_SetError("Photon: OpenGL ES support is not compiled in"); | |
939 return -1; | |
940 #endif /* SDL_VIDEO_OPENGL_ES */ | |
941 } | |
942 | |
943 /* Finally create the window */ | |
944 wdata->window=PtCreateWidget(PtWindow, Pt_NO_PARENT, winargc, winargs); | |
945 if (wdata->window==NULL) | |
946 { | |
947 SDL_SetError("Photon: Can't create window widget"); | |
948 SDL_free(wdata); | |
949 return -1; | |
950 } | |
951 | |
952 /* Show widget */ | |
953 status=PtRealizeWidget(wdata->window); | |
954 if (status!=0) | |
955 { | |
956 SDL_SetError("Photon: Can't realize window widget"); | |
957 PtDestroyWidget(wdata->window); | |
958 SDL_free(wdata); | |
959 return; | |
960 } | |
961 | |
962 /* Just created SDL window always gets focus */ | |
963 window->flags|=SDL_WINDOW_INPUT_FOCUS; | |
964 | |
965 /* Create window-specific cursor after creation */ | |
966 if (didata->cursor_visible==SDL_TRUE) | |
967 { | |
968 /* Setup cursor type. shape and default color */ | |
969 PtSetResource(wdata->window, Pt_ARG_CURSOR_COLOR, Ph_CURSOR_DEFAULT_COLOR, 0); | |
970 PtSetResource(wdata->window, Pt_ARG_CURSOR_TYPE, Ph_CURSOR_BITMAP, 0); | |
971 PtSetResource(wdata->window, Pt_ARG_BITMAP_CURSOR, didata->cursor, didata->cursor->hdr.len+sizeof(PhRegionDataHdr_t)); | |
972 } | |
973 else | |
974 { | |
975 PtSetResource(wdata->window, Pt_ARG_CURSOR_TYPE, Ph_CURSOR_NONE, 0); | |
976 } | |
977 | |
978 /* Set window region sensible to mouse motion events */ | |
979 status=PhRegionQuery(PtWidgetRid(wdata->window), &wregion, NULL, NULL, 0); | |
980 if (status!=0) | |
981 { | |
982 SDL_SetError("Photon: Can't set region sensivity to mouse motion events"); | |
983 PtDestroyWidget(wdata->window); | |
984 SDL_free(wdata); | |
985 return -1; | |
986 } | |
987 wregion.events_sense|=Ph_EV_PTR_MOTION_BUTTON | Ph_EV_PTR_MOTION_NOBUTTON; | |
988 status=PhRegionChange(Ph_REGION_EV_SENSE, 0, &wregion, NULL, NULL); | |
989 if (status<0) | |
990 { | |
991 SDL_SetError("Photon: Can't change region sensivity"); | |
992 PtDestroyWidget(wdata->window); | |
993 SDL_free(wdata); | |
994 return -1; | |
995 } | |
996 | |
997 /* Flush all widget operations again */ | |
998 PtFlush(); | |
999 | |
1000 /* By default last created window got a input focus */ | |
1001 SDL_SetKeyboardFocus(0, window->id); | |
215 | 1002 |
216 /* Window has been successfully created */ | 1003 /* Window has been successfully created */ |
217 return 0; | 1004 return 0; |
218 } | 1005 } |
219 | 1006 |
220 int photon_createwindowfrom(_THIS, SDL_Window* window, const void* data) | 1007 int photon_createwindowfrom(_THIS, SDL_Window* window, const void* data) |
221 { | 1008 { |
1009 /* TODO: it is possible */ | |
1010 | |
222 /* Failed to create window from another window */ | 1011 /* Failed to create window from another window */ |
223 return -1; | 1012 return -1; |
224 } | 1013 } |
225 | 1014 |
226 void photon_setwindowtitle(_THIS, SDL_Window* window) | 1015 void photon_setwindowtitle(_THIS, SDL_Window* window) |
227 { | 1016 { |
1017 SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; | |
1018 int32_t status; | |
1019 | |
1020 /* Set window title */ | |
1021 if (window->title!=NULL) | |
1022 { | |
1023 status=PtSetResource(wdata->window, Pt_ARG_WINDOW_TITLE, window->title, 0); | |
1024 } | |
1025 else | |
1026 { | |
1027 status=PtSetResource(wdata->window, Pt_ARG_WINDOW_TITLE, "", 0); | |
1028 } | |
1029 | |
1030 if (status!=0) | |
1031 { | |
1032 SDL_SetError("Photon: Can't set window title"); | |
1033 } | |
1034 | |
1035 /* Flush all widget operations */ | |
1036 PtFlush(); | |
228 } | 1037 } |
229 | 1038 |
230 void photon_setwindowicon(_THIS, SDL_Window* window, SDL_Surface* icon) | 1039 void photon_setwindowicon(_THIS, SDL_Window* window, SDL_Surface* icon) |
231 { | 1040 { |
1041 SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; | |
1042 int32_t status; | |
1043 | |
1044 /* TODO: Use iconify ? */ | |
1045 | |
1046 /* Flush all widget operations */ | |
1047 PtFlush(); | |
232 } | 1048 } |
233 | 1049 |
234 void photon_setwindowposition(_THIS, SDL_Window* window) | 1050 void photon_setwindowposition(_THIS, SDL_Window* window) |
235 { | 1051 { |
1052 SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; | |
1053 SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata; | |
1054 PhPoint_t winpos; | |
1055 int32_t status; | |
1056 | |
1057 /* Check if upper level requests WM to position window */ | |
1058 if ((window->x==SDL_WINDOWPOS_UNDEFINED) && (window->y==SDL_WINDOWPOS_UNDEFINED)) | |
1059 { | |
1060 /* Do not set widget position, let WM to set it */ | |
1061 } | |
1062 else | |
1063 { | |
1064 if (window->x==SDL_WINDOWPOS_UNDEFINED) | |
1065 { | |
1066 window->x=0; | |
1067 } | |
1068 if (window->y==SDL_WINDOWPOS_UNDEFINED) | |
1069 { | |
1070 window->y=0; | |
1071 } | |
1072 if (window->x==SDL_WINDOWPOS_CENTERED) | |
1073 { | |
1074 window->x=(didata->current_mode.w-window->w)/2; | |
1075 } | |
1076 if (window->y==SDL_WINDOWPOS_CENTERED) | |
1077 { | |
1078 window->y=(didata->current_mode.h-window->h)/2; | |
1079 } | |
1080 | |
1081 /* Now set window position */ | |
1082 winpos.x=window->x; | |
1083 winpos.y=window->y; | |
1084 status=PtSetResource(wdata->window, Pt_ARG_POS, &winpos, 0); | |
1085 if (status!=0) | |
1086 { | |
1087 SDL_SetError("Photon: Can't set window position"); | |
1088 } | |
1089 } | |
1090 | |
1091 /* Flush all widget operations */ | |
1092 PtFlush(); | |
236 } | 1093 } |
237 | 1094 |
238 void photon_setwindowsize(_THIS, SDL_Window* window) | 1095 void photon_setwindowsize(_THIS, SDL_Window* window) |
239 { | 1096 { |
1097 SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; | |
1098 PhDim_t winsize; | |
1099 int32_t status; | |
1100 | |
1101 winsize.w=window->w; | |
1102 winsize.h=window->h; | |
1103 | |
1104 status=PtSetResource(wdata->window, Pt_ARG_DIM, &winsize, 0); | |
1105 if (status!=0) | |
1106 { | |
1107 SDL_SetError("Photon: Can't set window size"); | |
1108 } | |
1109 | |
1110 /* Flush all widget operations */ | |
1111 PtFlush(); | |
240 } | 1112 } |
241 | 1113 |
242 void photon_showwindow(_THIS, SDL_Window* window) | 1114 void photon_showwindow(_THIS, SDL_Window* window) |
243 { | 1115 { |
1116 SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; | |
1117 int32_t status; | |
1118 | |
1119 /* Bring focus to window and put it in front of others */ | |
1120 PtWindowToFront(wdata->window); | |
1121 | |
1122 /* Flush all widget operations */ | |
1123 PtFlush(); | |
244 } | 1124 } |
245 | 1125 |
246 void photon_hidewindow(_THIS, SDL_Window* window) | 1126 void photon_hidewindow(_THIS, SDL_Window* window) |
247 { | 1127 { |
1128 SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; | |
1129 PhWindowEvent_t winevent; | |
1130 int32_t status; | |
1131 | |
1132 SDL_memset(&winevent, 0x00, sizeof(PhWindowEvent_t)); | |
1133 winevent.event_f=Ph_WM_HIDE; | |
1134 winevent.rid=PtWidgetRid(wdata->window); | |
1135 winevent.event_state=Ph_WM_EVSTATE_HIDE; | |
1136 | |
1137 status=PtForwardWindowEvent(&winevent); | |
1138 if (status!=0) | |
1139 { | |
1140 SDL_SetError("Photon: Can't hide window"); | |
1141 } | |
1142 | |
1143 /* Flush all widget operations */ | |
1144 PtFlush(); | |
248 } | 1145 } |
249 | 1146 |
250 void photon_raisewindow(_THIS, SDL_Window* window) | 1147 void photon_raisewindow(_THIS, SDL_Window* window) |
251 { | 1148 { |
1149 SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; | |
1150 PhWindowEvent_t winevent; | |
1151 int32_t status; | |
1152 | |
1153 SDL_memset(&winevent, 0x00, sizeof(PhWindowEvent_t)); | |
1154 winevent.event_f=Ph_WM_HIDE; | |
1155 winevent.rid=PtWidgetRid(wdata->window); | |
1156 winevent.event_state=Ph_WM_EVSTATE_UNHIDE; | |
1157 | |
1158 status=PtForwardWindowEvent(&winevent); | |
1159 if (status!=0) | |
1160 { | |
1161 SDL_SetError("Photon: Can't hide window"); | |
1162 } | |
1163 | |
1164 /* Flush all widget operations */ | |
1165 PtFlush(); | |
252 } | 1166 } |
253 | 1167 |
254 void photon_maximizewindow(_THIS, SDL_Window* window) | 1168 void photon_maximizewindow(_THIS, SDL_Window* window) |
255 { | 1169 { |
1170 SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; | |
1171 PhWindowEvent_t winevent; | |
1172 int32_t status; | |
1173 | |
1174 /* Flush all widget operations */ | |
1175 PtFlush(); | |
256 } | 1176 } |
257 | 1177 |
258 void photon_minimizewindow(_THIS, SDL_Window* window) | 1178 void photon_minimizewindow(_THIS, SDL_Window* window) |
259 { | 1179 { |
1180 SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; | |
1181 PhWindowEvent_t winevent; | |
1182 int32_t status; | |
1183 | |
1184 SDL_memset(&winevent, 0x00, sizeof(PhWindowEvent_t)); | |
1185 winevent.event_f=Ph_WM_HIDE; | |
1186 winevent.rid=PtWidgetRid(wdata->window); | |
1187 winevent.event_state=Ph_WM_EVSTATE_HIDE; | |
1188 | |
1189 status=PtForwardWindowEvent(&winevent); | |
1190 if (status!=0) | |
1191 { | |
1192 SDL_SetError("Photon: Can't hide window"); | |
1193 } | |
1194 | |
1195 /* Flush all widget operations */ | |
1196 PtFlush(); | |
260 } | 1197 } |
261 | 1198 |
262 void photon_restorewindow(_THIS, SDL_Window* window) | 1199 void photon_restorewindow(_THIS, SDL_Window* window) |
263 { | 1200 { |
1201 SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; | |
1202 PhWindowEvent_t winevent; | |
1203 int32_t status; | |
1204 | |
1205 /* Flush all widget operations */ | |
1206 PtFlush(); | |
264 } | 1207 } |
265 | 1208 |
266 void photon_setwindowgrab(_THIS, SDL_Window* window) | 1209 void photon_setwindowgrab(_THIS, SDL_Window* window) |
267 { | 1210 { |
1211 SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; | |
1212 PhWindowEvent_t winevent; | |
1213 int32_t status; | |
1214 | |
1215 /* Flush all widget operations */ | |
1216 PtFlush(); | |
268 } | 1217 } |
269 | 1218 |
270 void photon_destroywindow(_THIS, SDL_Window* window) | 1219 void photon_destroywindow(_THIS, SDL_Window* window) |
271 { | 1220 { |
1221 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; | |
272 SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata; | 1222 SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata; |
273 SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; | 1223 SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; |
1224 int32_t status; | |
274 | 1225 |
275 if (wdata!=NULL) | 1226 if (wdata!=NULL) |
276 { | 1227 { |
277 } | 1228 status=PtDestroyWidget(wdata->window); |
1229 if (status!=0) | |
1230 { | |
1231 SDL_SetError("Photon: Can't destroy window widget"); | |
1232 } | |
1233 wdata->window=NULL; | |
1234 | |
1235 #if defined(SDL_VIDEO_OPENGL_ES) | |
1236 if (phdata->gfinitialized==SDL_TRUE) | |
1237 { | |
1238 /* Destroy OpenGL ES surface if it was created */ | |
1239 if (wdata->gles_surface!=EGL_NO_SURFACE) | |
1240 { | |
1241 eglDestroySurface(phdata->egldisplay, wdata->gles_surface); | |
1242 } | |
1243 | |
1244 /* Free OpenGL ES target surface */ | |
1245 if (wdata->gfsurface!=NULL) | |
1246 { | |
1247 gf_surface_free(wdata->gfsurface); | |
1248 } | |
1249 | |
1250 phdata->egl_refcount--; | |
1251 if (phdata->egl_refcount==0) | |
1252 { | |
1253 /* Terminate connection to OpenGL ES */ | |
1254 if (phdata->egldisplay!=EGL_NO_DISPLAY) | |
1255 { | |
1256 eglTerminate(phdata->egldisplay); | |
1257 phdata->egldisplay=EGL_NO_DISPLAY; | |
1258 } | |
1259 } | |
1260 } | |
1261 #endif /* SDL_VIDEO_OPENGL_ES */ | |
1262 } | |
1263 | |
1264 /* Flush all widget operations */ | |
1265 PtFlush(); | |
278 } | 1266 } |
279 | 1267 |
280 /*****************************************************************************/ | 1268 /*****************************************************************************/ |
281 /* SDL Window Manager function */ | 1269 /* SDL Window Manager function */ |
282 /*****************************************************************************/ | 1270 /*****************************************************************************/ |
299 /*****************************************************************************/ | 1287 /*****************************************************************************/ |
300 /* SDL OpenGL/OpenGL ES functions */ | 1288 /* SDL OpenGL/OpenGL ES functions */ |
301 /*****************************************************************************/ | 1289 /*****************************************************************************/ |
302 int photon_gl_loadlibrary(_THIS, const char* path) | 1290 int photon_gl_loadlibrary(_THIS, const char* path) |
303 { | 1291 { |
304 /* Failed to load new GL library */ | 1292 #if defined(SDL_VIDEO_OPENGL_ES) |
305 return -1; | 1293 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; |
1294 | |
1295 if (phdata->gfinitialized!=SDL_TRUE) | |
1296 { | |
1297 SDL_SetError("Photon: GF initialization failed, no OpenGL ES support"); | |
1298 return NULL; | |
1299 } | |
1300 | |
1301 /* Check if OpenGL ES library is specified for GF driver */ | |
1302 if (path==NULL) | |
1303 { | |
1304 path=SDL_getenv("SDL_OPENGL_LIBRARY"); | |
1305 if (path==NULL) | |
1306 { | |
1307 path=SDL_getenv("SDL_OPENGLES_LIBRARY"); | |
1308 } | |
1309 } | |
1310 | |
1311 /* Check if default library loading requested */ | |
1312 if (path==NULL) | |
1313 { | |
1314 /* Already linked with GF library which provides egl* subset of */ | |
1315 /* functions, use Common profile of OpenGL ES library by default */ | |
1316 path="/usr/lib/libGLES_CM.so.1"; | |
1317 } | |
1318 | |
1319 /* Load dynamic library */ | |
1320 _this->gl_config.dll_handle=SDL_LoadObject(path); | |
1321 if (!_this->gl_config.dll_handle) | |
1322 { | |
1323 /* Failed to load new GL ES library */ | |
1324 SDL_SetError("Photon: Failed to locate OpenGL ES library"); | |
1325 return -1; | |
1326 } | |
1327 | |
1328 /* Store OpenGL ES library path and name */ | |
1329 SDL_strlcpy(_this->gl_config.driver_path, path, SDL_arraysize(_this->gl_config.driver_path)); | |
1330 | |
1331 /* New OpenGL ES library is loaded */ | |
1332 return 0; | |
1333 #else | |
1334 SDL_SetError("Photon: OpenGL ES support is not compiled in"); | |
1335 return -1; | |
1336 #endif /* SDL_VIDEO_OPENGL_ES */ | |
306 } | 1337 } |
307 | 1338 |
308 void* photon_gl_getprocaddres(_THIS, const char* proc) | 1339 void* photon_gl_getprocaddres(_THIS, const char* proc) |
309 { | 1340 { |
310 /* Failed to get GL function address pointer */ | 1341 #if defined(SDL_VIDEO_OPENGL_ES) |
311 return NULL; | 1342 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; |
1343 void* function_address; | |
1344 | |
1345 if (phdata->gfinitialized!=SDL_TRUE) | |
1346 { | |
1347 SDL_SetError("Photon: GF initialization failed, no OpenGL ES support"); | |
1348 return NULL; | |
1349 } | |
1350 | |
1351 /* Try to get function address through the egl interface */ | |
1352 function_address=eglGetProcAddress(proc); | |
1353 if (function_address!=NULL) | |
1354 { | |
1355 return function_address; | |
1356 } | |
1357 | |
1358 /* Then try to get function in the OpenGL ES library */ | |
1359 if (_this->gl_config.dll_handle) | |
1360 { | |
1361 function_address=SDL_LoadFunction(_this->gl_config.dll_handle, proc); | |
1362 if (function_address!=NULL) | |
1363 { | |
1364 return function_address; | |
1365 } | |
1366 } | |
1367 | |
1368 /* Add emulated OpenGL ES 1.1 functions */ | |
1369 if (SDL_strcmp(proc, "glTexParameteri")==0) | |
1370 { | |
1371 return glTexParameteri; | |
1372 } | |
1373 if (SDL_strcmp(proc, "glTexParameteriv")==0) | |
1374 { | |
1375 return glTexParameteriv; | |
1376 } | |
1377 if (SDL_strcmp(proc, "glColor4ub")==0) | |
1378 { | |
1379 return glColor4ub; | |
1380 } | |
1381 | |
1382 /* Failed to get GL ES function address pointer */ | |
1383 SDL_SetError("Photon: Cannot locate OpenGL ES function name"); | |
1384 return NULL; | |
1385 #else | |
1386 SDL_SetError("Photon: OpenGL ES support is not compiled in"); | |
1387 return NULL; | |
1388 #endif /* SDL_VIDEO_OPENGL_ES */ | |
312 } | 1389 } |
313 | 1390 |
314 void photon_gl_unloadlibrary(_THIS) | 1391 void photon_gl_unloadlibrary(_THIS) |
315 { | 1392 { |
1393 #if defined(SDL_VIDEO_OPENGL_ES) | |
1394 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; | |
1395 | |
1396 if (phdata->gfinitialized==SDL_TRUE) | |
1397 { | |
1398 /* Unload OpenGL ES library */ | |
1399 if (_this->gl_config.dll_handle) | |
1400 { | |
1401 SDL_UnloadObject(_this->gl_config.dll_handle); | |
1402 _this->gl_config.dll_handle=NULL; | |
1403 } | |
1404 } | |
1405 else | |
1406 { | |
1407 SDL_SetError("Photon: GF initialization failed, no OpenGL ES support"); | |
1408 } | |
1409 #else | |
1410 SDL_SetError("Photon: OpenGL ES support is not compiled in"); | |
1411 return; | |
1412 #endif /* SDL_VIDEO_OPENGL_ES */ | |
316 } | 1413 } |
317 | 1414 |
318 SDL_GLContext photon_gl_createcontext(_THIS, SDL_Window* window) | 1415 SDL_GLContext photon_gl_createcontext(_THIS, SDL_Window* window) |
319 { | 1416 { |
320 /* Failed to create GL context */ | 1417 #if defined(SDL_VIDEO_OPENGL_ES) |
321 return NULL; | 1418 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; |
1419 SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; | |
1420 SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata; | |
1421 EGLBoolean status; | |
1422 int32_t gfstatus; | |
1423 EGLint configs; | |
1424 uint32_t attr_pos; | |
1425 EGLint attr_value; | |
1426 EGLint cit; | |
1427 | |
1428 /* Check if GF was initialized */ | |
1429 if (phdata->gfinitialized!=SDL_TRUE) | |
1430 { | |
1431 SDL_SetError("Photon: GF initialization failed, no OpenGL ES support"); | |
1432 return NULL; | |
1433 } | |
1434 | |
1435 /* Prepare attributes list to pass them to OpenGL ES */ | |
1436 attr_pos=0; | |
1437 wdata->gles_attributes[attr_pos++]=EGL_NATIVE_VISUAL_ID; | |
1438 wdata->gles_attributes[attr_pos++]=qnxgf_sdl_to_gf_pixelformat(didata->current_mode.format); | |
1439 wdata->gles_attributes[attr_pos++]=EGL_RED_SIZE; | |
1440 wdata->gles_attributes[attr_pos++]=_this->gl_config.red_size; | |
1441 wdata->gles_attributes[attr_pos++]=EGL_GREEN_SIZE; | |
1442 wdata->gles_attributes[attr_pos++]=_this->gl_config.green_size; | |
1443 wdata->gles_attributes[attr_pos++]=EGL_BLUE_SIZE; | |
1444 wdata->gles_attributes[attr_pos++]=_this->gl_config.blue_size; | |
1445 wdata->gles_attributes[attr_pos++]=EGL_ALPHA_SIZE; | |
1446 | |
1447 /* Setup alpha size in bits */ | |
1448 if (_this->gl_config.alpha_size) | |
1449 { | |
1450 wdata->gles_attributes[attr_pos++]=_this->gl_config.alpha_size; | |
1451 } | |
1452 else | |
1453 { | |
1454 wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; | |
1455 } | |
1456 | |
1457 /* Setup color buffer size */ | |
1458 if (_this->gl_config.buffer_size) | |
1459 { | |
1460 wdata->gles_attributes[attr_pos++]=EGL_BUFFER_SIZE; | |
1461 wdata->gles_attributes[attr_pos++]=_this->gl_config.buffer_size; | |
1462 } | |
1463 else | |
1464 { | |
1465 wdata->gles_attributes[attr_pos++]=EGL_BUFFER_SIZE; | |
1466 wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; | |
1467 } | |
1468 | |
1469 /* Setup depth buffer bits */ | |
1470 wdata->gles_attributes[attr_pos++]=EGL_DEPTH_SIZE; | |
1471 wdata->gles_attributes[attr_pos++]=_this->gl_config.depth_size; | |
1472 | |
1473 /* Setup stencil bits */ | |
1474 if (_this->gl_config.stencil_size) | |
1475 { | |
1476 wdata->gles_attributes[attr_pos++]=EGL_STENCIL_SIZE; | |
1477 wdata->gles_attributes[attr_pos++]=_this->gl_config.buffer_size; | |
1478 } | |
1479 else | |
1480 { | |
1481 wdata->gles_attributes[attr_pos++]=EGL_STENCIL_SIZE; | |
1482 wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; | |
1483 } | |
1484 | |
1485 /* Set number of samples in multisampling */ | |
1486 if (_this->gl_config.multisamplesamples) | |
1487 { | |
1488 wdata->gles_attributes[attr_pos++]=EGL_SAMPLES; | |
1489 wdata->gles_attributes[attr_pos++]=_this->gl_config.multisamplesamples; | |
1490 } | |
1491 | |
1492 /* Multisample buffers, OpenGL ES 1.0 spec defines 0 or 1 buffer */ | |
1493 if (_this->gl_config.multisamplebuffers) | |
1494 { | |
1495 wdata->gles_attributes[attr_pos++]=EGL_SAMPLE_BUFFERS; | |
1496 wdata->gles_attributes[attr_pos++]=_this->gl_config.multisamplebuffers; | |
1497 } | |
1498 | |
1499 /* Finish attributes list */ | |
1500 wdata->gles_attributes[attr_pos]=EGL_NONE; | |
1501 | |
1502 /* Request first suitable framebuffer configuration */ | |
1503 status=eglChooseConfig(phdata->egldisplay, wdata->gles_attributes, | |
1504 wdata->gles_configs, SDL_VIDEO_GF_OPENGLES_CONFS, &configs); | |
1505 if (status!=EGL_TRUE) | |
1506 { | |
1507 SDL_SetError("Photon: Can't find closest configuration for OpenGL ES"); | |
1508 return NULL; | |
1509 } | |
1510 | |
1511 /* Check if nothing has been found, try "don't care" settings */ | |
1512 if (configs==0) | |
1513 { | |
1514 int32_t it; | |
1515 int32_t jt; | |
1516 GLint depthbits[4]={32, 24, 16, EGL_DONT_CARE}; | |
1517 | |
1518 for (it=0; it<4; it++) | |
1519 { | |
1520 for (jt=16; jt>=0; jt--) | |
1521 { | |
1522 /* Don't care about color buffer bits, use what exist */ | |
1523 /* Replace previous set data with EGL_DONT_CARE */ | |
1524 attr_pos=0; | |
1525 wdata->gles_attributes[attr_pos++]=EGL_NATIVE_VISUAL_ID; | |
1526 wdata->gles_attributes[attr_pos++]=qnxgf_sdl_to_gf_pixelformat(didata->current_mode.format); | |
1527 wdata->gles_attributes[attr_pos++]=EGL_RED_SIZE; | |
1528 wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; | |
1529 wdata->gles_attributes[attr_pos++]=EGL_GREEN_SIZE; | |
1530 wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; | |
1531 wdata->gles_attributes[attr_pos++]=EGL_BLUE_SIZE; | |
1532 wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; | |
1533 wdata->gles_attributes[attr_pos++]=EGL_ALPHA_SIZE; | |
1534 wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; | |
1535 wdata->gles_attributes[attr_pos++]=EGL_BUFFER_SIZE; | |
1536 wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; | |
1537 | |
1538 /* Try to find requested or smallest depth */ | |
1539 if (_this->gl_config.depth_size) | |
1540 { | |
1541 wdata->gles_attributes[attr_pos++]=EGL_DEPTH_SIZE; | |
1542 wdata->gles_attributes[attr_pos++]=depthbits[it]; | |
1543 } | |
1544 else | |
1545 { | |
1546 wdata->gles_attributes[attr_pos++]=EGL_DEPTH_SIZE; | |
1547 wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; | |
1548 } | |
1549 | |
1550 if (_this->gl_config.stencil_size) | |
1551 { | |
1552 wdata->gles_attributes[attr_pos++]=EGL_STENCIL_SIZE; | |
1553 wdata->gles_attributes[attr_pos++]=jt; | |
1554 } | |
1555 else | |
1556 { | |
1557 wdata->gles_attributes[attr_pos++]=EGL_STENCIL_SIZE; | |
1558 wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; | |
1559 } | |
1560 | |
1561 wdata->gles_attributes[attr_pos++]=EGL_SAMPLES; | |
1562 wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; | |
1563 wdata->gles_attributes[attr_pos++]=EGL_SAMPLE_BUFFERS; | |
1564 wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; | |
1565 wdata->gles_attributes[attr_pos]=EGL_NONE; | |
1566 | |
1567 /* Request first suitable framebuffer configuration */ | |
1568 status=eglChooseConfig(phdata->egldisplay, wdata->gles_attributes, | |
1569 wdata->gles_configs, SDL_VIDEO_GF_OPENGLES_CONFS, &configs); | |
1570 if (status!=EGL_TRUE) | |
1571 { | |
1572 SDL_SetError("Photon: Can't find closest configuration for OpenGL ES"); | |
1573 return NULL; | |
1574 } | |
1575 if (configs!=0) | |
1576 { | |
1577 break; | |
1578 } | |
1579 } | |
1580 if (configs!=0) | |
1581 { | |
1582 break; | |
1583 } | |
1584 } | |
1585 | |
1586 /* No available configs */ | |
1587 if (configs==0) | |
1588 { | |
1589 SDL_SetError("Photon: Can't find any configuration for OpenGL ES"); | |
1590 return NULL; | |
1591 } | |
1592 } | |
1593 | |
1594 /* Initialize config index */ | |
1595 wdata->gles_config=0; | |
1596 | |
1597 /* Now check each configuration to find out the best */ | |
1598 for (cit=0; cit<configs; cit++) | |
1599 { | |
1600 uint32_t stencil_found; | |
1601 uint32_t depth_found; | |
1602 | |
1603 stencil_found=0; | |
1604 depth_found=0; | |
1605 | |
1606 if (_this->gl_config.stencil_size) | |
1607 { | |
1608 status=eglGetConfigAttrib(phdata->egldisplay, wdata->gles_configs[cit], EGL_STENCIL_SIZE, &attr_value); | |
1609 if (status==EGL_TRUE) | |
1610 { | |
1611 if (attr_value!=0) | |
1612 { | |
1613 stencil_found=1; | |
1614 } | |
1615 } | |
1616 } | |
1617 else | |
1618 { | |
1619 stencil_found=1; | |
1620 } | |
1621 | |
1622 if (_this->gl_config.depth_size) | |
1623 { | |
1624 status=eglGetConfigAttrib(phdata->egldisplay, wdata->gles_configs[cit], EGL_DEPTH_SIZE, &attr_value); | |
1625 if (status==EGL_TRUE) | |
1626 { | |
1627 if (attr_value!=0) | |
1628 { | |
1629 depth_found=1; | |
1630 } | |
1631 } | |
1632 } | |
1633 else | |
1634 { | |
1635 depth_found=1; | |
1636 } | |
1637 | |
1638 /* Exit from loop if found appropriate configuration */ | |
1639 if ((depth_found!=0) && (stencil_found!=0)) | |
1640 { | |
1641 break; | |
1642 } | |
1643 } | |
1644 | |
1645 /* If best could not be found, use first */ | |
1646 if (cit==configs) | |
1647 { | |
1648 cit=0; | |
1649 } | |
1650 wdata->gles_config=cit; | |
1651 | |
1652 /* Create OpenGL ES context */ | |
1653 wdata->gles_context=eglCreateContext(phdata->egldisplay, wdata->gles_configs[wdata->gles_config], EGL_NO_CONTEXT, NULL); | |
1654 if (wdata->gles_context==EGL_NO_CONTEXT) | |
1655 { | |
1656 SDL_SetError("Photon: OpenGL ES context creation has been failed"); | |
1657 return NULL; | |
1658 } | |
1659 | |
1660 /* Check if surface is exist */ | |
1661 if (wdata->gfsurface!=NULL) | |
1662 { | |
1663 gf_surface_free(wdata->gfsurface); | |
1664 wdata->gfsurface=NULL; | |
1665 } | |
1666 | |
1667 /* Create GF surface */ | |
1668 gfstatus=gf_surface_create(&wdata->gfsurface, phdata->gfdev, window->w, window->h, | |
1669 qnxgf_sdl_to_gf_pixelformat(didata->current_mode.format), NULL, | |
1670 GF_SURFACE_CREATE_2D_ACCESSIBLE | GF_SURFACE_CREATE_3D_ACCESSIBLE | | |
1671 GF_SURFACE_CREATE_SHAREABLE); | |
1672 if (gfstatus!=GF_ERR_OK) | |
1673 { | |
1674 eglDestroyContext(phdata->egldisplay, wdata->gles_context); | |
1675 wdata->gles_context=EGL_NO_CONTEXT; | |
1676 SDL_SetError("Photon: Can't create GF 3D surface (%08X)", gfstatus); | |
1677 return NULL; | |
1678 } | |
1679 | |
1680 /* Create pixmap 3D target surface */ | |
1681 wdata->gles_surface=eglCreatePixmapSurface(phdata->egldisplay, wdata->gles_configs[wdata->gles_config], wdata->gfsurface, NULL); | |
1682 if (wdata->gles_surface==EGL_NO_SURFACE) | |
1683 { | |
1684 gf_surface_free(wdata->gfsurface); | |
1685 eglDestroyContext(phdata->egldisplay, wdata->gles_context); | |
1686 wdata->gles_context=EGL_NO_CONTEXT; | |
1687 SDL_SetError("Photon: Can't create EGL pixmap surface"); | |
1688 return NULL; | |
1689 } | |
1690 | |
1691 /* Make just created context current */ | |
1692 status=eglMakeCurrent(phdata->egldisplay, wdata->gles_surface, wdata->gles_surface, wdata->gles_context); | |
1693 if (status!=EGL_TRUE) | |
1694 { | |
1695 /* Destroy OpenGL ES surface */ | |
1696 eglDestroySurface(phdata->egldisplay, wdata->gles_surface); | |
1697 gf_surface_free(wdata->gfsurface); | |
1698 eglDestroyContext(phdata->egldisplay, wdata->gles_context); | |
1699 wdata->gles_context=EGL_NO_CONTEXT; | |
1700 SDL_SetError("Photon: Can't set OpenGL ES context on creation"); | |
1701 return NULL; | |
1702 } | |
1703 | |
1704 /* Setup into SDL internals state of OpenGL ES: */ | |
1705 /* it is accelerated or not */ | |
1706 if ((didata->caps & SDL_PHOTON_ACCELERATED_3D)==SDL_PHOTON_ACCELERATED_3D) | |
1707 { | |
1708 _this->gl_config.accelerated=1; | |
1709 } | |
1710 else | |
1711 { | |
1712 _this->gl_config.accelerated=0; | |
1713 } | |
1714 | |
1715 /* Always clear stereo enable, since OpenGL ES do not supports stereo */ | |
1716 _this->gl_config.stereo=0; | |
1717 | |
1718 /* Get back samples and samplebuffers configurations. Rest framebuffer */ | |
1719 /* parameters could be obtained through the OpenGL ES API */ | |
1720 status=eglGetConfigAttrib(phdata->egldisplay, wdata->gles_configs[wdata->gles_config], EGL_SAMPLES, &attr_value); | |
1721 if (status==EGL_TRUE) | |
1722 { | |
1723 _this->gl_config.multisamplesamples=attr_value; | |
1724 } | |
1725 status=eglGetConfigAttrib(phdata->egldisplay, wdata->gles_configs[wdata->gles_config], EGL_SAMPLE_BUFFERS, &attr_value); | |
1726 if (status==EGL_TRUE) | |
1727 { | |
1728 _this->gl_config.multisamplebuffers=attr_value; | |
1729 } | |
1730 | |
1731 /* Get back stencil and depth buffer sizes */ | |
1732 status=eglGetConfigAttrib(phdata->egldisplay, wdata->gles_configs[wdata->gles_config], EGL_DEPTH_SIZE, &attr_value); | |
1733 if (status==EGL_TRUE) | |
1734 { | |
1735 _this->gl_config.depth_size=attr_value; | |
1736 } | |
1737 status=eglGetConfigAttrib(phdata->egldisplay, wdata->gles_configs[wdata->gles_config], EGL_STENCIL_SIZE, &attr_value); | |
1738 if (status==EGL_TRUE) | |
1739 { | |
1740 _this->gl_config.stencil_size=attr_value; | |
1741 } | |
1742 | |
1743 /* Under Photon OpenGL ES output can't be double buffered */ | |
1744 _this->gl_config.double_buffer=0; | |
1745 | |
1746 /* Check if current device is not the same as target */ | |
1747 if (phdata->current_device_id!=didata->device_id) | |
1748 { | |
1749 /* Set target device as default for Pd and Pg functions */ | |
1750 status=PdSetTargetDevice(NULL, phdata->rid[didata->device_id]); | |
1751 if (status!=0) | |
1752 { | |
1753 /* Destroy OpenGL ES surface */ | |
1754 eglDestroySurface(phdata->egldisplay, wdata->gles_surface); | |
1755 gf_surface_free(wdata->gfsurface); | |
1756 eglDestroyContext(phdata->egldisplay, wdata->gles_context); | |
1757 wdata->gles_context=EGL_NO_CONTEXT; | |
1758 SDL_SetError("Photon: Can't set default target device\n"); | |
1759 return NULL; | |
1760 } | |
1761 phdata->current_device_id=didata->device_id; | |
1762 } | |
1763 | |
1764 wdata->phsurface=PdCreateOffscreenContextGF(wdata->gfsurface); | |
1765 if (wdata->phsurface==NULL) | |
1766 { | |
1767 /* Destroy OpenGL ES surface */ | |
1768 eglDestroySurface(phdata->egldisplay, wdata->gles_surface); | |
1769 gf_surface_free(wdata->gfsurface); | |
1770 eglDestroyContext(phdata->egldisplay, wdata->gles_context); | |
1771 wdata->gles_context=EGL_NO_CONTEXT; | |
1772 SDL_SetError("Photon: Can't bind GF surface to Photon\n"); | |
1773 return NULL; | |
1774 } | |
1775 | |
1776 /* GL ES context was successfully created */ | |
1777 return wdata->gles_context; | |
1778 #else | |
1779 SDL_SetError("Photon: OpenGL ES support is not compiled in"); | |
1780 return NULL; | |
1781 #endif /* SDL_VIDEO_OPENGL_ES */ | |
322 } | 1782 } |
323 | 1783 |
324 int photon_gl_makecurrent(_THIS, SDL_Window* window, SDL_GLContext context) | 1784 int photon_gl_makecurrent(_THIS, SDL_Window* window, SDL_GLContext context) |
325 { | 1785 { |
326 /* Failed to set current GL context */ | 1786 #if defined(SDL_VIDEO_OPENGL_ES) |
327 return -1; | 1787 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; |
1788 SDL_WindowData* wdata; | |
1789 EGLBoolean status; | |
1790 | |
1791 if (phdata->gfinitialized!=SDL_TRUE) | |
1792 { | |
1793 SDL_SetError("Photon: GF initialization failed, no OpenGL ES support"); | |
1794 return -1; | |
1795 } | |
1796 | |
1797 if ((window==NULL) && (context==NULL)) | |
1798 { | |
1799 status=eglMakeCurrent(phdata->egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | |
1800 if (status!=EGL_TRUE) | |
1801 { | |
1802 /* Failed to set current GL ES context */ | |
1803 SDL_SetError("Photon: Can't set OpenGL ES context"); | |
1804 return -1; | |
1805 } | |
1806 } | |
1807 else | |
1808 { | |
1809 wdata=(SDL_WindowData*)window->driverdata; | |
1810 if (wdata->gles_surface==EGL_NO_SURFACE) | |
1811 { | |
1812 SDL_SetError("Photon: OpenGL ES surface is not initialized for this window"); | |
1813 return -1; | |
1814 } | |
1815 if (wdata->gles_context==EGL_NO_CONTEXT) | |
1816 { | |
1817 SDL_SetError("Photon: OpenGL ES context is not initialized for this window"); | |
1818 return -1; | |
1819 } | |
1820 if (wdata->gles_context!=context) | |
1821 { | |
1822 SDL_SetError("Photon: OpenGL ES context is not belong to this window"); | |
1823 return -1; | |
1824 } | |
1825 status=eglMakeCurrent(phdata->egldisplay, wdata->gles_surface, wdata->gles_surface, wdata->gles_context); | |
1826 if (status!=EGL_TRUE) | |
1827 { | |
1828 /* Failed to set current GL ES context */ | |
1829 SDL_SetError("Photon: Can't set OpenGL ES context"); | |
1830 return -1; | |
1831 } | |
1832 } | |
1833 | |
1834 return 0; | |
1835 #else | |
1836 SDL_SetError("Photon: OpenGL ES support is not compiled in"); | |
1837 return -1; | |
1838 #endif /* SDL_VIDEO_OPENGL_ES */ | |
328 } | 1839 } |
329 | 1840 |
330 int photon_gl_setswapinterval(_THIS, int interval) | 1841 int photon_gl_setswapinterval(_THIS, int interval) |
331 { | 1842 { |
332 /* Failed to set swap interval */ | 1843 #if defined(SDL_VIDEO_OPENGL_ES) |
333 return -1; | 1844 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; |
1845 EGLBoolean status; | |
1846 | |
1847 if (phdata->gfinitialized!=SDL_TRUE) | |
1848 { | |
1849 SDL_SetError("Photon: GF initialization failed, no OpenGL ES support"); | |
1850 return -1; | |
1851 } | |
1852 | |
1853 /* Check if OpenGL ES connection has been initialized */ | |
1854 if (phdata->egldisplay!=EGL_NO_DISPLAY) | |
1855 { | |
1856 /* Set swap OpenGL ES interval */ | |
1857 status=eglSwapInterval(phdata->egldisplay, interval); | |
1858 if (status==EGL_TRUE) | |
1859 { | |
1860 /* Return success to upper level */ | |
1861 phdata->swapinterval=interval; | |
1862 return 0; | |
1863 } | |
1864 } | |
1865 | |
1866 /* Failed to set swap interval */ | |
1867 SDL_SetError("Photon: Cannot set swap interval"); | |
1868 return -1; | |
1869 #else | |
1870 SDL_SetError("Photon: OpenGL ES support is not compiled in"); | |
1871 return -1; | |
1872 #endif /* SDL_VIDEO_OPENGL_ES */ | |
334 } | 1873 } |
335 | 1874 |
336 int photon_gl_getswapinterval(_THIS) | 1875 int photon_gl_getswapinterval(_THIS) |
337 { | 1876 { |
338 /* Failed to get default swap interval */ | 1877 #if defined(SDL_VIDEO_OPENGL_ES) |
339 return -1; | 1878 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; |
1879 | |
1880 if (phdata->gfinitialized!=SDL_TRUE) | |
1881 { | |
1882 SDL_SetError("Photon: GF initialization failed, no OpenGL ES support"); | |
1883 return -1; | |
1884 } | |
1885 | |
1886 /* Return default swap interval value */ | |
1887 return phdata->swapinterval; | |
1888 #else | |
1889 SDL_SetError("Photon: OpenGL ES support is not compiled in"); | |
1890 return -1; | |
1891 #endif /* SDL_VIDEO_OPENGL_ES */ | |
340 } | 1892 } |
341 | 1893 |
342 void photon_gl_swapwindow(_THIS, SDL_Window* window) | 1894 void photon_gl_swapwindow(_THIS, SDL_Window* window) |
343 { | 1895 { |
1896 #if defined(SDL_VIDEO_OPENGL_ES) | |
1897 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; | |
1898 SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; | |
1899 SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata; | |
1900 PhRect_t* dst_rect; | |
1901 PhRect_t src_rect; | |
1902 | |
1903 if (phdata->gfinitialized!=SDL_TRUE) | |
1904 { | |
1905 SDL_SetError("Photon: GF initialization failed, no OpenGL ES support"); | |
1906 return; | |
1907 } | |
1908 | |
1909 /* Many applications do not uses glFinish(), so we call it for them */ | |
1910 glFinish(); | |
1911 | |
1912 /* Wait until OpenGL ES rendering is completed */ | |
1913 eglWaitGL(); | |
1914 | |
1915 /* Wait for VSYNC manually, if it was enabled */ | |
1916 if (phdata->swapinterval!=0) | |
1917 { | |
1918 /* Wait for VSYNC, we use GF function, since Photon requires */ | |
1919 /* to enter to the Direct mode to call PgWaitVSync() */ | |
1920 gf_display_wait_vsync(didata->display); | |
1921 } | |
1922 | |
1923 /* Set blit area */ | |
1924 dst_rect=PtGetCanvas(wdata->window); | |
1925 src_rect.ul.x=0; | |
1926 src_rect.ul.y=0; | |
1927 src_rect.lr.x=window->w-1; | |
1928 src_rect.lr.y=window->h-1; | |
1929 | |
1930 /* Blit OpenGL ES pixmap surface directly to window region */ | |
1931 PgFFlush(Ph_START_DRAW); | |
1932 PgSetRegionCx(PhDCGetCurrent(), PtWidgetRid(wdata->window)); | |
1933 PgClearTranslationCx(PgGetGCCx(PhDCGetCurrent())); | |
1934 PgContextBlit(wdata->phsurface, &src_rect, NULL, dst_rect); | |
1935 PgFFlush(Ph_DONE_DRAW); | |
1936 PgWaitHWIdle(); | |
1937 | |
1938 eglSwapBuffers(phdata->egldisplay, wdata->gles_surface); | |
1939 #else | |
1940 SDL_SetError("Photon: OpenGL ES support is not compiled in"); | |
1941 return; | |
1942 #endif /* SDL_VIDEO_OPENGL_ES */ | |
344 } | 1943 } |
345 | 1944 |
346 void photon_gl_deletecontext(_THIS, SDL_GLContext context) | 1945 void photon_gl_deletecontext(_THIS, SDL_GLContext context) |
347 { | 1946 { |
1947 #if defined(SDL_VIDEO_OPENGL_ES) | |
1948 SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata; | |
1949 EGLBoolean status; | |
1950 | |
1951 if (phdata->gfinitialized!=SDL_TRUE) | |
1952 { | |
1953 SDL_SetError("Photon: GF initialization failed, no OpenGL ES support"); | |
1954 return; | |
1955 } | |
1956 | |
1957 /* Check if OpenGL ES connection has been initialized */ | |
1958 if (phdata->egldisplay!=EGL_NO_DISPLAY) | |
1959 { | |
1960 if (context!=EGL_NO_CONTEXT) | |
1961 { | |
1962 status=eglDestroyContext(phdata->egldisplay, context); | |
1963 if (status!=EGL_TRUE) | |
1964 { | |
1965 /* Error during OpenGL ES context destroying */ | |
1966 SDL_SetError("Photon: OpenGL ES context destroy error"); | |
1967 return; | |
1968 } | |
1969 } | |
1970 } | |
1971 | |
1972 return; | |
1973 #else | |
1974 SDL_SetError("Photon: OpenGL ES support is not compiled in"); | |
1975 return; | |
1976 #endif /* SDL_VIDEO_OPENGL_ES */ | |
348 } | 1977 } |
349 | 1978 |
350 /*****************************************************************************/ | 1979 /*****************************************************************************/ |
351 /* SDL Event handling function */ | 1980 /* SDL Event handling function */ |
352 /*****************************************************************************/ | 1981 /*****************************************************************************/ |
353 void photon_pumpevents(_THIS) | 1982 void photon_pumpevents(_THIS) |
354 { | 1983 { |
1984 uint8_t eventbuffer[SDL_VIDEO_PHOTON_EVENT_SIZE]; | |
1985 PhEvent_t* event=(PhEvent_t*)eventbuffer; | |
1986 int32_t status; | |
1987 uint32_t finish=0; | |
1988 uint32_t it; | |
1989 SDL_Window* window; | |
1990 SDL_WindowData* wdata; | |
1991 | |
1992 do { | |
1993 status=PhEventPeek(event, SDL_VIDEO_PHOTON_EVENT_SIZE); | |
1994 switch (status) | |
1995 { | |
1996 case Ph_RESIZE_MSG: | |
1997 { | |
1998 SDL_SetError("Photon: Event size too much for buffer"); | |
1999 return; | |
2000 } | |
2001 break; | |
2002 case Ph_EVENT_MSG: | |
2003 { | |
2004 /* Find a window, to which this handle destinated */ | |
2005 status=0; | |
2006 for (it=0; it<SDL_CurrentDisplay.num_windows; it++) | |
2007 { | |
2008 wdata=(SDL_WindowData*)SDL_CurrentDisplay.windows[it].driverdata; | |
2009 | |
2010 /* Find the proper window */ | |
2011 if (wdata->window!=NULL) | |
2012 { | |
2013 if (PtWidgetRid(wdata->window)==event->collector.rid) | |
2014 { | |
2015 window=(SDL_Window*)&SDL_CurrentDisplay.windows[it]; | |
2016 status=1; | |
2017 break; | |
2018 } | |
2019 } | |
2020 else | |
2021 { | |
2022 continue; | |
2023 } | |
2024 } | |
2025 if (status==0) | |
2026 { | |
2027 window=NULL; | |
2028 } | |
2029 | |
2030 /* Event is ready */ | |
2031 switch(event->type) | |
2032 { | |
2033 case Ph_EV_BOUNDARY: | |
2034 { | |
2035 switch(event->subtype) | |
2036 { | |
2037 case Ph_EV_PTR_ENTER: | |
2038 { | |
2039 /* Mouse cursor over handled window */ | |
2040 if (window!=NULL) | |
2041 { | |
2042 SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_ENTER, 0, 0); | |
2043 SDL_SetMouseFocus(0, window->id); | |
2044 } | |
2045 } | |
2046 break; | |
2047 case Ph_EV_PTR_LEAVE: | |
2048 { | |
2049 /* Mouse cursor out of handled window */ | |
2050 if (window!=NULL) | |
2051 { | |
2052 SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_LEAVE, 0, 0); | |
2053 } | |
2054 } | |
2055 break; | |
2056 } | |
2057 } | |
2058 break; | |
2059 case Ph_EV_PTR_MOTION_BUTTON: | |
2060 case Ph_EV_PTR_MOTION_NOBUTTON: | |
2061 { | |
2062 PhPointerEvent_t* pevent=NULL; | |
2063 PhRect_t* prects=NULL; | |
2064 | |
2065 /* Get event data */ | |
2066 pevent=PhGetData(event); | |
2067 /* Get associated event rectangles */ | |
2068 prects=PhGetRects(event); | |
2069 if ((pevent!=NULL) && (prects!=NULL)) | |
2070 { | |
2071 SDL_SendMouseMotion(0, 0, prects->ul.x, prects->ul.y, 0); | |
2072 } | |
2073 } | |
2074 break; | |
2075 case Ph_EV_BUT_PRESS: | |
2076 { | |
2077 /* Button press event */ | |
2078 PhPointerEvent_t* pevent=NULL; | |
2079 uint32_t sdlbutton=0x00000000; | |
2080 | |
2081 /* Get event data */ | |
2082 pevent=PhGetData(event); | |
2083 if (pevent!=NULL) | |
2084 { | |
2085 for (it=0; it<sizeof(pevent->buttons)*8; it++) | |
2086 { | |
2087 if ((pevent->buttons&(0x0001<<it))==(0x0001<<it)) | |
2088 { | |
2089 switch (it) | |
2090 { | |
2091 case 0: | |
2092 { | |
2093 sdlbutton=SDL_BUTTON_RIGHT; | |
2094 } | |
2095 break; | |
2096 case 1: | |
2097 { | |
2098 sdlbutton=SDL_BUTTON_MIDDLE; | |
2099 } | |
2100 break; | |
2101 case 2: | |
2102 { | |
2103 sdlbutton=SDL_BUTTON_LEFT; | |
2104 } | |
2105 break; | |
2106 default: | |
2107 { | |
2108 sdlbutton=it+1; | |
2109 } | |
2110 break; | |
2111 } | |
2112 SDL_SendMouseButton(0, SDL_PRESSED, sdlbutton); | |
2113 } | |
2114 } | |
2115 } | |
2116 } | |
2117 break; | |
2118 case Ph_EV_BUT_RELEASE: | |
2119 { | |
2120 /* Button press event */ | |
2121 PhPointerEvent_t* pevent=NULL; | |
2122 uint32_t sdlbutton=0x00000000; | |
2123 | |
2124 /* Get event data */ | |
2125 pevent=PhGetData(event); | |
2126 if (pevent!=NULL) | |
2127 { | |
2128 for (it=0; it<sizeof(pevent->buttons)*8; it++) | |
2129 { | |
2130 if ((pevent->buttons&(0x0001<<it))==(0x0001<<it)) | |
2131 { | |
2132 switch (it) | |
2133 { | |
2134 case 0: | |
2135 { | |
2136 sdlbutton=SDL_BUTTON_RIGHT; | |
2137 } | |
2138 break; | |
2139 case 1: | |
2140 { | |
2141 sdlbutton=SDL_BUTTON_MIDDLE; | |
2142 } | |
2143 break; | |
2144 case 2: | |
2145 { | |
2146 sdlbutton=SDL_BUTTON_LEFT; | |
2147 } | |
2148 break; | |
2149 default: | |
2150 { | |
2151 sdlbutton=it+1; | |
2152 } | |
2153 break; | |
2154 } | |
2155 } | |
2156 } | |
2157 } | |
2158 | |
2159 switch(event->subtype) | |
2160 { | |
2161 case Ph_EV_RELEASE_REAL: | |
2162 { | |
2163 /* Real release button event */ | |
2164 SDL_SendMouseButton(0, SDL_RELEASED, sdlbutton); | |
2165 } | |
2166 break; | |
2167 case Ph_EV_RELEASE_PHANTOM: | |
2168 { | |
2169 /* We will get phantom button release */ | |
2170 /* event in case if it was unpressed */ | |
2171 /* outside of window */ | |
2172 if (window!=NULL) | |
2173 { | |
2174 if ((window->flags & SDL_WINDOW_MOUSE_FOCUS)!=SDL_WINDOW_MOUSE_FOCUS) | |
2175 { | |
2176 /* Send phantom button release */ | |
2177 SDL_SendMouseButton(0, SDL_RELEASED, sdlbutton); | |
2178 } | |
2179 } | |
2180 } | |
2181 break; | |
2182 } | |
2183 } | |
2184 break; | |
2185 case Ph_EV_EXPOSE: | |
2186 { | |
2187 switch(event->subtype) | |
2188 { | |
2189 case Ph_NORMAL_EXPOSE: | |
2190 { | |
2191 PhRect_t* rects=NULL; | |
2192 | |
2193 /* Get array of rectangles to be updated */ | |
2194 rects=PhGetRects(event); | |
2195 if (rects==NULL) | |
2196 { | |
2197 break; | |
2198 } | |
2199 | |
2200 /* Cycle through each rectangle */ | |
2201 for (it=0; it<event->num_rects; it++) | |
2202 { | |
2203 /* TODO: update the damaged rectangles */ | |
2204 } | |
2205 | |
2206 /* Flush all blittings */ | |
2207 PgFlush(); | |
2208 } | |
2209 break; | |
2210 case Ph_CAPTURE_EXPOSE: | |
2211 { | |
2212 /* We need to redraw entire screen */ | |
2213 PgFFlush(Ph_START_DRAW); | |
2214 | |
2215 /* TODO: redraw the whole screen */ | |
2216 | |
2217 PgFFlush(Ph_DONE_DRAW); | |
2218 } | |
2219 break; | |
2220 case Ph_GRAPHIC_EXPOSE: | |
2221 { | |
2222 /* TODO: What this event means ? */ | |
2223 } | |
2224 break; | |
2225 } | |
2226 } | |
2227 break; | |
2228 case Ph_EV_INFO: | |
2229 { | |
2230 } | |
2231 break; | |
2232 case Ph_EV_KEY: | |
2233 { | |
2234 PhKeyEvent_t* keyevent=NULL; | |
2235 SDL_scancode scancode=SDL_SCANCODE_UNKNOWN; | |
2236 SDL_bool pressed=SDL_FALSE; | |
2237 | |
2238 keyevent=PhGetData(event); | |
2239 if (keyevent==NULL) | |
2240 { | |
2241 break; | |
2242 } | |
2243 | |
2244 /* Check if key is repeated */ | |
2245 if ((keyevent->key_flags & Pk_KF_Key_Repeat)==Pk_KF_Key_Repeat) | |
2246 { | |
2247 /* Ignore such events */ | |
2248 break; | |
2249 } | |
2250 | |
2251 /* Check if key has its own scancode */ | |
2252 if ((keyevent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid) | |
2253 { | |
2254 if ((keyevent->key_flags & Pk_KF_Key_Down)==Pk_KF_Key_Down) | |
2255 { | |
2256 pressed=SDL_TRUE; | |
2257 } | |
2258 else | |
2259 { | |
2260 pressed=SDL_FALSE; | |
2261 } | |
2262 scancode=photon_to_sdl_keymap(keyevent->key_scan); | |
2263 | |
2264 /* Add details for the pressed key */ | |
2265 if ((keyevent->key_flags & Pk_KF_Cap_Valid)==Pk_KF_Cap_Valid) | |
2266 { | |
2267 switch(keyevent->key_cap) | |
2268 { | |
2269 case Pk_Hyper_R: /* Right windows flag key */ | |
2270 scancode=SDL_SCANCODE_RGUI; | |
2271 break; | |
2272 case Pk_Control_R: /* Right Ctrl key */ | |
2273 scancode=SDL_SCANCODE_RCTRL; | |
2274 break; | |
2275 case Pk_Alt_R: /* Right Alt key */ | |
2276 scancode=SDL_SCANCODE_RALT; | |
2277 break; | |
2278 case Pk_Up: /* Up key but with invalid scan */ | |
2279 if (scancode!=SDL_SCANCODE_UP) | |
2280 { | |
2281 /* This is a mouse wheel event */ | |
2282 SDL_SendMouseWheel(0, 0, 1); | |
2283 return; | |
2284 } | |
2285 break; | |
2286 case Pk_KP_8: /* Up arrow or 8 on keypad */ | |
2287 scancode=SDL_SCANCODE_KP_8; | |
2288 break; | |
2289 case Pk_Down: /* Down key but with invalid scan */ | |
2290 if (scancode!=SDL_SCANCODE_DOWN) | |
2291 { | |
2292 /* This is a mouse wheel event */ | |
2293 SDL_SendMouseWheel(0, 0, -1); | |
2294 return; | |
2295 } | |
2296 break; | |
2297 case Pk_KP_2: /* Down arrow or 2 on keypad */ | |
2298 scancode=SDL_SCANCODE_KP_2; | |
2299 break; | |
2300 case Pk_Left: /* Left arrow key */ | |
2301 scancode=SDL_SCANCODE_LEFT; | |
2302 break; | |
2303 case Pk_KP_4: /* Left arrow or 4 on keypad */ | |
2304 scancode=SDL_SCANCODE_KP_4; | |
2305 break; | |
2306 case Pk_Right: /* Right arrow key */ | |
2307 scancode=SDL_SCANCODE_RIGHT; | |
2308 break; | |
2309 case Pk_KP_6: /* Right arrow or 6 on keypad */ | |
2310 scancode=SDL_SCANCODE_KP_6; | |
2311 break; | |
2312 case Pk_Insert: /* Insert key */ | |
2313 scancode=SDL_SCANCODE_INSERT; | |
2314 break; | |
2315 case Pk_KP_0: /* Insert or 0 on keypad */ | |
2316 scancode=SDL_SCANCODE_KP_0; | |
2317 break; | |
2318 case Pk_Home: /* Home key */ | |
2319 scancode=SDL_SCANCODE_HOME; | |
2320 break; | |
2321 case Pk_KP_7: /* Home or 7 on keypad */ | |
2322 scancode=SDL_SCANCODE_KP_7; | |
2323 break; | |
2324 case Pk_Pg_Up: /* PageUp key */ | |
2325 scancode=SDL_SCANCODE_PAGEUP; | |
2326 break; | |
2327 case Pk_KP_9: /* PgUp or 9 on keypad */ | |
2328 scancode=SDL_SCANCODE_KP_9; | |
2329 break; | |
2330 case Pk_Delete: /* Delete key */ | |
2331 scancode=SDL_SCANCODE_DELETE; | |
2332 break; | |
2333 case Pk_KP_Decimal: /* Del or . on keypad */ | |
2334 scancode=SDL_SCANCODE_KP_PERIOD; | |
2335 break; | |
2336 case Pk_End: /* End key */ | |
2337 scancode=SDL_SCANCODE_END; | |
2338 break; | |
2339 case Pk_KP_1: /* End or 1 on keypad */ | |
2340 scancode=SDL_SCANCODE_KP_1; | |
2341 break; | |
2342 case Pk_Pg_Down: /* PageDown key */ | |
2343 scancode=SDL_SCANCODE_PAGEDOWN; | |
2344 break; | |
2345 case Pk_KP_3: /* PgDn or 3 on keypad */ | |
2346 scancode=SDL_SCANCODE_KP_3; | |
2347 break; | |
2348 case Pk_KP_5: /* 5 on keypad */ | |
2349 scancode=SDL_SCANCODE_KP_5; | |
2350 break; | |
2351 case Pk_KP_Enter: | |
2352 scancode=SDL_SCANCODE_KP_ENTER; | |
2353 break; | |
2354 case Pk_KP_Add: | |
2355 scancode=SDL_SCANCODE_KP_PLUS; | |
2356 break; | |
2357 case Pk_KP_Subtract: | |
2358 scancode=SDL_SCANCODE_KP_MINUS; | |
2359 break; | |
2360 case Pk_KP_Multiply: | |
2361 scancode=SDL_SCANCODE_KP_MULTIPLY; | |
2362 break; | |
2363 case Pk_KP_Divide: | |
2364 scancode=SDL_SCANCODE_KP_DIVIDE; | |
2365 break; | |
2366 case Pk_Pause: | |
2367 scancode=SDL_SCANCODE_PAUSE; | |
2368 break; | |
2369 } | |
2370 } | |
2371 | |
2372 /* Finally check if scancode has been decoded */ | |
2373 if (scancode==SDL_SCANCODE_UNKNOWN) | |
2374 { | |
2375 /* Something was pressed, which is not supported */ | |
2376 break; | |
2377 } | |
2378 | |
2379 /* Report pressed/released key to SDL */ | |
2380 if (pressed==SDL_TRUE) | |
2381 { | |
2382 SDL_SendKeyboardKey(0, SDL_PRESSED, scancode); | |
2383 } | |
2384 else | |
2385 { | |
2386 SDL_SendKeyboardKey(0, SDL_RELEASED, scancode); | |
2387 } | |
2388 | |
2389 /* Photon doesn't send a release event for PrnScr key */ | |
2390 if ((scancode==SDL_SCANCODE_PRINTSCREEN) && (pressed)) | |
2391 { | |
2392 SDL_SendKeyboardKey(0, SDL_RELEASED, scancode); | |
2393 } | |
2394 } | |
2395 } | |
2396 break; | |
2397 case Ph_EV_SERVICE: | |
2398 { | |
2399 } | |
2400 break; | |
2401 case Ph_EV_SYSTEM: | |
2402 { | |
2403 } | |
2404 break; | |
2405 case Ph_EV_WM: | |
2406 { | |
2407 PhWindowEvent_t* wmevent=NULL; | |
2408 | |
2409 /* Get associated event data */ | |
2410 wmevent=PhGetData(event); | |
2411 if (wmevent==NULL) | |
2412 { | |
2413 break; | |
2414 } | |
2415 | |
2416 switch(wmevent->event_f) | |
2417 { | |
2418 case Ph_WM_CLOSE: | |
2419 { | |
2420 if (window!=NULL) | |
2421 { | |
2422 SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_CLOSE, 0, 0); | |
2423 } | |
2424 } | |
2425 break; | |
2426 case Ph_WM_FOCUS: | |
2427 { | |
2428 if (wmevent->event_state==Ph_WM_EVSTATE_FOCUS) | |
2429 { | |
2430 if (window!=NULL) | |
2431 { | |
2432 PhRegion_t wregion; | |
2433 | |
2434 SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0); | |
2435 SDL_SetKeyboardFocus(0, window->id); | |
2436 | |
2437 /* Set window region sensible to mouse motion events */ | |
2438 PhRegionQuery(PtWidgetRid(wdata->window), &wregion, NULL, NULL, 0); | |
2439 wregion.events_sense|=Ph_EV_PTR_MOTION_BUTTON | Ph_EV_PTR_MOTION_NOBUTTON; | |
2440 PhRegionChange(Ph_REGION_EV_SENSE, 0, &wregion, NULL, NULL); | |
2441 } | |
2442 } | |
2443 if (wmevent->event_state==Ph_WM_EVSTATE_FOCUSLOST) | |
2444 { | |
2445 if (window!=NULL) | |
2446 { | |
2447 PhRegion_t wregion; | |
2448 | |
2449 SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0); | |
2450 | |
2451 /* Set window region ignore mouse motion events */ | |
2452 PhRegionQuery(PtWidgetRid(wdata->window), &wregion, NULL, NULL, 0); | |
2453 wregion.events_sense&=~(Ph_EV_PTR_MOTION_BUTTON | Ph_EV_PTR_MOTION_NOBUTTON); | |
2454 PhRegionChange(Ph_REGION_EV_SENSE, 0, &wregion, NULL, NULL); | |
2455 } | |
2456 } | |
2457 } | |
2458 break; | |
2459 case Ph_WM_MOVE: | |
2460 { | |
2461 if (window!=NULL) | |
2462 { | |
2463 SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_MOVED, wmevent->pos.x, wmevent->pos.y); | |
2464 } | |
2465 } | |
2466 break; | |
2467 case Ph_WM_RESIZE: | |
2468 { | |
2469 if (window!=NULL) | |
2470 { | |
2471 } | |
2472 } | |
2473 break; | |
2474 case Ph_WM_HIDE: | |
2475 { | |
2476 if (window!=NULL) | |
2477 { | |
2478 } | |
2479 } | |
2480 break; | |
2481 case Ph_WM_MAX: | |
2482 { | |
2483 if (window!=NULL) | |
2484 { | |
2485 } | |
2486 } | |
2487 break; | |
2488 case Ph_WM_RESTORE: | |
2489 { | |
2490 if (window!=NULL) | |
2491 { | |
2492 } | |
2493 } | |
2494 break; | |
2495 } | |
2496 } | |
2497 break; | |
2498 } | |
2499 PtEventHandler(event); | |
2500 } | |
2501 break; | |
2502 case 0: | |
2503 { | |
2504 /* All events are read */ | |
2505 finish=1; | |
2506 break; | |
2507 } | |
2508 case -1: | |
2509 { | |
2510 /* Error occured in event reading */ | |
2511 SDL_SetError("Photon: Can't read event"); | |
2512 return; | |
2513 } | |
2514 break; | |
2515 } | |
2516 if (finish!=0) | |
2517 { | |
2518 break; | |
2519 } | |
2520 } while(1); | |
355 } | 2521 } |
356 | 2522 |
357 /*****************************************************************************/ | 2523 /*****************************************************************************/ |
358 /* SDL screen saver related functions */ | 2524 /* SDL screen saver related functions */ |
359 /*****************************************************************************/ | 2525 /*****************************************************************************/ |