--- a/src/video/photon/SDL_photon.c Fri Apr 24 03:46:54 2009 +0000
+++ b/src/video/photon/SDL_photon.c Tue Apr 28 04:30:52 2009 +0000
@@ -24,15 +24,104 @@
(mike@malva.ua, lestat@i.com.ua)
*/
+/* SDL internals */
#include "SDL_config.h"
-
#include "../SDL_sysvideo.h"
#include "SDL_version.h"
#include "SDL_syswm.h"
+#include "SDL_loadso.h"
+#include "SDL_events.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_keyboard_c.h"
-#include "../SDL_sysvideo.h"
+/* Photon declarations */
+#include "SDL_photon.h"
+
+/* Pixel format conversion routines */
+#include "SDL_photon_pixelfmt.h"
+
+/* Use GF's pixel format functions for OpenGL ES context creation */
+#if defined(SDL_VIDEO_OPENGL_ES)
+ #include "../qnxgf/SDL_gf_pixelfmt.h"
+
+ /* If GF driver is not compiled in, include some of usefull functions */
+ #if !defined(SDL_VIDEO_DRIVER_QNXGF)
+ #include "../qnxgf/SDL_gf_pixelfmt.c"
+ #endif /* SDL_VIDEO_DRIVER_QNXGF */
+#endif /* SDL_VIDEO_OPENGL_ES */
+
+/* Use GF's OpenGL ES 1.1 functions emulation */
+#if defined(SDL_VIDEO_OPENGL_ES)
+ #include "../qnxgf/SDL_gf_opengles.h"
+
+ /* If GF driver is not compiled in, include some of usefull functions */
+ #if !defined(SDL_VIDEO_DRIVER_QNXGF)
+ #include "../qnxgf/SDL_gf_opengles.c"
+ #endif /* SDL_VIDEO_DRIVER_QNXGF */
+#endif /* SDL_VIDEO_OPENGL_ES */
-#include "SDL_photon.h"
+/* Low level device graphics driver names, which they are reporting */
+Photon_DeviceCaps photon_devicename[]=
+{
+ /* ATI Rage 128 graphics driver (devg-ati_rage128) */
+ {"ati_rage128", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* Fujitsu Carmine graphics driver (devg-carmine.so) */
+ {"carmine", SDL_PHOTON_ACCELERATED | SDL_PHOTON_ACCELERATED_3D},
+ /* C&T graphics driver (devg-chips.so) */
+ {"chips", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* Fujitsu Coral graphics driver (devg-coral.so) */
+ {"coral", SDL_PHOTON_ACCELERATED | SDL_PHOTON_ACCELERATED_3D},
+ /* Intel integrated graphics driver (devg-extreme2.so) */
+ {"extreme2", SDL_PHOTON_ACCELERATED | SDL_PHOTON_ACCELERATED_3D},
+ /* Unaccelerated FB driver (devg-flat.so) */
+ {"flat", SDL_PHOTON_UNACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* NS Geode graphics driver (devg-geode.so) */
+ {"geode", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* Geode LX graphics driver (devg-geodelx.so) */
+ {"geodelx", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* Intel integrated graphics driver (devg-gma9xx.so) */
+ {"gma", SDL_PHOTON_ACCELERATED | SDL_PHOTON_ACCELERATED_3D},
+ /* Intel integrated graphics driver (devg-i810.so) */
+ {"i810", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* Intel integrated graphics driver (devg-i830.so) */
+ {"i830", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* Geode LX graphics driver (devg-lx800.so) */
+ {"lx800", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* Matrox Gxx graphics driver (devg-matroxg.so) */
+ {"matroxg", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* Intel Poulsbo graphics driver (devg-poulsbo.so) */
+ {"poulsbo", SDL_PHOTON_ACCELERATED | SDL_PHOTON_ACCELERATED_3D},
+ /* ATI Radeon driver (devg-radeon.so) */
+ {"radeon", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* ATI Rage driver (devg-rage.so) */
+ {"rage", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* S3 Savage graphics driver (devg-s3_savage.so) */
+ {"s3_savage", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* SiS630 integrated graphics driver (devg-sis630.so) */
+ {"sis630", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* PowerVR SGX 535 graphics driver (devg-poulsbo.so) */
+ {"sgx", SDL_PHOTON_ACCELERATED | SDL_PHOTON_ACCELERATED_3D},
+ /* SM Voyager GX graphics driver (devg-smi5xx.so) */
+ {"smi5xx", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* Silicon Motion graphics driver (devg-smi7xx.so) */
+ {"smi7xx", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* SVGA unaccelerated gfx driver (devg-svga.so) */
+ {"svga", SDL_PHOTON_UNACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* nVidia TNT graphics driver (devg-tnt.so) */
+ {"tnt", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* VIA integrated graphics driver (devg-tvia.so) */
+ {"tvia", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* VIA UniChrome graphics driver (devg-unichrome.so) */
+ {"unichrome", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* VESA unaccelerated gfx driver (devg-vesa.so) */
+ {"vesa", SDL_PHOTON_UNACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* VmWare graphics driver (devg-volari.so) */
+ {"vmware", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* XGI XP10 graphics driver (devg-volari.so), OpenGL 1.5*/
+ {"volari", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D},
+ /* End of list */
+ {NULL, 0x00000000}
+};
static SDL_bool photon_initialized=SDL_FALSE;
@@ -62,13 +151,26 @@
static void photon_destroy(SDL_VideoDevice* device)
{
+ SDL_VideoData* phdata=(SDL_VideoData*) device->driverdata;
+
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ if (phdata->gfinitialized!=SDL_FALSE)
+ {
+ gf_dev_detach(phdata->gfdev);
+ }
+ #endif /* SDL_VIDEO_OPENGL_ES */
+
+ if (device->driverdata!=NULL)
+ {
+ device->driverdata=NULL;
+ }
}
static SDL_VideoDevice* photon_create(int devindex)
{
- SDL_VideoDevice* device;
- SDL_VideoData* phdata;
- int status;
+ SDL_VideoDevice* device;
+ SDL_VideoData* phdata;
+ int status;
/* Check if photon could be initialized */
status=photon_available();
@@ -78,6 +180,13 @@
return NULL;
}
+ /* Photon agregates all video devices to one with multiple heads */
+ if (devindex!=0)
+ {
+ /* devindex could be zero only in Photon SDL driver */
+ return NULL;
+ }
+
/* Initialize SDL_VideoDevice structure */
device=(SDL_VideoDevice*)SDL_calloc(1, sizeof(SDL_VideoDevice));
if (device==NULL)
@@ -96,9 +205,85 @@
}
device->driverdata=phdata;
+ /* Get all photon display devices */
+ phdata->avail_rids=PdGetDevices(&phdata->rid[0], SDL_VIDEO_PHOTON_MAX_RIDS);
+ if (phdata->avail_rids>SDL_VIDEO_PHOTON_MAX_RIDS)
+ {
+ phdata->avail_rids=SDL_VIDEO_PHOTON_MAX_RIDS;
+ }
+
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ /* TODO: add real device detection versus multiple heads */
+ status=gf_dev_attach(&phdata->gfdev, GF_DEVICE_INDEX(0), &phdata->gfdev_info);
+ if (status!=GF_ERR_OK)
+ {
+ /* Do not fail right now, if GF can't be attached */
+ phdata->gfinitialized=SDL_FALSE;
+ }
+ else
+ {
+ phdata->gfinitialized=SDL_TRUE;
+ }
+ #endif /* SDL_VIDEO_OPENGL_ES */
+
+ /* Set default target device */
+ status=PdSetTargetDevice(NULL, phdata->rid[0]);
+ if (status==-1)
+ {
+ SDL_SetError("Photon: Can't set default target device");
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ gf_dev_detach(phdata->gfdev);
+ #endif /* SDL_VIDEO_OPENGL_ES */
+ SDL_free(phdata);
+ SDL_free(device);
+ return NULL;
+ }
+ phdata->current_device_id=0;
+
/* Setup amount of available displays and current display */
device->num_displays=0;
device->current_display=0;
+
+ /* Set device free function */
+ device->free=photon_destroy;
+
+ /* Setup all functions which we can handle */
+ device->VideoInit=photon_videoinit;
+ device->VideoQuit=photon_videoquit;
+ device->GetDisplayModes=photon_getdisplaymodes;
+ device->SetDisplayMode=photon_setdisplaymode;
+ device->SetDisplayPalette=photon_setdisplaypalette;
+ device->GetDisplayPalette=photon_getdisplaypalette;
+ device->SetDisplayGammaRamp=photon_setdisplaygammaramp;
+ device->GetDisplayGammaRamp=photon_getdisplaygammaramp;
+ device->CreateWindow=photon_createwindow;
+ device->CreateWindowFrom=photon_createwindowfrom;
+ device->SetWindowTitle=photon_setwindowtitle;
+ device->SetWindowIcon=photon_setwindowicon;
+ device->SetWindowPosition=photon_setwindowposition;
+ device->SetWindowSize=photon_setwindowsize;
+ device->ShowWindow=photon_showwindow;
+ device->HideWindow=photon_hidewindow;
+ device->RaiseWindow=photon_raisewindow;
+ device->MaximizeWindow=photon_maximizewindow;
+ device->MinimizeWindow=photon_minimizewindow;
+ device->RestoreWindow=photon_restorewindow;
+ device->SetWindowGrab=photon_setwindowgrab;
+ device->DestroyWindow=photon_destroywindow;
+ device->GetWindowWMInfo=photon_getwindowwminfo;
+ device->GL_LoadLibrary=photon_gl_loadlibrary;
+ device->GL_GetProcAddress=photon_gl_getprocaddres;
+ device->GL_UnloadLibrary=photon_gl_unloadlibrary;
+ device->GL_CreateContext=photon_gl_createcontext;
+ device->GL_MakeCurrent=photon_gl_makecurrent;
+ device->GL_SetSwapInterval=photon_gl_setswapinterval;
+ device->GL_GetSwapInterval=photon_gl_getswapinterval;
+ device->GL_SwapWindow=photon_gl_swapwindow;
+ device->GL_DeleteContext=photon_gl_deletecontext;
+ device->PumpEvents=photon_pumpevents;
+ device->SuspendScreenSaver=photon_suspendscreensaver;
+
+ return device;
}
VideoBootStrap photon_bootstrap=
@@ -114,18 +299,147 @@
/*****************************************************************************/
int photon_videoinit(_THIS)
{
- SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
+ SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
+ PgHWCaps_t hwcaps;
+ PgVideoModeInfo_t modeinfo;
+ int32_t status;
+ SDL_VideoDisplay display;
+ SDL_DisplayMode current_mode;
+ SDL_DisplayData* didata;
+ uint32_t it;
+ uint32_t jt;
+ char* override;
+
+ /* By default Photon do not uses swap on VSYNC */
+ phdata->swapinterval=0;
+
+ for (it=0; it<phdata->avail_rids; it++)
+ {
+ didata=(SDL_DisplayData*)SDL_calloc(1, sizeof(SDL_DisplayData));
+ if (didata==NULL)
+ {
+ /* memory allocation error */
+ SDL_OutOfMemory();
+ return -1;
+ }
+
+ /* Allocate two cursors with SDL_VIDEO_PHOTON_MAX_CURSOR_SIZE size */
+ /* and 128 bytes of spare place */
+ didata->cursor_size=((SDL_VIDEO_PHOTON_MAX_CURSOR_SIZE*4)>>3)+128;
+ didata->cursor=(PhCursorDef_t*)SDL_calloc(1, didata->cursor_size);
+ if (didata->cursor==NULL)
+ {
+ /* memory allocation error */
+ SDL_OutOfMemory();
+ SDL_free(didata);
+ return -1;
+ }
+
+ /* Initialize GF in case of OpenGL ES support is compiled in */
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ /* TODO: add real device detection versus multiple heads */
+ if (phdata->gfinitialized==SDL_TRUE)
+ {
+ status=gf_display_attach(&didata->display, phdata->gfdev, it, &didata->display_info);
+ if (status!=GF_ERR_OK)
+ {
+ /* Just shutdown GF, do not fail */
+ gf_dev_detach(phdata->gfdev);
+ phdata->gfinitialized=SDL_FALSE;
+ }
+ }
+ #endif /* SDL_VIDEO_OPENGL_ES */
+
+ /* Check if current device is not the same as target */
+ if (phdata->current_device_id!=it)
+ {
+ /* Set target device as default for Pd and Pg functions */
+ status=PdSetTargetDevice(NULL, phdata->rid[it]);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't set default target device\n");
+ SDL_free(didata->cursor);
+ SDL_free(didata);
+ return -1;
+ }
+ phdata->current_device_id=it;
+ }
+
+ /* Store device id */
+ didata->device_id=it;
- /* Check for environment variables which could override some SDL settings */
-// didata->custom_refresh=0;
-// override = SDL_getenv("SDL_VIDEO_PHOTON_REFRESH_RATE");
-// if (override!=NULL)
-// {
-// if (SDL_sscanf(override, "%u", &didata->custom_refresh)!=1)
-// {
-// didata->custom_refresh=0;
-// }
-// }
+ /* Query photon about graphics hardware caps and current video mode */
+ status=PgGetGraphicsHWCaps(&hwcaps);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't get graphics capabilities");
+ SDL_free(didata->cursor);
+ SDL_free(didata);
+ return -1;
+ }
+
+ /* Get current video mode details */
+ status=PgGetVideoModeInfo(hwcaps.current_video_mode, &modeinfo);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't get current video mode information");
+ SDL_free(didata->cursor);
+ SDL_free(didata);
+ return -1;
+ }
+
+ /* Setup current desktop mode for SDL */
+ SDL_zero(current_mode);
+ current_mode.w=modeinfo.width;
+ current_mode.h=modeinfo.height;
+ current_mode.refresh_rate=hwcaps.current_rrate;
+ current_mode.format=photon_image_to_sdl_pixelformat(modeinfo.type);
+ current_mode.driverdata=NULL;
+
+ /* Copy device name */
+ SDL_strlcpy(didata->description, hwcaps.chip_name, SDL_VIDEO_PHOTON_DEVICENAME_MAX-1);
+
+ /* Search device capabilities and possible workarounds */
+ jt=0;
+ do {
+ if (photon_devicename[jt].name==NULL)
+ {
+ break;
+ }
+ if (SDL_strncmp(photon_devicename[jt].name, didata->description, SDL_strlen(photon_devicename[jt].name))==0)
+ {
+ didata->caps=photon_devicename[jt].caps;
+ }
+ jt++;
+ } while(1);
+
+ /* Initialize display structure */
+ SDL_zero(display);
+ display.desktop_mode=current_mode;
+ display.current_mode=current_mode;
+ display.driverdata=didata;
+ didata->current_mode=current_mode;
+ SDL_AddVideoDisplay(&display);
+
+ /* Check for environment variables which could override some SDL settings */
+ didata->custom_refresh=0;
+ override=SDL_getenv("SDL_VIDEO_PHOTON_REFRESH_RATE");
+ if (override!=NULL)
+ {
+ if (SDL_sscanf(override, "%u", &didata->custom_refresh)!=1)
+ {
+ didata->custom_refresh=0;
+ }
+ }
+ }
+
+ /* Add photon input devices */
+ status=photon_addinputdevices(_this);
+ if (status!=0)
+ {
+ /* SDL error is set by photon_addinputdevices() function */
+ return -1;
+ }
/* Add photon renderer to SDL */
photon_addrenderdriver(_this);
@@ -136,6 +450,7 @@
void photon_videoquit(_THIS)
{
+ SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
SDL_DisplayData* didata;
uint32_t it;
@@ -143,19 +458,270 @@
for(it=0; it<_this->num_displays; it++)
{
didata=_this->displays[it].driverdata;
+
+ if (didata->cursor!=NULL)
+ {
+ SDL_free(didata->cursor);
+ }
+
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ if (phdata->gfinitialized==SDL_TRUE)
+ {
+ /* Detach GF display */
+ gf_display_detach(didata->display);
+ }
+ #endif /* SDL_VIDEO_OPENGL_ES */
}
}
void photon_getdisplaymodes(_THIS)
{
- SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata;
- SDL_DisplayMode mode;
+ SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
+ SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata;
+ SDL_DisplayMode mode;
+ PgVideoModes_t modes;
+ PgVideoModeInfo_t modeinfo;
+ int32_t status;
+ uint32_t it;
+ uint32_t jt;
+
+ /* Check if current device is not the same as target */
+ if (phdata->current_device_id!=didata->device_id)
+ {
+ /* Set target device as default for Pd and Pg functions */
+ status=PdSetTargetDevice(NULL, phdata->rid[didata->device_id]);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't set default target device\n");
+ return;
+ }
+ phdata->current_device_id=didata->device_id;
+ }
+ /* Get array of available video modes */
+ status=PgGetVideoModeList(&modes);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't get video mode list");
+ return;
+ }
+
+ for (it=0; it<modes.num_modes; it++)
+ {
+ status=PgGetVideoModeInfo(modes.modes[it], &modeinfo);
+ if (status!=0)
+ {
+ /* Maybe something wrong with this particular mode, skip it */
+ continue;
+ }
+
+ jt=0;
+ do {
+ if (modeinfo.refresh_rates[jt]!=0)
+ {
+ mode.w=modeinfo.width;
+ mode.h=modeinfo.height;
+ mode.refresh_rate=modeinfo.refresh_rates[jt];
+ mode.format=photon_image_to_sdl_pixelformat(modeinfo.type);
+ mode.driverdata=NULL;
+ SDL_AddDisplayMode(_this->current_display, &mode);
+ jt++;
+ }
+ else
+ {
+ break;
+ }
+ } while(1);
+ }
}
int photon_setdisplaymode(_THIS, SDL_DisplayMode* mode)
{
- SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata;
+ SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
+ SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata;
+ PgVideoModes_t modes;
+ PgVideoModeInfo_t modeinfo;
+ PgDisplaySettings_t modesettings;
+ uint32_t refresh_rate=0;
+ int32_t status;
+ uint32_t it;
+
+ /* Check if current device is not the same as target */
+ if (phdata->current_device_id!=didata->device_id)
+ {
+ /* Set target device as default for Pd and Pg functions */
+ status=PdSetTargetDevice(NULL, phdata->rid[didata->device_id]);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't set default target device\n");
+ return;
+ }
+ phdata->current_device_id=didata->device_id;
+ }
+
+ /* Get array of available video modes */
+ status=PgGetVideoModeList(&modes);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't get video mode list");
+ return;
+ }
+
+ /* Current display dimensions and bpp are no more valid */
+ didata->current_mode.format=SDL_PIXELFORMAT_UNKNOWN;
+ didata->current_mode.w=0;
+ didata->current_mode.h=0;
+
+ /* Check if custom refresh rate requested */
+ if (didata->custom_refresh!=0)
+ {
+ refresh_rate=didata->custom_refresh;
+ }
+ else
+ {
+ refresh_rate=mode->refresh_rate;
+ }
+
+ /* Check if SDL GF driver needs to find appropriate refresh rate itself */
+ if (refresh_rate==0)
+ {
+ SDL_DisplayMode tempmode;
+
+ /* Clear display mode structure */
+ SDL_memset(&tempmode, 0x00, sizeof(SDL_DisplayMode));
+ tempmode.refresh_rate=0x0000FFFF;
+
+ /* Check if window width and height matches one of our modes */
+ for (it=0; it<SDL_CurrentDisplay.num_display_modes; it++)
+ {
+ if ((SDL_CurrentDisplay.display_modes[it].w==mode->w) &&
+ (SDL_CurrentDisplay.display_modes[it].h==mode->h) &&
+ (SDL_CurrentDisplay.display_modes[it].format==mode->format))
+ {
+ /* Find the lowest refresh rate available */
+ if (tempmode.refresh_rate>SDL_CurrentDisplay.display_modes[it].refresh_rate)
+ {
+ tempmode=SDL_CurrentDisplay.display_modes[it];
+ }
+ }
+ }
+ if (tempmode.refresh_rate!=0x0000FFFF)
+ {
+ refresh_rate=tempmode.refresh_rate;
+ }
+ else
+ {
+ /* Let video driver decide what to do with this */
+ refresh_rate=0;
+ }
+ }
+
+ /* Check if SDL GF driver needs to check custom refresh rate */
+ if (didata->custom_refresh!=0)
+ {
+ SDL_DisplayMode tempmode;
+
+ /* Clear display mode structure */
+ SDL_memset(&tempmode, 0x00, sizeof(SDL_DisplayMode));
+ tempmode.refresh_rate=0x0000FFFF;
+
+ /* Check if window width and height matches one of our modes */
+ for (it=0; it<SDL_CurrentDisplay.num_display_modes; it++)
+ {
+ if ((SDL_CurrentDisplay.display_modes[it].w==mode->w) &&
+ (SDL_CurrentDisplay.display_modes[it].h==mode->h) &&
+ (SDL_CurrentDisplay.display_modes[it].format==mode->format))
+ {
+ /* Find the lowest refresh rate available */
+ if (tempmode.refresh_rate>SDL_CurrentDisplay.display_modes[it].refresh_rate)
+ {
+ tempmode=SDL_CurrentDisplay.display_modes[it];
+ }
+
+ /* Check if requested refresh rate found */
+ if (refresh_rate==SDL_CurrentDisplay.display_modes[it].refresh_rate)
+ {
+ tempmode=SDL_CurrentDisplay.display_modes[it];
+ break;
+ }
+ }
+ }
+ if (tempmode.refresh_rate!=0x0000FFFF)
+ {
+ refresh_rate=tempmode.refresh_rate;
+ }
+ else
+ {
+ /* Let video driver decide what to do with this */
+ refresh_rate=0;
+ }
+ }
+
+ /* Find photon's video mode number */
+ for (it=0; it<modes.num_modes; it++)
+ {
+ uint32_t jt;
+ uint32_t foundrefresh;
+
+ /* Get current video mode details */
+ status=PgGetVideoModeInfo(modes.modes[it], &modeinfo);
+ if (status!=0)
+ {
+ /* Maybe something wrong with this particular mode, skip it */
+ continue;
+ }
+ if ((modeinfo.width==mode->w) && (modeinfo.height==mode->h) &&
+ (modeinfo.type==photon_sdl_to_image_pixelformat(mode->format)))
+ {
+ /* Mode is found, find requested refresh rate, this case is for */
+ /* video drivers, which provide non-generic video modes. */
+ jt=0;
+ foundrefresh=0;
+ do {
+ if (modeinfo.refresh_rates[jt]!=0)
+ {
+ if (modeinfo.refresh_rates[jt]==refresh_rate)
+ {
+ foundrefresh=1;
+ break;
+ }
+ jt++;
+ }
+ else
+ {
+ break;
+ }
+ } while(1);
+ if (foundrefresh!=0)
+ {
+ break;
+ }
+ }
+ }
+
+ /* Check if video mode has not been found */
+ if (it==modes.num_modes)
+ {
+ SDL_SetError("Photon: Can't find appropriate video mode");
+ return -1;
+ }
+
+ /* Fill mode settings */
+ modesettings.flags=0x00000000;
+ modesettings.mode=modes.modes[it];
+ modesettings.refresh=refresh_rate;
+
+ /* Finally set new video mode */
+ status=PgSetVideoMode(&modesettings);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't set new video mode");
+ return -1;
+ }
+
+ /* Store new video mode parameters */
+ didata->current_mode=*mode;
+ didata->current_mode.refresh_rate=refresh_rate;
return 0;
}
@@ -192,8 +758,15 @@
int photon_createwindow(_THIS, SDL_Window* window)
{
+ SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata;
SDL_WindowData* wdata;
+ PhDim_t winsize;
+ PhPoint_t winpos;
+ PtArg_t winargs[32];
+ uint32_t winargc=0;
+ int32_t status;
+ PhRegion_t wregion;
/* Allocate window internal data */
wdata=(SDL_WindowData*)SDL_calloc(1, sizeof(SDL_WindowData));
@@ -206,75 +779,490 @@
/* Setup driver data for this window */
window->driverdata=wdata;
+ /* Set initial window title */
+ if (window->title!=NULL)
+ {
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_TITLE, window->title, 0);
+ }
+ else
+ {
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_TITLE, "", 0);
+ }
+
+ /* TODO: handle SDL_WINDOW_INPUT_GRABBED */
+
+ /* Disable default window filling on redraw */
+ PtSetArg(&winargs[winargc++], Pt_ARG_BASIC_FLAGS, Pt_TRUE, Pt_BASIC_PREVENT_FILL);
+
+ /* Set default maximum and minimum window sizes */
+ winsize.w=0;
+ winsize.h=0;
+ PtSetArg(&winargs[winargc++], Pt_ARG_MAX_HEIGHT, 0, 0);
+ PtSetArg(&winargs[winargc++], Pt_ARG_MAX_WIDTH, 0, 0);
+ PtSetArg(&winargs[winargc++], Pt_ARG_MIN_HEIGHT, 0, 0);
+ PtSetArg(&winargs[winargc++], Pt_ARG_MIN_WIDTH, 0, 0);
+ PtSetArg(&winargs[winargc++], Pt_ARG_MAXIMUM_DIM, &winsize, 0);
+ PtSetArg(&winargs[winargc++], Pt_ARG_MINIMUM_DIM, &winsize, 0);
+
+ /* Reset default managed events to disable */
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE,
+ Ph_WM_APP_DEF_MANAGED);
+ /* Set which events we will not handle, let WM to handle them */
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE,
+ Ph_WM_BACKDROP | Ph_WM_TOFRONT | Ph_WM_COLLAPSE | Ph_WM_FFRONT |
+ Ph_WM_FOCUS | Ph_WM_HELP | Ph_WM_HIDE | Ph_WM_MAX |
+ Ph_WM_MENU | Ph_WM_MOVE | Ph_WM_RESIZE | Ph_WM_RESTORE |
+ Ph_WM_TASKBAR | Ph_WM_TOBACK);
+
+ /* Reset default notify events to disable */
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_FALSE,
+ Ph_WM_RESIZE | Ph_WM_CLOSE | Ph_WM_HELP);
+ /* Set which events we will handle */
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE,
+ Ph_WM_CLOSE | Ph_WM_COLLAPSE | Ph_WM_FOCUS | Ph_WM_MAX |
+ Ph_WM_MOVE | Ph_WM_RESIZE | Ph_WM_RESTORE | Ph_WM_HIDE);
+
+ /* Borderless window can't be resizeable */
+ if ((window->flags & SDL_WINDOW_BORDERLESS)==SDL_WINDOW_BORDERLESS)
+ {
+ window->flags&=~(SDL_WINDOW_RESIZABLE);
+ }
+
+ /* Reset all default decorations */
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Ph_WM_APP_DEF_RENDER);
+
+ /* Fullscreen window has its own decorations */
+ if ((window->flags & SDL_WINDOW_FULLSCREEN)==SDL_WINDOW_FULLSCREEN)
+ {
+ window->flags|=SDL_WINDOW_BORDERLESS;
+ window->flags&=~(SDL_WINDOW_RESIZABLE);
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE,
+ Ph_WM_RENDER_CLOSE | Ph_WM_RENDER_TITLE);
+ }
+ else
+ {
+ uint32_t decorations=Ph_WM_RENDER_CLOSE | Ph_WM_RENDER_MENU | Ph_WM_RENDER_MIN |
+ Ph_WM_RENDER_TITLE | Ph_WM_RENDER_MOVE;
+
+ if ((window->flags & SDL_WINDOW_RESIZABLE)==SDL_WINDOW_RESIZABLE)
+ {
+ decorations|=Ph_WM_RENDER_BORDER | Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX;
+ }
+ if ((window->flags & SDL_WINDOW_BORDERLESS)!=SDL_WINDOW_BORDERLESS)
+ {
+ decorations|=Ph_WM_RENDER_BORDER;
+ }
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, decorations);
+ }
+
+ /* Set initial window state */
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISFOCUS);
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISALTKEY);
+
+ /* Set window dimensions */
+ winsize.w=window->w;
+ winsize.h=window->h;
+ PtSetArg(&winargs[winargc++], Pt_ARG_DIM, &winsize, 0);
+
+ /* Check if upper level requests WM to position window */
+ if ((window->x==SDL_WINDOWPOS_UNDEFINED) && (window->y==SDL_WINDOWPOS_UNDEFINED))
+ {
+ /* Do not set widget position, let WM to set it */
+ }
+ else
+ {
+ if (window->x==SDL_WINDOWPOS_UNDEFINED)
+ {
+ window->x=0;
+ }
+ if (window->y==SDL_WINDOWPOS_UNDEFINED)
+ {
+ window->y=0;
+ }
+ if (window->x==SDL_WINDOWPOS_CENTERED)
+ {
+ window->x=(didata->current_mode.w-window->w)/2;
+ }
+ if (window->y==SDL_WINDOWPOS_CENTERED)
+ {
+ window->y=(didata->current_mode.h-window->h)/2;
+ }
+
+ /* Now set window position */
+ winpos.x=window->x;
+ winpos.y=window->y;
+ PtSetArg(&winargs[winargc++], Pt_ARG_POS, &winpos, 0);
+ }
+
+ /* Add SDL window id as user data */
+ PtSetArg(&winargs[winargc++], Pt_ARG_POINTER, (void*)window->id, 0);
+
/* Check if window must support OpenGL ES rendering */
if ((window->flags & SDL_WINDOW_OPENGL)==SDL_WINDOW_OPENGL)
{
- /* Mark this window as OpenGL ES compatible */
- wdata->uses_gles=SDL_TRUE;
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ EGLBoolean initstatus;
+
+ /* Check if GF was initialized correctly */
+ if (phdata->gfinitialized==SDL_FALSE)
+ {
+ SDL_SetError("Photon: GF initialization failed, no OpenGL ES support");
+ return -1;
+ }
+
+ /* Mark this window as OpenGL ES compatible */
+ wdata->uses_gles=SDL_TRUE;
+
+ /* Create connection to OpenGL ES */
+ if (phdata->egldisplay==EGL_NO_DISPLAY)
+ {
+ phdata->egldisplay=eglGetDisplay(phdata->gfdev);
+ if (phdata->egldisplay==EGL_NO_DISPLAY)
+ {
+ SDL_SetError("Photon: Can't get connection to OpenGL ES");
+ return -1;
+ }
+
+ /* Initialize OpenGL ES library, ignore EGL version */
+ initstatus=eglInitialize(phdata->egldisplay, NULL, NULL);
+ if (initstatus!=EGL_TRUE)
+ {
+ SDL_SetError("Photon: Can't init OpenGL ES library");
+ return -1;
+ }
+ }
+
+ /* Increment GL ES reference count usage */
+ phdata->egl_refcount++;
+ #else
+ SDL_SetError("Photon: OpenGL ES support is not compiled in");
+ return -1;
+ #endif /* SDL_VIDEO_OPENGL_ES */
+ }
+
+ /* Finally create the window */
+ wdata->window=PtCreateWidget(PtWindow, Pt_NO_PARENT, winargc, winargs);
+ if (wdata->window==NULL)
+ {
+ SDL_SetError("Photon: Can't create window widget");
+ SDL_free(wdata);
+ return -1;
}
+ /* Show widget */
+ status=PtRealizeWidget(wdata->window);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't realize window widget");
+ PtDestroyWidget(wdata->window);
+ SDL_free(wdata);
+ return;
+ }
+
+ /* Just created SDL window always gets focus */
+ window->flags|=SDL_WINDOW_INPUT_FOCUS;
+
+ /* Create window-specific cursor after creation */
+ if (didata->cursor_visible==SDL_TRUE)
+ {
+ /* Setup cursor type. shape and default color */
+ PtSetResource(wdata->window, Pt_ARG_CURSOR_COLOR, Ph_CURSOR_DEFAULT_COLOR, 0);
+ PtSetResource(wdata->window, Pt_ARG_CURSOR_TYPE, Ph_CURSOR_BITMAP, 0);
+ PtSetResource(wdata->window, Pt_ARG_BITMAP_CURSOR, didata->cursor, didata->cursor->hdr.len+sizeof(PhRegionDataHdr_t));
+ }
+ else
+ {
+ PtSetResource(wdata->window, Pt_ARG_CURSOR_TYPE, Ph_CURSOR_NONE, 0);
+ }
+
+ /* Set window region sensible to mouse motion events */
+ status=PhRegionQuery(PtWidgetRid(wdata->window), &wregion, NULL, NULL, 0);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't set region sensivity to mouse motion events");
+ PtDestroyWidget(wdata->window);
+ SDL_free(wdata);
+ return -1;
+ }
+ wregion.events_sense|=Ph_EV_PTR_MOTION_BUTTON | Ph_EV_PTR_MOTION_NOBUTTON;
+ status=PhRegionChange(Ph_REGION_EV_SENSE, 0, &wregion, NULL, NULL);
+ if (status<0)
+ {
+ SDL_SetError("Photon: Can't change region sensivity");
+ PtDestroyWidget(wdata->window);
+ SDL_free(wdata);
+ return -1;
+ }
+
+ /* Flush all widget operations again */
+ PtFlush();
+
+ /* By default last created window got a input focus */
+ SDL_SetKeyboardFocus(0, window->id);
+
/* Window has been successfully created */
return 0;
}
int photon_createwindowfrom(_THIS, SDL_Window* window, const void* data)
{
+ /* TODO: it is possible */
+
/* Failed to create window from another window */
return -1;
}
void photon_setwindowtitle(_THIS, SDL_Window* window)
{
+ SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata;
+ int32_t status;
+
+ /* Set window title */
+ if (window->title!=NULL)
+ {
+ status=PtSetResource(wdata->window, Pt_ARG_WINDOW_TITLE, window->title, 0);
+ }
+ else
+ {
+ status=PtSetResource(wdata->window, Pt_ARG_WINDOW_TITLE, "", 0);
+ }
+
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't set window title");
+ }
+
+ /* Flush all widget operations */
+ PtFlush();
}
void photon_setwindowicon(_THIS, SDL_Window* window, SDL_Surface* icon)
{
+ SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata;
+ int32_t status;
+
+ /* TODO: Use iconify ? */
+
+ /* Flush all widget operations */
+ PtFlush();
}
void photon_setwindowposition(_THIS, SDL_Window* window)
{
+ SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata;
+ SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata;
+ PhPoint_t winpos;
+ int32_t status;
+
+ /* Check if upper level requests WM to position window */
+ if ((window->x==SDL_WINDOWPOS_UNDEFINED) && (window->y==SDL_WINDOWPOS_UNDEFINED))
+ {
+ /* Do not set widget position, let WM to set it */
+ }
+ else
+ {
+ if (window->x==SDL_WINDOWPOS_UNDEFINED)
+ {
+ window->x=0;
+ }
+ if (window->y==SDL_WINDOWPOS_UNDEFINED)
+ {
+ window->y=0;
+ }
+ if (window->x==SDL_WINDOWPOS_CENTERED)
+ {
+ window->x=(didata->current_mode.w-window->w)/2;
+ }
+ if (window->y==SDL_WINDOWPOS_CENTERED)
+ {
+ window->y=(didata->current_mode.h-window->h)/2;
+ }
+
+ /* Now set window position */
+ winpos.x=window->x;
+ winpos.y=window->y;
+ status=PtSetResource(wdata->window, Pt_ARG_POS, &winpos, 0);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't set window position");
+ }
+ }
+
+ /* Flush all widget operations */
+ PtFlush();
}
void photon_setwindowsize(_THIS, SDL_Window* window)
{
+ SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata;
+ PhDim_t winsize;
+ int32_t status;
+
+ winsize.w=window->w;
+ winsize.h=window->h;
+
+ status=PtSetResource(wdata->window, Pt_ARG_DIM, &winsize, 0);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't set window size");
+ }
+
+ /* Flush all widget operations */
+ PtFlush();
}
void photon_showwindow(_THIS, SDL_Window* window)
{
+ SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata;
+ int32_t status;
+
+ /* Bring focus to window and put it in front of others */
+ PtWindowToFront(wdata->window);
+
+ /* Flush all widget operations */
+ PtFlush();
}
void photon_hidewindow(_THIS, SDL_Window* window)
{
+ SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata;
+ PhWindowEvent_t winevent;
+ int32_t status;
+
+ SDL_memset(&winevent, 0x00, sizeof(PhWindowEvent_t));
+ winevent.event_f=Ph_WM_HIDE;
+ winevent.rid=PtWidgetRid(wdata->window);
+ winevent.event_state=Ph_WM_EVSTATE_HIDE;
+
+ status=PtForwardWindowEvent(&winevent);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't hide window");
+ }
+
+ /* Flush all widget operations */
+ PtFlush();
}
void photon_raisewindow(_THIS, SDL_Window* window)
{
+ SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata;
+ PhWindowEvent_t winevent;
+ int32_t status;
+
+ SDL_memset(&winevent, 0x00, sizeof(PhWindowEvent_t));
+ winevent.event_f=Ph_WM_HIDE;
+ winevent.rid=PtWidgetRid(wdata->window);
+ winevent.event_state=Ph_WM_EVSTATE_UNHIDE;
+
+ status=PtForwardWindowEvent(&winevent);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't hide window");
+ }
+
+ /* Flush all widget operations */
+ PtFlush();
}
void photon_maximizewindow(_THIS, SDL_Window* window)
{
+ SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata;
+ PhWindowEvent_t winevent;
+ int32_t status;
+
+ /* Flush all widget operations */
+ PtFlush();
}
void photon_minimizewindow(_THIS, SDL_Window* window)
{
+ SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata;
+ PhWindowEvent_t winevent;
+ int32_t status;
+
+ SDL_memset(&winevent, 0x00, sizeof(PhWindowEvent_t));
+ winevent.event_f=Ph_WM_HIDE;
+ winevent.rid=PtWidgetRid(wdata->window);
+ winevent.event_state=Ph_WM_EVSTATE_HIDE;
+
+ status=PtForwardWindowEvent(&winevent);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't hide window");
+ }
+
+ /* Flush all widget operations */
+ PtFlush();
}
void photon_restorewindow(_THIS, SDL_Window* window)
{
+ SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata;
+ PhWindowEvent_t winevent;
+ int32_t status;
+
+ /* Flush all widget operations */
+ PtFlush();
}
void photon_setwindowgrab(_THIS, SDL_Window* window)
{
+ SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata;
+ PhWindowEvent_t winevent;
+ int32_t status;
+
+ /* Flush all widget operations */
+ PtFlush();
}
void photon_destroywindow(_THIS, SDL_Window* window)
{
+ SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata;
SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata;
+ int32_t status;
if (wdata!=NULL)
{
+ status=PtDestroyWidget(wdata->window);
+ if (status!=0)
+ {
+ SDL_SetError("Photon: Can't destroy window widget");
+ }
+ wdata->window=NULL;
+
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ if (phdata->gfinitialized==SDL_TRUE)
+ {
+ /* Destroy OpenGL ES surface if it was created */
+ if (wdata->gles_surface!=EGL_NO_SURFACE)
+ {
+ eglDestroySurface(phdata->egldisplay, wdata->gles_surface);
+ }
+
+ /* Free OpenGL ES target surface */
+ if (wdata->gfsurface!=NULL)
+ {
+ gf_surface_free(wdata->gfsurface);
+ }
+
+ phdata->egl_refcount--;
+ if (phdata->egl_refcount==0)
+ {
+ /* Terminate connection to OpenGL ES */
+ if (phdata->egldisplay!=EGL_NO_DISPLAY)
+ {
+ eglTerminate(phdata->egldisplay);
+ phdata->egldisplay=EGL_NO_DISPLAY;
+ }
+ }
+ }
+ #endif /* SDL_VIDEO_OPENGL_ES */
}
+
+ /* Flush all widget operations */
+ PtFlush();
}
/*****************************************************************************/
@@ -301,50 +1289,691 @@
/*****************************************************************************/
int photon_gl_loadlibrary(_THIS, const char* path)
{
- /* Failed to load new GL library */
- return -1;
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
+
+ if (phdata->gfinitialized!=SDL_TRUE)
+ {
+ SDL_SetError("Photon: GF initialization failed, no OpenGL ES support");
+ return NULL;
+ }
+
+ /* Check if OpenGL ES library is specified for GF driver */
+ if (path==NULL)
+ {
+ path=SDL_getenv("SDL_OPENGL_LIBRARY");
+ if (path==NULL)
+ {
+ path=SDL_getenv("SDL_OPENGLES_LIBRARY");
+ }
+ }
+
+ /* Check if default library loading requested */
+ if (path==NULL)
+ {
+ /* Already linked with GF library which provides egl* subset of */
+ /* functions, use Common profile of OpenGL ES library by default */
+ path="/usr/lib/libGLES_CM.so.1";
+ }
+
+ /* Load dynamic library */
+ _this->gl_config.dll_handle=SDL_LoadObject(path);
+ if (!_this->gl_config.dll_handle)
+ {
+ /* Failed to load new GL ES library */
+ SDL_SetError("Photon: Failed to locate OpenGL ES library");
+ return -1;
+ }
+
+ /* Store OpenGL ES library path and name */
+ SDL_strlcpy(_this->gl_config.driver_path, path, SDL_arraysize(_this->gl_config.driver_path));
+
+ /* New OpenGL ES library is loaded */
+ return 0;
+ #else
+ SDL_SetError("Photon: OpenGL ES support is not compiled in");
+ return -1;
+ #endif /* SDL_VIDEO_OPENGL_ES */
}
void* photon_gl_getprocaddres(_THIS, const char* proc)
{
- /* Failed to get GL function address pointer */
- return NULL;
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
+ void* function_address;
+
+ if (phdata->gfinitialized!=SDL_TRUE)
+ {
+ SDL_SetError("Photon: GF initialization failed, no OpenGL ES support");
+ return NULL;
+ }
+
+ /* Try to get function address through the egl interface */
+ function_address=eglGetProcAddress(proc);
+ if (function_address!=NULL)
+ {
+ return function_address;
+ }
+
+ /* Then try to get function in the OpenGL ES library */
+ if (_this->gl_config.dll_handle)
+ {
+ function_address=SDL_LoadFunction(_this->gl_config.dll_handle, proc);
+ if (function_address!=NULL)
+ {
+ return function_address;
+ }
+ }
+
+ /* Add emulated OpenGL ES 1.1 functions */
+ if (SDL_strcmp(proc, "glTexParameteri")==0)
+ {
+ return glTexParameteri;
+ }
+ if (SDL_strcmp(proc, "glTexParameteriv")==0)
+ {
+ return glTexParameteriv;
+ }
+ if (SDL_strcmp(proc, "glColor4ub")==0)
+ {
+ return glColor4ub;
+ }
+
+ /* Failed to get GL ES function address pointer */
+ SDL_SetError("Photon: Cannot locate OpenGL ES function name");
+ return NULL;
+ #else
+ SDL_SetError("Photon: OpenGL ES support is not compiled in");
+ return NULL;
+ #endif /* SDL_VIDEO_OPENGL_ES */
}
void photon_gl_unloadlibrary(_THIS)
{
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
+
+ if (phdata->gfinitialized==SDL_TRUE)
+ {
+ /* Unload OpenGL ES library */
+ if (_this->gl_config.dll_handle)
+ {
+ SDL_UnloadObject(_this->gl_config.dll_handle);
+ _this->gl_config.dll_handle=NULL;
+ }
+ }
+ else
+ {
+ SDL_SetError("Photon: GF initialization failed, no OpenGL ES support");
+ }
+ #else
+ SDL_SetError("Photon: OpenGL ES support is not compiled in");
+ return;
+ #endif /* SDL_VIDEO_OPENGL_ES */
}
SDL_GLContext photon_gl_createcontext(_THIS, SDL_Window* window)
{
- /* Failed to create GL context */
- return NULL;
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
+ SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata;
+ SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata;
+ EGLBoolean status;
+ int32_t gfstatus;
+ EGLint configs;
+ uint32_t attr_pos;
+ EGLint attr_value;
+ EGLint cit;
+
+ /* Check if GF was initialized */
+ if (phdata->gfinitialized!=SDL_TRUE)
+ {
+ SDL_SetError("Photon: GF initialization failed, no OpenGL ES support");
+ return NULL;
+ }
+
+ /* Prepare attributes list to pass them to OpenGL ES */
+ attr_pos=0;
+ wdata->gles_attributes[attr_pos++]=EGL_NATIVE_VISUAL_ID;
+ wdata->gles_attributes[attr_pos++]=qnxgf_sdl_to_gf_pixelformat(didata->current_mode.format);
+ wdata->gles_attributes[attr_pos++]=EGL_RED_SIZE;
+ wdata->gles_attributes[attr_pos++]=_this->gl_config.red_size;
+ wdata->gles_attributes[attr_pos++]=EGL_GREEN_SIZE;
+ wdata->gles_attributes[attr_pos++]=_this->gl_config.green_size;
+ wdata->gles_attributes[attr_pos++]=EGL_BLUE_SIZE;
+ wdata->gles_attributes[attr_pos++]=_this->gl_config.blue_size;
+ wdata->gles_attributes[attr_pos++]=EGL_ALPHA_SIZE;
+
+ /* Setup alpha size in bits */
+ if (_this->gl_config.alpha_size)
+ {
+ wdata->gles_attributes[attr_pos++]=_this->gl_config.alpha_size;
+ }
+ else
+ {
+ wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE;
+ }
+
+ /* Setup color buffer size */
+ if (_this->gl_config.buffer_size)
+ {
+ wdata->gles_attributes[attr_pos++]=EGL_BUFFER_SIZE;
+ wdata->gles_attributes[attr_pos++]=_this->gl_config.buffer_size;
+ }
+ else
+ {
+ wdata->gles_attributes[attr_pos++]=EGL_BUFFER_SIZE;
+ wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE;
+ }
+
+ /* Setup depth buffer bits */
+ wdata->gles_attributes[attr_pos++]=EGL_DEPTH_SIZE;
+ wdata->gles_attributes[attr_pos++]=_this->gl_config.depth_size;
+
+ /* Setup stencil bits */
+ if (_this->gl_config.stencil_size)
+ {
+ wdata->gles_attributes[attr_pos++]=EGL_STENCIL_SIZE;
+ wdata->gles_attributes[attr_pos++]=_this->gl_config.buffer_size;
+ }
+ else
+ {
+ wdata->gles_attributes[attr_pos++]=EGL_STENCIL_SIZE;
+ wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE;
+ }
+
+ /* Set number of samples in multisampling */
+ if (_this->gl_config.multisamplesamples)
+ {
+ wdata->gles_attributes[attr_pos++]=EGL_SAMPLES;
+ wdata->gles_attributes[attr_pos++]=_this->gl_config.multisamplesamples;
+ }
+
+ /* Multisample buffers, OpenGL ES 1.0 spec defines 0 or 1 buffer */
+ if (_this->gl_config.multisamplebuffers)
+ {
+ wdata->gles_attributes[attr_pos++]=EGL_SAMPLE_BUFFERS;
+ wdata->gles_attributes[attr_pos++]=_this->gl_config.multisamplebuffers;
+ }
+
+ /* Finish attributes list */
+ wdata->gles_attributes[attr_pos]=EGL_NONE;
+
+ /* Request first suitable framebuffer configuration */
+ status=eglChooseConfig(phdata->egldisplay, wdata->gles_attributes,
+ wdata->gles_configs, SDL_VIDEO_GF_OPENGLES_CONFS, &configs);
+ if (status!=EGL_TRUE)
+ {
+ SDL_SetError("Photon: Can't find closest configuration for OpenGL ES");
+ return NULL;
+ }
+
+ /* Check if nothing has been found, try "don't care" settings */
+ if (configs==0)
+ {
+ int32_t it;
+ int32_t jt;
+ GLint depthbits[4]={32, 24, 16, EGL_DONT_CARE};
+
+ for (it=0; it<4; it++)
+ {
+ for (jt=16; jt>=0; jt--)
+ {
+ /* Don't care about color buffer bits, use what exist */
+ /* Replace previous set data with EGL_DONT_CARE */
+ attr_pos=0;
+ wdata->gles_attributes[attr_pos++]=EGL_NATIVE_VISUAL_ID;
+ wdata->gles_attributes[attr_pos++]=qnxgf_sdl_to_gf_pixelformat(didata->current_mode.format);
+ wdata->gles_attributes[attr_pos++]=EGL_RED_SIZE;
+ wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE;
+ wdata->gles_attributes[attr_pos++]=EGL_GREEN_SIZE;
+ wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE;
+ wdata->gles_attributes[attr_pos++]=EGL_BLUE_SIZE;
+ wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE;
+ wdata->gles_attributes[attr_pos++]=EGL_ALPHA_SIZE;
+ wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE;
+ wdata->gles_attributes[attr_pos++]=EGL_BUFFER_SIZE;
+ wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE;
+
+ /* Try to find requested or smallest depth */
+ if (_this->gl_config.depth_size)
+ {
+ wdata->gles_attributes[attr_pos++]=EGL_DEPTH_SIZE;
+ wdata->gles_attributes[attr_pos++]=depthbits[it];
+ }
+ else
+ {
+ wdata->gles_attributes[attr_pos++]=EGL_DEPTH_SIZE;
+ wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE;
+ }
+
+ if (_this->gl_config.stencil_size)
+ {
+ wdata->gles_attributes[attr_pos++]=EGL_STENCIL_SIZE;
+ wdata->gles_attributes[attr_pos++]=jt;
+ }
+ else
+ {
+ wdata->gles_attributes[attr_pos++]=EGL_STENCIL_SIZE;
+ wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE;
+ }
+
+ wdata->gles_attributes[attr_pos++]=EGL_SAMPLES;
+ wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE;
+ wdata->gles_attributes[attr_pos++]=EGL_SAMPLE_BUFFERS;
+ wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE;
+ wdata->gles_attributes[attr_pos]=EGL_NONE;
+
+ /* Request first suitable framebuffer configuration */
+ status=eglChooseConfig(phdata->egldisplay, wdata->gles_attributes,
+ wdata->gles_configs, SDL_VIDEO_GF_OPENGLES_CONFS, &configs);
+ if (status!=EGL_TRUE)
+ {
+ SDL_SetError("Photon: Can't find closest configuration for OpenGL ES");
+ return NULL;
+ }
+ if (configs!=0)
+ {
+ break;
+ }
+ }
+ if (configs!=0)
+ {
+ break;
+ }
+ }
+
+ /* No available configs */
+ if (configs==0)
+ {
+ SDL_SetError("Photon: Can't find any configuration for OpenGL ES");
+ return NULL;
+ }
+ }
+
+ /* Initialize config index */
+ wdata->gles_config=0;
+
+ /* Now check each configuration to find out the best */
+ for (cit=0; cit<configs; cit++)
+ {
+ uint32_t stencil_found;
+ uint32_t depth_found;
+
+ stencil_found=0;
+ depth_found=0;
+
+ if (_this->gl_config.stencil_size)
+ {
+ status=eglGetConfigAttrib(phdata->egldisplay, wdata->gles_configs[cit], EGL_STENCIL_SIZE, &attr_value);
+ if (status==EGL_TRUE)
+ {
+ if (attr_value!=0)
+ {
+ stencil_found=1;
+ }
+ }
+ }
+ else
+ {
+ stencil_found=1;
+ }
+
+ if (_this->gl_config.depth_size)
+ {
+ status=eglGetConfigAttrib(phdata->egldisplay, wdata->gles_configs[cit], EGL_DEPTH_SIZE, &attr_value);
+ if (status==EGL_TRUE)
+ {
+ if (attr_value!=0)
+ {
+ depth_found=1;
+ }
+ }
+ }
+ else
+ {
+ depth_found=1;
+ }
+
+ /* Exit from loop if found appropriate configuration */
+ if ((depth_found!=0) && (stencil_found!=0))
+ {
+ break;
+ }
+ }
+
+ /* If best could not be found, use first */
+ if (cit==configs)
+ {
+ cit=0;
+ }
+ wdata->gles_config=cit;
+
+ /* Create OpenGL ES context */
+ wdata->gles_context=eglCreateContext(phdata->egldisplay, wdata->gles_configs[wdata->gles_config], EGL_NO_CONTEXT, NULL);
+ if (wdata->gles_context==EGL_NO_CONTEXT)
+ {
+ SDL_SetError("Photon: OpenGL ES context creation has been failed");
+ return NULL;
+ }
+
+ /* Check if surface is exist */
+ if (wdata->gfsurface!=NULL)
+ {
+ gf_surface_free(wdata->gfsurface);
+ wdata->gfsurface=NULL;
+ }
+
+ /* Create GF surface */
+ gfstatus=gf_surface_create(&wdata->gfsurface, phdata->gfdev, window->w, window->h,
+ qnxgf_sdl_to_gf_pixelformat(didata->current_mode.format), NULL,
+ GF_SURFACE_CREATE_2D_ACCESSIBLE | GF_SURFACE_CREATE_3D_ACCESSIBLE |
+ GF_SURFACE_CREATE_SHAREABLE);
+ if (gfstatus!=GF_ERR_OK)
+ {
+ eglDestroyContext(phdata->egldisplay, wdata->gles_context);
+ wdata->gles_context=EGL_NO_CONTEXT;
+ SDL_SetError("Photon: Can't create GF 3D surface (%08X)", gfstatus);
+ return NULL;
+ }
+
+ /* Create pixmap 3D target surface */
+ wdata->gles_surface=eglCreatePixmapSurface(phdata->egldisplay, wdata->gles_configs[wdata->gles_config], wdata->gfsurface, NULL);
+ if (wdata->gles_surface==EGL_NO_SURFACE)
+ {
+ gf_surface_free(wdata->gfsurface);
+ eglDestroyContext(phdata->egldisplay, wdata->gles_context);
+ wdata->gles_context=EGL_NO_CONTEXT;
+ SDL_SetError("Photon: Can't create EGL pixmap surface");
+ return NULL;
+ }
+
+ /* Make just created context current */
+ status=eglMakeCurrent(phdata->egldisplay, wdata->gles_surface, wdata->gles_surface, wdata->gles_context);
+ if (status!=EGL_TRUE)
+ {
+ /* Destroy OpenGL ES surface */
+ eglDestroySurface(phdata->egldisplay, wdata->gles_surface);
+ gf_surface_free(wdata->gfsurface);
+ eglDestroyContext(phdata->egldisplay, wdata->gles_context);
+ wdata->gles_context=EGL_NO_CONTEXT;
+ SDL_SetError("Photon: Can't set OpenGL ES context on creation");
+ return NULL;
+ }
+
+ /* Setup into SDL internals state of OpenGL ES: */
+ /* it is accelerated or not */
+ if ((didata->caps & SDL_PHOTON_ACCELERATED_3D)==SDL_PHOTON_ACCELERATED_3D)
+ {
+ _this->gl_config.accelerated=1;
+ }
+ else
+ {
+ _this->gl_config.accelerated=0;
+ }
+
+ /* Always clear stereo enable, since OpenGL ES do not supports stereo */
+ _this->gl_config.stereo=0;
+
+ /* Get back samples and samplebuffers configurations. Rest framebuffer */
+ /* parameters could be obtained through the OpenGL ES API */
+ status=eglGetConfigAttrib(phdata->egldisplay, wdata->gles_configs[wdata->gles_config], EGL_SAMPLES, &attr_value);
+ if (status==EGL_TRUE)
+ {
+ _this->gl_config.multisamplesamples=attr_value;
+ }
+ status=eglGetConfigAttrib(phdata->egldisplay, wdata->gles_configs[wdata->gles_config], EGL_SAMPLE_BUFFERS, &attr_value);
+ if (status==EGL_TRUE)
+ {
+ _this->gl_config.multisamplebuffers=attr_value;
+ }
+
+ /* Get back stencil and depth buffer sizes */
+ status=eglGetConfigAttrib(phdata->egldisplay, wdata->gles_configs[wdata->gles_config], EGL_DEPTH_SIZE, &attr_value);
+ if (status==EGL_TRUE)
+ {
+ _this->gl_config.depth_size=attr_value;
+ }
+ status=eglGetConfigAttrib(phdata->egldisplay, wdata->gles_configs[wdata->gles_config], EGL_STENCIL_SIZE, &attr_value);
+ if (status==EGL_TRUE)
+ {
+ _this->gl_config.stencil_size=attr_value;
+ }
+
+ /* Under Photon OpenGL ES output can't be double buffered */
+ _this->gl_config.double_buffer=0;
+
+ /* Check if current device is not the same as target */
+ if (phdata->current_device_id!=didata->device_id)
+ {
+ /* Set target device as default for Pd and Pg functions */
+ status=PdSetTargetDevice(NULL, phdata->rid[didata->device_id]);
+ if (status!=0)
+ {
+ /* Destroy OpenGL ES surface */
+ eglDestroySurface(phdata->egldisplay, wdata->gles_surface);
+ gf_surface_free(wdata->gfsurface);
+ eglDestroyContext(phdata->egldisplay, wdata->gles_context);
+ wdata->gles_context=EGL_NO_CONTEXT;
+ SDL_SetError("Photon: Can't set default target device\n");
+ return NULL;
+ }
+ phdata->current_device_id=didata->device_id;
+ }
+
+ wdata->phsurface=PdCreateOffscreenContextGF(wdata->gfsurface);
+ if (wdata->phsurface==NULL)
+ {
+ /* Destroy OpenGL ES surface */
+ eglDestroySurface(phdata->egldisplay, wdata->gles_surface);
+ gf_surface_free(wdata->gfsurface);
+ eglDestroyContext(phdata->egldisplay, wdata->gles_context);
+ wdata->gles_context=EGL_NO_CONTEXT;
+ SDL_SetError("Photon: Can't bind GF surface to Photon\n");
+ return NULL;
+ }
+
+ /* GL ES context was successfully created */
+ return wdata->gles_context;
+ #else
+ SDL_SetError("Photon: OpenGL ES support is not compiled in");
+ return NULL;
+ #endif /* SDL_VIDEO_OPENGL_ES */
}
int photon_gl_makecurrent(_THIS, SDL_Window* window, SDL_GLContext context)
{
- /* Failed to set current GL context */
- return -1;
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
+ SDL_WindowData* wdata;
+ EGLBoolean status;
+
+ if (phdata->gfinitialized!=SDL_TRUE)
+ {
+ SDL_SetError("Photon: GF initialization failed, no OpenGL ES support");
+ return -1;
+ }
+
+ if ((window==NULL) && (context==NULL))
+ {
+ status=eglMakeCurrent(phdata->egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (status!=EGL_TRUE)
+ {
+ /* Failed to set current GL ES context */
+ SDL_SetError("Photon: Can't set OpenGL ES context");
+ return -1;
+ }
+ }
+ else
+ {
+ wdata=(SDL_WindowData*)window->driverdata;
+ if (wdata->gles_surface==EGL_NO_SURFACE)
+ {
+ SDL_SetError("Photon: OpenGL ES surface is not initialized for this window");
+ return -1;
+ }
+ if (wdata->gles_context==EGL_NO_CONTEXT)
+ {
+ SDL_SetError("Photon: OpenGL ES context is not initialized for this window");
+ return -1;
+ }
+ if (wdata->gles_context!=context)
+ {
+ SDL_SetError("Photon: OpenGL ES context is not belong to this window");
+ return -1;
+ }
+ status=eglMakeCurrent(phdata->egldisplay, wdata->gles_surface, wdata->gles_surface, wdata->gles_context);
+ if (status!=EGL_TRUE)
+ {
+ /* Failed to set current GL ES context */
+ SDL_SetError("Photon: Can't set OpenGL ES context");
+ return -1;
+ }
+ }
+
+ return 0;
+ #else
+ SDL_SetError("Photon: OpenGL ES support is not compiled in");
+ return -1;
+ #endif /* SDL_VIDEO_OPENGL_ES */
}
int photon_gl_setswapinterval(_THIS, int interval)
{
- /* Failed to set swap interval */
- return -1;
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
+ EGLBoolean status;
+
+ if (phdata->gfinitialized!=SDL_TRUE)
+ {
+ SDL_SetError("Photon: GF initialization failed, no OpenGL ES support");
+ return -1;
+ }
+
+ /* Check if OpenGL ES connection has been initialized */
+ if (phdata->egldisplay!=EGL_NO_DISPLAY)
+ {
+ /* Set swap OpenGL ES interval */
+ status=eglSwapInterval(phdata->egldisplay, interval);
+ if (status==EGL_TRUE)
+ {
+ /* Return success to upper level */
+ phdata->swapinterval=interval;
+ return 0;
+ }
+ }
+
+ /* Failed to set swap interval */
+ SDL_SetError("Photon: Cannot set swap interval");
+ return -1;
+ #else
+ SDL_SetError("Photon: OpenGL ES support is not compiled in");
+ return -1;
+ #endif /* SDL_VIDEO_OPENGL_ES */
}
int photon_gl_getswapinterval(_THIS)
{
- /* Failed to get default swap interval */
- return -1;
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
+
+ if (phdata->gfinitialized!=SDL_TRUE)
+ {
+ SDL_SetError("Photon: GF initialization failed, no OpenGL ES support");
+ return -1;
+ }
+
+ /* Return default swap interval value */
+ return phdata->swapinterval;
+ #else
+ SDL_SetError("Photon: OpenGL ES support is not compiled in");
+ return -1;
+ #endif /* SDL_VIDEO_OPENGL_ES */
}
void photon_gl_swapwindow(_THIS, SDL_Window* window)
{
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
+ SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata;
+ SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata;
+ PhRect_t* dst_rect;
+ PhRect_t src_rect;
+
+ if (phdata->gfinitialized!=SDL_TRUE)
+ {
+ SDL_SetError("Photon: GF initialization failed, no OpenGL ES support");
+ return;
+ }
+
+ /* Many applications do not uses glFinish(), so we call it for them */
+ glFinish();
+
+ /* Wait until OpenGL ES rendering is completed */
+ eglWaitGL();
+
+ /* Wait for VSYNC manually, if it was enabled */
+ if (phdata->swapinterval!=0)
+ {
+ /* Wait for VSYNC, we use GF function, since Photon requires */
+ /* to enter to the Direct mode to call PgWaitVSync() */
+ gf_display_wait_vsync(didata->display);
+ }
+
+ /* Set blit area */
+ dst_rect=PtGetCanvas(wdata->window);
+ src_rect.ul.x=0;
+ src_rect.ul.y=0;
+ src_rect.lr.x=window->w-1;
+ src_rect.lr.y=window->h-1;
+
+ /* Blit OpenGL ES pixmap surface directly to window region */
+ PgFFlush(Ph_START_DRAW);
+ PgSetRegionCx(PhDCGetCurrent(), PtWidgetRid(wdata->window));
+ PgClearTranslationCx(PgGetGCCx(PhDCGetCurrent()));
+ PgContextBlit(wdata->phsurface, &src_rect, NULL, dst_rect);
+ PgFFlush(Ph_DONE_DRAW);
+ PgWaitHWIdle();
+
+ eglSwapBuffers(phdata->egldisplay, wdata->gles_surface);
+ #else
+ SDL_SetError("Photon: OpenGL ES support is not compiled in");
+ return;
+ #endif /* SDL_VIDEO_OPENGL_ES */
}
void photon_gl_deletecontext(_THIS, SDL_GLContext context)
{
+ #if defined(SDL_VIDEO_OPENGL_ES)
+ SDL_VideoData* phdata=(SDL_VideoData*)_this->driverdata;
+ EGLBoolean status;
+
+ if (phdata->gfinitialized!=SDL_TRUE)
+ {
+ SDL_SetError("Photon: GF initialization failed, no OpenGL ES support");
+ return;
+ }
+
+ /* Check if OpenGL ES connection has been initialized */
+ if (phdata->egldisplay!=EGL_NO_DISPLAY)
+ {
+ if (context!=EGL_NO_CONTEXT)
+ {
+ status=eglDestroyContext(phdata->egldisplay, context);
+ if (status!=EGL_TRUE)
+ {
+ /* Error during OpenGL ES context destroying */
+ SDL_SetError("Photon: OpenGL ES context destroy error");
+ return;
+ }
+ }
+ }
+
+ return;
+ #else
+ SDL_SetError("Photon: OpenGL ES support is not compiled in");
+ return;
+ #endif /* SDL_VIDEO_OPENGL_ES */
}
/*****************************************************************************/
@@ -352,6 +1981,543 @@
/*****************************************************************************/
void photon_pumpevents(_THIS)
{
+ uint8_t eventbuffer[SDL_VIDEO_PHOTON_EVENT_SIZE];
+ PhEvent_t* event=(PhEvent_t*)eventbuffer;
+ int32_t status;
+ uint32_t finish=0;
+ uint32_t it;
+ SDL_Window* window;
+ SDL_WindowData* wdata;
+
+ do {
+ status=PhEventPeek(event, SDL_VIDEO_PHOTON_EVENT_SIZE);
+ switch (status)
+ {
+ case Ph_RESIZE_MSG:
+ {
+ SDL_SetError("Photon: Event size too much for buffer");
+ return;
+ }
+ break;
+ case Ph_EVENT_MSG:
+ {
+ /* Find a window, to which this handle destinated */
+ status=0;
+ for (it=0; it<SDL_CurrentDisplay.num_windows; it++)
+ {
+ wdata=(SDL_WindowData*)SDL_CurrentDisplay.windows[it].driverdata;
+
+ /* Find the proper window */
+ if (wdata->window!=NULL)
+ {
+ if (PtWidgetRid(wdata->window)==event->collector.rid)
+ {
+ window=(SDL_Window*)&SDL_CurrentDisplay.windows[it];
+ status=1;
+ break;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+ if (status==0)
+ {
+ window=NULL;
+ }
+
+ /* Event is ready */
+ switch(event->type)
+ {
+ case Ph_EV_BOUNDARY:
+ {
+ switch(event->subtype)
+ {
+ case Ph_EV_PTR_ENTER:
+ {
+ /* Mouse cursor over handled window */
+ if (window!=NULL)
+ {
+ SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_ENTER, 0, 0);
+ SDL_SetMouseFocus(0, window->id);
+ }
+ }
+ break;
+ case Ph_EV_PTR_LEAVE:
+ {
+ /* Mouse cursor out of handled window */
+ if (window!=NULL)
+ {
+ SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_LEAVE, 0, 0);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ case Ph_EV_PTR_MOTION_BUTTON:
+ case Ph_EV_PTR_MOTION_NOBUTTON:
+ {
+ PhPointerEvent_t* pevent=NULL;
+ PhRect_t* prects=NULL;
+
+ /* Get event data */
+ pevent=PhGetData(event);
+ /* Get associated event rectangles */
+ prects=PhGetRects(event);
+ if ((pevent!=NULL) && (prects!=NULL))
+ {
+ SDL_SendMouseMotion(0, 0, prects->ul.x, prects->ul.y, 0);
+ }
+ }
+ break;
+ case Ph_EV_BUT_PRESS:
+ {
+ /* Button press event */
+ PhPointerEvent_t* pevent=NULL;
+ uint32_t sdlbutton=0x00000000;
+
+ /* Get event data */
+ pevent=PhGetData(event);
+ if (pevent!=NULL)
+ {
+ for (it=0; it<sizeof(pevent->buttons)*8; it++)
+ {
+ if ((pevent->buttons&(0x0001<<it))==(0x0001<<it))
+ {
+ switch (it)
+ {
+ case 0:
+ {
+ sdlbutton=SDL_BUTTON_RIGHT;
+ }
+ break;
+ case 1:
+ {
+ sdlbutton=SDL_BUTTON_MIDDLE;
+ }
+ break;
+ case 2:
+ {
+ sdlbutton=SDL_BUTTON_LEFT;
+ }
+ break;
+ default:
+ {
+ sdlbutton=it+1;
+ }
+ break;
+ }
+ SDL_SendMouseButton(0, SDL_PRESSED, sdlbutton);
+ }
+ }
+ }
+ }
+ break;
+ case Ph_EV_BUT_RELEASE:
+ {
+ /* Button press event */
+ PhPointerEvent_t* pevent=NULL;
+ uint32_t sdlbutton=0x00000000;
+
+ /* Get event data */
+ pevent=PhGetData(event);
+ if (pevent!=NULL)
+ {
+ for (it=0; it<sizeof(pevent->buttons)*8; it++)
+ {
+ if ((pevent->buttons&(0x0001<<it))==(0x0001<<it))
+ {
+ switch (it)
+ {
+ case 0:
+ {
+ sdlbutton=SDL_BUTTON_RIGHT;
+ }
+ break;
+ case 1:
+ {
+ sdlbutton=SDL_BUTTON_MIDDLE;
+ }
+ break;
+ case 2:
+ {
+ sdlbutton=SDL_BUTTON_LEFT;
+ }
+ break;
+ default:
+ {
+ sdlbutton=it+1;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ switch(event->subtype)
+ {
+ case Ph_EV_RELEASE_REAL:
+ {
+ /* Real release button event */
+ SDL_SendMouseButton(0, SDL_RELEASED, sdlbutton);
+ }
+ break;
+ case Ph_EV_RELEASE_PHANTOM:
+ {
+ /* We will get phantom button release */
+ /* event in case if it was unpressed */
+ /* outside of window */
+ if (window!=NULL)
+ {
+ if ((window->flags & SDL_WINDOW_MOUSE_FOCUS)!=SDL_WINDOW_MOUSE_FOCUS)
+ {
+ /* Send phantom button release */
+ SDL_SendMouseButton(0, SDL_RELEASED, sdlbutton);
+ }
+ }
+ }
+ break;
+ }
+ }
+ break;
+ case Ph_EV_EXPOSE:
+ {
+ switch(event->subtype)
+ {
+ case Ph_NORMAL_EXPOSE:
+ {
+ PhRect_t* rects=NULL;
+
+ /* Get array of rectangles to be updated */
+ rects=PhGetRects(event);
+ if (rects==NULL)
+ {
+ break;
+ }
+
+ /* Cycle through each rectangle */
+ for (it=0; it<event->num_rects; it++)
+ {
+ /* TODO: update the damaged rectangles */
+ }
+
+ /* Flush all blittings */
+ PgFlush();
+ }
+ break;
+ case Ph_CAPTURE_EXPOSE:
+ {
+ /* We need to redraw entire screen */
+ PgFFlush(Ph_START_DRAW);
+
+ /* TODO: redraw the whole screen */
+
+ PgFFlush(Ph_DONE_DRAW);
+ }
+ break;
+ case Ph_GRAPHIC_EXPOSE:
+ {
+ /* TODO: What this event means ? */
+ }
+ break;
+ }
+ }
+ break;
+ case Ph_EV_INFO:
+ {
+ }
+ break;
+ case Ph_EV_KEY:
+ {
+ PhKeyEvent_t* keyevent=NULL;
+ SDL_scancode scancode=SDL_SCANCODE_UNKNOWN;
+ SDL_bool pressed=SDL_FALSE;
+
+ keyevent=PhGetData(event);
+ if (keyevent==NULL)
+ {
+ break;
+ }
+
+ /* Check if key is repeated */
+ if ((keyevent->key_flags & Pk_KF_Key_Repeat)==Pk_KF_Key_Repeat)
+ {
+ /* Ignore such events */
+ break;
+ }
+
+ /* Check if key has its own scancode */
+ if ((keyevent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid)
+ {
+ if ((keyevent->key_flags & Pk_KF_Key_Down)==Pk_KF_Key_Down)
+ {
+ pressed=SDL_TRUE;
+ }
+ else
+ {
+ pressed=SDL_FALSE;
+ }
+ scancode=photon_to_sdl_keymap(keyevent->key_scan);
+
+ /* Add details for the pressed key */
+ if ((keyevent->key_flags & Pk_KF_Cap_Valid)==Pk_KF_Cap_Valid)
+ {
+ switch(keyevent->key_cap)
+ {
+ case Pk_Hyper_R: /* Right windows flag key */
+ scancode=SDL_SCANCODE_RGUI;
+ break;
+ case Pk_Control_R: /* Right Ctrl key */
+ scancode=SDL_SCANCODE_RCTRL;
+ break;
+ case Pk_Alt_R: /* Right Alt key */
+ scancode=SDL_SCANCODE_RALT;
+ break;
+ case Pk_Up: /* Up key but with invalid scan */
+ if (scancode!=SDL_SCANCODE_UP)
+ {
+ /* This is a mouse wheel event */
+ SDL_SendMouseWheel(0, 0, 1);
+ return;
+ }
+ break;
+ case Pk_KP_8: /* Up arrow or 8 on keypad */
+ scancode=SDL_SCANCODE_KP_8;
+ break;
+ case Pk_Down: /* Down key but with invalid scan */
+ if (scancode!=SDL_SCANCODE_DOWN)
+ {
+ /* This is a mouse wheel event */
+ SDL_SendMouseWheel(0, 0, -1);
+ return;
+ }
+ break;
+ case Pk_KP_2: /* Down arrow or 2 on keypad */
+ scancode=SDL_SCANCODE_KP_2;
+ break;
+ case Pk_Left: /* Left arrow key */
+ scancode=SDL_SCANCODE_LEFT;
+ break;
+ case Pk_KP_4: /* Left arrow or 4 on keypad */
+ scancode=SDL_SCANCODE_KP_4;
+ break;
+ case Pk_Right: /* Right arrow key */
+ scancode=SDL_SCANCODE_RIGHT;
+ break;
+ case Pk_KP_6: /* Right arrow or 6 on keypad */
+ scancode=SDL_SCANCODE_KP_6;
+ break;
+ case Pk_Insert: /* Insert key */
+ scancode=SDL_SCANCODE_INSERT;
+ break;
+ case Pk_KP_0: /* Insert or 0 on keypad */
+ scancode=SDL_SCANCODE_KP_0;
+ break;
+ case Pk_Home: /* Home key */
+ scancode=SDL_SCANCODE_HOME;
+ break;
+ case Pk_KP_7: /* Home or 7 on keypad */
+ scancode=SDL_SCANCODE_KP_7;
+ break;
+ case Pk_Pg_Up: /* PageUp key */
+ scancode=SDL_SCANCODE_PAGEUP;
+ break;
+ case Pk_KP_9: /* PgUp or 9 on keypad */
+ scancode=SDL_SCANCODE_KP_9;
+ break;
+ case Pk_Delete: /* Delete key */
+ scancode=SDL_SCANCODE_DELETE;
+ break;
+ case Pk_KP_Decimal: /* Del or . on keypad */
+ scancode=SDL_SCANCODE_KP_PERIOD;
+ break;
+ case Pk_End: /* End key */
+ scancode=SDL_SCANCODE_END;
+ break;
+ case Pk_KP_1: /* End or 1 on keypad */
+ scancode=SDL_SCANCODE_KP_1;
+ break;
+ case Pk_Pg_Down: /* PageDown key */
+ scancode=SDL_SCANCODE_PAGEDOWN;
+ break;
+ case Pk_KP_3: /* PgDn or 3 on keypad */
+ scancode=SDL_SCANCODE_KP_3;
+ break;
+ case Pk_KP_5: /* 5 on keypad */
+ scancode=SDL_SCANCODE_KP_5;
+ break;
+ case Pk_KP_Enter:
+ scancode=SDL_SCANCODE_KP_ENTER;
+ break;
+ case Pk_KP_Add:
+ scancode=SDL_SCANCODE_KP_PLUS;
+ break;
+ case Pk_KP_Subtract:
+ scancode=SDL_SCANCODE_KP_MINUS;
+ break;
+ case Pk_KP_Multiply:
+ scancode=SDL_SCANCODE_KP_MULTIPLY;
+ break;
+ case Pk_KP_Divide:
+ scancode=SDL_SCANCODE_KP_DIVIDE;
+ break;
+ case Pk_Pause:
+ scancode=SDL_SCANCODE_PAUSE;
+ break;
+ }
+ }
+
+ /* Finally check if scancode has been decoded */
+ if (scancode==SDL_SCANCODE_UNKNOWN)
+ {
+ /* Something was pressed, which is not supported */
+ break;
+ }
+
+ /* Report pressed/released key to SDL */
+ if (pressed==SDL_TRUE)
+ {
+ SDL_SendKeyboardKey(0, SDL_PRESSED, scancode);
+ }
+ else
+ {
+ SDL_SendKeyboardKey(0, SDL_RELEASED, scancode);
+ }
+
+ /* Photon doesn't send a release event for PrnScr key */
+ if ((scancode==SDL_SCANCODE_PRINTSCREEN) && (pressed))
+ {
+ SDL_SendKeyboardKey(0, SDL_RELEASED, scancode);
+ }
+ }
+ }
+ break;
+ case Ph_EV_SERVICE:
+ {
+ }
+ break;
+ case Ph_EV_SYSTEM:
+ {
+ }
+ break;
+ case Ph_EV_WM:
+ {
+ PhWindowEvent_t* wmevent=NULL;
+
+ /* Get associated event data */
+ wmevent=PhGetData(event);
+ if (wmevent==NULL)
+ {
+ break;
+ }
+
+ switch(wmevent->event_f)
+ {
+ case Ph_WM_CLOSE:
+ {
+ if (window!=NULL)
+ {
+ SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_CLOSE, 0, 0);
+ }
+ }
+ break;
+ case Ph_WM_FOCUS:
+ {
+ if (wmevent->event_state==Ph_WM_EVSTATE_FOCUS)
+ {
+ if (window!=NULL)
+ {
+ PhRegion_t wregion;
+
+ SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
+ SDL_SetKeyboardFocus(0, window->id);
+
+ /* Set window region sensible to mouse motion events */
+ PhRegionQuery(PtWidgetRid(wdata->window), &wregion, NULL, NULL, 0);
+ wregion.events_sense|=Ph_EV_PTR_MOTION_BUTTON | Ph_EV_PTR_MOTION_NOBUTTON;
+ PhRegionChange(Ph_REGION_EV_SENSE, 0, &wregion, NULL, NULL);
+ }
+ }
+ if (wmevent->event_state==Ph_WM_EVSTATE_FOCUSLOST)
+ {
+ if (window!=NULL)
+ {
+ PhRegion_t wregion;
+
+ SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
+
+ /* Set window region ignore mouse motion events */
+ PhRegionQuery(PtWidgetRid(wdata->window), &wregion, NULL, NULL, 0);
+ wregion.events_sense&=~(Ph_EV_PTR_MOTION_BUTTON | Ph_EV_PTR_MOTION_NOBUTTON);
+ PhRegionChange(Ph_REGION_EV_SENSE, 0, &wregion, NULL, NULL);
+ }
+ }
+ }
+ break;
+ case Ph_WM_MOVE:
+ {
+ if (window!=NULL)
+ {
+ SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_MOVED, wmevent->pos.x, wmevent->pos.y);
+ }
+ }
+ break;
+ case Ph_WM_RESIZE:
+ {
+ if (window!=NULL)
+ {
+ }
+ }
+ break;
+ case Ph_WM_HIDE:
+ {
+ if (window!=NULL)
+ {
+ }
+ }
+ break;
+ case Ph_WM_MAX:
+ {
+ if (window!=NULL)
+ {
+ }
+ }
+ break;
+ case Ph_WM_RESTORE:
+ {
+ if (window!=NULL)
+ {
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ PtEventHandler(event);
+ }
+ break;
+ case 0:
+ {
+ /* All events are read */
+ finish=1;
+ break;
+ }
+ case -1:
+ {
+ /* Error occured in event reading */
+ SDL_SetError("Photon: Can't read event");
+ return;
+ }
+ break;
+ }
+ if (finish!=0)
+ {
+ break;
+ }
+ } while(1);
}
/*****************************************************************************/
--- a/src/video/photon/SDL_photon_render.c Fri Apr 24 03:46:54 2009 +0000
+++ b/src/video/photon/SDL_photon_render.c Tue Apr 28 04:30:52 2009 +0000
@@ -35,24 +35,24 @@
#include "SDL_photon.h"
static SDL_Renderer* photon_createrenderer(SDL_Window* window, Uint32 flags);
-static int photon_displaymodechanged(SDL_Renderer* renderer);
-static int photon_activaterenderer(SDL_Renderer* renderer);
-static int photon_createtexture(SDL_Renderer* renderer, SDL_Texture* texture);
-static int photon_querytexturepixels(SDL_Renderer* renderer, SDL_Texture* texture, void** pixels, int* pitch);
-static int photon_settexturepalette(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Color* colors, int firstcolor, int ncolors);
-static int photon_gettexturepalette(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Color* colors, int firstcolor, int ncolors);
-static int photon_settexturecolormod(SDL_Renderer* renderer, SDL_Texture* texture);
-static int photon_settexturealphamod(SDL_Renderer* renderer, SDL_Texture* texture);
-static int photon_settextureblendmode(SDL_Renderer* renderer, SDL_Texture* texture);
-static int photon_settexturescalemode(SDL_Renderer* renderer, SDL_Texture* texture);
-static int photon_updatetexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, const void* pixels, int pitch);
-static int photon_locktexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, int markDirty, void** pixels, int* pitch);
+static int photon_displaymodechanged(SDL_Renderer* renderer);
+static int photon_activaterenderer(SDL_Renderer* renderer);
+static int photon_createtexture(SDL_Renderer* renderer, SDL_Texture* texture);
+static int photon_querytexturepixels(SDL_Renderer* renderer, SDL_Texture* texture, void** pixels, int* pitch);
+static int photon_settexturepalette(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Color* colors, int firstcolor, int ncolors);
+static int photon_gettexturepalette(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Color* colors, int firstcolor, int ncolors);
+static int photon_settexturecolormod(SDL_Renderer* renderer, SDL_Texture* texture);
+static int photon_settexturealphamod(SDL_Renderer* renderer, SDL_Texture* texture);
+static int photon_settextureblendmode(SDL_Renderer* renderer, SDL_Texture* texture);
+static int photon_settexturescalemode(SDL_Renderer* renderer, SDL_Texture* texture);
+static int photon_updatetexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, const void* pixels, int pitch);
+static int photon_locktexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, int markDirty, void** pixels, int* pitch);
static void photon_unlocktexture(SDL_Renderer* renderer, SDL_Texture* texture);
static void photon_dirtytexture(SDL_Renderer* renderer, SDL_Texture* texture, int numrects, const SDL_Rect* rects);
-static int photon_renderpoint(SDL_Renderer* renderer, int x, int y);
-static int photon_renderline(SDL_Renderer* renderer, int x1, int y1, int x2, int y2);
-static int photon_renderfill(SDL_Renderer* renderer, const SDL_Rect* rect);
-static int photon_rendercopy(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* srcrect, const SDL_Rect* dstrect);
+static int photon_renderpoint(SDL_Renderer* renderer, int x, int y);
+static int photon_renderline(SDL_Renderer* renderer, int x1, int y1, int x2, int y2);
+static int photon_renderfill(SDL_Renderer* renderer, const SDL_Rect* rect);
+static int photon_rendercopy(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* srcrect, const SDL_Rect* dstrect);
static void photon_renderpresent(SDL_Renderer* renderer);
static void photon_destroytexture(SDL_Renderer* renderer, SDL_Texture* texture);
static void photon_destroyrenderer(SDL_Renderer* renderer);