Commit a47948aa authored by Sam Lantinga's avatar Sam Lantinga

Nobody is currently maintaining the QNX code, so removing it for now.

parent 09a85588
...@@ -13,7 +13,7 @@ level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, ...@@ -13,7 +13,7 @@ level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL,
and 2D framebuffer across multiple platforms. and 2D framebuffer across multiple platforms.
The current version supports Windows, Windows CE, Mac OS X, Linux, FreeBSD, The current version supports Windows, Windows CE, Mac OS X, Linux, FreeBSD,
NetBSD, OpenBSD, BSD/OS, Solaris, QNX, iOS, and Android. The code contains NetBSD, OpenBSD, BSD/OS, Solaris, iOS, and Android. The code contains
support for other operating systems but those are not officially supported. support for other operating systems but those are not officially supported.
SDL is written in C, but works with C++ natively, and has bindings to SDL is written in C, but works with C++ natively, and has bindings to
......
...@@ -30,5 +30,4 @@ Pandora - maintained by Scott Smith <pickle136@sbcglobal.net> ...@@ -30,5 +30,4 @@ Pandora - maintained by Scott Smith <pickle136@sbcglobal.net>
Platforms that need maintainers Platforms that need maintainers
=============================== ===============================
Nintendo DS Nintendo DS
QNX
Haiku Haiku
README.QNX by Mike Gorchak <mike@malva.ua>, <lestat@i.com.ua>
Last changed at 10 Jun 2009.
QNX Photon and GF drivers are being constructed, OpenGL ES support is
finished. Still no 2D renderer support in GF and Photon drivers.
QNX QSA (QNX Sound Architecture) driver is ready.
QNX HID input driver is finished.
----------------------
-- SDL QSA driver --
----------------------
Due to QNX Sound Architecture limitations software could not determine
what playback channels are designed for, so some casus can be. For example,
output after testmultiaudio test utility execution:
Using audio driver: qsa
playing on device #0: ('Vortex 8820 @ fb000000 d0')...done.
playing on device #1: ('Vortex 8820 @ fb000000 d1')...done.
playing on device #2: ('i8x0 @ d800 d0')...done.
playing on device #3: ('i8x0 @ d800 d1')...done.
playing on all devices...
Open device 3 failed: QSA: snd_pcm_channel_params failed: Invalid argument
If speakers are connected to both audio cards: Vortex 8820 and Intel
Integrated Audio we can hear sound playback on device #0 and devices #2, #3
only. Device #1 is an unknown PCM channel which does not produce any sound.
As for error during device #3 opening, it's caused by QSA software mixer
channel, because it can't open real hardware device #2, since it's already
opened by SDL.
After simultaneous sound playback on all devices utility testmultiaudio
stays running waiting for sound playback finish on device #1, which is
locked up due to some Aureal Vortex 8820 driver limitations.
---------------------
-- SDL GF driver --
---------------------
Here is an additional information about SDL GF driver:
* 0. Introduction.
* 1. Environment variables which SDL GF driver supports.
* 2. Custom video modes.
* 3. Limitations.
0. Introduction.
SDL GF driver is a layer between SDL and QNX Graphics Framework (GF).
SDL GF driver also supports OpenGL ES through the QNX Graphics Framework.
Hardware accelerated features which SDL can support depend on real hardware
capabilities.
1. Environment variables which GF driver supports.
GF driver supports the following environment variables for QNX GF
specific customization options:
a) SDL_VIDEO_GF_REFRESH_RATE - refresh rate of video output in Hz.
Without this environment variable declaration SDL controls refresh
rate of your display. If this enironment variable is set to 0, SDL
will control refresh rate of display, otherwise value of flag
SDL_VIDEO_GF_REFRESH_RATE is used for all screen resolutions as
refresh rate. This example will set 60Hz refresh rate as refresh rate
for all graphics modes:
export SDL_VIDEO_GF_REFRESH_RATE=60
2. Custom video modes.
Since most QNX graphics drivers support GENERIC video modes, i.e. you
can specify any horizontal and vertical resolution and any refresh rate,
SDL GF driver uses its own fullscreen modes list, which can be incomplete.
You can add any custom video mode, which your QNX graphics driver supports
by editing file ./src/video/qnxgf/SDL_qnxgf.c. Custom graphics mode
definition looks like this:
{0, 1024, 640, 60, NULL}, /* 1024x640 mode is 60Hz only */
You must specify horizontal resolution as the second parameter, vertical
resolution as the third one and refresh rate as the fourth parameter.
Please leave the first and the last parameters as 0 and NULL. Then send me
your changes to e-mail address which is specified in the header of this
document.
3. Limitations.
There are few limitations while using SDL GF driver:
a) Since GF driver supports fullscreen modes only, when flag
SDL_WINDOW_FULLSCREEN is not specified, SDL GF driver will try to find the
fullscreen graphics mode which corresponds to SDL window size. Refresh rate
will be the lowest available, if SDL_VIDEO_GF_REFRESH_RATE environment
variable is not set.
b) As confirmed by QSSL none of existing video drivers has support of
doublescan low-resolution video modes. So modes below 640x480 are not
supported. If your video driver supports low-resolution video modes, please
add SDL_GF_LOWRESOLUTION flag to the gf_devicename array in the SDL_qnxgf.c
source file.
c) Since GF framework supports hardware mouse cursor only, you'll get
hardware mouse cursor in case of specific graphics driver supports it.
-------------------------
-- SDL Photon driver --
-------------------------
----------------------------
-- SDL HID input driver --
----------------------------
...@@ -1326,70 +1326,6 @@ AC_HELP_STRING([--enable-video-x11-xdamage-xfixes], [enable X11 Xdamage and Xfix ...@@ -1326,70 +1326,6 @@ AC_HELP_STRING([--enable-video-x11-xdamage-xfixes], [enable X11 Xdamage and Xfix
fi fi
} }
dnl Check for QNX photon video driver
CheckPHOTON()
{
AC_ARG_ENABLE(video-photon,
AC_HELP_STRING([--enable-video-photon], [use QNX Photon video driver [[default=yes]]]),
, enable_video_photon=yes)
if test x$enable_video = xyes -a x$enable_video_photon = xyes; then
AC_MSG_CHECKING(for QNX Photon support)
video_photon=no
AC_TRY_COMPILE([
#include <Ph.h>
#include <Pt.h>
#include <photon/Pg.h>
#include <photon/PdDirect.h>
],[
PgDisplaySettings_t *visual;
],[
video_photon=yes
])
AC_MSG_RESULT($video_photon)
if test x$video_photon = xyes; then
AC_DEFINE(SDL_VIDEO_DRIVER_PHOTON)
SOURCES="$SOURCES $srcdir/src/video/photon/*.c"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lph -lphrender"
have_video=yes
CheckOpenGLQNX
fi
fi
}
dnl Check for QNX photon video driver
CheckQNXGF()
{
AC_ARG_ENABLE(video-qnxgf,
AC_HELP_STRING([--enable-video-qnxgf], [use QNX GF video driver [[default=yes]]]),
, enable_video_qnxgf=yes)
if test x$enable_video = xyes -a x$enable_video_qnxgf = xyes; then
AC_MSG_CHECKING(for QNX GF support)
video_qnxgf=no
AC_TRY_COMPILE([
#include <gf/gf.h>
#include <gf/gf3d.h>
],[
gf_3d_config_info_t* gfinfo;
],[
video_qnxgf=yes
])
AC_MSG_RESULT($video_qnxgf)
if test x$video_qnxgf = xyes; then
AC_DEFINE(SDL_VIDEO_DRIVER_QNXGF)
SOURCES="$SOURCES $srcdir/src/video/qnxgf/*.c"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lgf"
# Add HIDDI library for HID support using GF
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lhiddi"
have_video=yes
CheckOpenGLESQNX
fi
fi
}
dnl Set up the BWindow video driver if enabled dnl Set up the BWindow video driver if enabled
CheckBWINDOW() CheckBWINDOW()
{ {
...@@ -1594,65 +1530,6 @@ CheckOpenGLX11() ...@@ -1594,65 +1530,6 @@ CheckOpenGLX11()
fi fi
} }
dnl Find QNX 6.x Software OpenGL
CheckOpenGLQNX()
{
if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then
AC_MSG_CHECKING(for QNX 6.x Photon OpenGL support)
video_opengl=no
AC_TRY_COMPILE([
#include <GL/gl.h>
],[
],[
video_opengl=yes
])
AC_MSG_RESULT($video_opengl)
if test x$video_opengl = xyes; then
AC_DEFINE(SDL_VIDEO_OPENGL)
AC_DEFINE(SDL_VIDEO_RENDER_OGL)
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lGL"
fi
fi
}
dnl Find QNX 6.3 and above OpenGL ES implementation
CheckOpenGLESQNX()
{
if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then
AC_MSG_CHECKING(for QNX OpenGL ES (CM) support)
video_opengl=no
AC_TRY_COMPILE([
#include <GLES/egl.h>
],[
],[
video_opengl=yes
])
AC_MSG_RESULT($video_opengl)
if test x$video_opengl = xyes; then
AC_DEFINE(SDL_VIDEO_OPENGL_ES)
AC_DEFINE(SDL_VIDEO_RENDER_OGL_ES)
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lGLES_CM"
else
AC_MSG_CHECKING(for QNX OpenGL ES (CL) support)
video_opengl=no
AC_TRY_COMPILE([
#define COMMON_LITE
#include <GLES/egl.h>
],[
],[
video_opengl=yes
])
AC_MSG_RESULT($video_opengl)
if test x$video_opengl = xyes; then
AC_DEFINE(SDL_VIDEO_OPENGL_ES)
AC_DEFINE(SDL_VIDEO_RENDER_OGL_ES)
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lGLES_CLS"
fi
fi
fi
}
dnl Check for Windows OpenGL dnl Check for Windows OpenGL
CheckWINDOWSGL() CheckWINDOWSGL()
{ {
...@@ -1796,10 +1673,6 @@ AC_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [[default=yes]]]) ...@@ -1796,10 +1673,6 @@ AC_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [[default=yes]]])
pthread_cflags="-D_REENTRANT" pthread_cflags="-D_REENTRANT"
pthread_lib="-L/usr/lib -lpthread" pthread_lib="-L/usr/lib -lpthread"
;; ;;
*-*-qnx*)
pthread_cflags=""
pthread_lib=""
;;
*-*-osf*) *-*-osf*)
pthread_cflags="-D_REENTRANT" pthread_cflags="-D_REENTRANT"
if test x$ac_cv_prog_gcc = xyes; then if test x$ac_cv_prog_gcc = xyes; then
...@@ -2287,54 +2160,6 @@ case "$host" in ...@@ -2287,54 +2160,6 @@ case "$host" in
have_timers=yes have_timers=yes
fi fi
;; ;;
*-*-qnx*)
EXTRA_CFLAGS="-I/usr/include $CFLAGS"
EXTRA_LDLAGS="-L/usr/lib $LDFLAGS"
ARCH=qnx
CheckVisibilityHidden
CheckDummyVideo
CheckDiskAudio
CheckDummyAudio
CheckDLOPEN
CheckPulseAudio
CheckESD
CheckNAS
CheckPHOTON
CheckQNXGF
CheckX11
CheckOpenGLX11
CheckPTHREAD
CheckClockGettime
# Set up files for the audio library
if test x$enable_audio = xyes; then
AC_DEFINE(SDL_AUDIO_DRIVER_QSA)
SOURCES="$SOURCES $srcdir/src/audio/qsa/*.c"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lasound"
have_audio=yes
fi
# Set up files for the timer library
if test x$enable_timers = xyes; then
AC_DEFINE(SDL_TIMER_UNIX)
SOURCES="$SOURCES $srcdir/src/timer/unix/*.c"
have_timers=yes
fi
# Set up dummy files for the joystick for now
if test x$enable_joystick = xyes; then
AC_DEFINE(SDL_JOYSTICK_DUMMY)
SOURCES="$SOURCES $srcdir/src/joystick/dummy/*.c"
have_joystick=yes
fi
# Set up dummy files for the haptic for now
if test x$enable_haptic = xyes; then
AC_DEFINE(SDL_HAPTIC_DUMMY)
SOURCES="$SOURCES $srcdir/src/haptic/dummy/*.c"
have_haptic=yes
fi
;;
*-wince* | *-mingw32ce) *-wince* | *-mingw32ce)
ARCH=win32 ARCH=win32
CheckDummyVideo CheckDummyVideo
......
...@@ -37,10 +37,6 @@ ...@@ -37,10 +37,6 @@
* level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, * level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL,
* and 2D framebuffer across multiple platforms. * and 2D framebuffer across multiple platforms.
* *
* The current version supports Windows, Windows CE, Mac OS X, Linux,
* FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, and QNX. The code contains
* support for other operating systems but those are not officially supported.
*
* SDL is written in C, but works with C++ natively, and has bindings to * SDL is written in C, but works with C++ natively, and has bindings to
* several other languages, including Ada, C#, Eiffel, Erlang, Euphoria, * several other languages, including Ada, C#, Eiffel, Erlang, Euphoria,
* Guile, Haskell, Java, Lisp, Lua, ML, Objective C, Pascal, Perl, PHP, * Guile, Haskell, Java, Lisp, Lua, ML, Objective C, Pascal, Perl, PHP,
......
...@@ -261,8 +261,6 @@ ...@@ -261,8 +261,6 @@
#undef SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC #undef SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC
#undef SDL_VIDEO_DRIVER_DUMMY #undef SDL_VIDEO_DRIVER_DUMMY
#undef SDL_VIDEO_DRIVER_NDS #undef SDL_VIDEO_DRIVER_NDS
#undef SDL_VIDEO_DRIVER_PHOTON
#undef SDL_VIDEO_DRIVER_QNXGF
#undef SDL_VIDEO_DRIVER_WINDOWS #undef SDL_VIDEO_DRIVER_WINDOWS
#undef SDL_VIDEO_DRIVER_X11 #undef SDL_VIDEO_DRIVER_X11
#undef SDL_VIDEO_DRIVER_X11_DYNAMIC #undef SDL_VIDEO_DRIVER_X11_DYNAMIC
......
...@@ -211,9 +211,6 @@ GL_SetError(const char *prefix, GLenum result) ...@@ -211,9 +211,6 @@ GL_SetError(const char *prefix, GLenum result)
static int static int
GL_LoadFunctions(GL_RenderData * data) GL_LoadFunctions(GL_RenderData * data)
{ {
#if defined(__QNXNTO__) && (_NTO_VERSION < 630)
#define __SDL_NOGETPROCADDR__
#endif
#ifdef __SDL_NOGETPROCADDR__ #ifdef __SDL_NOGETPROCADDR__
#define SDL_PROC(ret,func,params) data->func=func; #define SDL_PROC(ret,func,params) data->func=func;
#else #else
......
...@@ -30,14 +30,7 @@ ...@@ -30,14 +30,7 @@
#include "SDL_rect_c.h" #include "SDL_rect_c.h"
#include "SDL_yuv_sw_c.h" #include "SDL_yuv_sw_c.h"
#if defined(__QNXNTO__) #if defined(SDL_VIDEO_DRIVER_PANDORA)
/* Include QNX system header to check QNX version later */
#include <sys/neutrino.h>
#endif /* __QNXNTO__ */
#if defined(SDL_VIDEO_DRIVER_QNXGF) || \
defined(SDL_VIDEO_DRIVER_PHOTON) || \
defined(SDL_VIDEO_DRIVER_PANDORA)
/* Empty function stub to get OpenGL ES 1.x support without */ /* Empty function stub to get OpenGL ES 1.x support without */
/* OpenGL ES extension GL_OES_draw_texture supported */ /* OpenGL ES extension GL_OES_draw_texture supported */
...@@ -47,7 +40,7 @@ glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height) ...@@ -47,7 +40,7 @@ glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
return; return;
} }
#endif /* QNXGF || PHOTON || PANDORA */ #endif /* PANDORA */
/* OpenGL ES 1.1 renderer implementation, based on the OpenGL renderer */ /* OpenGL ES 1.1 renderer implementation, based on the OpenGL renderer */
...@@ -229,16 +222,6 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -229,16 +222,6 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->info.flags = SDL_RENDERER_ACCELERATED; renderer->info.flags = SDL_RENDERER_ACCELERATED;
#if defined(__QNXNTO__)
#if _NTO_VERSION<=641
/* QNX's OpenGL ES implementation is broken regarding */
/* packed textures support, affected versions 6.3.2, 6.4.0, 6.4.1 */
renderer->info.num_texture_formats = 2;
renderer->info.texture_formats[0] = SDL_PIXELFORMAT_ABGR8888;
renderer->info.texture_formats[1] = SDL_PIXELFORMAT_BGR24;
#endif /* _NTO_VERSION */
#endif /* __QNXNTO__ */
if (GLES_LoadFunctions(data) < 0) { if (GLES_LoadFunctions(data) < 0) {
GLES_DestroyRenderer(renderer); GLES_DestroyRenderer(renderer);
return NULL; return NULL;
......
...@@ -397,30 +397,21 @@ extern VideoBootStrap WINDOWS_bootstrap; ...@@ -397,30 +397,21 @@ extern VideoBootStrap WINDOWS_bootstrap;
#if SDL_VIDEO_DRIVER_BWINDOW #if SDL_VIDEO_DRIVER_BWINDOW
extern VideoBootStrap BWINDOW_bootstrap; extern VideoBootStrap BWINDOW_bootstrap;
#endif #endif
#if SDL_VIDEO_DRIVER_PHOTON #if SDL_VIDEO_DRIVER_PANDORA
extern VideoBootStrap photon_bootstrap; extern VideoBootStrap PND_bootstrap;
#endif
#if SDL_VIDEO_DRIVER_QNXGF
extern VideoBootStrap qnxgf_bootstrap;
#endif
#if SDL_VIDEO_DRIVER_EPOC
extern VideoBootStrap EPOC_bootstrap;
#endif
#if SDL_VIDEO_DRIVER_UIKIT
extern VideoBootStrap UIKIT_bootstrap;
#endif
#if SDL_VIDEO_DRIVER_DUMMY
extern VideoBootStrap DUMMY_bootstrap;
#endif #endif
#if SDL_VIDEO_DRIVER_NDS #if SDL_VIDEO_DRIVER_NDS
extern VideoBootStrap NDS_bootstrap; extern VideoBootStrap NDS_bootstrap;
#endif #endif
#if SDL_VIDEO_DRIVER_PANDORA #if SDL_VIDEO_DRIVER_UIKIT
extern VideoBootStrap PND_bootstrap; extern VideoBootStrap UIKIT_bootstrap;
#endif #endif
#if SDL_VIDEO_DRIVER_ANDROID #if SDL_VIDEO_DRIVER_ANDROID
extern VideoBootStrap Android_bootstrap; extern VideoBootStrap Android_bootstrap;
#endif #endif
#if SDL_VIDEO_DRIVER_DUMMY
extern VideoBootStrap DUMMY_bootstrap;
#endif
#define SDL_CurrentDisplay (&_this->displays[_this->current_display]) #define SDL_CurrentDisplay (&_this->displays[_this->current_display])
......
...@@ -70,14 +70,8 @@ static VideoBootStrap *bootstrap[] = { ...@@ -70,14 +70,8 @@ static VideoBootStrap *bootstrap[] = {
#if SDL_VIDEO_DRIVER_BWINDOW #if SDL_VIDEO_DRIVER_BWINDOW
&BWINDOW_bootstrap, &BWINDOW_bootstrap,
#endif #endif
#if SDL_VIDEO_DRIVER_PHOTON #if SDL_VIDEO_DRIVER_PANDORA
&photon_bootstrap, &PND_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_QNXGF
&qnxgf_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_EPOC
&EPOC_bootstrap,
#endif #endif
#if SDL_VIDEO_DRIVER_NDS #if SDL_VIDEO_DRIVER_NDS
&NDS_bootstrap, &NDS_bootstrap,
...@@ -85,14 +79,11 @@ static VideoBootStrap *bootstrap[] = { ...@@ -85,14 +79,11 @@ static VideoBootStrap *bootstrap[] = {
#if SDL_VIDEO_DRIVER_UIKIT #if SDL_VIDEO_DRIVER_UIKIT
&UIKIT_bootstrap, &UIKIT_bootstrap,
#endif #endif
#if SDL_VIDEO_DRIVER_DUMMY
&DUMMY_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_PANDORA
&PND_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_ANDROID #if SDL_VIDEO_DRIVER_ANDROID
&Android_bootstrap, &Android_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_DUMMY
&DUMMY_bootstrap,
#endif #endif
NULL NULL
}; };
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Photon GUI SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#ifndef __SDL_PHOTON_H__
#define __SDL_PHOTON_H__
/* GF headers must be included first for the Photon GF functions */
#if defined(SDL_VIDEO_OPENGL_ES)
#include <gf/gf.h>
#include <GLES/egl.h>
#endif /* SDL_VIDEO_OPENGL_ES */
#include "SDL_config.h"
#include "../SDL_sysvideo.h"
#include <Ph.h>
#include <Pt.h>
#include <photon/PkKeyDef.h>
/* Maximum display devices, which can handle SDL Photon driver */
#define SDL_VIDEO_PHOTON_MAX_RIDS 16
typedef struct SDL_VideoData
{
PhRid_t rid[SDL_VIDEO_PHOTON_MAX_RIDS];
uint32_t avail_rids;
uint32_t current_device_id;
#if defined(SDL_VIDEO_OPENGL_ES)
gf_dev_t gfdev; /* GF device handle */
gf_dev_info_t gfdev_info; /* GF device information */
SDL_bool gfinitialized; /* GF device initialization status */
EGLDisplay egldisplay; /* OpenGL ES display connection */
uint32_t egl_refcount; /* OpenGL ES reference count */
uint32_t swapinterval; /* OpenGL ES default swap interval */
EGLContext lgles_context; /* Last used OpenGL ES context */
EGLSurface lgles_surface; /* Last used OpenGL ES target surface */
#endif /* SDL_VIDEO_OPENGL_ES */
} SDL_VideoData;
/* This is hardcoded value in photon/Pg.h */
#define SDL_VIDEO_PHOTON_DEVICENAME_MAX 41
#define SDL_VIDEO_PHOTON_MAX_CURSOR_SIZE 128
/* Maximum event message size with data payload */
#define SDL_VIDEO_PHOTON_EVENT_SIZE 8192
/* Current video mode graphics capabilities */
#define SDL_VIDEO_PHOTON_CAP_ALPHA_BLEND 0x00000001
#define SDL_VIDEO_PHOTON_CAP_SCALED_BLIT 0x00000002
typedef struct SDL_DisplayData
{
uint32_t device_id;
uint32_t custom_refresh; /* Custom refresh rate for all modes */
SDL_DisplayMode current_mode; /* Current video mode */
uint8_t description[SDL_VIDEO_PHOTON_DEVICENAME_MAX];
/* Device description */
uint32_t caps; /* Device capabilities */
PhCursorDef_t *cursor; /* Global cursor settings */
SDL_bool cursor_visible; /* SDL_TRUE if cursor visible */
uint32_t cursor_size; /* Cursor size in memory w/ structure */
uint32_t mode_2dcaps; /* Current video mode 2D capabilities */
SDL_bool direct_mode; /* Direct mode state */
#if defined(SDL_VIDEO_OPENGL_ES)
gf_display_t display; /* GF display handle */
gf_display_info_t display_info; /* GF display information */
#endif /* SDL_VIDEO_OPENGL_ES */
} SDL_DisplayData;
/* Maximum amount of OpenGL ES framebuffer configurations */
#define SDL_VIDEO_GF_OPENGLES_CONFS 32
typedef struct SDL_WindowData
{
SDL_bool uses_gles; /* if true window must support OpenGL ES */
PtWidget_t *window; /* window handle */
#if defined(SDL_VIDEO_OPENGL_ES)
EGLConfig gles_configs[SDL_VIDEO_GF_OPENGLES_CONFS];
/* OpenGL ES framebuffer confs */
EGLint gles_config; /* OpenGL ES configuration index */
EGLContext gles_context; /* OpenGL ES context */
EGLint gles_attributes[256]; /* OpenGL ES attributes for context */
EGLSurface gles_surface; /* OpenGL ES target rendering surface */
gf_surface_t gfsurface; /* OpenGL ES GF's surface */
PdOffscreenContext_t *phsurface; /* OpenGL ES Photon's surface */
#endif /* SDL_VIDEO_OPENGL_ES */
} SDL_WindowData;
/****************************************************************************/
/* Low level Photon graphics driver capabilities */
/****************************************************************************/
typedef struct Photon_DeviceCaps
{
uint8_t *name;
uint32_t caps;
} Photon_DeviceCaps;
#define SDL_PHOTON_UNACCELERATED 0x00000000
#define SDL_PHOTON_ACCELERATED 0x00000001
#define SDL_PHOTON_UNACCELERATED_3D 0x00000000
#define SDL_PHOTON_ACCELERATED_3D 0x00000004
/****************************************************************************/
/* SDL_VideoDevice functions declaration */
/****************************************************************************/
/* Display and window functions */
int photon_videoinit(_THIS);
void photon_videoquit(_THIS);
void photon_getdisplaymodes(_THIS);
int photon_setdisplaymode(_THIS, SDL_DisplayMode * mode);
int photon_setdisplaygammaramp(_THIS, Uint16 * ramp);
int photon_getdisplaygammaramp(_THIS, Uint16 * ramp);
int photon_createwindow(_THIS, SDL_Window * window);
int photon_createwindowfrom(_THIS, SDL_Window * window, const void *data);
void photon_setwindowtitle(_THIS, SDL_Window * window);
void photon_setwindowicon(_THIS, SDL_Window * window, SDL_Surface * icon);
void photon_setwindowposition(_THIS, SDL_Window * window);
void photon_setwindowsize(_THIS, SDL_Window * window);
void photon_showwindow(_THIS, SDL_Window * window);
void photon_hidewindow(_THIS, SDL_Window * window);
void photon_raisewindow(_THIS, SDL_Window * window);
void photon_maximizewindow(_THIS, SDL_Window * window);
void photon_minimizewindow(_THIS, SDL_Window * window);
void photon_restorewindow(_THIS, SDL_Window * window);
void photon_setwindowgrab(_THIS, SDL_Window * window);
void photon_destroywindow(_THIS, SDL_Window * window);
/* Window manager function */
SDL_bool photon_getwindowwminfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo *info);
/* OpenGL/OpenGL ES functions */
int photon_gl_loadlibrary(_THIS, const char *path);
void *photon_gl_getprocaddres(_THIS, const char *proc);
void photon_gl_unloadlibrary(_THIS);
SDL_GLContext photon_gl_createcontext(_THIS, SDL_Window * window);
int photon_gl_makecurrent(_THIS, SDL_Window * window, SDL_GLContext context);
int photon_gl_setswapinterval(_THIS, int interval);
int photon_gl_getswapinterval(_THIS);
void photon_gl_swapwindow(_THIS, SDL_Window * window);
void photon_gl_deletecontext(_THIS, SDL_GLContext context);
/* Helper function, which re-creates surface, not an API */
int photon_gl_recreatesurface(_THIS, SDL_Window * window, uint32_t width, uint32_t height);
/* Event handling function */
void photon_pumpevents(_THIS);
/* Screen saver related function */
void photon_suspendscreensaver(_THIS);
#endif /* __SDL_PHOTON_H__ */
/* vi: set ts=4 sw=4 expandtab: */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Photon GUI SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#include "SDL_photon_input.h"
#include "SDL_config.h"
#include "SDL_events.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_keyboard_c.h"
#include "SDL_photon_keycodes.h"
/* Mouse related functions */
SDL_Cursor *photon_createcursor(SDL_Surface * surface, int hot_x, int hot_y);
int photon_showcursor(SDL_Cursor * cursor);
void photon_movecursor(SDL_Cursor * cursor);
void photon_freecursor(SDL_Cursor * cursor);
void photon_warpmouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y);
void photon_freemouse(SDL_Mouse * mouse);
int32_t
photon_addinputdevices(_THIS)
{
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
SDL_DisplayData *didata = NULL;
struct SDL_Mouse photon_mouse;
SDL_MouseData *mdata = NULL;
SDL_Keyboard photon_keyboard;
SDLKey keymap[SDL_NUM_SCANCODES];
uint32_t it;
for (it = 0; it < _this->num_displays; it++) {
SDL_VideoDisplay *display = &_this->displays[it];
/* Clear SDL mouse structure */
SDL_memset(&photon_mouse, 0x00, sizeof(struct SDL_Mouse));
/* Allocate SDL_MouseData structure */
mdata = (SDL_MouseData *) SDL_calloc(1, sizeof(SDL_MouseData));
if (mdata == NULL) {
SDL_OutOfMemory();
return -1;
}
/* Mark this mouse with ID 0 */
photon_mouse.id = it;
photon_mouse.driverdata = (void *) mdata;
photon_mouse.CreateCursor = photon_createcursor;
photon_mouse.ShowCursor = photon_showcursor;
photon_mouse.MoveCursor = photon_movecursor;
photon_mouse.FreeCursor = photon_freecursor;
photon_mouse.WarpMouse = photon_warpmouse;
photon_mouse.FreeMouse = photon_freemouse;
/* Get display data */
didata = (SDL_DisplayData *) display->driverdata;
/* Store SDL_DisplayData pointer in the mouse driver internals */
mdata->didata = didata;
/* Register mouse cursor in SDL */
SDL_AddMouse(&photon_mouse, "Photon mouse cursor", 0, 0, 1);
}
/* Photon maps all keyboards to one */
SDL_zero(photon_keyboard);
SDL_AddKeyboard(&photon_keyboard, -1);
/* Add default scancode to key mapping */
SDL_GetDefaultKeymap(keymap);
SDL_SetKeymap(0, 0, keymap, SDL_NUM_SCANCODES);
return 0;
}
int32_t
photon_delinputdevices(_THIS)
{
/* Destroy all of the mice */
SDL_MouseQuit();
}
/*****************************************************************************/
/* Photon mouse related functions */
/*****************************************************************************/
SDL_Cursor *
photon_createcursor(SDL_Surface * surface, int hot_x, int hot_y)
{
PhCursorDef_t *internal_cursor;
SDL_Cursor *sdl_cursor;
uint8_t *image0 = NULL;
uint8_t *image1 = NULL;
uint32_t it;
uint32_t jt;
uint32_t shape_color;
/* SDL converts monochrome cursor shape to 32bpp cursor shape */
/* and we must convert it back to monochrome, this routine handles */
/* 24/32bpp surfaces only */
if ((surface->format->BitsPerPixel != 32)
&& (surface->format->BitsPerPixel != 24)) {
SDL_SetError("Photon: Cursor shape is not 24/32bpp.");
return NULL;
}
/* Checking data parameters */
if ((surface->w == 0) || (surface->h == 0)) {
SDL_SetError("Photon: Cursor shape dimensions are zero");
return NULL;
}
/* Allocate memory for the internal cursor format */
internal_cursor = (PhCursorDef_t *) SDL_calloc(1, sizeof(PhCursorDef_t) +
((((surface->w +
7) >> 3) *
surface->h) * 2) - 1);
if (internal_cursor == NULL) {
SDL_OutOfMemory();
return NULL;
}
/* Allocate memory for the SDL cursor */
sdl_cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(SDL_Cursor));
if (sdl_cursor == NULL) {
SDL_free(internal_cursor);
SDL_OutOfMemory();
return NULL;
}
/* Set driverdata as photon cursor format */
image0 = (uint8_t *) internal_cursor;
image0 += sizeof(PhCursorDef_t) - 1;
image1 = image0;
image1 += ((surface->w + 7) >> 3) * surface->h;
sdl_cursor->driverdata = (void *) internal_cursor;
internal_cursor->hdr.len =
(sizeof(PhCursorDef_t) - sizeof(PhRegionDataHdr_t)) +
((((surface->w + 7) >> 3) * surface->h) * 2) - 1;
internal_cursor->hdr.type = Ph_RDATA_CURSOR;
internal_cursor->size1.x = surface->w;
internal_cursor->size1.y = surface->h;
internal_cursor->size2.x = surface->w;
internal_cursor->size2.y = surface->h;
internal_cursor->offset1.x = -hot_x;
internal_cursor->offset1.y = -hot_y;
internal_cursor->offset2.x = -hot_x;
internal_cursor->offset2.y = -hot_y;
internal_cursor->bytesperline1 = ((surface->w + 7) >> 3);
internal_cursor->bytesperline2 = ((surface->w + 7) >> 3);
internal_cursor->color1 = (SDL_PHOTON_MOUSE_COLOR_BLACK) & 0x00FFFFFF;
internal_cursor->color2 = (SDL_PHOTON_MOUSE_COLOR_WHITE) & 0x00FFFFFF;
/* Convert cursor from 32 bpp */
for (jt = 0; jt < surface->h; jt++) {
for (it = 0; it < surface->w; it++) {
shape_color =
*((uint32_t *) ((uint8_t *) surface->pixels +
jt * surface->pitch +
it * surface->format->BytesPerPixel));
switch (shape_color) {
case SDL_PHOTON_MOUSE_COLOR_BLACK:
{
*(image0 + jt * (internal_cursor->bytesperline1) +
(it >> 3)) |= 0x80 >> (it % 8);
*(image1 + jt * (internal_cursor->bytesperline2) +
(it >> 3)) &= ~(0x80 >> (it % 8));
}
break;
case SDL_PHOTON_MOUSE_COLOR_WHITE:
{
*(image0 + jt * (internal_cursor->bytesperline1) +
(it >> 3)) &= ~(0x80 >> (it % 8));
*(image1 + jt * (internal_cursor->bytesperline2) +
(it >> 3)) |= 0x80 >> (it % 8);
}
break;
case SDL_PHOTON_MOUSE_COLOR_TRANS:
{
*(image0 + jt * (internal_cursor->bytesperline1) +
(it >> 3)) &= ~(0x80 >> (it % 8));
*(image1 + jt * (internal_cursor->bytesperline2) +
(it >> 3)) &= ~(0x80 >> (it % 8));
}
break;
default:
{
/* The same as transparent color, must not happen */
*(image0 + jt * (internal_cursor->bytesperline1) +
(it >> 3)) &= ~(0x80 >> (it % 8));
*(image1 + jt * (internal_cursor->bytesperline2) +
(it >> 3)) &= ~(0x80 >> (it % 8));
}
break;
}
}
}
return sdl_cursor;
}
int
photon_showcursor(SDL_Cursor * cursor)
{
SDL_VideoDisplay *display;
SDL_DisplayData *didata;
SDL_Window *window;
SDL_WindowData *wdata;
PhCursorDef_t *internal_cursor;
int32_t status;
/* Get current window id */
window = SDL_GetFocusWindow();
if (!window) {
SDL_MouseData *mdata = NULL;
/* If there is no current window, then someone calls this function */
/* to set global mouse settings during SDL initialization */
if (cursor != NULL) {
/* Store cursor for future usage */
mdata = (SDL_MouseData *) cursor->mouse->driverdata;
didata = (SDL_DisplayData *) mdata->didata;
internal_cursor = (PhCursorDef_t *) cursor->driverdata;
if (didata->cursor_size >=
(internal_cursor->hdr.len + sizeof(PhRegionDataHdr_t))) {
SDL_memcpy(didata->cursor, internal_cursor,
internal_cursor->hdr.len +
sizeof(PhRegionDataHdr_t));
} else {
/* Partitial cursor image */
SDL_memcpy(didata->cursor, internal_cursor,
didata->cursor_size);
}
didata->cursor_visible = SDL_TRUE;
return 0;
} else {
/* We can't get SDL_DisplayData at this point, return fake success */
return 0;
}
} else {
/* Sanity checks */
display = window->display;
if (display != NULL) {
didata = (SDL_DisplayData *) display->driverdata;
if (didata != NULL) {
wdata = (SDL_WindowData *) window->driverdata;
if (wdata == NULL) {
return -1;
}
} else {
return -1;
}
} else {
return -1;
}
}
/* return if window widget has been destroyed already */
if (wdata->window == NULL) {
return;
}
/* Check if we need to set new shape or disable cursor shape */
if (cursor != NULL) {
/* Retrieve photon cursor shape */
internal_cursor = (PhCursorDef_t *) cursor->driverdata;
if (internal_cursor == NULL) {
SDL_SetError("Photon: Internal cursor data is absent");
return -1;
}
/* Setup cursor type */
status =
PtSetResource(wdata->window, Pt_ARG_CURSOR_TYPE, Ph_CURSOR_BITMAP,
0);
if (status != 0) {
SDL_SetError("Photon: Failed to set cursor type to bitmap");
return -1;
}
/* Setup cursor color to default */
status =
PtSetResource(wdata->window, Pt_ARG_CURSOR_COLOR,
Ph_CURSOR_DEFAULT_COLOR, 0);
if (status != 0) {
SDL_SetError("Photon: Failed to set cursor color");
return -1;
}
/* Setup cursor shape */
status =
PtSetResource(wdata->window, Pt_ARG_BITMAP_CURSOR,
internal_cursor,
internal_cursor->hdr.len +
sizeof(PhRegionDataHdr_t));
if (status != 0) {
SDL_SetError("Photon: Failed to set cursor color");
return -1;
}
/* Store current cursor for future usage */
if (didata->cursor_size >=
(internal_cursor->hdr.len + sizeof(PhRegionDataHdr_t))) {
SDL_memcpy(didata->cursor, internal_cursor,
internal_cursor->hdr.len + sizeof(PhRegionDataHdr_t));
} else {
/* Partitial cursor image */
SDL_memcpy(didata->cursor, internal_cursor, didata->cursor_size);
}
/* Set cursor visible */
didata->cursor_visible = SDL_TRUE;
} else {
/* SDL requests to disable cursor */
status =
PtSetResource(wdata->window, Pt_ARG_CURSOR_TYPE, Ph_CURSOR_NONE,
0);
if (status != 0) {
SDL_SetError("Photon: Can't disable cursor");
return -1;
}
/* Set cursor invisible */
didata->cursor_visible = SDL_FALSE;
}
/* Flush all pending widget data */
PtFlush();
/* New cursor shape is set */
return 0;
}
void
photon_movecursor(SDL_Cursor * cursor)
{
SDL_VideoDisplay *display;
SDL_DisplayData *didata;
SDL_Window *window;
SDL_WindowData *wdata;
SDL_WindowID window_id;
int32_t status;
/* Get current window id */
window_id = SDL_GetFocusWindow();
if (window_id <= 0) {
didata = (SDL_DisplayData *) cursor->mouse->driverdata;
} else {
/* Sanity checks */
window = SDL_GetWindowFromID(window_id);
if (window != NULL) {
display = window->display;
if (display != NULL) {
didata = (SDL_DisplayData *) display->driverdata;
if (didata != NULL) {
wdata = (SDL_WindowData *) window->driverdata;
if (wdata == NULL) {
return;
}
} else {
return;
}
} else {
return;
}
} else {
return;
}
}
/* No need to move mouse cursor manually in the photon */
return;
}
void
photon_freecursor(SDL_Cursor * cursor)
{
PhCursorDef_t *internal_cursor = NULL;
if (cursor != NULL) {
internal_cursor = (PhCursorDef_t *) cursor->driverdata;
if (internal_cursor != NULL) {
SDL_free(internal_cursor);
cursor->driverdata = NULL;
}
}
}
void
photon_warpmouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y)
{
SDL_VideoDisplay *display;
SDL_DisplayData *didata;
SDL_WindowData *wdata;
int16_t wx;
int16_t wy;
/* Sanity checks */
if (window != NULL) {
display = window->display;
if (display != NULL) {
didata = (SDL_DisplayData *) display->driverdata;
if (didata != NULL) {
wdata = (SDL_WindowData *) window->driverdata;
if (wdata == NULL) {
return;
}
} else {
return;
}
} else {
return;
}
} else {
return;
}
PtGetAbsPosition(wdata->window, &wx, &wy);
PhMoveCursorAbs(PhInputGroup(NULL), wx + x, wy + y);
return;
}
void
photon_freemouse(SDL_Mouse * mouse)
{
if (mouse->driverdata == NULL) {
return;
}
/* Mouse framework doesn't deletes automatically our driverdata */
SDL_free(mouse->driverdata);
mouse->driverdata = NULL;
return;
}
SDL_ScanCode
photon_to_sdl_keymap(uint32_t key)
{
SDL_ScanCode scancode = SDL_SCANCODE_UNKNOWN;
switch (key & 0x0000007F) {
case PHOTON_SCANCODE_ESCAPE:
scancode = SDL_SCANCODE_ESCAPE;
break;
case PHOTON_SCANCODE_F1:
scancode = SDL_SCANCODE_F1;
break;
case PHOTON_SCANCODE_F2:
scancode = SDL_SCANCODE_F2;
break;
case PHOTON_SCANCODE_F3:
scancode = SDL_SCANCODE_F3;
break;
case PHOTON_SCANCODE_F4:
scancode = SDL_SCANCODE_F4;
break;
case PHOTON_SCANCODE_F5:
scancode = SDL_SCANCODE_F5;
break;
case PHOTON_SCANCODE_F6:
scancode = SDL_SCANCODE_F6;
break;
case PHOTON_SCANCODE_F7:
scancode = SDL_SCANCODE_F7;
break;
case PHOTON_SCANCODE_F8:
scancode = SDL_SCANCODE_F8;
break;
case PHOTON_SCANCODE_F9:
scancode = SDL_SCANCODE_F9;
break;
case PHOTON_SCANCODE_F10:
scancode = SDL_SCANCODE_F10;
break;
case PHOTON_SCANCODE_F11:
scancode = SDL_SCANCODE_F11;
break;
case PHOTON_SCANCODE_F12:
scancode = SDL_SCANCODE_F12;
break;
case PHOTON_SCANCODE_BACKQOUTE:
scancode = SDL_SCANCODE_GRAVE;
break;
case PHOTON_SCANCODE_1:
scancode = SDL_SCANCODE_1;
break;
case PHOTON_SCANCODE_2:
scancode = SDL_SCANCODE_2;
break;
case PHOTON_SCANCODE_3:
scancode = SDL_SCANCODE_3;
break;
case PHOTON_SCANCODE_4:
scancode = SDL_SCANCODE_4;
break;
case PHOTON_SCANCODE_5:
scancode = SDL_SCANCODE_5;
break;
case PHOTON_SCANCODE_6:
scancode = SDL_SCANCODE_6;
break;
case PHOTON_SCANCODE_7:
scancode = SDL_SCANCODE_7;
break;
case PHOTON_SCANCODE_8:
scancode = SDL_SCANCODE_8;
break;
case PHOTON_SCANCODE_9:
scancode = SDL_SCANCODE_9;
break;
case PHOTON_SCANCODE_0:
scancode = SDL_SCANCODE_0;
break;
case PHOTON_SCANCODE_MINUS:
scancode = SDL_SCANCODE_MINUS;
break;
case PHOTON_SCANCODE_EQUAL:
scancode = SDL_SCANCODE_EQUALS;
break;
case PHOTON_SCANCODE_BACKSPACE:
scancode = SDL_SCANCODE_BACKSPACE;
break;
case PHOTON_SCANCODE_TAB:
scancode = SDL_SCANCODE_TAB;
break;
case PHOTON_SCANCODE_Q:
scancode = SDL_SCANCODE_Q;
break;
case PHOTON_SCANCODE_W:
scancode = SDL_SCANCODE_W;
break;
case PHOTON_SCANCODE_E:
scancode = SDL_SCANCODE_E;
break;
case PHOTON_SCANCODE_R:
scancode = SDL_SCANCODE_R;
break;
case PHOTON_SCANCODE_T:
scancode = SDL_SCANCODE_T;
break;
case PHOTON_SCANCODE_Y:
scancode = SDL_SCANCODE_Y;
break;
case PHOTON_SCANCODE_U:
scancode = SDL_SCANCODE_U;
break;
case PHOTON_SCANCODE_I:
scancode = SDL_SCANCODE_I;
break;
case PHOTON_SCANCODE_O:
scancode = SDL_SCANCODE_O;
break;
case PHOTON_SCANCODE_P:
scancode = SDL_SCANCODE_P;
break;
case PHOTON_SCANCODE_LEFT_SQ_BR:
scancode = SDL_SCANCODE_LEFTBRACKET;
break;
case PHOTON_SCANCODE_RIGHT_SQ_BR:
scancode = SDL_SCANCODE_RIGHTBRACKET;
break;
case PHOTON_SCANCODE_ENTER:
scancode = SDL_SCANCODE_RETURN;
break;
case PHOTON_SCANCODE_CAPSLOCK:
scancode = SDL_SCANCODE_CAPSLOCK;
break;
case PHOTON_SCANCODE_A:
scancode = SDL_SCANCODE_A;
break;
case PHOTON_SCANCODE_S:
scancode = SDL_SCANCODE_S;
break;
case PHOTON_SCANCODE_D:
scancode = SDL_SCANCODE_D;
break;
case PHOTON_SCANCODE_F:
scancode = SDL_SCANCODE_F;
break;
case PHOTON_SCANCODE_G:
scancode = SDL_SCANCODE_G;
break;
case PHOTON_SCANCODE_H:
scancode = SDL_SCANCODE_H;
break;
case PHOTON_SCANCODE_J:
scancode = SDL_SCANCODE_J;
break;
case PHOTON_SCANCODE_K:
scancode = SDL_SCANCODE_K;
break;
case PHOTON_SCANCODE_L:
scancode = SDL_SCANCODE_L;
break;
case PHOTON_SCANCODE_SEMICOLON:
scancode = SDL_SCANCODE_SEMICOLON;
break;
case PHOTON_SCANCODE_QUOTE:
scancode = SDL_SCANCODE_APOSTROPHE;
break;
case PHOTON_SCANCODE_BACKSLASH:
scancode = SDL_SCANCODE_BACKSLASH;
break;
case PHOTON_SCANCODE_LEFT_SHIFT:
scancode = SDL_SCANCODE_LSHIFT;
break;
case PHOTON_SCANCODE_Z:
scancode = SDL_SCANCODE_Z;
break;
case PHOTON_SCANCODE_X:
scancode = SDL_SCANCODE_X;
break;
case PHOTON_SCANCODE_C:
scancode = SDL_SCANCODE_C;
break;
case PHOTON_SCANCODE_V:
scancode = SDL_SCANCODE_V;
break;
case PHOTON_SCANCODE_B:
scancode = SDL_SCANCODE_B;
break;
case PHOTON_SCANCODE_N:
scancode = SDL_SCANCODE_N;
break;
case PHOTON_SCANCODE_M:
scancode = SDL_SCANCODE_M;
break;
case PHOTON_SCANCODE_COMMA:
scancode = SDL_SCANCODE_COMMA;
break;
case PHOTON_SCANCODE_POINT:
scancode = SDL_SCANCODE_PERIOD;
break;
case PHOTON_SCANCODE_SLASH:
scancode = SDL_SCANCODE_SLASH;
break;
case PHOTON_SCANCODE_RIGHT_SHIFT:
scancode = SDL_SCANCODE_RSHIFT;
break;
case PHOTON_SCANCODE_CTRL:
scancode = SDL_SCANCODE_LCTRL;
break;
case PHOTON_SCANCODE_WFLAG:
scancode = SDL_SCANCODE_LGUI;
break;
case PHOTON_SCANCODE_ALT:
scancode = SDL_SCANCODE_LALT;
break;
case PHOTON_SCANCODE_SPACE:
scancode = SDL_SCANCODE_SPACE;
break;
case PHOTON_SCANCODE_MENU:
scancode = SDL_SCANCODE_MENU;
break;
case PHOTON_SCANCODE_PRNSCR:
scancode = SDL_SCANCODE_PRINTSCREEN;
break;
case PHOTON_SCANCODE_SCROLLLOCK:
scancode = SDL_SCANCODE_SCROLLLOCK;
break;
case PHOTON_SCANCODE_INSERT:
scancode = SDL_SCANCODE_INSERT;
break;
case PHOTON_SCANCODE_HOME:
scancode = SDL_SCANCODE_HOME;
break;
case PHOTON_SCANCODE_PAGEUP:
scancode = SDL_SCANCODE_PAGEUP;
break;
case PHOTON_SCANCODE_DELETE:
scancode = SDL_SCANCODE_DELETE;
break;
case PHOTON_SCANCODE_END:
scancode = SDL_SCANCODE_END;
break;
case PHOTON_SCANCODE_PAGEDOWN:
scancode = SDL_SCANCODE_PAGEDOWN;
break;
case PHOTON_SCANCODE_UP:
scancode = SDL_SCANCODE_UP;
break;
case PHOTON_SCANCODE_DOWN:
scancode = SDL_SCANCODE_DOWN;
break;
case PHOTON_SCANCODE_LEFT:
scancode = SDL_SCANCODE_LEFT;
break;
case PHOTON_SCANCODE_RIGHT:
scancode = SDL_SCANCODE_RIGHT;
break;
case PHOTON_SCANCODE_NUMLOCK:
scancode = SDL_SCANCODE_NUMLOCKCLEAR;
break;
default:
break;
}
return scancode;
}
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Photon GUI SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#ifndef __SDL_PHOTON_INPUT_H__
#define __SDL_PHOTON_INPUT_H__
#include "SDL_config.h"
#include "SDL_video.h"
#include "../SDL_sysvideo.h"
#include "SDL_photon.h"
typedef struct SDL_MouseData
{
SDL_DisplayData *didata;
} SDL_MouseData;
int32_t photon_addinputdevices(_THIS);
int32_t photon_delinputdevices(_THIS);
#define SDL_PHOTON_MOUSE_COLOR_BLACK 0xFF000000
#define SDL_PHOTON_MOUSE_COLOR_WHITE 0xFFFFFFFF
#define SDL_PHOTON_MOUSE_COLOR_TRANS 0x00000000
SDL_ScanCode photon_to_sdl_keymap(uint32_t key);
#endif /* __SDL_GF_INPUT_H__ */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Photon GUI SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#ifndef __SDL_PHOTON_KEYCODES_H__
#define __SDL_PHOTON_KEYCODES_H__
#define PHOTON_SCANCODE_ESCAPE 0x01
#define PHOTON_SCANCODE_F1 0x3B
#define PHOTON_SCANCODE_F2 0x3C
#define PHOTON_SCANCODE_F3 0x3D
#define PHOTON_SCANCODE_F4 0x3E
#define PHOTON_SCANCODE_F5 0x3F
#define PHOTON_SCANCODE_F6 0x40
#define PHOTON_SCANCODE_F7 0x41
#define PHOTON_SCANCODE_F8 0x42
#define PHOTON_SCANCODE_F9 0x43
#define PHOTON_SCANCODE_F10 0x44
#define PHOTON_SCANCODE_F11 0x57
#define PHOTON_SCANCODE_F12 0x58
#define PHOTON_SCANCODE_BACKQOUTE 0x29
#define PHOTON_SCANCODE_1 0x02
#define PHOTON_SCANCODE_2 0x03
#define PHOTON_SCANCODE_3 0x04
#define PHOTON_SCANCODE_4 0x05
#define PHOTON_SCANCODE_5 0x06
#define PHOTON_SCANCODE_6 0x07
#define PHOTON_SCANCODE_7 0x08
#define PHOTON_SCANCODE_8 0x09
#define PHOTON_SCANCODE_9 0x0A
#define PHOTON_SCANCODE_0 0x0B
#define PHOTON_SCANCODE_MINUS 0x0C
#define PHOTON_SCANCODE_EQUAL 0x0D
#define PHOTON_SCANCODE_BACKSPACE 0x0E
#define PHOTON_SCANCODE_TAB 0x0F
#define PHOTON_SCANCODE_Q 0x10
#define PHOTON_SCANCODE_W 0x11
#define PHOTON_SCANCODE_E 0x12
#define PHOTON_SCANCODE_R 0x13
#define PHOTON_SCANCODE_T 0x14
#define PHOTON_SCANCODE_Y 0x15
#define PHOTON_SCANCODE_U 0x16
#define PHOTON_SCANCODE_I 0x17
#define PHOTON_SCANCODE_O 0x18
#define PHOTON_SCANCODE_P 0x19
#define PHOTON_SCANCODE_LEFT_SQ_BR 0x1A
#define PHOTON_SCANCODE_RIGHT_SQ_BR 0x1B
#define PHOTON_SCANCODE_ENTER 0x1C
#define PHOTON_SCANCODE_CAPSLOCK 0x3A
#define PHOTON_SCANCODE_A 0x1E
#define PHOTON_SCANCODE_S 0x1F
#define PHOTON_SCANCODE_D 0x20
#define PHOTON_SCANCODE_F 0x21
#define PHOTON_SCANCODE_G 0x22
#define PHOTON_SCANCODE_H 0x23
#define PHOTON_SCANCODE_J 0x24
#define PHOTON_SCANCODE_K 0x25
#define PHOTON_SCANCODE_L 0x26
#define PHOTON_SCANCODE_SEMICOLON 0x27
#define PHOTON_SCANCODE_QUOTE 0x28
#define PHOTON_SCANCODE_BACKSLASH 0x2B
#define PHOTON_SCANCODE_LEFT_SHIFT 0x2A
#define PHOTON_SCANCODE_Z 0x2C
#define PHOTON_SCANCODE_X 0x2D
#define PHOTON_SCANCODE_C 0x2E
#define PHOTON_SCANCODE_V 0x2F
#define PHOTON_SCANCODE_B 0x30
#define PHOTON_SCANCODE_N 0x31
#define PHOTON_SCANCODE_M 0x32
#define PHOTON_SCANCODE_COMMA 0x33
#define PHOTON_SCANCODE_POINT 0x34
#define PHOTON_SCANCODE_SLASH 0x35
#define PHOTON_SCANCODE_RIGHT_SHIFT 0x36
#define PHOTON_SCANCODE_CTRL 0x1D
#define PHOTON_SCANCODE_WFLAG 0x5B
#define PHOTON_SCANCODE_ALT 0x38
#define PHOTON_SCANCODE_SPACE 0x39
#define PHOTON_SCANCODE_MENU 0x5D
#define PHOTON_SCANCODE_PRNSCR 0x54 /* only key pressed event, no release */
#define PHOTON_SCANCODE_SCROLLLOCK 0x46
#if 0 /* pause doesn't generates a scancode */
#define PHOTON_SCANCODE_PAUSE 0x??
#endif
#define PHOTON_SCANCODE_INSERT 0x52
#define PHOTON_SCANCODE_HOME 0x47
#define PHOTON_SCANCODE_PAGEUP 0x49
#define PHOTON_SCANCODE_DELETE 0x53
#define PHOTON_SCANCODE_END 0x4F
#define PHOTON_SCANCODE_PAGEDOWN 0x51
#define PHOTON_SCANCODE_UP 0x48
#define PHOTON_SCANCODE_DOWN 0x50
#define PHOTON_SCANCODE_LEFT 0x4B
#define PHOTON_SCANCODE_RIGHT 0x4D
#define PHOTON_SCANCODE_NUMLOCK 0x45
#endif /* __SDL_PHOTON_KEYCODES_H__ */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Photon GUI SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#include "SDL_photon_pixelfmt.h"
uint32_t
photon_bits_to_sdl_pixelformat(uint32_t pixelfmt)
{
switch (pixelfmt) {
case 8:
{
return SDL_PIXELFORMAT_INDEX8;
}
break;
case 15:
{
return SDL_PIXELFORMAT_ARGB1555;
}
break;
case 16:
{
return SDL_PIXELFORMAT_RGB565;
}
break;
case 24:
{
return SDL_PIXELFORMAT_RGB888;
}
break;
case 32:
{
return SDL_PIXELFORMAT_ARGB8888;
}
break;
}
}
uint32_t
photon_sdl_to_bits_pixelformat(uint32_t pixelfmt)
{
switch (pixelfmt) {
case SDL_PIXELFORMAT_INDEX8:
{
return 8;
}
break;
case SDL_PIXELFORMAT_ARGB1555:
{
return 15;
}
break;
case SDL_PIXELFORMAT_RGB555:
{
return 15;
}
break;
case SDL_PIXELFORMAT_ABGR1555:
{
return 15;
}
break;
case SDL_PIXELFORMAT_RGB565:
{
return 16;
}
break;
case SDL_PIXELFORMAT_RGB24:
{
return 24;
}
break;
case SDL_PIXELFORMAT_RGB888:
{
return 32;
}
break;
case SDL_PIXELFORMAT_BGRA8888:
{
return 32;
}
break;
case SDL_PIXELFORMAT_ARGB8888:
{
return 32;
}
break;
case SDL_PIXELFORMAT_YV12:
{
return 8;
}
break;
case SDL_PIXELFORMAT_YUY2:
{
return 16;
}
break;
case SDL_PIXELFORMAT_UYVY:
{
return 16;
}
break;
case SDL_PIXELFORMAT_YVYU:
{
return 16;
}
break;
}
return 0;
}
uint32_t
photon_image_to_sdl_pixelformat(uint32_t pixelfmt)
{
switch (pixelfmt) {
case Pg_IMAGE_PALETTE_BYTE:
{
return SDL_PIXELFORMAT_INDEX8;
}
break;
case Pg_IMAGE_DIRECT_8888:
{
return SDL_PIXELFORMAT_ARGB8888;
}
break;
case Pg_IMAGE_DIRECT_888:
{
return SDL_PIXELFORMAT_RGB24;
}
break;
case Pg_IMAGE_DIRECT_565:
{
return SDL_PIXELFORMAT_RGB565;
}
break;
case Pg_IMAGE_DIRECT_555:
{
return SDL_PIXELFORMAT_RGB555;
}
break;
case Pg_IMAGE_DIRECT_1555:
{
return SDL_PIXELFORMAT_ARGB1555;
}
break;
}
return 0;
}
uint32_t
photon_sdl_to_image_pixelformat(uint32_t pixelfmt)
{
switch (pixelfmt) {
case SDL_PIXELFORMAT_INDEX8:
{
return Pg_IMAGE_PALETTE_BYTE;
}
break;
case SDL_PIXELFORMAT_ARGB8888:
{
return Pg_IMAGE_DIRECT_8888;
}
break;
case SDL_PIXELFORMAT_RGB888:
{
return Pg_IMAGE_DIRECT_8888;
}
break;
case SDL_PIXELFORMAT_RGB24:
{
return Pg_IMAGE_DIRECT_888;
}
break;
case SDL_PIXELFORMAT_RGB565:
{
return Pg_IMAGE_DIRECT_565;
}
break;
case SDL_PIXELFORMAT_ARGB1555:
{
return Pg_IMAGE_DIRECT_1555;
}
break;
case SDL_PIXELFORMAT_RGB555:
{
return Pg_IMAGE_DIRECT_555;
}
break;
}
return 0;
}
/* vi: set ts=4 sw=4 expandtab: */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Photon GUI SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#include "SDL_config.h"
#include "../SDL_sysvideo.h"
#include <Ph.h>
#ifndef __SDL_PHOTON_PIXELFMT_H__
#define __SDL_PHOTON_PIXELFMT_H__
uint32_t photon_bits_to_sdl_pixelformat(uint32_t pixelfmt);
uint32_t photon_sdl_to_bits_pixelformat(uint32_t pixelfmt);
uint32_t photon_image_to_sdl_pixelformat(uint32_t pixelfmt);
uint32_t photon_sdl_to_image_pixelformat(uint32_t pixelfmt);
#endif /* __SDL_PHOTON_PIXELFMT_H__ */
/* vi: set ts=4 sw=4 expandtab: */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Photon GUI SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#include "SDL_config.h"
#include "../SDL_pixels_c.h"
#include "../SDL_yuv_sw_c.h"
#include "SDL_video.h"
#include "SDL_photon_render.h"
#include "SDL_photon.h"
#ifndef Pg_OSC_MEM_LINEAR_ACCESSIBLE
/* For QNX 6.3.2 compatibility */
#define Pg_OSC_MEM_LINEAR_ACCESSIBLE 0
#endif /* Pg_OSC_MEM_LINEAR_ACCESSIBLE */
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_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_renderreadpixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 format, void * pixels, int pitch);
static int photon_renderwritepixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 format, const void * pixels, int pitch);
static void photon_renderpresent(SDL_Renderer * renderer);
static void photon_destroytexture(SDL_Renderer * renderer,
SDL_Texture * texture);
static void photon_destroyrenderer(SDL_Renderer * renderer);
static int _photon_recreate_surfaces(SDL_Renderer * renderer);
SDL_RenderDriver photon_renderdriver = {
photon_createrenderer,
{
"photon",
(SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_PRESENTDISCARD |
SDL_RENDERER_ACCELERATED),
9,
{SDL_PIXELFORMAT_RGB555,
SDL_PIXELFORMAT_RGB565,
SDL_PIXELFORMAT_RGB24,
SDL_PIXELFORMAT_RGB888,
SDL_PIXELFORMAT_ARGB8888,
SDL_PIXELFORMAT_YV12,
SDL_PIXELFORMAT_YUY2,
SDL_PIXELFORMAT_UYVY,
SDL_PIXELFORMAT_YVYU},
0,
0}
};
static SDL_Renderer *
photon_createrenderer(SDL_Window * window, Uint32 flags)
{
SDL_VideoDisplay *display = window->display;
SDL_DisplayData *didata = (SDL_DisplayData *) display->driverdata;
SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
SDL_Renderer *renderer = NULL;
SDL_RenderData *rdata = NULL;
/* Allocate new renderer structure */
renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(SDL_Renderer));
if (renderer == NULL) {
SDL_OutOfMemory();
return NULL;
}
/* Allocate renderer data */
rdata = (SDL_RenderData *) SDL_calloc(1, sizeof(SDL_RenderData));
if (rdata == NULL) {
SDL_free(renderer);
SDL_OutOfMemory();
return NULL;
}
renderer->DisplayModeChanged = photon_displaymodechanged;
renderer->ActivateRenderer = photon_activaterenderer;
renderer->CreateTexture = photon_createtexture;
renderer->QueryTexturePixels = photon_querytexturepixels;
renderer->UpdateTexture = photon_updatetexture;
renderer->LockTexture = photon_locktexture;
renderer->UnlockTexture = photon_unlocktexture;
renderer->DirtyTexture = photon_dirtytexture;
renderer->RenderPoint = photon_renderpoint;
renderer->RenderLine = photon_renderline;
renderer->RenderFill = photon_renderfill;
renderer->RenderCopy = photon_rendercopy;
renderer->RenderReadPixels = photon_renderreadpixels;
renderer->RenderWritePixels = photon_renderwritepixels;
renderer->RenderPresent = photon_renderpresent;
renderer->DestroyTexture = photon_destroytexture;
renderer->DestroyRenderer = photon_destroyrenderer;
renderer->info = photon_renderdriver.info;
renderer->window = window;
renderer->driverdata = rdata;
/* Copy direct_mode status */
rdata->direct_mode=didata->direct_mode;
/* Set render acceleration flag in case it is accelerated */
if ((didata->caps & SDL_PHOTON_ACCELERATED) == SDL_PHOTON_ACCELERATED) {
renderer->info.flags = SDL_RENDERER_ACCELERATED;
} else {
renderer->info.flags = 0;
}
/* Check if upper level requested synchronization on vsync signal */
if ((flags & SDL_RENDERER_PRESENTVSYNC) == SDL_RENDERER_PRESENTVSYNC) {
if (rdata->direct_mode==SDL_TRUE)
{
/* We can control vsync only in direct mode */
rdata->enable_vsync = SDL_TRUE;
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
}
else
{
rdata->enable_vsync = SDL_FALSE;
}
} else {
rdata->enable_vsync = SDL_FALSE;
}
/* Check what buffer copy/flip scheme is requested */
rdata->surfaces_count = 0;
if ((flags & SDL_RENDERER_SINGLEBUFFER) == SDL_RENDERER_SINGLEBUFFER) {
if ((flags & SDL_RENDERER_PRESENTDISCARD) ==
SDL_RENDERER_PRESENTDISCARD) {
renderer->info.flags |=
SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD;
} else {
renderer->info.flags |=
SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY;
}
rdata->surfaces_count = 1;
rdata->surface_visible_idx = 0;
rdata->surface_render_idx = 0;
} else {
if ((flags & SDL_RENDERER_PRESENTFLIP2) == SDL_RENDERER_PRESENTFLIP2) {
renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
rdata->surfaces_count = 2;
rdata->surface_visible_idx = 0;
rdata->surface_render_idx = 1;
} else {
if ((flags & SDL_RENDERER_PRESENTFLIP3) ==
SDL_RENDERER_PRESENTFLIP3) {
renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
rdata->surfaces_count = 3;
rdata->surface_visible_idx = 0;
rdata->surface_render_idx = 1;
} else {
renderer->info.flags |=
SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY;
rdata->surfaces_count = 1;
rdata->surface_visible_idx = 0;
rdata->surface_render_idx = 0;
}
}
}
/* Create new graphics context for the renderer */
if (rdata->gc==NULL)
{
rdata->gc=PgCreateGC(0);
PgDefaultGC(rdata->gc);
}
/* Setup textures supported by current renderer instance */
renderer->info.num_texture_formats=1;
renderer->info.texture_formats[0]=didata->current_mode.format;
/* Initialize surfaces */
_photon_recreate_surfaces(renderer);
return renderer;
}
void
photon_addrenderdriver(_THIS)
{
uint32_t it;
for (it = 0; it < _this->num_displays; it++) {
SDL_AddRenderDriver(&_this->displays[it], &photon_renderdriver);
}
}
/****************************************************************************/
/* Renderer helper functions */
/****************************************************************************/
static int _photon_recreate_surfaces(SDL_Renderer * renderer)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
SDL_VideoDisplay *display = NULL;
SDL_DisplayData *didata = NULL;
SDL_Window *window = NULL;
SDL_WindowData *wdata = NULL;
SDL_VideoData *phdata = NULL;
uint32_t allocate_task=SDL_PHOTON_SURFTYPE_UNKNOWN;
int32_t status;
/* Obtain window and display structures */
window=SDL_GetWindowFromID(renderer->window);
wdata=(SDL_WindowData*)window->driverdata;
display=window->display;
didata=(SDL_DisplayData *) display->driverdata;
phdata=(SDL_VideoData *) display->device->driverdata;
/* Check if it is OpenGL ES window */
if ((window->flags & SDL_WINDOW_OPENGL) == SDL_WINDOW_OPENGL) {
/* If so, do not waste surfaces */
rdata->surfaces_type=SDL_PHOTON_SURFTYPE_UNKNOWN;
return 0;
}
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
{
/* Try to allocate offscreen surfaces */
allocate_task=SDL_PHOTON_SURFTYPE_OFFSCREEN;
}
else
{
uint32_t it;
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_OFFSCREEN)
{
/* Create offscreen surfaces */
allocate_task=SDL_PHOTON_SURFTYPE_OFFSCREEN;
/* Before destroying surfaces, be sure, that rendering was completed */
PgFlush();
PgWaitHWIdle();
/* Destroy current surfaces */
for (it=0; it<SDL_PHOTON_MAX_SURFACES; it++)
{
if (rdata->osurfaces[it] != NULL)
{
PhDCRelease(rdata->osurfaces[it]);
rdata->osurfaces[it] = NULL;
}
}
}
else
{
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_PHIMAGE)
{
/* Create shared phimage surfaces */
allocate_task=SDL_PHOTON_SURFTYPE_PHIMAGE;
/* Destroy current surfaces */
for (it=0; it<SDL_PHOTON_MAX_SURFACES; it++)
{
if (rdata->pcontexts[it]!=NULL)
{
PmMemReleaseMC(rdata->pcontexts[it]);
rdata->pcontexts[it]=NULL;
}
if (rdata->psurfaces[it]!=NULL)
{
if (rdata->psurfaces[it]->palette!=NULL)
{
SDL_free(rdata->psurfaces[it]->palette);
rdata->psurfaces[it]->palette=NULL;
}
/* Destroy shared memory for PhImage_t */
PgShmemDestroy(rdata->psurfaces[it]->image);
rdata->psurfaces[it]->image=NULL;
SDL_free(rdata->psurfaces[it]);
rdata->psurfaces[it]=NULL;
}
}
}
}
}
/* 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 -1;
}
phdata->current_device_id = didata->device_id;
}
switch (allocate_task)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
{
int32_t it;
int32_t jt;
/* Try the hardware accelerated offscreen surfaces first */
for (it=0; it<rdata->surfaces_count; it++)
{
rdata->osurfaces[it]=PdCreateOffscreenContext(0, window->w, window->h,
Pg_OSC_MEM_LINEAR_ACCESSIBLE | Pg_OSC_MEM_PAGE_ALIGN |
/* in case if 2D acceleration is available use it */
Pg_OSC_MEM_2D_WRITABLE | Pg_OSC_MEM_2D_READABLE);
/* If we can't create an offscreen surface, then fallback to software */
if (rdata->osurfaces[it]==NULL)
{
/* Destroy previously allocated surface(s) */
for (jt = it - 1; jt > 0; jt--)
{
PhDCRelease(rdata->osurfaces[jt]);
rdata->osurfaces[jt] = NULL;
}
break;
}
}
/* Check if all required surfaces have been created */
if (rdata->osurfaces[0]!=NULL)
{
rdata->surfaces_type=SDL_PHOTON_SURFTYPE_OFFSCREEN;
/* exit from switch if surfaces have been created */
break;
}
else
{
/* else fall through to software phimage surface allocation */
}
}
/* fall through */
case SDL_PHOTON_SURFTYPE_PHIMAGE:
{
int32_t it;
int32_t jt;
uint32_t image_pfmt=photon_sdl_to_image_pixelformat(didata->current_mode.format);
/* Try to allocate the software surfaces in shared memory */
for (it=0; it<rdata->surfaces_count; it++)
{
/* If this surface with palette, create a palette space */
if (image_pfmt==Pg_IMAGE_PALETTE_BYTE)
{
rdata->psurfaces[it]=PhCreateImage(NULL, window->w, window->h,
image_pfmt, NULL, 256, 1);
}
else
{
rdata->psurfaces[it]=PhCreateImage(NULL, window->w, window->h,
image_pfmt, NULL, 0, 1);
}
if (rdata->psurfaces[it]!=NULL)
{
PhPoint_t translation={0, 0};
PhDim_t dimension={window->w, window->h};
/* Create memory context for PhImage_t */
rdata->pcontexts[it]=PmMemCreateMC(rdata->psurfaces[it], &dimension, &translation);
}
if ((rdata->psurfaces[it]==NULL) || (rdata->pcontexts[it]==NULL))
{
/* Destroy previously allocated surface(s) */
for (jt = it - 1; jt > 0; jt--)
{
if (rdata->pcontexts[jt]!=NULL)
{
PmMemReleaseMC(rdata->pcontexts[it]);
rdata->pcontexts[jt]=NULL;
}
if (rdata->psurfaces[jt]!=NULL)
{
if (rdata->psurfaces[jt]->palette!=NULL)
{
SDL_free(rdata->psurfaces[jt]->palette);
rdata->psurfaces[jt]->palette=NULL;
}
/* Destroy shared memory for PhImage_t */
PgShmemDestroy(rdata->psurfaces[jt]->image);
rdata->psurfaces[jt]->image=NULL;
SDL_free(rdata->psurfaces[jt]);
rdata->psurfaces[jt] = NULL;
}
}
break;
}
}
/* Check if all required surfaces have been created */
if (rdata->psurfaces[0]!=NULL)
{
rdata->surfaces_type=SDL_PHOTON_SURFTYPE_PHIMAGE;
}
else
{
rdata->surfaces_type=SDL_PHOTON_SURFTYPE_UNKNOWN;
}
}
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
default:
{
/* do nothing with surface allocation */
rdata->surfaces_type=SDL_PHOTON_SURFTYPE_UNKNOWN;
}
break;
}
/* Check if one of two allocation scheme was successful */
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
{
SDL_SetError("Photon: primary surface(s) allocation failure");
return -1;
}
/* Store current surface dimensions */
rdata->window_width=window->w;
rdata->window_height=window->h;
/* If current copy/flip scheme is single buffer, then set initial parameters */
if ((renderer->info.flags & SDL_RENDERER_SINGLEBUFFER)==SDL_RENDERER_SINGLEBUFFER)
{
rdata->surface_visible_idx = 0;
rdata->surface_render_idx = 0;
}
/* If current copy/flip scheme is double buffer, then set initial parameters */
if ((renderer->info.flags & SDL_RENDERER_PRESENTFLIP2)==SDL_RENDERER_PRESENTFLIP2)
{
rdata->surface_visible_idx = 0;
rdata->surface_render_idx = 1;
}
/* If current copy/flip scheme is triple buffer, then set initial parameters */
if ((renderer->info.flags & SDL_RENDERER_PRESENTFLIP3)==SDL_RENDERER_PRESENTFLIP3)
{
rdata->surface_visible_idx = 0;
rdata->surface_render_idx = 1;
}
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
PgSetGCCx(rdata->osurfaces[rdata->surface_render_idx], rdata->gc);
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
PgSetGCCx(rdata->pcontexts[rdata->surface_render_idx], rdata->gc);
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
default:
break;
}
return 0;
}
int _photon_update_rectangles(SDL_Renderer* renderer, PhRect_t* rect)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
SDL_Window *window = window=SDL_GetWindowFromID(renderer->window);
SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
PhPoint_t src_point;
/* If currently single buffer is in use, we have to flush all data */
if (rdata->surface_render_idx==rdata->surface_visible_idx)
{
/* Flush all undrawn graphics data to surface */
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
PgFlushCx(rdata->osurfaces[rdata->surface_visible_idx]);
PgWaitHWIdle();
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
PmMemFlush(rdata->pcontexts[rdata->surface_visible_idx], rdata->psurfaces[rdata->surface_visible_idx]);
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
default:
return;
}
}
PgSetRegionCx(PhDCGetCurrent(), PtWidgetRid(wdata->window));
src_point.x = rect->ul.x;
src_point.y = rect->ul.y;
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
PgContextBlit(rdata->osurfaces[rdata->surface_visible_idx], rect, NULL, rect);
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
PgDrawPhImageRectv(&src_point, rdata->psurfaces[rdata->surface_visible_idx], rect, 0);
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
default:
break;
}
}
int _photon_set_blending(SDL_Renderer* renderer, uint32_t blendmode, uint32_t globalalpha, uint32_t blendsource)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
/* Switch on requested graphics context modifiers */
switch (blendmode)
{
case SDL_BLENDMODE_BLEND:
/* Enable and set chroma key and alpha blending */
if (blendsource==SDL_PHOTON_TEXTURE_BLEND)
{
PgSetChromaCx(rdata->gc, PgRGB(255, 255, 255), Pg_CHROMA_SRC_MATCH | Pg_CHROMA_NODRAW);
PgChromaOnCx(rdata->gc);
}
PgSetAlphaCx(rdata->gc, Pg_ALPHA_OP_SRC_GLOBAL | Pg_BLEND_SRC_As | Pg_BLEND_DST_1mAs, NULL, NULL, globalalpha, 0);
PgAlphaOnCx(rdata->gc);
break;
case SDL_BLENDMODE_ADD:
/* Enable and set chroma key and alpha blending */
if (blendsource==SDL_PHOTON_TEXTURE_BLEND)
{
PgSetChromaCx(rdata->gc, PgRGB(255, 255, 255), Pg_CHROMA_SRC_MATCH | Pg_CHROMA_NODRAW);
PgChromaOnCx(rdata->gc);
}
PgSetAlphaCx(rdata->gc, Pg_ALPHA_OP_SRC_GLOBAL | Pg_BLEND_SRC_As | Pg_BLEND_DST_1, NULL, NULL, globalalpha, 0);
PgAlphaOnCx(rdata->gc);
break;
case SDL_BLENDMODE_NONE:
/* Do nothing */
break;
default:
return -1;
}
return 0;
}
int _photon_reset_blending(SDL_Renderer* renderer, uint32_t blendmode, uint32_t blendsource)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
/* Switch off graphics context modifiers */
switch (blendmode)
{
case SDL_BLENDMODE_BLEND:
/* Disable chroma key and alpha blending */
if (blendsource==SDL_PHOTON_TEXTURE_BLEND)
{
PgChromaOffCx(rdata->gc);
}
PgAlphaOffCx(rdata->gc);
break;
case SDL_BLENDMODE_ADD:
/* Disable chroma key and alpha blending */
if (blendsource==SDL_PHOTON_TEXTURE_BLEND)
{
PgChromaOffCx(rdata->gc);
}
PgAlphaOffCx(rdata->gc);
break;
case SDL_BLENDMODE_NONE:
/* Do nothing */
break;
default:
return -1;
}
return 0;
}
/****************************************************************************/
/* SDL render interface */
/****************************************************************************/
static int
photon_activaterenderer(SDL_Renderer * renderer)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
SDL_WindowData *wdata = (SDL_WindowData *)window->driverdata;
if ((rdata->window_width!=window->w) || (rdata->window_height!=window->h))
{
return _photon_recreate_surfaces(renderer);
}
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
PgSetGCCx(rdata->osurfaces[rdata->surface_render_idx], rdata->gc);
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
PgSetGCCx(rdata->pcontexts[rdata->surface_render_idx], rdata->gc);
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
default:
break;
}
return 0;
}
static int
photon_displaymodechanged(SDL_Renderer * renderer)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
SDL_VideoDisplay *display = window->display;
SDL_DisplayData *didata = (SDL_DisplayData *) display->driverdata;
/* Copy direct_mode status */
rdata->direct_mode=didata->direct_mode;
/* Update the surfaces */
return _photon_recreate_surfaces(renderer);
}
static int
photon_createtexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
SDL_VideoDisplay *display = window->display;
SDL_DisplayData *didata = (SDL_DisplayData *) display->driverdata;
SDL_TextureData *tdata = NULL;
uint32_t it;
/* Check, if it is not initialized */
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
{
SDL_SetError("Photon: can't create texture for OpenGL ES window");
return -1;
}
/* Check if requested texture format is supported */
for (it=0; it<renderer->info.num_texture_formats; it++)
{
if (renderer->info.texture_formats[it]==texture->format)
{
break;
}
}
if (it==renderer->info.num_texture_formats)
{
SDL_SetError("Photon: requested texture format is not supported");
return -1;
}
/* Allocate texture driver data */
tdata = (SDL_TextureData *) SDL_calloc(1, sizeof(SDL_TextureData));
if (tdata == NULL) {
SDL_OutOfMemory();
return -1;
}
/* Set texture driver data */
texture->driverdata = tdata;
/* Try offscreen allocation only in case if displayable buffers are also offscreen */
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_OFFSCREEN)
{
/* Try to allocate offscreen memory first */
tdata->osurface=PdCreateOffscreenContext(0, texture->w, texture->h,
Pg_OSC_MEM_LINEAR_ACCESSIBLE | Pg_OSC_MEM_PAGE_ALIGN |
/* in case if 2D acceleration is available use it */
Pg_OSC_MEM_2D_WRITABLE | Pg_OSC_MEM_2D_READABLE);
}
/* Check if offscreen allocation has been failed or not performed */
if (tdata->osurface==NULL)
{
PhPoint_t translation={0, 0};
PhDim_t dimension={texture->w, texture->h};
uint32_t image_pfmt=photon_sdl_to_image_pixelformat(didata->current_mode.format);
/* Allocate photon image */
if (image_pfmt==Pg_IMAGE_PALETTE_BYTE)
{
tdata->psurface=PhCreateImage(NULL, texture->w, texture->h,
image_pfmt, NULL, 256, 1);
}
else
{
tdata->psurface=PhCreateImage(NULL, texture->w, texture->h,
image_pfmt, NULL, 0, 1);
}
if (tdata->psurface==NULL)
{
return -1;
}
/* Create memory context for PhImage_t */
tdata->pcontext=PmMemCreateMC(tdata->psurface, &dimension, &translation);
if (tdata->pcontext==NULL)
{
/* Destroy PhImage */
if (tdata->psurface!=NULL)
{
if (tdata->psurface->palette!=NULL)
{
SDL_free(tdata->psurface->palette);
tdata->psurface->palette=NULL;
}
/* Destroy shared memory for PhImage_t */
PgShmemDestroy(tdata->psurface->image);
tdata->psurface->image=NULL;
SDL_free(tdata->psurface);
tdata->psurface=NULL;
}
}
tdata->surface_type=SDL_PHOTON_SURFTYPE_PHIMAGE;
}
else
{
tdata->surface_type=SDL_PHOTON_SURFTYPE_OFFSCREEN;
}
return 0;
}
static int
photon_querytexturepixels(SDL_Renderer * renderer, SDL_Texture * texture,
void **pixels, int *pitch)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
SDL_TextureData* tdata=(SDL_TextureData*)texture->driverdata;
/* Check, if it is not initialized */
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
{
SDL_SetError("Photon: can't query texture pixels for OpenGL ES window");
return -1;
}
/* Clear outcoming parameters */
*pixels=NULL;
*pitch=0;
switch (tdata->surface_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
*pixels=(void*)PdGetOffscreenContextPtr(tdata->osurface);
*pitch=tdata->osurface->pitch;
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
*pixels=(void*)tdata->psurface->image;
*pitch=tdata->psurface->bpl;
break;
default:
break;
}
return 0;
}
static int
photon_updatetexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, const void *pixels, int pitch)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
SDL_TextureData* tdata=(SDL_TextureData*)texture->driverdata;
uint8_t* src=(uint8_t*)pixels;
uint8_t* dst;
uint32_t dst_pitch;
uint32_t it;
uint32_t copy_length;
/* Check, if it is not initialized */
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
{
SDL_SetError("Photon: can't update texture for OpenGL ES window");
return -1;
}
switch (tdata->surface_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
dst=(uint8_t*)PdGetOffscreenContextPtr(tdata->osurface);
dst_pitch=tdata->osurface->pitch;
if (dst==NULL)
{
SDL_SetError("Photon: can't get pointer to texture surface");
return -1;
}
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
dst=(uint8_t*)tdata->psurface->image;
dst_pitch=tdata->psurface->bpl;
if (dst==NULL)
{
SDL_SetError("Photon: can't get pointer to texture surface");
return -1;
}
break;
default:
SDL_SetError("Photon: invalid internal surface type");
return -1;
}
dst+=rect->y * dst_pitch + rect->x * SDL_BYTESPERPIXEL(texture->format);
copy_length=rect->w * SDL_BYTESPERPIXEL(texture->format);
for (it = 0; it < rect->h; it++)
{
SDL_memcpy(dst, src, copy_length);
src+=pitch;
dst+=dst_pitch;
}
return 0;
}
static int
photon_locktexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, int markDirty, void **pixels,
int *pitch)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
SDL_TextureData* tdata=(SDL_TextureData*)texture->driverdata;
/* Check, if it is not initialized */
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
{
SDL_SetError("Photon: can't lock texture for OpenGL ES window");
return -1;
}
/* Clear outcoming parameters */
*pixels=NULL;
*pitch=0;
switch (tdata->surface_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
*pixels=(void*)((uint8_t*)PdGetOffscreenContextPtr(tdata->osurface) +
rect->y * tdata->osurface->pitch +
rect->x * SDL_BYTESPERPIXEL(texture->format));
*pitch=tdata->osurface->pitch;
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
*pixels=(void*)((uint8_t*)tdata->psurface->image +
rect->y * tdata->osurface->pitch +
rect->x * SDL_BYTESPERPIXEL(texture->format));
*pitch=tdata->psurface->bpl;
break;
default:
break;
}
return 0;
}
static void
photon_unlocktexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
/* Check, if it is not initialized */
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
{
SDL_SetError("Photon: can't unlock texture for OpenGL ES window");
return;
}
}
static void
photon_dirtytexture(SDL_Renderer * renderer, SDL_Texture * texture,
int numrects, const SDL_Rect * rects)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
/* Check, if it is not initialized */
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
{
SDL_SetError("Photon: can't update dirty texture for OpenGL ES window");
return;
}
}
static int
photon_renderpoint(SDL_Renderer * renderer, int x, int y)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
/* Check, if it is not initialized */
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
{
SDL_SetError("Photon: can't render point in OpenGL ES window");
return -1;
}
/* Enable blending, if requested */
_photon_set_blending(renderer, renderer->blendMode, renderer->a, SDL_PHOTON_DRAW_BLEND);
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
PgDrawIPixelCx(rdata->osurfaces[rdata->surface_render_idx], x, y);
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
PgDrawIPixelCx(rdata->pcontexts[rdata->surface_render_idx], x, y);
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
default:
break;
}
/* Disable blending, if it was enabled */
_photon_reset_blending(renderer, renderer->blendMode, SDL_PHOTON_DRAW_BLEND);
return 0;
}
static int
photon_renderline(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
/* Check, if it is not initialized */
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
{
SDL_SetError("Photon: can't render line in OpenGL ES window");
return -1;
}
/* Enable blending, if requested */
_photon_set_blending(renderer, renderer->blendMode, renderer->a, SDL_PHOTON_DRAW_BLEND);
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
PgDrawILineCx(rdata->osurfaces[rdata->surface_render_idx], x1, y1, x2, y2);
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
PgDrawILineCx(rdata->pcontexts[rdata->surface_render_idx], x1, y1, x2, y2);
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
default:
break;
}
/* Disable blending, if it was enabled */
_photon_reset_blending(renderer, renderer->blendMode, SDL_PHOTON_DRAW_BLEND);
return 0;
}
static int
photon_renderfill(SDL_Renderer * renderer, const SDL_Rect * rect)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
/* Check, if it is not initialized */
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
{
SDL_SetError("Photon: can't render filled box in OpenGL ES window");
return -1;
}
/* Enable blending, if requested */
_photon_set_blending(renderer, renderer->blendMode, renderer->a, SDL_PHOTON_DRAW_BLEND);
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
PgDrawIRectCx(rdata->osurfaces[rdata->surface_render_idx], rect->x, rect->y, rect->w+rect->x-1, rect->h+rect->y-1, Pg_DRAW_FILL);
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
PgDrawIRectCx(rdata->pcontexts[rdata->surface_render_idx], rect->x, rect->y, rect->w+rect->x-1, rect->h+rect->y-1, Pg_DRAW_FILL);
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
default:
break;
}
/* Disable blending, if it was enabled */
_photon_reset_blending(renderer, renderer->blendMode, SDL_PHOTON_DRAW_BLEND);
return 0;
}
static int
photon_rendercopy(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
SDL_TextureData* tdata=(SDL_TextureData*)texture->driverdata;
PhRect_t src_rect;
PhRect_t dst_rect;
PhPoint_t dst_point;
/* Check, if it is not initialized */
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
{
SDL_SetError("Photon: can't blit textures in OpenGL ES window");
return -1;
}
_photon_set_blending(renderer, texture->blendMode, texture->a, SDL_PHOTON_TEXTURE_BLEND);
/* Set source blit area */
src_rect.ul.x = srcrect->x;
src_rect.ul.y = srcrect->y;
src_rect.lr.x = srcrect->x + srcrect->w - 1;
src_rect.lr.y = srcrect->y + srcrect->h - 1;
/* Set destination blit area */
dst_rect.ul.x = dstrect->x;
dst_rect.ul.y = dstrect->y;
dst_rect.lr.x = dstrect->x + dstrect->w - 1;
dst_rect.lr.y = dstrect->y + dstrect->h - 1;
/* Set destination point */
dst_point.x = dstrect->x;
dst_point.y = dstrect->y;
/* Do blit */
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
/* two possible combinations */
switch (tdata->surface_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
/* easiest full accelerated combination: offscreen->offscreen */
PgContextBlitCx(rdata->osurfaces[rdata->surface_render_idx], tdata->osurface,
&src_rect, rdata->osurfaces[rdata->surface_render_idx], &dst_rect);
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
/* not accelerated combination: PhImage->offscreen */
/* scaling is not supported in this method */
PgDrawPhImageRectCxv(rdata->osurfaces[rdata->surface_render_idx], &dst_point,
tdata->psurface, &src_rect, 0);
break;
default:
break;
}
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
/* two possible combinations */
switch (tdata->surface_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
/* not supported combination: offscreen->PhImage */
return -1;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
/* not accelerated combination, but fast: PhImage->PhImage */
/* scaling is not supported in this method */
PgDrawPhImageRectCxv(rdata->pcontexts[rdata->surface_render_idx], &dst_point, tdata->psurface, &src_rect, 0);
break;
default:
break;
}
break;
}
_photon_reset_blending(renderer, texture->blendMode, SDL_PHOTON_TEXTURE_BLEND);
return 0;
}
static void
photon_renderpresent(SDL_Renderer * renderer)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
SDL_Window *window = window=SDL_GetWindowFromID(renderer->window);
SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
PhRect_t src_rect;
PhPoint_t src_point;
/* Check, if it is not initialized */
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
{
SDL_SetError("Photon: can't render present for OpenGL ES window");
return;
}
/* Flush all undrawn graphics data to surface */
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
PgFlushCx(rdata->osurfaces[rdata->surface_render_idx]);
PgWaitHWIdle();
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
PmMemFlush(rdata->pcontexts[rdata->surface_render_idx], rdata->psurfaces[rdata->surface_render_idx]);
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
default:
return;
}
PgFFlush(Ph_START_DRAW);
PgSetRegionCx(PhDCGetCurrent(), PtWidgetRid(wdata->window));
/* Set blit area */
src_rect.ul.x = 0;
src_rect.ul.y = 0;
src_rect.lr.x = rdata->window_width - 1;
src_rect.lr.y = rdata->window_height - 1;
src_point.x = 0;
src_point.y = 0;
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
PgContextBlit(rdata->osurfaces[rdata->surface_render_idx], &src_rect, NULL, &src_rect);
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
PgDrawPhImagev(&src_point, rdata->psurfaces[rdata->surface_render_idx], 0);
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
default:
break;
}
/* finish blit */
PgFFlush(Ph_DONE_DRAW);
PgWaitHWIdle();
/* Check if we are using double buffering */
if ((renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) == SDL_RENDERER_PRESENTFLIP2)
{
rdata->surface_visible_idx=rdata->surface_render_idx;
rdata->surface_render_idx=(rdata->surface_render_idx + 1) % 2;
}
/* Check if we are using triple buffering */
if ((renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) == SDL_RENDERER_PRESENTFLIP3)
{
rdata->surface_visible_idx=rdata->surface_render_idx;
rdata->surface_render_idx=(rdata->surface_render_idx + 1) % 3;
}
}
static void
photon_destroytexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
SDL_TextureData* tdata=(SDL_TextureData*)texture->driverdata;
/* Check if partially created texture must be destroyed */
if (tdata==NULL)
{
return;
}
/* Check, if it is not initialized */
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
{
SDL_SetError("Photon: can't destroy texture for OpenGL ES window");
return;
}
switch (tdata->surface_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
if (tdata->osurface!=NULL)
{
PhDCRelease(tdata->osurface);
tdata->osurface = NULL;
}
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
if (tdata->pcontext!=NULL)
{
PmMemReleaseMC(tdata->pcontext);
tdata->pcontext=NULL;
}
if (tdata->psurface!=NULL)
{
if (tdata->psurface->palette!=NULL)
{
SDL_free(tdata->psurface->palette);
tdata->psurface->palette=NULL;
}
/* Destroy shared memory for PhImage_t */
PgShmemDestroy(tdata->psurface->image);
tdata->psurface->image=NULL;
SDL_free(tdata->psurface);
tdata->psurface=NULL;
}
break;
default:
break;
}
}
static void
photon_destroyrenderer(SDL_Renderer * renderer)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
SDL_WindowData *wdata = (SDL_WindowData *)window->driverdata;
uint32_t it;
/* Before destroying the renderer, be sure, that rendering was completed */
PgFlush();
PgWaitHWIdle();
/* Destroy graphics context */
if (rdata->gc!=NULL)
{
PgDestroyGC(rdata->gc);
rdata->gc=NULL;
}
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
{
/* Destroy current surfaces */
for (it=0; it<SDL_PHOTON_MAX_SURFACES; it++)
{
if (rdata->osurfaces[it] != NULL)
{
PhDCRelease(rdata->osurfaces[it]);
rdata->osurfaces[it] = NULL;
}
}
}
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
{
/* Destroy current surfaces */
for (it=0; it<SDL_PHOTON_MAX_SURFACES; it++)
{
if (rdata->pcontexts[it]!=NULL)
{
PmMemReleaseMC(rdata->pcontexts[it]);
rdata->pcontexts[it]=NULL;
}
if (rdata->psurfaces[it]!=NULL)
{
if (rdata->psurfaces[it]->palette!=NULL)
{
SDL_free(rdata->psurfaces[it]->palette);
rdata->psurfaces[it]->palette=NULL;
}
/* Destroy shared memory for PhImage_t */
PgShmemDestroy(rdata->psurfaces[it]->image);
rdata->psurfaces[it]->image=NULL;
SDL_free(rdata->psurfaces[it]);
rdata->psurfaces[it]=NULL;
}
}
}
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
default:
{
/* nothing to do */
}
break;
}
}
static int
photon_renderreadpixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 format, void * pixels, int pitch)
{
SDL_RenderData *rdata = (SDL_RenderData *)renderer->driverdata;
Uint32 sformat=0;
uint8_t* spixels=NULL;
unsigned int spitch=0;
/* Flush all undrawn graphics data to surface */
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
PgFlushCx(rdata->osurfaces[rdata->surface_render_idx]);
PgWaitHWIdle();
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
PmMemFlush(rdata->pcontexts[rdata->surface_render_idx], rdata->psurfaces[rdata->surface_render_idx]);
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
default:
return;
}
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
sformat=photon_image_to_sdl_pixelformat(rdata->osurfaces[rdata->surface_render_idx]->format);
spixels=(uint8_t*)PdGetOffscreenContextPtr(rdata->osurfaces[rdata->surface_render_idx]);
spitch=rdata->osurfaces[rdata->surface_render_idx]->pitch;
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
sformat=photon_image_to_sdl_pixelformat(rdata->psurfaces[rdata->surface_render_idx]->type);
spixels=(uint8_t*)rdata->psurfaces[rdata->surface_render_idx]->image;
spitch=rdata->psurfaces[rdata->surface_render_idx]->bpl;
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
default:
SDL_SetError("Photon: surfaces are not initialized");
return -1;
}
/* Adjust surface pixels pointer to the rectangle coordinates */
spixels+=rect->y*spitch + rect->x*SDL_BYTESPERPIXEL(sformat);
SDL_ConvertPixels(rect->w, rect->h,
sformat, spixels, spitch,
format, pixels, pitch);
return 0;
}
static int
photon_renderwritepixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 format, const void * pixels, int pitch)
{
SDL_RenderData *rdata = (SDL_RenderData *)renderer->driverdata;
Uint32 sformat=0;
uint8_t* spixels=NULL;
unsigned int spitch=0;
/* Flush all undrawn graphics data to surface */
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
PgFlushCx(rdata->osurfaces[rdata->surface_render_idx]);
PgWaitHWIdle();
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
PmMemFlush(rdata->pcontexts[rdata->surface_render_idx], rdata->psurfaces[rdata->surface_render_idx]);
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
default:
return;
}
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
sformat=photon_image_to_sdl_pixelformat(rdata->osurfaces[rdata->surface_render_idx]->format);
spixels=(uint8_t*)PdGetOffscreenContextPtr(rdata->osurfaces[rdata->surface_render_idx]);
spitch=rdata->osurfaces[rdata->surface_render_idx]->pitch;
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
sformat=photon_image_to_sdl_pixelformat(rdata->psurfaces[rdata->surface_render_idx]->type);
spixels=(uint8_t*)rdata->psurfaces[rdata->surface_render_idx]->image;
spitch=rdata->psurfaces[rdata->surface_render_idx]->bpl;
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
default:
SDL_SetError("Photon: surfaces are not initialized");
return -1;
}
/* Adjust surface pixels pointer to the rectangle coordinates */
spixels+=rect->y*spitch + rect->x*SDL_BYTESPERPIXEL(sformat);
SDL_ConvertPixels(rect->w, rect->h, format, pixels, pitch,
sformat, spixels, spitch);
return 0;
}
/* vi: set ts=4 sw=4 expandtab: */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Photon GUI SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#ifndef __SDL_PHOTON_RENDER_H__
#define __SDL_PHOTON_RENDER_H__
#include "../SDL_sysvideo.h"
#include <Ph.h>
#include <photon/PhRender.h>
#define SDL_PHOTON_MAX_SURFACES 3
#define SDL_PHOTON_SURFTYPE_UNKNOWN 0x00000000
#define SDL_PHOTON_SURFTYPE_OFFSCREEN 0x00000001
#define SDL_PHOTON_SURFTYPE_PHIMAGE 0x00000002
#define SDL_PHOTON_UNKNOWN_BLEND 0x00000000
#define SDL_PHOTON_DRAW_BLEND 0x00000001
#define SDL_PHOTON_TEXTURE_BLEND 0x00000002
typedef struct SDL_RenderData
{
SDL_bool enable_vsync; /* VSYNC flip synchronization enable */
uint32_t surface_visible_idx; /* Index of visible surface */
uint32_t surface_render_idx; /* Index of render surface */
uint32_t surfaces_count; /* Amount of allocated surfaces */
uint32_t surfaces_type; /* Type of allocated surfaces */
uint32_t window_width; /* Last active window width */
uint32_t window_height; /* Last active window height */
PhGC_t* gc; /* Graphics context */
SDL_bool direct_mode; /* Direct Mode state */
PdOffscreenContext_t* osurfaces[SDL_PHOTON_MAX_SURFACES];
PhImage_t* psurfaces[SDL_PHOTON_MAX_SURFACES];
PmMemoryContext_t* pcontexts[SDL_PHOTON_MAX_SURFACES];
} SDL_RenderData;
typedef struct SDL_TextureData
{
uint32_t surface_type;
PdOffscreenContext_t* osurface;
PhImage_t* psurface;
PmMemoryContext_t* pcontext;
} SDL_TextureData;
extern void photon_addrenderdriver(_THIS);
/* Helper function, which redraws the backbuffer */
int _photon_update_rectangles(SDL_Renderer* renderer, PhRect_t* rect);
#endif /* __SDL_PHOTON_RENDER_H__ */
/* vi: set ts=4 sw=4 expandtab: */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Graphics Framework SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#include "SDL_gf_input.h"
#include "SDL_config.h"
#include "SDL_events.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_keyboard_c.h"
/* Include QNX HIDDI definitions */
#include "SDL_hiddi_keyboard.h"
#include "SDL_hiddi_mouse.h"
#include "SDL_hiddi_joystick.h"
/* Mouse related functions */
SDL_Cursor *gf_createcursor(SDL_Surface * surface, int hot_x, int hot_y);
int gf_showcursor(SDL_Cursor * cursor);
void gf_movecursor(SDL_Cursor * cursor);
void gf_freecursor(SDL_Cursor * cursor);
void gf_warpmouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y);
void gf_freemouse(SDL_Mouse * mouse);
/* HIDDI interacting functions */
static int32_t hiddi_connect_devices();
static int32_t hiddi_disconnect_devices();
int32_t
gf_addinputdevices(_THIS)
{
SDL_VideoData *gfdata = (SDL_VideoData *) _this->driverdata;
SDL_DisplayData *didata;
struct SDL_Mouse gf_mouse;
SDL_Keyboard gf_keyboard;
SDLKey keymap[SDL_NUM_SCANCODES];
SDL_MouseData *mdata;
uint32_t it;
for (it = 0; it < _this->num_displays; it++) {
SDL_VideoDisplay *display = &_this->displays[it];
/* Clear SDL mouse structure */
SDL_memset(&gf_mouse, 0x00, sizeof(struct SDL_Mouse));
/* Allocate SDL_MouseData structure */
mdata = (SDL_MouseData *) SDL_calloc(1, sizeof(SDL_MouseData));
if (mdata == NULL) {
SDL_OutOfMemory();
return -1;
}
/* Mark this mouse with ID 0 */
gf_mouse.id = it;
gf_mouse.driverdata = (void *) mdata;
gf_mouse.CreateCursor = gf_createcursor;
gf_mouse.ShowCursor = gf_showcursor;
gf_mouse.MoveCursor = gf_movecursor;
gf_mouse.FreeCursor = gf_freecursor;
gf_mouse.WarpMouse = gf_warpmouse;
gf_mouse.FreeMouse = gf_freemouse;
/* Get display data */
didata = (SDL_DisplayData *) display->driverdata;
/* Store SDL_DisplayData pointer in the mouse driver internals */
mdata->didata = didata;
/* Set cursor pos to 0,0 to avoid cursor disappearing in some drivers */
gf_cursor_set_pos(didata->display, 0, 0, 0);
/* Register mouse cursor in SDL */
SDL_AddMouse(&gf_mouse, "GF mouse cursor", 0, 0, 1);
}
/* Keyboard could be one only */
SDL_zero(gf_keyboard);
SDL_AddKeyboard(&gf_keyboard, -1);
/* Add scancode to key mapping, HIDDI uses USB HID codes, so */
/* map will be exact one-to-one */
SDL_GetDefaultKeymap(keymap);
SDL_SetKeymap(0, 0, keymap, SDL_NUM_SCANCODES);
/* Connect to HID server and enumerate all input devices */
hiddi_connect_devices();
return 0;
}
int32_t
gf_delinputdevices(_THIS)
{
/* Disconnect from HID server and release input devices */
hiddi_disconnect_devices();
/* Delete keyboard */
SDL_KeyboardQuit();
/* Destroy all of the mice */
SDL_MouseQuit();
}
/*****************************************************************************/
/* GF Mouse related functions */
/*****************************************************************************/
SDL_Cursor *
gf_createcursor(SDL_Surface * surface, int hot_x, int hot_y)
{
gf_cursor_t *internal_cursor;
SDL_Cursor *sdl_cursor;
uint8_t *image0 = NULL;
uint8_t *image1 = NULL;
uint32_t it;
uint32_t jt;
uint32_t shape_color;
/* SDL converts monochrome cursor shape to 32bpp cursor shape */
/* and we must convert it back to monochrome, this routine handles */
/* 24/32bpp surfaces only */
if ((surface->format->BitsPerPixel != 32)
&& (surface->format->BitsPerPixel != 24)) {
SDL_SetError("GF: Cursor shape is not 24/32bpp.");
return NULL;
}
/* Since GF is not checking data, we must check */
if ((surface->w == 0) || (surface->h == 0)) {
SDL_SetError("GF: Cursor shape dimensions are zero");
return NULL;
}
/* Allocate memory for the internal cursor format */
internal_cursor = (gf_cursor_t *) SDL_calloc(1, sizeof(gf_cursor_t));
if (internal_cursor == NULL) {
SDL_OutOfMemory();
return NULL;
}
/* Allocate memory for the SDL cursor */
sdl_cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(SDL_Cursor));
if (sdl_cursor == NULL) {
SDL_free(internal_cursor);
SDL_OutOfMemory();
return NULL;
}
/* Allocate two monochrome images */
image0 = (uint8_t *) SDL_calloc(1, ((surface->w + 7) / 8) * surface->h);
if (image0 == NULL) {
SDL_free(sdl_cursor);
SDL_free(internal_cursor);
SDL_OutOfMemory();
return NULL;
}
image1 = (uint8_t *) SDL_calloc(1, ((surface->w + 7) >> 3) * surface->h);
if (image1 == NULL) {
SDL_free(image0);
SDL_free(sdl_cursor);
SDL_free(internal_cursor);
SDL_OutOfMemory();
return NULL;
}
/* Set driverdata as GF cursor format */
sdl_cursor->driverdata = (void *) internal_cursor;
internal_cursor->type = GF_CURSOR_BITMAP;
internal_cursor->hotspot.x = hot_x;
internal_cursor->hotspot.y = hot_y;
internal_cursor->cursor.bitmap.w = surface->w;
internal_cursor->cursor.bitmap.h = surface->h;
internal_cursor->cursor.bitmap.color0 = SDL_GF_MOUSE_COLOR_BLACK;
internal_cursor->cursor.bitmap.color1 = SDL_GF_MOUSE_COLOR_WHITE;
/* Setup cursor shape images */
internal_cursor->cursor.bitmap.stride = ((surface->w + 7) >> 3);
internal_cursor->cursor.bitmap.image0 = image0;
internal_cursor->cursor.bitmap.image1 = image1;
/* Convert cursor from 32 bpp */
for (jt = 0; jt < surface->h; jt++) {
for (it = 0; it < surface->w; it++) {
shape_color =
*((uint32_t *) ((uint8_t *) surface->pixels +
jt * surface->pitch +
it * surface->format->BytesPerPixel));
switch (shape_color) {
case SDL_GF_MOUSE_COLOR_BLACK:
{
*(image0 + jt * (internal_cursor->cursor.bitmap.stride) +
(it >> 3)) |= 0x80 >> (it % 8);
*(image1 + jt * (internal_cursor->cursor.bitmap.stride) +
(it >> 3)) &= ~(0x80 >> (it % 8));
}
break;
case SDL_GF_MOUSE_COLOR_WHITE:
{
*(image0 + jt * (internal_cursor->cursor.bitmap.stride) +
(it >> 3)) &= ~(0x80 >> (it % 8));
*(image1 + jt * (internal_cursor->cursor.bitmap.stride) +
(it >> 3)) |= 0x80 >> (it % 8);
}
break;
case SDL_GF_MOUSE_COLOR_TRANS:
{
*(image0 + jt * (internal_cursor->cursor.bitmap.stride) +
(it >> 3)) &= ~(0x80 >> (it % 8));
*(image1 + jt * (internal_cursor->cursor.bitmap.stride) +
(it >> 3)) &= ~(0x80 >> (it % 8));
}
break;
default:
{
/* The same as transparent color, must not happen */
*(image0 + jt * (internal_cursor->cursor.bitmap.stride) +
(it >> 3)) &= ~(0x80 >> (it % 8));
*(image1 + jt * (internal_cursor->cursor.bitmap.stride) +
(it >> 3)) &= ~(0x80 >> (it % 8));
}
break;
}
}
}
return sdl_cursor;
}
int
gf_showcursor(SDL_Cursor * cursor)
{
SDL_VideoDisplay *display;
SDL_DisplayData *didata;
SDL_Window *window;
SDL_WindowID window_id;
gf_cursor_t *internal_cursor;
int32_t status;
/* Get current window id */
window_id = SDL_GetFocusWindow();
if (window_id <= 0) {
SDL_MouseData *mdata = NULL;
/* If there is no current window, then someone calls this function */
/* to set global mouse settings during SDL initialization */
if (cursor != NULL) {
mdata = (SDL_MouseData *) cursor->mouse->driverdata;
didata = (SDL_DisplayData *) mdata->didata;
if ((didata == NULL) || (mdata == NULL)) {
return;
}
} else {
/* We can't get SDL_DisplayData at this point, return fake success */
return 0;
}
} else {
/* Sanity checks */
window = SDL_GetWindowFromID(window_id);
if (window != NULL) {
display = window->display;
if (display != NULL) {
didata = (SDL_DisplayData *) display->driverdata;
if (didata == NULL) {
return -1;
}
} else {
return -1;
}
} else {
return -1;
}
}
/* Check if we need to set new shape or disable cursor shape */
if (cursor != NULL) {
/* Retrieve GF cursor shape */
internal_cursor = (gf_cursor_t *) cursor->driverdata;
if (internal_cursor == NULL) {
SDL_SetError("GF: Internal cursor data is absent");
return -1;
}
if ((internal_cursor->cursor.bitmap.image0 == NULL) ||
(internal_cursor->cursor.bitmap.image1 == NULL)) {
SDL_SetError("GF: Cursor shape is absent");
return -1;
}
/* Store last shown cursor to display data */
didata->cursor.type = internal_cursor->type;
didata->cursor.hotspot.x = internal_cursor->hotspot.x;
didata->cursor.hotspot.y = internal_cursor->hotspot.y;
if (internal_cursor->cursor.bitmap.w > SDL_VIDEO_GF_MAX_CURSOR_SIZE) {
didata->cursor.cursor.bitmap.w = SDL_VIDEO_GF_MAX_CURSOR_SIZE;
} else {
didata->cursor.cursor.bitmap.w = internal_cursor->cursor.bitmap.w;
}
if (didata->cursor.cursor.bitmap.h > SDL_VIDEO_GF_MAX_CURSOR_SIZE) {
didata->cursor.cursor.bitmap.h = SDL_VIDEO_GF_MAX_CURSOR_SIZE;
} else {
didata->cursor.cursor.bitmap.h = internal_cursor->cursor.bitmap.h;
}
didata->cursor.cursor.bitmap.color0 =
internal_cursor->cursor.bitmap.color0;
didata->cursor.cursor.bitmap.color1 =
internal_cursor->cursor.bitmap.color1;
didata->cursor.cursor.bitmap.stride =
internal_cursor->cursor.bitmap.stride;
SDL_memcpy(didata->cursor.cursor.bitmap.image0,
internal_cursor->cursor.bitmap.image0,
((internal_cursor->cursor.bitmap.w +
7) / (sizeof(uint8_t) * 8)) *
internal_cursor->cursor.bitmap.h);
SDL_memcpy(didata->cursor.cursor.bitmap.image1,
internal_cursor->cursor.bitmap.image1,
((internal_cursor->cursor.bitmap.w +
7) / (sizeof(uint8_t) * 8)) *
internal_cursor->cursor.bitmap.h);
/* Setup cursor shape */
status = gf_cursor_set(didata->display, 0, internal_cursor);
if (status != GF_ERR_OK) {
if (status != GF_ERR_NOSUPPORT) {
SDL_SetError("GF: Can't set hardware cursor shape");
return -1;
}
}
/* Enable just set cursor */
status = gf_cursor_enable(didata->display, 0);
if (status != GF_ERR_OK) {
if (status != GF_ERR_NOSUPPORT) {
SDL_SetError("GF: Can't enable hardware cursor");
return -1;
}
}
/* Set cursor visible */
didata->cursor_visible = SDL_TRUE;
} else {
/* SDL requests to disable cursor */
status = gf_cursor_disable(didata->display, 0);
if (status != GF_ERR_OK) {
if (status != GF_ERR_NOSUPPORT) {
SDL_SetError("GF: Can't disable hardware cursor");
return -1;
}
}
/* Set cursor invisible */
didata->cursor_visible = SDL_FALSE;
}
/* New cursor shape is set */
return 0;
}
void
gf_movecursor(SDL_Cursor * cursor)
{
SDL_VideoDisplay *display;
SDL_DisplayData *didata;
SDL_Window *window;
SDL_WindowID window_id;
int32_t status;
uint32_t xmax;
uint32_t ymax;
/* Get current window id */
window_id = SDL_GetFocusWindow();
if (window_id <= 0) {
didata = (SDL_DisplayData *) cursor->mouse->driverdata;
if (didata == NULL) {
return;
}
} else {
/* Sanity checks */
window = SDL_GetWindowFromID(window_id);
if (window != NULL) {
display = window->display;
if (display != NULL) {
didata = (SDL_DisplayData *) display->driverdata;
if (didata == NULL) {
return;
}
} else {
return;
}
} else {
return;
}
}
/* Add checks for out of screen bounds position */
if (cursor->mouse->x < 0) {
cursor->mouse->x = 0;
}
if (cursor->mouse->y < 0) {
cursor->mouse->y = 0;
}
/* Get window size to clamp maximum coordinates */
SDL_GetWindowSize(window_id, &xmax, &ymax);
if (cursor->mouse->x >= xmax) {
cursor->mouse->x = xmax - 1;
}
if (cursor->mouse->y >= ymax) {
cursor->mouse->y = ymax - 1;
}
status =
gf_cursor_set_pos(didata->display, 0, cursor->mouse->x,
cursor->mouse->y);
if (status != GF_ERR_OK) {
if (status != GF_ERR_NOSUPPORT) {
SDL_SetError("GF: Can't set hardware cursor position");
return;
}
}
}
void
gf_freecursor(SDL_Cursor * cursor)
{
gf_cursor_t *internal_cursor;
if (cursor != NULL) {
internal_cursor = (gf_cursor_t *) cursor->driverdata;
if (internal_cursor != NULL) {
if (internal_cursor->cursor.bitmap.image0 != NULL) {
SDL_free((uint8_t *) internal_cursor->cursor.bitmap.image0);
}
if (internal_cursor->cursor.bitmap.image1 != NULL) {
SDL_free((uint8_t *) internal_cursor->cursor.bitmap.image1);
}
SDL_free(internal_cursor);
}
}
}
void
gf_warpmouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y)
{
SDL_VideoDisplay *display;
SDL_DisplayData *didata;
uint32_t xmax;
uint32_t ymax;
int32_t status;
/* Sanity checks */
if (window != NULL) {
display = window->display;
if (display != NULL) {
didata = (SDL_DisplayData *) display->driverdata;
if (didata == NULL) {
return;
}
} else {
return;
}
} else {
return;
}
/* Add checks for out of screen bounds position */
if (x < 0) {
x = 0;
}
if (y < 0) {
y = 0;
}
/* Get window size to clamp maximum coordinates */
SDL_GetWindowSize(window, &xmax, &ymax);
if (x >= xmax) {
x = xmax - 1;
}
if (y >= ymax) {
y = ymax - 1;
}
status = gf_cursor_set_pos(didata->display, 0, x, y);
if (status != GF_ERR_OK) {
if (status != GF_ERR_NOSUPPORT) {
SDL_SetError("GF: Can't set hardware cursor position");
return;
}
}
}
void
gf_freemouse(SDL_Mouse * mouse)
{
if (mouse->driverdata == NULL) {
return;
}
/* Mouse framework doesn't deletes automatically our driverdata */
SDL_free(mouse->driverdata);
mouse->driverdata = NULL;
return;
}
/*****************************************************************************/
/* HIDDI handlers code */
/*****************************************************************************/
static key_packet key_last_state[SDL_HIDDI_MAX_DEVICES];
static void
hiddi_keyboard_handler(uint32_t devno, uint8_t * report_data,
uint32_t report_len)
{
key_packet *packet;
uint32_t it;
uint32_t jt;
packet = (key_packet *) report_data;
/* Check for special states */
switch (report_len) {
case 8: /* 8 bytes of report length */
{
for (it = 0; it < 6; it++) {
/* Check for keyboard overflow, when it can't handle */
/* many simultaneous pressed keys */
if (packet->codes[it] == HIDDI_KEY_OVERFLOW) {
return;
}
}
}
break;
default:
{
/* Do not process unknown reports */
return;
}
break;
}
/* Check if modifier key was pressed */
if (packet->modifiers != key_last_state[devno].modifiers) {
if (((packet->modifiers & HIDDI_MKEY_LEFT_CTRL) ==
HIDDI_MKEY_LEFT_CTRL)
&& (key_last_state[devno].modifiers & HIDDI_MKEY_LEFT_CTRL) == 0) {
/* Left Ctrl key was pressed */
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LCTRL);
}
if (((packet->modifiers & HIDDI_MKEY_LEFT_CTRL) == 0) &&
(key_last_state[devno].modifiers & HIDDI_MKEY_LEFT_CTRL) ==
HIDDI_MKEY_LEFT_CTRL) {
/* Left Ctrl key was released */
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LCTRL);
}
if (((packet->modifiers & HIDDI_MKEY_LEFT_SHIFT) ==
HIDDI_MKEY_LEFT_SHIFT)
&& (key_last_state[devno].modifiers & HIDDI_MKEY_LEFT_SHIFT) == 0) {
/* Left Shift key was pressed */
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LSHIFT);
}
if (((packet->modifiers & HIDDI_MKEY_LEFT_SHIFT) == 0) &&
(key_last_state[devno].modifiers & HIDDI_MKEY_LEFT_SHIFT) ==
HIDDI_MKEY_LEFT_SHIFT) {
/* Left Shift key was released */
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LSHIFT);
}
if (((packet->modifiers & HIDDI_MKEY_LEFT_ALT) == HIDDI_MKEY_LEFT_ALT)
&& (key_last_state[devno].modifiers & HIDDI_MKEY_LEFT_ALT) == 0) {
/* Left Alt key was pressed */
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LALT);
}
if (((packet->modifiers & HIDDI_MKEY_LEFT_ALT) == 0) &&
(key_last_state[devno].modifiers & HIDDI_MKEY_LEFT_ALT) ==
HIDDI_MKEY_LEFT_ALT) {
/* Left Alt key was released */
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LALT);
}
if (((packet->modifiers & HIDDI_MKEY_LEFT_WFLAG) ==
HIDDI_MKEY_LEFT_WFLAG)
&& (key_last_state[devno].modifiers & HIDDI_MKEY_LEFT_WFLAG) == 0) {
/* Left Windows flag key was pressed */
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LGUI);
}
if (((packet->modifiers & HIDDI_MKEY_LEFT_WFLAG) == 0) &&
(key_last_state[devno].modifiers & HIDDI_MKEY_LEFT_WFLAG) ==
HIDDI_MKEY_LEFT_WFLAG) {
/* Left Windows flag key was released */
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LGUI);
}
if (((packet->modifiers & HIDDI_MKEY_RIGHT_CTRL) ==
HIDDI_MKEY_RIGHT_CTRL)
&& (key_last_state[devno].modifiers & HIDDI_MKEY_RIGHT_CTRL) == 0) {
/* Right Ctrl key was pressed */
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_RCTRL);
}
if (((packet->modifiers & HIDDI_MKEY_RIGHT_CTRL) == 0) &&
(key_last_state[devno].modifiers & HIDDI_MKEY_RIGHT_CTRL) ==
HIDDI_MKEY_RIGHT_CTRL) {
/* Right Ctrl key was released */
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RCTRL);
}
if (((packet->modifiers & HIDDI_MKEY_RIGHT_SHIFT) ==
HIDDI_MKEY_RIGHT_SHIFT)
&& (key_last_state[devno].modifiers & HIDDI_MKEY_RIGHT_SHIFT) ==
0) {
/* Right Shift key was pressed */
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_RSHIFT);
}
if (((packet->modifiers & HIDDI_MKEY_RIGHT_SHIFT) == 0) &&
(key_last_state[devno].modifiers & HIDDI_MKEY_RIGHT_SHIFT) ==
HIDDI_MKEY_RIGHT_SHIFT) {
/* Right Shift key was released */
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RSHIFT);
}
if (((packet->modifiers & HIDDI_MKEY_RIGHT_ALT) ==
HIDDI_MKEY_RIGHT_ALT)
&& (key_last_state[devno].modifiers & HIDDI_MKEY_RIGHT_ALT) == 0) {
/* Right Alt key was pressed */
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_RALT);
}
if (((packet->modifiers & HIDDI_MKEY_RIGHT_ALT) == 0) &&
(key_last_state[devno].modifiers & HIDDI_MKEY_RIGHT_ALT) ==
HIDDI_MKEY_RIGHT_ALT) {
/* Right Alt key was released */
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RALT);
}
if (((packet->modifiers & HIDDI_MKEY_RIGHT_WFLAG) ==
HIDDI_MKEY_RIGHT_WFLAG)
&& (key_last_state[devno].modifiers & HIDDI_MKEY_RIGHT_WFLAG) ==
0) {
/* Right Windows flag key was pressed */
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_RGUI);
}
if (((packet->modifiers & HIDDI_MKEY_RIGHT_WFLAG) == 0) &&
(key_last_state[devno].modifiers & HIDDI_MKEY_RIGHT_WFLAG) ==
HIDDI_MKEY_RIGHT_WFLAG) {
/* Right Windows flag key was released */
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RGUI);
}
}
/* Check each key in the press/release buffer */
switch (report_len) {
case 8: /* 8 bytes of report length */
{
/* Check if at least one key was unpressed */
for (it = 0; it < 6; it++) {
if (key_last_state[devno].codes[it] == HIDDI_KEY_UNPRESSED) {
/* if stored keycode is zero, find another */
continue;
}
for (jt = 0; jt < 6; jt++) {
/* Find stored keycode in the current pressed codes */
if (packet->codes[jt] == key_last_state[devno].codes[it]) {
/* If found then particular key state is not changed */
break;
}
}
/* Check if pressed key can't longer be found */
if (jt == 6) {
SDL_SendKeyboardKey(0, SDL_RELEASED,
key_last_state[devno].codes[it]);
}
}
/* Check if at least one new key was pressed */
for (it = 0; it < 6; it++) {
if (packet->codes[it] == HIDDI_KEY_UNPRESSED) {
continue;
}
for (jt = 0; jt < 6; jt++) {
/* Find new keycode it the array of old pressed keys */
if (packet->codes[it] == key_last_state[devno].codes[jt]) {
break;
}
}
/* Check if new key was pressed */
if (jt == 6) {
SDL_SendKeyboardKey(0, SDL_PRESSED, packet->codes[it]);
}
}
}
default: /* unknown keyboard report type */
{
/* Ignore all unknown reports */
}
break;
}
/* Store last state */
key_last_state[devno] = *packet;
}
static uint32_t mouse_last_state_button[SDL_HIDDI_MAX_DEVICES];
static uint32_t collect_reports = 0;
static void
hiddi_mouse_handler(uint32_t devno, uint8_t * report_data,
uint32_t report_len)
{
uint32_t it;
uint32_t sdlbutton;
/* We do not want to collect stored events */
if (collect_reports == 0) {
return;
}
/* Check for special states */
switch (report_len) {
case 8: /* 8 bytes of report length, usually multi-button USB mice */
{
mouse_packet8 *packet;
packet = (mouse_packet8 *) report_data;
/* Send motion event if motion really was */
if ((packet->horizontal_precision != 0)
|| (packet->vertical_precision != 0)) {
SDL_SendMouseMotion(0, 1, packet->horizontal_precision,
packet->vertical_precision, 0);
}
/* Send mouse button press/release events */
if (mouse_last_state_button[devno] != packet->buttons) {
/* Cycle all buttons status */
for (it = 0; it < 8; it++) {
/* convert hiddi button id to sdl button id */
switch (it) {
case 0:
{
sdlbutton = SDL_BUTTON_LEFT;
}
break;
case 1:
{
sdlbutton = SDL_BUTTON_RIGHT;
}
break;
case 2:
{
sdlbutton = SDL_BUTTON_MIDDLE;
}
break;
default:
{
sdlbutton = it + 1;
}
break;
}
/* Button pressed */
if (((packet->buttons & (0x01 << it)) == (0x01 << it)) &&
((mouse_last_state_button[devno] & (0x01 << it)) ==
0x00)) {
SDL_SendMouseButton(0, SDL_PRESSED, sdlbutton);
}
/* Button released */
if (((packet->buttons & (0x01 << it)) == 0x00) &&
((mouse_last_state_button[devno] & (0x01 << it)) ==
(0x01 << it))) {
SDL_SendMouseButton(0, SDL_RELEASED, sdlbutton);
}
}
mouse_last_state_button[devno] = packet->buttons;
}
/* Send mouse wheel events */
if (packet->wheel != 0) {
/* Send vertical wheel event only */
SDL_SendMouseWheel(0, 0, packet->wheel);
}
}
break;
case 4: /* 4 bytes of report length, usually PS/2 mice */
{
mouse_packet4 *packet;
packet = (mouse_packet4 *) report_data;
/* Send motion event if motion really was */
if ((packet->horizontal != 0) || (packet->vertical != 0)) {
SDL_SendMouseMotion(0, 1, packet->horizontal,
packet->vertical, 0);
}
/* Send mouse button press/release events */
if (mouse_last_state_button[devno] != packet->buttons) {
/* Cycle all buttons status */
for (it = 0; it < 8; it++) {
/* convert hiddi button id to sdl button id */
switch (it) {
case 0:
{
sdlbutton = SDL_BUTTON_LEFT;
}
break;
case 1:
{
sdlbutton = SDL_BUTTON_RIGHT;
}
break;
case 2:
{
sdlbutton = SDL_BUTTON_MIDDLE;
}
break;
default:
{
sdlbutton = it + 1;
}
break;
}
/* Button pressed */
if (((packet->buttons & (0x01 << it)) == (0x01 << it)) &&
((mouse_last_state_button[devno] & (0x01 << it)) ==
0x00)) {
SDL_SendMouseButton(0, SDL_PRESSED, sdlbutton);
}
/* Button released */
if (((packet->buttons & (0x01 << it)) == 0x00) &&
((mouse_last_state_button[devno] & (0x01 << it)) ==
(0x01 << it))) {
SDL_SendMouseButton(0, SDL_RELEASED, sdlbutton);
}
}
mouse_last_state_button[devno] = packet->buttons;
}
/* Send mouse wheel events */
if (packet->wheel != 0) {
/* Send vertical wheel event only */
SDL_SendMouseWheel(0, 0, packet->wheel);
}
}
break;
}
}
/*****************************************************************************/
/* HIDDI interacting code */
/*****************************************************************************/
static hidd_device_ident_t hiddevice = {
HIDD_CONNECT_WILDCARD, /* vendor id: any */
HIDD_CONNECT_WILDCARD, /* product id: any */
HIDD_CONNECT_WILDCARD, /* version: any */
};
static hidd_connect_parm_t hidparams =
{ NULL, HID_VERSION, HIDD_VERSION, 0, 0, &hiddevice, NULL, 0 };
static void hiddi_insertion(struct hidd_connection *connection,
hidd_device_instance_t * device_instance);
static void hiddi_removal(struct hidd_connection *connection,
hidd_device_instance_t * instance);
static void hiddi_report(struct hidd_connection *connection,
struct hidd_report *report, void *report_data,
uint32_t report_len, uint32_t flags, void *user);
static hidd_funcs_t hidfuncs =
{ _HIDDI_NFUNCS, hiddi_insertion, hiddi_removal, hiddi_report, NULL };
/* HID handle, singletone */
struct hidd_connection *connection = NULL;
/* SDL detected input device types, singletone */
static uint32_t sdl_input_devices[SDL_HIDDI_MAX_DEVICES];
static int
hiddi_register_for_reports(struct hidd_collection *col,
hidd_device_instance_t * device_instance)
{
int it;
uint16_t num_col;
struct hidd_collection **hidd_collections;
struct hidd_report_instance *report_instance;
struct hidd_report *report;
int status = 0;
hidview_device_t *device;
for (it = 0; it < 10 && !status; it++) {
status =
hidd_get_report_instance(col, it, HID_INPUT_REPORT,
&report_instance);
if (status == EOK) {
status =
hidd_report_attach(connection, device_instance,
report_instance, 0,
sizeof(hidview_device_t), &report);
if (status == EOK) {
device = hidd_report_extra(report);
device->report = report;
device->instance = report_instance;
}
}
}
hidd_get_collections(NULL, col, &hidd_collections, &num_col);
for (it = 0; it < num_col; it++) {
hiddi_register_for_reports(hidd_collections[it], device_instance);
}
return EOK;
}
static void
hiddi_insertion(struct hidd_connection *connection,
hidd_device_instance_t * device_instance)
{
uint32_t it;
struct hidd_collection **hidd_collections;
uint16_t num_col;
/* get root level collections */
hidd_get_collections(device_instance, NULL, &hidd_collections, &num_col);
for (it = 0; it < num_col; it++) {
hiddi_register_for_reports(hidd_collections[it], device_instance);
}
}
static void
hiddi_removal(struct hidd_connection *connection,
hidd_device_instance_t * instance)
{
hidd_reports_detach(connection, instance);
}
static void
hiddi_report(struct hidd_connection *connection, hidd_report_t * report,
void *report_data, uint32_t report_len, uint32_t flags,
void *user)
{
if (report->dev_inst->devno >= SDL_HIDDI_MAX_DEVICES) {
/* Unknown HID device, with devno number out of supported range */
return;
}
/* Check device type which generates event */
switch (sdl_input_devices[report->dev_inst->devno]) {
case SDL_GF_HIDDI_NONE:
{
/* We do not handle other devices type */
return;
}
break;
case SDL_GF_HIDDI_MOUSE:
{
/* Call mouse handler */
hiddi_mouse_handler(report->dev_inst->devno, report_data,
report_len);
}
break;
case SDL_GF_HIDDI_KEYBOARD:
{
/* Call keyboard handler */
hiddi_keyboard_handler(report->dev_inst->devno, report_data,
report_len);
}
break;
case SDL_GF_HIDDI_JOYSTICK:
{
/* Call joystick handler */
}
break;
}
}
static
hiddi_get_device_type(uint8_t * report_data, uint16_t report_length)
{
hid_byte_t byte;
uint16_t usage_page = 0;
uint16_t usage = 0;
uint16_t data = 0;
while (report_length && !(usage_page && usage)) {
if (hidp_analyse_byte(*report_data, &byte)) {
/* Error in parser, do nothing */
}
data = hidp_get_data((report_data + 1), &byte);
switch (byte.HIDB_Type) {
case HID_TYPE_GLOBAL:
if (!usage_page && byte.HIDB_Tag == HID_GLOBAL_USAGE_PAGE) {
usage_page = data;
}
break;
case HID_TYPE_LOCAL:
if (!usage && byte.HIDB_Tag == HID_LOCAL_USAGE) {
usage = data;
}
break;
}
report_data += byte.HIDB_Length + 1;
report_length -= byte.HIDB_Length + 1;
}
switch (usage_page) {
case HIDD_PAGE_DESKTOP:
{
switch (usage) {
case HIDD_USAGE_MOUSE:
{
return SDL_GF_HIDDI_MOUSE;
}
break;
case HIDD_USAGE_JOYSTICK:
{
return SDL_GF_HIDDI_JOYSTICK;
}
break;
case HIDD_USAGE_KEYBOARD:
{
return SDL_GF_HIDDI_KEYBOARD;
}
break;
}
}
break;
case HIDD_PAGE_DIGITIZER:
{
/* Do not handle digitizers */
}
break;
case HIDD_PAGE_CONSUMER:
{
/* Do not handle consumer input devices */
}
break;
}
return SDL_GF_HIDDI_NONE;
}
static int32_t
hiddi_connect_devices()
{
int32_t status;
uint32_t it;
uint8_t *report_data;
uint16_t report_length;
hidd_device_instance_t instance;
/* Cleanup initial keys and mice state */
SDL_memset(key_last_state, 0x00,
sizeof(key_packet) * SDL_HIDDI_MAX_DEVICES);
SDL_memset(mouse_last_state_button, 0x00,
sizeof(uint32_t) * SDL_HIDDI_MAX_DEVICES);
status = hidd_connect(&hidparams, &connection);
if (status != EOK) {
connection=NULL;
return -1;
}
for (it = 0; it < SDL_HIDDI_MAX_DEVICES; it++) {
/* Get device instance */
status = hidd_get_device_instance(connection, it, &instance);
if (status != EOK) {
continue;
}
status =
hidd_get_report_desc(connection, &instance, &report_data,
&report_length);
if (status != EOK) {
continue;
}
status = hiddi_get_device_type(report_data, report_length);
sdl_input_devices[it] = status;
free(report_data);
}
/* Disconnect from HID server */
status = hidd_disconnect(connection);
if (status != EOK) {
connection=NULL;
return -1;
}
/* Add handlers for HID devices */
hidparams.funcs = &hidfuncs;
status = hidd_connect(&hidparams, &connection);
if (status != EOK) {
connection=NULL;
return -1;
}
return 0;
}
static int32_t
hiddi_disconnect_devices()
{
int32_t status;
hiddi_disable_mouse();
/* Disconnect from HID server */
if (connection!=NULL)
{
status = hidd_disconnect(connection);
if (status != EOK) {
return -1;
}
}
}
void
hiddi_enable_mouse()
{
collect_reports = 1;
}
void
hiddi_disable_mouse()
{
collect_reports = 0;
}
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Graphics Framework SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#ifndef __SDL_GF_INPUT_H__
#define __SDL_GF_INPUT_H__
#include "SDL_config.h"
#include "SDL_video.h"
#include "../SDL_sysvideo.h"
#include <errno.h>
#include <gf/gf.h>
#include <sys/hiddi.h>
#include <sys/hidut.h>
#include "SDL_qnxgf.h"
typedef struct SDL_MouseData
{
SDL_DisplayData *didata;
} SDL_MouseData;
int32_t gf_addinputdevices(_THIS);
int32_t gf_delinputdevices(_THIS);
#define SDL_GF_MOUSE_COLOR_BLACK 0xFF000000
#define SDL_GF_MOUSE_COLOR_WHITE 0xFFFFFFFF
#define SDL_GF_MOUSE_COLOR_TRANS 0x00000000
/*****************************************************************************/
/* This is HIDDI closed interface declarations */
/*****************************************************************************/
#define HID_TYPE_MAIN 0x0
#define HID_TYPE_GLOBAL 0x1
#define HID_TYPE_LOCAL 0x2
#define HID_TYPE_RESERVED 0x3
#define HID_GLOBAL_USAGE_PAGE 0x0
#define HID_LOCAL_USAGE 0x0
typedef struct _hid_byte
{
uint8_t HIDB_Length;
uint8_t HIDB_Type;
uint8_t HIDB_Tag;
uint8_t reserved[1];
} hid_byte_t;
typedef struct _hidd_global_item
{
uint16_t usage_page;
uint16_t logical_min;
uint16_t logical_max;
uint16_t physical_min;
uint16_t physical_max;
uint16_t unit_expo;
uint16_t unit;
uint16_t report_size;
uint16_t report_id;
uint16_t report_count;
} hidd_global_item_t;
typedef struct _hidd_local_item
{
uint16_t type;
uint8_t reserved[2];
uint32_t value;
struct _hidd_local_item *next_local;
struct _hidd_local_item *alt_local;
} hidd_local_item_t;
typedef struct _hidd_local_table
{
hidd_local_item_t *usage_info;
hidd_local_item_t *designator_info;
hidd_local_item_t *string_info;
uint8_t delimiter;
uint8_t reserved[3];
} hidd_local_table_t;
typedef struct _hidd_field
{
struct hidd_report_instance *report;
struct hidd_collection *collection;
uint16_t report_offset;
uint16_t flags;
hidd_global_item_t gitem;
hidd_local_table_t *ltable;
struct _hidd_field *next_field;
void *user;
} hidd_field_t;
typedef struct hidd_report_instance
{
uint8_t report_id;
uint8_t reserved[1];
uint16_t report_type;
hidd_field_t *field;
uint16_t num_field;
uint16_t byte_len;
uint16_t bit_len;
uint8_t reserved2[2];
struct hidd_collection *collection;
struct hidd_report_instance *next_col_report;
struct hidd_report_instance *next_report;
} hidd_report_instance_t;
typedef struct hidd_report
{
TAILQ_ENTRY(hidd_report) link;
hidd_report_instance_t *rinst;
hidd_device_instance_t *dev_inst;
uint32_t flags;
struct hidd_connection *connection;
void *user;
} hidd_report_t;
typedef struct hidview_device
{
struct hidd_report_instance *instance;
struct hidd_report *report;
} hidview_device_t;
/*****************************************************************************/
/* Closed HIDDI interface declarations end */
/*****************************************************************************/
/* Maximum devices and subdevices amount per host */
#define SDL_HIDDI_MAX_DEVICES 64
/* Detected device/subdevice type for SDL */
#define SDL_GF_HIDDI_NONE 0x00000000
#define SDL_GF_HIDDI_MOUSE 0x00000001
#define SDL_GF_HIDDI_KEYBOARD 0x00000002
#define SDL_GF_HIDDI_JOYSTICK 0x00000003
extern void hiddi_enable_mouse();
extern void hiddi_disable_mouse();
#endif /* __SDL_GF_INPUT_H__ */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Graphics Framework SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#include <GLES/gl.h>
#include <GLES/glext.h>
/* This is OpenGL ES 1.0 helper functions from OpenGL ES 1.1 specification, */
/* which could be implemented independently from hardware, just wrappers */
GLAPI void APIENTRY
glTexParameteri(GLenum target, GLenum pname, GLint param)
{
glTexParameterx(target, pname, (GLfixed) param);
return;
}
GLAPI void APIENTRY
glTexParameteriv(GLenum target, GLenum pname, const GLint * params)
{
/* Retrieve one parameter only */
glTexParameterx(target, pname, (GLfixed) * params);
return;
}
GLAPI void APIENTRY
glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
{
glColor4f(((GLfloat) red) / 255.f, ((GLfloat) green) / 255.f,
((GLfloat) blue) / 255.f, ((GLfloat) alpha) / 255.f);
return;
}
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Graphics Framework SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#ifndef __SDL_GF_OPENGLES_H__
#define __SDL_GF_OPENGLES_H__
#include <GLES/gl.h>
#include <GLES/glext.h>
GLAPI void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param);
GLAPI void APIENTRY glTexParameteriv(GLenum target, GLenum pname,
const GLint * params);
GLAPI void APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue,
GLubyte alpha);
#endif /* __SDL_GF_OPENGLES_H__ */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Graphics Framework SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#include "SDL_config.h"
#include "SDL_gf_pixelfmt.h"
gf_format_t
qnxgf_sdl_to_gf_pixelformat(uint32_t pixelfmt)
{
switch (pixelfmt) {
case SDL_PIXELFORMAT_INDEX8:
{
return GF_FORMAT_PAL8;
}
break;
case SDL_PIXELFORMAT_ARGB1555:
{
return GF_FORMAT_PACK_ARGB1555;
}
break;
case SDL_PIXELFORMAT_RGB555:
{
/* RGB555 is the same as ARGB1555, but alpha is ignored */
return GF_FORMAT_PACK_ARGB1555;
}
break;
case SDL_PIXELFORMAT_RGB565:
{
return GF_FORMAT_PACK_RGB565;
}
break;
case SDL_PIXELFORMAT_BGR565:
{
return GF_FORMAT_PKBE_RGB565;
}
break;
case SDL_PIXELFORMAT_RGB24:
{
/* GF has wrong components order */
return GF_FORMAT_BGR888;
}
break;
case SDL_PIXELFORMAT_RGB888:
{
/* The same format as ARGB8888, but with alpha ignored */
/* and GF has wrong components order */
return GF_FORMAT_BGRA8888;
}
break;
case SDL_PIXELFORMAT_ARGB8888:
{
/* GF has wrong components order */
return GF_FORMAT_BGRA8888;
}
break;
case SDL_PIXELFORMAT_BGRA8888:
{
/* GF has wrong components order */
return GF_FORMAT_ARGB8888;
}
break;
case SDL_PIXELFORMAT_YV12:
{
return GF_FORMAT_PLANAR_YUV_YV12;
}
break;
case SDL_PIXELFORMAT_YUY2:
{
return GF_FORMAT_PACK_YUV_YUY2;
}
break;
case SDL_PIXELFORMAT_UYVY:
{
return GF_FORMAT_PACK_YUV_UYVY;
}
break;
case SDL_PIXELFORMAT_YVYU:
{
return GF_FORMAT_PACK_YUV_YVYU;
}
break;
}
return GF_FORMAT_INVALID;
}
uint32_t
qnxgf_gf_to_sdl_pixelformat(gf_format_t pixelfmt)
{
switch (pixelfmt) {
case GF_FORMAT_PAL8:
{
return SDL_PIXELFORMAT_INDEX8;
}
break;
case GF_FORMAT_PKLE_ARGB1555:
{
return SDL_PIXELFORMAT_ARGB1555;
}
break;
case GF_FORMAT_PACK_ARGB1555:
{
return SDL_PIXELFORMAT_ARGB1555;
}
break;
case GF_FORMAT_PKBE_RGB565:
{
return SDL_PIXELFORMAT_BGR565;
}
break;
case GF_FORMAT_PKLE_RGB565:
{
return SDL_PIXELFORMAT_RGB565;
}
break;
case GF_FORMAT_PACK_RGB565:
{
return SDL_PIXELFORMAT_RGB565;
}
break;
case GF_FORMAT_BGR888:
{
/* GF has wrong components order */
return SDL_PIXELFORMAT_RGB24;
}
break;
case GF_FORMAT_BGRA8888:
{
/* GF has wrong components order */
return SDL_PIXELFORMAT_ARGB8888;
}
break;
case GF_FORMAT_ARGB8888:
{
/* GF has wrong components order */
return SDL_PIXELFORMAT_BGRA8888;
}
break;
case GF_FORMAT_PLANAR_YUV_YV12:
{
return SDL_PIXELFORMAT_YV12;
}
break;
case GF_FORMAT_PACK_YUV_YUY2:
{
return SDL_PIXELFORMAT_YUY2;
}
break;
case GF_FORMAT_PACK_YUV_UYVY:
{
return SDL_PIXELFORMAT_UYVY;
}
break;
case GF_FORMAT_PACK_YUV_YVYU:
{
return SDL_PIXELFORMAT_YVYU;
}
break;
}
return SDL_PIXELFORMAT_UNKNOWN;
}
/* vi: set ts=4 sw=4 expandtab: */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Graphics Framework SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#ifndef __SDL_GF_PIXELFMT_H__
#define __SDL_GF_PIXELFMT_H__
#include "../SDL_sysvideo.h"
#include <gf/gf.h>
gf_format_t qnxgf_sdl_to_gf_pixelformat(uint32_t pixelfmt);
uint32_t qnxgf_gf_to_sdl_pixelformat(gf_format_t pixelfmt);
#endif /* __SDL_GF_PIXELFMT_H__ */
/* vi: set ts=4 sw=4 expandtab: */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Graphics Framework SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#include "SDL_config.h"
#include "../SDL_pixels_c.h"
#include "../SDL_yuv_sw_c.h"
#include "SDL_video.h"
#include "SDL_gf_render.h"
#include "SDL_qnxgf.h"
static SDL_Renderer *gf_createrenderer(SDL_Window * window, Uint32 flags);
static int gf_displaymodechanged(SDL_Renderer * renderer);
static int gf_activaterenderer(SDL_Renderer * renderer);
static int gf_createtexture(SDL_Renderer * renderer, SDL_Texture * texture);
static int gf_querytexturepixels(SDL_Renderer * renderer,
SDL_Texture * texture, void **pixels,
int *pitch);
static int gf_settexturepalette(SDL_Renderer * renderer,
SDL_Texture * texture,
const SDL_Color * colors, int firstcolor,
int ncolors);
static int gf_gettexturepalette(SDL_Renderer * renderer,
SDL_Texture * texture, SDL_Color * colors,
int firstcolor, int ncolors);
static int gf_updatetexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, const void *pixels,
int pitch);
static int gf_locktexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, int markDirty, void **pixels,
int *pitch);
static void gf_unlocktexture(SDL_Renderer * renderer, SDL_Texture * texture);
static void gf_dirtytexture(SDL_Renderer * renderer, SDL_Texture * texture,
int numrects, const SDL_Rect * rects);
static int gf_renderpoint(SDL_Renderer * renderer, int x, int y);
static int gf_renderline(SDL_Renderer * renderer, int x1, int y1, int x2,
int y2);
static int gf_renderfill(SDL_Renderer * renderer, const SDL_Rect * rect);
static int gf_rendercopy(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect);
static void gf_renderpresent(SDL_Renderer * renderer);
static void gf_destroytexture(SDL_Renderer * renderer, SDL_Texture * texture);
static void gf_destroyrenderer(SDL_Renderer * renderer);
SDL_RenderDriver gf_renderdriver = {
gf_createrenderer,
{
"qnxgf",
(SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_PRESENTDISCARD |
SDL_RENDERER_ACCELERATED),
12,
{
SDL_PIXELFORMAT_RGB555,
SDL_PIXELFORMAT_RGB565,
SDL_PIXELFORMAT_RGB888,
SDL_PIXELFORMAT_BGR888,
SDL_PIXELFORMAT_ARGB8888,
SDL_PIXELFORMAT_RGBA8888,
SDL_PIXELFORMAT_ABGR8888,
SDL_PIXELFORMAT_BGRA8888,
SDL_PIXELFORMAT_YV12,
SDL_PIXELFORMAT_YUY2,
SDL_PIXELFORMAT_UYVY,
SDL_PIXELFORMAT_YVYU},
0,
0}
};
static SDL_Renderer *
gf_createrenderer(SDL_Window * window, Uint32 flags)
{
SDL_VideoDisplay *display = window->display;
SDL_DisplayData *didata = (SDL_DisplayData *) display->driverdata;
SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
SDL_Renderer *renderer = NULL;
SDL_RenderData *rdata = NULL;
uint32_t it;
int32_t jt;
int32_t status;
/* Check if it is OpenGL ES window */
if ((window->flags & SDL_WINDOW_OPENGL) == SDL_WINDOW_OPENGL) {
/* No error, just no need to create 2D renderer for OpenGL ES window */
return NULL;
}
/* Allocate new renderer structure */
renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(SDL_Renderer));
if (renderer == NULL) {
SDL_OutOfMemory();
return NULL;
}
/* Allocate renderer data */
rdata = (SDL_RenderData *) SDL_calloc(1, sizeof(SDL_RenderData));
if (rdata == NULL) {
SDL_free(renderer);
SDL_OutOfMemory();
return NULL;
}
renderer->DisplayModeChanged = gf_displaymodechanged;
renderer->ActivateRenderer = gf_activaterenderer;
renderer->CreateTexture = gf_createtexture;
renderer->QueryTexturePixels = gf_querytexturepixels;
renderer->UpdateTexture = gf_updatetexture;
renderer->LockTexture = gf_locktexture;
renderer->UnlockTexture = gf_unlocktexture;
renderer->DirtyTexture = gf_dirtytexture;
renderer->RenderPoint = gf_renderpoint;
renderer->RenderLine = gf_renderline;
renderer->RenderFill = gf_renderfill;
renderer->RenderCopy = gf_rendercopy;
renderer->RenderPresent = gf_renderpresent;
renderer->DestroyTexture = gf_destroytexture;
renderer->DestroyRenderer = gf_destroyrenderer;
renderer->info = gf_renderdriver.info;
renderer->window = window;
renderer->driverdata = rdata;
/* Set render acceleration flag in case it is accelerated */
if ((didata->caps & SDL_GF_ACCELERATED) == SDL_GF_ACCELERATED) {
renderer->info.flags = SDL_RENDERER_ACCELERATED;
} else {
renderer->info.flags &= ~(SDL_RENDERER_ACCELERATED);
}
rdata->window = window;
/* Check if upper level requested synchronization on vsync signal */
if ((flags & SDL_RENDERER_PRESENTVSYNC) == SDL_RENDERER_PRESENTVSYNC) {
rdata->enable_vsync = SDL_TRUE;
} else {
rdata->enable_vsync = SDL_FALSE;
}
/* Check what buffer copy/flip scheme is requested */
rdata->surfaces_count = 0;
if ((flags & SDL_RENDERER_SINGLEBUFFER) == SDL_RENDERER_SINGLEBUFFER) {
if ((flags & SDL_RENDERER_PRESENTDISCARD) ==
SDL_RENDERER_PRESENTDISCARD) {
renderer->info.flags |=
SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD;
} else {
renderer->info.flags |=
SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY;
}
rdata->surfaces_count = 1;
rdata->surface_visible_idx = 0;
rdata->surface_render_idx = 0;
} else {
if ((flags & SDL_RENDERER_PRESENTFLIP2) == SDL_RENDERER_PRESENTFLIP2) {
renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
rdata->surfaces_count = 2;
rdata->surface_visible_idx = 0;
rdata->surface_render_idx = 1;
} else {
if ((flags & SDL_RENDERER_PRESENTFLIP3) ==
SDL_RENDERER_PRESENTFLIP3) {
renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
rdata->surfaces_count = 3;
rdata->surface_visible_idx = 0;
rdata->surface_render_idx = 1;
} else {
renderer->info.flags |=
SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY;
rdata->surfaces_count = 1;
rdata->surface_visible_idx = 0;
rdata->surface_render_idx = 0;
}
}
}
/* Create layer surfaces, which could be visible */
for (it = 0; it < rdata->surfaces_count; it++) {
/* TODO: add palette creation */
/* Create displayable surfaces */
status =
gf_surface_create_layer(&rdata->surface[it], &didata->layer, 1, 0,
didata->current_mode.w,
didata->current_mode.h,
qnxgf_sdl_to_gf_pixelformat(didata->
current_mode.
format), NULL,
GF_SURFACE_CREATE_2D_ACCESSIBLE);
if (status != GF_ERR_OK) {
/* Free already allocated surfaces */
for (jt = it - 1; jt > 0; jt--) {
gf_surface_free(rdata->surface[jt]);
rdata->surface[jt] = NULL;
}
SDL_free(rdata);
SDL_free(renderer);
if (status == GF_ERR_MEM) {
SDL_SetError("unsufficient free video memory");
} else {
SDL_SetError("error during displayable surface creation");
}
return NULL;
}
/* Get detailed information about allocated surface */
gf_surface_get_info(rdata->surface[it], &rdata->surface_info[it]);
}
return renderer;
}
void
gf_addrenderdriver(_THIS)
{
uint32_t it;
for (it = 0; it < _this->num_displays; it++) {
SDL_AddRenderDriver(&_this->displays[it], &gf_renderdriver);
}
}
/****************************************************************************/
/* SDL render interface */
/****************************************************************************/
static int
gf_displaymodechanged(SDL_Renderer * renderer)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
/* Remove all allocated surfaces, they are no more valid */
/* TODO: Add video mode change detection and new parameters detection */
return 0;
}
static int
gf_activaterenderer(SDL_Renderer * renderer)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
SDL_VideoDisplay *display = rdata->window->display;
SDL_DisplayData *didata = (SDL_DisplayData *) display->driverdata;
/* Setup current surface as visible */
// gf_layer_set_surfaces(didata->layer, &rdata->surface[rdata->surface_visible_idx], 1);
/* Set visible surface when hardware in idle state */
// gf_layer_update(didata->layer, GF_LAYER_UPDATE_NO_WAIT_IDLE);
return 0;
}
static int
gf_createtexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
SDL_RenderData *renderdata = (SDL_RenderData *) renderer->driverdata;
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
SDL_VideoDisplay *display = window->display;
SDL_TextureData *tdata = NULL;
/* Allocate texture driver data */
tdata = (SDL_TextureData *) SDL_calloc(1, sizeof(SDL_TextureData));
if (tdata == NULL) {
SDL_OutOfMemory();
return -1;
}
/* Set texture driver data */
texture->driverdata = tdata;
}
static int
gf_querytexturepixels(SDL_Renderer * renderer, SDL_Texture * texture,
void **pixels, int *pitch)
{
}
static int
gf_updatetexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, const void *pixels, int pitch)
{
}
static int
gf_locktexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, int markDirty, void **pixels,
int *pitch)
{
}
static void
gf_unlocktexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
}
static void
gf_dirtytexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects,
const SDL_Rect * rects)
{
}
static int
gf_renderpoint(SDL_Renderer * renderer, int x, int y)
{
}
static int
gf_renderline(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
{
}
static int
gf_renderfill(SDL_Renderer * renderer, const SDL_Rect * rect)
{
}
static int
gf_rendercopy(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect)
{
}
static void
gf_renderpresent(SDL_Renderer * renderer)
{
}
static void
gf_destroytexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
}
static void
gf_destroyrenderer(SDL_Renderer * renderer)
{
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
uint32_t it;
for (it = 0; it < rdata->surfaces_count; it++) {
if (rdata->surface[it] != NULL) {
gf_surface_free(rdata->surface[it]);
}
}
}
/* vi: set ts=4 sw=4 expandtab: */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Graphics Framework SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#ifndef __SDL_GF_RENDER_H__
#define __SDL_GF_RENDER_H__
#include "../SDL_sysvideo.h"
#include <gf/gf.h>
#define SDL_GF_MAX_SURFACES 3
typedef struct SDL_RenderData
{
SDL_Window *window; /* SDL window type */
SDL_bool enable_vsync; /* VSYNC flip synchronization enable */
gf_surface_t surface[SDL_GF_MAX_SURFACES]; /* Surface handles */
gf_surface_info_t surface_info[SDL_GF_MAX_SURFACES]; /* Surface info */
uint32_t surface_visible_idx; /* Index of visible surface */
uint32_t surface_render_idx; /* Index of render surface */
uint32_t surfaces_count; /* Amount of allocated surfaces */
} SDL_RenderData;
typedef struct SDL_TextureData
{
gf_surface_t surface;
gf_surface_info_t surface_info;
} SDL_TextureData;
extern void gf_addrenderdriver(_THIS);
#endif /* __SDL_GF_RENDER_H__ */
/* vi: set ts=4 sw=4 expandtab: */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Graphics Framework SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#ifndef __SDL_HIDDI_JOYSTICK_H__
#define __SDL_HIDDI_JOYSTICK_H__
#include <inttypes.h>
#endif /* __SDL_HIDDI_JOYSTICK_H__ */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Graphics Framework SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#ifndef __SDL_HIDDI_KEYBOARD_H__
#define __SDL_HIDDI_KEYBOARD_H__
#include <inttypes.h>
/* PS/2 and USB keyboards are generating this packet */
typedef struct key_packet
{
uint8_t modifiers;
uint8_t data;
uint8_t codes[6];
} key_packet;
/* Key modifier codes */
#define HIDDI_MKEY_LEFT_CTRL 0x00000001
#define HIDDI_MKEY_LEFT_SHIFT 0x00000002
#define HIDDI_MKEY_LEFT_ALT 0x00000004
#define HIDDI_MKEY_LEFT_WFLAG 0x00000008
#define HIDDI_MKEY_RIGHT_CTRL 0x00000010
#define HIDDI_MKEY_RIGHT_SHIFT 0x00000020
#define HIDDI_MKEY_RIGHT_ALT 0x00000040
#define HIDDI_MKEY_RIGHT_WFLAG 0x00000080
/* Key codes */
#define HIDDI_KEY_UNPRESSED 0x00000000
#define HIDDI_KEY_OVERFLOW 0x00000001
#define HIDDI_KEY_ESC 0x00000029
#define HIDDI_KEY_F1 0x0000003A
#define HIDDI_KEY_F2 0x0000003B
#define HIDDI_KEY_F3 0x0000003C
#define HIDDI_KEY_F4 0x0000003D
#define HIDDI_KEY_F5 0x0000003E
#define HIDDI_KEY_F6 0x0000003F
#define HIDDI_KEY_F7 0x00000040
#define HIDDI_KEY_F8 0x00000041
#define HIDDI_KEY_F9 0x00000042
#define HIDDI_KEY_F10 0x00000043
#define HIDDI_KEY_F11 0x00000044
#define HIDDI_KEY_F12 0x00000045
#define HIDDI_KEY_BACKQUOTE 0x00000035
#define HIDDI_KEY_1 0x0000001E
#define HIDDI_KEY_2 0x0000001F
#define HIDDI_KEY_3 0x00000020
#define HIDDI_KEY_4 0x00000021
#define HIDDI_KEY_5 0x00000022
#define HIDDI_KEY_6 0x00000023
#define HIDDI_KEY_7 0x00000024
#define HIDDI_KEY_8 0x00000025
#define HIDDI_KEY_9 0x00000026
#define HIDDI_KEY_0 0x00000027
#define HIDDI_KEY_MINUS 0x0000002D
#define HIDDI_KEY_EQUAL 0x0000002E
#define HIDDI_KEY_BACKSPACE 0x0000002A
#define HIDDI_KEY_TAB 0x0000002B
#define HIDDI_KEY_Q 0x00000014
#define HIDDI_KEY_W 0x0000001A
#define HIDDI_KEY_E 0x00000008
#define HIDDI_KEY_R 0x00000015
#define HIDDI_KEY_T 0x00000017
#define HIDDI_KEY_Y 0x0000001C
#define HIDDI_KEY_U 0x00000018
#define HIDDI_KEY_I 0x0000000C
#define HIDDI_KEY_O 0x00000012
#define HIDDI_KEY_P 0x00000013
#define HIDDI_KEY_LEFT_SQ_BRACKET 0x0000002F
#define HIDDI_KEY_RIGHT_SQ_BRACKET 0x00000030
#define HIDDI_KEY_BACKSLASH 0x00000031
#define HIDDI_KEY_CAPSLOCK 0x00000039
#define HIDDI_KEY_A 0x00000004
#define HIDDI_KEY_S 0x00000016
#define HIDDI_KEY_D 0x00000007
#define HIDDI_KEY_F 0x00000009
#define HIDDI_KEY_G 0x0000000A
#define HIDDI_KEY_H 0x0000000B
#define HIDDI_KEY_J 0x0000000D
#define HIDDI_KEY_K 0x0000000E
#define HIDDI_KEY_L 0x0000000F
#define HIDDI_KEY_SEMICOLON 0x00000033
#define HIDDI_KEY_QUOTE 0x00000034
#define HIDDI_KEY_ENTER 0x00000028
#define HIDDI_KEY_Z 0x0000001D
#define HIDDI_KEY_X 0x0000001B
#define HIDDI_KEY_C 0x00000006
#define HIDDI_KEY_V 0x00000019
#define HIDDI_KEY_B 0x00000005
#define HIDDI_KEY_N 0x00000011
#define HIDDI_KEY_M 0x00000010
#define HIDDI_KEY_COMMA 0x00000036
#define HIDDI_KEY_POINT 0x00000037
#define HIDDI_KEY_SLASH 0x00000038
#define HIDDI_KEY_SPACE 0x0000002C
#define HIDDI_KEY_MENU 0x00000065
#define HIDDI_KEY_PRINTSCREEN 0x00000046
#define HIDDI_KEY_SCROLLLOCK 0x00000047
#define HIDDI_KEY_PAUSE 0x00000048
#define HIDDI_KEY_INSERT 0x00000049
#define HIDDI_KEY_HOME 0x0000004A
#define HIDDI_KEY_PAGEUP 0x0000004B
#define HIDDI_KEY_DELETE 0x0000004C
#define HIDDI_KEY_END 0x0000004D
#define HIDDI_KEY_PAGEDOWN 0x0000004E
#define HIDDI_KEY_UP 0x00000052
#define HIDDI_KEY_LEFT 0x00000050
#define HIDDI_KEY_DOWN 0x00000051
#define HIDDI_KEY_RIGHT 0x0000004F
#define HIDDI_KEY_NUMLOCK 0x00000053
#define HIDDI_KEY_GR_SLASH 0x00000054
#define HIDDI_KEY_GR_ASTERISK 0x00000055
#define HIDDI_KEY_GR_MINUS 0x00000056
#define HIDDI_KEY_GR_7 0x0000005F
#define HIDDI_KEY_GR_8 0x00000060
#define HIDDI_KEY_GR_9 0x00000061
#define HIDDI_KEY_GR_PLUS 0x00000057
#define HIDDI_KEY_GR_4 0x0000005C
#define HIDDI_KEY_GR_5 0x0000005D
#define HIDDI_KEY_GR_6 0x0000005E
#define HIDDI_KEY_GR_1 0x00000059
#define HIDDI_KEY_GR_2 0x0000005A
#define HIDDI_KEY_GR_3 0x0000005B
#define HIDDI_KEY_GR_ENTER 0x00000058
#define HIDDI_KEY_GR_0 0x00000062
#define HIDDI_KEY_GR_DELETE 0x00000063
#endif /* __SDL_HIDDI_KEYBOARD_H__ */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Graphics Framework SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#ifndef __SDL_HIDDI_MOUSE_H__
#define __SDL_HIDDI_MOUSE_H__
#include <inttypes.h>
/* USB keyboard multimedia keys are generating this packet */
typedef struct mouse_packet2
{
uint8_t buttons;
int8_t wheel;
} mouse_packet2;
/* PS/2 mice are generating this packet */
typedef struct mouse_packet4
{
uint8_t buttons;
int8_t horizontal;
int8_t vertical;
int8_t wheel;
} mouse_packet4;
/* USB keyboard with mice wheel onboard generating this packet */
typedef struct mouse_packet5
{
uint8_t buttons;
int8_t horizontal;
int8_t vertical;
int8_t wheel;
uint8_t state;
} mouse_packet5;
/* USB multi-button mice are generating this packet */
typedef struct mouse_packet8
{
uint8_t buttons;
int8_t horizontal;
int8_t vertical;
int8_t wheel;
int16_t horizontal_precision;
int16_t vertical_precision;
} mouse_packet8;
#endif /* __SDL_HIDDI_MOUSE_H__ */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Graphics Framework SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#include "SDL_config.h"
#include "../SDL_sysvideo.h"
#include "SDL_version.h"
#include "SDL_syswm.h"
#include "SDL_loadso.h"
/* Include QNX Graphics Framework declarations */
#include <gf/gf.h>
#include "SDL_qnxgf.h"
#include "SDL_gf_render.h"
#include "SDL_gf_pixelfmt.h"
#include "SDL_gf_opengles.h"
#include "SDL_gf_input.h"
/******************************************************************************/
/* SDL Generic video modes, which could provide GF */
/* This is real pain in the ass. GF is just wrapper around a selected driver */
/* some drivers could support double scan modes, like 320x200, 512x384, etc */
/* but some drivers are not. Later we can distinguish one driver from another */
/* Feel free to add any new custom graphics mode */
/******************************************************************************/
static const SDL_DisplayMode generic_mode[] = {
{0, 320, 200, 70, NULL}, /* 320x200 modes are 70Hz and 85Hz */
{0, 320, 200, 85, NULL},
{0, 320, 240, 70, NULL}, /* 320x240 modes are 70Hz and 85Hz */
{0, 320, 240, 85, NULL},
{0, 400, 300, 60, NULL}, /* 400x300 mode is 60Hz only */
{0, 480, 360, 60, NULL}, /* 480x360 mode is 60Hz only */
{0, 512, 384, 60, NULL}, /* 512x384 modes are 60Hz and 70Hz */
{0, 512, 384, 70, NULL},
{0, 640, 480, 60, NULL}, /* 640x480 modes are 60Hz, 75Hz, 85Hz */
{0, 640, 480, 75, NULL},
{0, 640, 480, 85, NULL},
{0, 800, 600, 60, NULL}, /* 800x600 modes are 60Hz, 75Hz, 85Hz */
{0, 800, 600, 75, NULL},
{0, 800, 600, 85, NULL},
{0, 800, 480, 60, NULL}, /* 800x480 mode is 60Hz only */
{0, 848, 480, 60, NULL}, /* 848x480 mode is 60Hz only */
{0, 960, 600, 60, NULL}, /* 960x600 mode is 60Hz only */
{0, 1024, 640, 60, NULL}, /* 1024x640 mode is 60Hz only */
{0, 1024, 768, 60, NULL}, /* 1024x768 modes are 60Hz, 70Hz, 75Hz */
{0, 1024, 768, 70, NULL},
{0, 1024, 768, 75, NULL},
{0, 1088, 612, 60, NULL}, /* 1088x612 mode is 60Hz only */
{0, 1152, 864, 60, NULL}, /* 1152x864 modes are 60Hz, 70Hz, 72Hz */
{0, 1152, 864, 70, NULL}, /* 75Hz and 85Hz */
{0, 1152, 864, 72, NULL},
{0, 1152, 864, 75, NULL},
{0, 1152, 864, 85, NULL},
{0, 1280, 720, 60, NULL}, /* 1280x720 mode is 60Hz only */
{0, 1280, 768, 60, NULL}, /* 1280x768 mode is 60Hz only */
{0, 1280, 800, 60, NULL}, /* 1280x800 mode is 60Hz only */
{0, 1280, 960, 60, NULL}, /* 1280x960 mode is 60Hz only */
{0, 1280, 1024, 60, NULL}, /* 1280x1024 modes are 60Hz, 75Hz, 85Hz and */
{0, 1280, 1024, 75, NULL}, /* 100 Hz */
{0, 1280, 1024, 85, NULL}, /* */
{0, 1280, 1024, 100, NULL}, /* */
{0, 1360, 768, 60, NULL}, /* 1360x768 mode is 60Hz only */
{0, 1400, 1050, 60, NULL}, /* 1400x1050 mode is 60Hz only */
{0, 1440, 900, 60, NULL}, /* 1440x900 mode is 60Hz only */
{0, 1440, 960, 60, NULL}, /* 1440x960 mode is 60Hz only */
{0, 1600, 900, 60, NULL}, /* 1600x900 mode is 60Hz only */
{0, 1600, 1024, 60, NULL}, /* 1600x1024 mode is 60Hz only */
{0, 1600, 1200, 60, NULL}, /* 1600x1200 mode is 60Hz only */
{0, 1680, 1050, 60, NULL}, /* 1680x1050 mode is 60Hz only */
{0, 1920, 1080, 60, NULL}, /* 1920x1080 mode is 60Hz only */
{0, 1920, 1200, 60, NULL}, /* 1920x1200 mode is 60Hz only */
{0, 1920, 1440, 60, NULL}, /* 1920x1440 mode is 60Hz only */
{0, 2048, 1536, 60, NULL}, /* 2048x1536 mode is 60Hz only */
{0, 2048, 1080, 60, NULL}, /* 2048x1080 mode is 60Hz only */
{0, 0, 0, 0, NULL} /* End of generic mode list */
};
/* Low level device graphics driver names, which they are reporting */
static const GF_DeviceCaps gf_devicename[] = {
/* ATI Rage 128 graphics driver (devg-ati_rage128) */
{"ati_rage128", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* Fujitsu Carmine graphics driver (devg-carmine.so) */
{"carmine", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_ACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* C&T graphics driver (devg-chips.so) */
{"chips", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* Fujitsu Coral graphics driver (devg-coral.so) */
{"coral", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_ACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* Intel integrated graphics driver (devg-extreme2.so) */
{"extreme2", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_ACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* Unaccelerated FB driver (devg-flat.so) */
{"flat", SDL_GF_UNACCELERATED | SDL_GF_LOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_NOVIDEOMEMORY},
/* NS Geode graphics driver (devg-geode.so) */
{"geode", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* Geode LX graphics driver (devg-geodelx.so) */
{"geodelx", SDL_GF_ACCELERATED | SDL_GF_LOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* Intel integrated graphics driver (devg-gma9xx.so) */
{"gma", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_ACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* Intel integrated graphics driver (devg-i810.so) */
{"i810", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* Intel integrated graphics driver (devg-i830.so) */
{"i830", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* Geode LX graphics driver (devg-lx800.so) */
{"lx800", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* Matrox Gxx graphics driver (devg-matroxg.so) */
{"matroxg", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* Intel Poulsbo graphics driver (devg-poulsbo.so) */
{"poulsbo", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_ACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* ATI Radeon driver (devg-radeon.so) */
{"radeon", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* ATI Rage driver (devg-rage.so) */
{"rage", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* S3 Savage graphics driver (devg-s3_savage.so) */
{"s3_savage", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* SiS630 integrated graphics driver (devg-sis630.so) */
{"sis630", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* PowerVR SGX 535 graphics driver (devg-poulsbo.so) */
{"sgx", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_ACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* SM Voyager GX graphics driver (devg-smi5xx.so) */
{"smi5xx", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* Silicon Motion graphics driver (devg-smi7xx.so) */
{"smi7xx", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* SVGA unaccelerated gfx driver (devg-svga.so) */
{"svga", SDL_GF_UNACCELERATED | SDL_GF_LOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_NOVIDEOMEMORY},
/* nVidia TNT graphics driver (devg-tnt.so) */
{"tnt", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* VIA integrated graphics driver (devg-tvia.so) */
{"tvia", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* VIA UniChrome graphics driver (devg-unichrome.so) */
{"unichrome", SDL_GF_ACCELERATED | SDL_GF_NOLOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* VESA unaccelerated gfx driver (devg-vesa.so) */
{"vesa", SDL_GF_UNACCELERATED | SDL_GF_LOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_NOVIDEOMEMORY},
/* VmWare graphics driver (devg-volari.so) */
{"vmware", SDL_GF_ACCELERATED | SDL_GF_LOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_NOVIDEOMEMORY},
/* XGI XP10 graphics driver (devg-volari.so) */
{"volari", SDL_GF_ACCELERATED | SDL_GF_LOWRESOLUTION |
SDL_GF_UNACCELERATED_3D | SDL_GF_VIDEOMEMORY},
/* End of list */
{NULL, 0x00000000}
};
/*****************************************************************************/
/* SDL Video Device initialization functions */
/*****************************************************************************/
static int
qnxgf_available(void)
{
gf_dev_t gfdev;
gf_dev_info_t gfdev_info;
int status;
/* Try to attach to graphics device driver */
status = gf_dev_attach(&gfdev, GF_DEVICE_INDEX(0), &gfdev_info);
if (status != GF_ERR_OK) {
return 0;
}
/* Detach from graphics device driver for now */
gf_dev_detach(gfdev);
return 1;
}
static void
qnxgf_destroy(SDL_VideoDevice * device)
{
SDL_VideoData *gfdata = (SDL_VideoData *) device->driverdata;
/* Detach from graphics device driver, if it was initialized */
if (gfdata->gfinitialized != SDL_FALSE) {
gf_dev_detach(gfdata->gfdev);
gfdata->gfdev = NULL;
}
if (device->driverdata != NULL) {
device->driverdata = NULL;
}
}
static SDL_VideoDevice *
qnxgf_create(int devindex)
{
SDL_VideoDevice *device;
SDL_VideoData *gfdata;
int status;
/* Initialize SDL_VideoDevice structure */
device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
if (device == NULL) {
SDL_OutOfMemory();
return NULL;
}
/* Initialize internal GF specific data */
gfdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
if (gfdata == NULL) {
SDL_OutOfMemory();
SDL_free(device);
return NULL;
}
device->driverdata = gfdata;
/* By default GF is not initialized */
gfdata->gfinitialized = SDL_FALSE;
/* Try to attach to graphics device driver */
status =
gf_dev_attach(&gfdata->gfdev, GF_DEVICE_INDEX(devindex),
&gfdata->gfdev_info);
if (status != GF_ERR_OK) {
SDL_OutOfMemory();
SDL_free(gfdata);
SDL_free(device);
return NULL;
}
if (gfdata->gfdev_info.description == NULL) {
gf_dev_detach(gfdata->gfdev);
SDL_SetError("GF: Failed to initialize graphics driver");
return NULL;
}
/* Setup amount of available displays and current display */
device->num_displays = 0;
device->current_display = 0;
/* Setup device shutdown function */
gfdata->gfinitialized = SDL_TRUE;
device->free = qnxgf_destroy;
/* Setup all functions which we can handle */
device->VideoInit = qnxgf_videoinit;
device->VideoQuit = qnxgf_videoquit;
device->GetDisplayModes = qnxgf_getdisplaymodes;
device->SetDisplayMode = qnxgf_setdisplaymode;
device->SetDisplayGammaRamp = qnxgf_setdisplaygammaramp;
device->GetDisplayGammaRamp = qnxgf_getdisplaygammaramp;
device->CreateWindow = qnxgf_createwindow;
device->CreateWindowFrom = qnxgf_createwindowfrom;
device->SetWindowTitle = qnxgf_setwindowtitle;
device->SetWindowIcon = qnxgf_setwindowicon;
device->SetWindowPosition = qnxgf_setwindowposition;
device->SetWindowSize = qnxgf_setwindowsize;
device->ShowWindow = qnxgf_showwindow;
device->HideWindow = qnxgf_hidewindow;
device->RaiseWindow = qnxgf_raisewindow;
device->MaximizeWindow = qnxgf_maximizewindow;
device->MinimizeWindow = qnxgf_minimizewindow;
device->RestoreWindow = qnxgf_restorewindow;
device->SetWindowGrab = qnxgf_setwindowgrab;
device->DestroyWindow = qnxgf_destroywindow;
device->GetWindowWMInfo = qnxgf_getwindowwminfo;
device->GL_LoadLibrary = qnxgf_gl_loadlibrary;
device->GL_GetProcAddress = qnxgf_gl_getprocaddres;
device->GL_UnloadLibrary = qnxgf_gl_unloadlibrary;
device->GL_CreateContext = qnxgf_gl_createcontext;
device->GL_MakeCurrent = qnxgf_gl_makecurrent;
device->GL_SetSwapInterval = qnxgf_gl_setswapinterval;
device->GL_GetSwapInterval = qnxgf_gl_getswapinterval;
device->GL_SwapWindow = qnxgf_gl_swapwindow;
device->GL_DeleteContext = qnxgf_gl_deletecontext;
device->PumpEvents = qnxgf_pumpevents;
device->SuspendScreenSaver = qnxgf_suspendscreensaver;
return device;
}
VideoBootStrap qnxgf_bootstrap = {
"qnxgf",
"SDL QNX Graphics Framework (GF) video driver",
qnxgf_available,
qnxgf_create
};
/*****************************************************************************/
/* SDL Video and Display initialization/handling functions */
/*****************************************************************************/
int
qnxgf_videoinit(_THIS)
{
SDL_VideoData *gfdata = (SDL_VideoData *) _this->driverdata;
uint32_t it;
uint32_t jt;
char *override;
int32_t status;
/* By default GF uses buffer swap on vsync */
gfdata->swapinterval = 1;
/* Add each detected output to SDL */
for (it = 0; it < gfdata->gfdev_info.ndisplays; it++) {
SDL_VideoDisplay display;
SDL_DisplayMode current_mode;
SDL_DisplayData *didata;
didata = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
if (didata == NULL) {
/* memory allocation problem */
SDL_OutOfMemory();
return -1;
}
/* Set default cursor settings, maximum 128x128 cursor */
didata->cursor_visible = SDL_FALSE;
didata->cursor.type = GF_CURSOR_BITMAP;
didata->cursor.hotspot.x = 0;
didata->cursor.hotspot.y = 0;
didata->cursor.cursor.bitmap.w = SDL_VIDEO_GF_MAX_CURSOR_SIZE;
didata->cursor.cursor.bitmap.h = SDL_VIDEO_GF_MAX_CURSOR_SIZE;
didata->cursor.cursor.bitmap.stride =
(didata->cursor.cursor.bitmap.w + 7) / (sizeof(uint8_t) * 8);
didata->cursor.cursor.bitmap.color0 = 0x00000000;
didata->cursor.cursor.bitmap.color1 = 0x00000000;
didata->cursor.cursor.bitmap.image0 =
SDL_calloc(sizeof(uint8_t),
(didata->cursor.cursor.bitmap.w +
7) * didata->cursor.cursor.bitmap.h /
(sizeof(uint8_t) * 8));
if (didata->cursor.cursor.bitmap.image0 == NULL) {
SDL_free(didata);
SDL_OutOfMemory();
return -1;
}
didata->cursor.cursor.bitmap.image1 =
SDL_calloc(sizeof(uint8_t),
(didata->cursor.cursor.bitmap.w +
7) * didata->cursor.cursor.bitmap.h /
(sizeof(uint8_t) * 8));
if (didata->cursor.cursor.bitmap.image1 == NULL) {
SDL_OutOfMemory();
SDL_free((void *) didata->cursor.cursor.bitmap.image0);
SDL_free(didata);
return -1;
}
/* Query current display settings */
status = gf_display_query(gfdata->gfdev, it, &didata->display_info);
if (status == GF_ERR_OK) {
SDL_zero(current_mode);
current_mode.w = didata->display_info.xres;
current_mode.h = didata->display_info.yres;
current_mode.refresh_rate = didata->display_info.refresh;
current_mode.format =
qnxgf_gf_to_sdl_pixelformat(didata->display_info.format);
current_mode.driverdata = NULL;
} else {
/* video initialization problem */
SDL_free((void *) didata->cursor.cursor.bitmap.image0);
SDL_free((void *) didata->cursor.cursor.bitmap.image1);
SDL_free(didata);
SDL_SetError("GF: Display query failed");
return -1;
}
/* Attach GF to selected display */
status = gf_display_attach(&didata->display, gfdata->gfdev, it, NULL);
if (status != GF_ERR_OK) {
/* video initialization problem */
SDL_free((void *) didata->cursor.cursor.bitmap.image0);
SDL_free((void *) didata->cursor.cursor.bitmap.image1);
SDL_free(didata);
SDL_SetError("GF: Couldn't attach to display");
return -1;
}
/* Initialize status variables */
didata->layer_attached = SDL_FALSE;
/* Attach to main display layer */
status =
gf_layer_attach(&didata->layer, didata->display,
didata->display_info.main_layer_index, 0);
if (status != GF_ERR_OK) {
/* Failed to attach to main layer */
SDL_free((void *) didata->cursor.cursor.bitmap.image0);
SDL_free((void *) didata->cursor.cursor.bitmap.image1);
SDL_free(didata);
SDL_SetError
("GF: Couldn't attach to main layer, it could be busy");
return -1;
}
/* Mark main display layer is attached */
didata->layer_attached = SDL_TRUE;
/* Set layer source and destination viewport */
gf_layer_set_src_viewport(didata->layer, 0, 0, current_mode.w - 1,
current_mode.h - 1);
gf_layer_set_dst_viewport(didata->layer, 0, 0, current_mode.w - 1,
current_mode.h - 1);
/* Create main visible on display surface */
status = gf_surface_create_layer(&didata->surface[0], &didata->layer,
1, 0, current_mode.w, current_mode.h,
qnxgf_sdl_to_gf_pixelformat
(current_mode.format), NULL,
GF_SURFACE_CREATE_2D_ACCESSIBLE |
GF_SURFACE_CREATE_3D_ACCESSIBLE |
GF_SURFACE_CREATE_SHAREABLE);
if (status != GF_ERR_OK) {
gf_layer_disable(didata->layer);
gf_layer_detach(didata->layer);
didata->layer_attached = SDL_FALSE;
SDL_free((void *) didata->cursor.cursor.bitmap.image0);
SDL_free((void *) didata->cursor.cursor.bitmap.image1);
SDL_free(didata);
SDL_SetError("GF: Can't create main layer surface at init (%d)\n",
status);
return -1;
}
/* Set just created surface as main visible on the layer */
// gf_layer_set_surfaces(didata->layer, &didata->surface[0], 1);
/* Update layer parameters */
status = gf_layer_update(didata->layer, GF_LAYER_UPDATE_NO_WAIT_IDLE);
if (status != GF_ERR_OK) {
/* Free allocated surface */
gf_surface_free(didata->surface[0]);
didata->surface[0] = NULL;
/* Disable and detach from layer */
gf_layer_disable(didata->layer);
gf_layer_detach(didata->layer);
didata->layer_attached = SDL_FALSE;
SDL_free((void *) didata->cursor.cursor.bitmap.image0);
SDL_free((void *) didata->cursor.cursor.bitmap.image1);
SDL_free(didata);
SDL_SetError("GF: Can't update layer parameters\n");
return -1;
}
/* Enable layer in case if hardware supports layer enable/disable */
gf_layer_enable(didata->layer);
/* Copy device name for each display */
SDL_strlcpy(didata->description, gfdata->gfdev_info.description,
SDL_VIDEO_GF_DEVICENAME_MAX - 1);
/* Search device capabilities and possible workarounds */
jt = 0;
do {
if (gf_devicename[jt].name == NULL) {
break;
}
if (SDL_strncmp
(gf_devicename[jt].name, didata->description,
SDL_strlen(gf_devicename[jt].name)) == 0) {
didata->caps = gf_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_GF_REFRESH_RATE");
if (override != NULL) {
if (SDL_sscanf(override, "%u", &didata->custom_refresh) != 1) {
didata->custom_refresh = 0;
}
}
/* Get all display modes for this display */
qnxgf_getdisplaymodes(_this, display);
}
/* Add GF renderer to SDL */
gf_addrenderdriver(_this);
/* Add GF input devices */
status = gf_addinputdevices(_this);
if (status != 0) {
/* SDL error is set by gf_addinputdevices() function */
return -1;
}
/* video has been initialized successfully */
return 1;
}
void
qnxgf_videoquit(_THIS)
{
SDL_VideoData *gfdata = (SDL_VideoData *) _this->driverdata;
SDL_DisplayData *didata = NULL;
uint32_t it;
/* Check if GF was initialized before */
if ((gfdata == NULL) || (gfdata->gfinitialized != SDL_TRUE))
{
/* If not, do not deinitialize */
return;
}
/* Stop collecting mouse events */
hiddi_disable_mouse();
/* Delete GF input devices */
gf_delinputdevices(_this);
/* SDL will restore old desktop mode on exit */
for (it = 0; it < _this->num_displays; it++) {
didata = _this->displays[it].driverdata;
/* Free cursor image */
if (didata->cursor.cursor.bitmap.image0 != NULL) {
SDL_free((void *) didata->cursor.cursor.bitmap.image0);
didata->cursor.cursor.bitmap.image0 = NULL;
}
if (didata->cursor.cursor.bitmap.image1 != NULL) {
SDL_free((void *) didata->cursor.cursor.bitmap.image1);
didata->cursor.cursor.bitmap.image1 = NULL;
}
/* Free main surface */
if (didata->surface[0] != NULL) {
gf_surface_free(didata->surface[0]);
didata->surface[0] = NULL;
}
/* Free back surface */
if (didata->surface[1] != NULL) {
gf_surface_free(didata->surface[1]);
didata->surface[1] = NULL;
}
/* Free second back surface */
if (didata->surface[2] != NULL) {
gf_surface_free(didata->surface[2]);
didata->surface[2] = NULL;
}
/* Detach layer before quit */
if (didata->layer_attached == SDL_TRUE) {
/* Disable layer if hardware supports this */
gf_layer_disable(didata->layer);
/* Detach from layer, free it for others */
gf_layer_detach(didata->layer);
didata->layer = NULL;
/* Mark it as detached */
didata->layer_attached = SDL_FALSE;
}
/* Detach from selected display */
gf_display_detach(didata->display);
didata->display = NULL;
}
}
void
qnxgf_getdisplaymodes(_THIS, SDL_VideoDisplay * display)
{
SDL_DisplayData *didata = (SDL_DisplayData *) display->driverdata;
SDL_DisplayMode mode;
gf_modeinfo_t modeinfo;
uint32_t it = 0;
uint32_t jt = 0;
uint32_t kt = 0;
int status;
do {
status = gf_display_query_mode(didata->display, it, &modeinfo);
if (status == GF_ERR_OK) {
/* Parsing current mode */
if ((modeinfo.flags & GF_MODE_GENERIC) == GF_MODE_GENERIC) {
/* This mode is generic, so we can add to SDL our resolutions */
/* Only pixel format is fixed, refresh rate could be any */
jt = 0;
do {
if (generic_mode[jt].w == 0) {
break;
}
/* Check if driver do not supports doublescan video modes */
if ((didata->caps & SDL_GF_LOWRESOLUTION) !=
SDL_GF_LOWRESOLUTION) {
if (generic_mode[jt].w < 640) {
jt++;
continue;
}
}
mode.w = generic_mode[jt].w;
mode.h = generic_mode[jt].h;
mode.refresh_rate = generic_mode[jt].refresh_rate;
mode.format =
qnxgf_gf_to_sdl_pixelformat(modeinfo.primary_format);
mode.driverdata = NULL;
SDL_AddDisplayMode(display, &mode);
/* If mode is RGBA8888, add the same mode as RGBx888 */
if (modeinfo.primary_format == GF_FORMAT_BGRA8888) {
mode.w = generic_mode[jt].w;
mode.h = generic_mode[jt].h;
mode.refresh_rate = generic_mode[jt].refresh_rate;
mode.format = SDL_PIXELFORMAT_RGB888;
mode.driverdata = NULL;
SDL_AddDisplayMode(display, &mode);
}
/* If mode is RGBA1555, add the same mode as RGBx555 */
if (modeinfo.primary_format == GF_FORMAT_PACK_ARGB1555) {
mode.w = generic_mode[jt].w;
mode.h = generic_mode[jt].h;
mode.refresh_rate = generic_mode[jt].refresh_rate;
mode.format = SDL_PIXELFORMAT_RGB555;
mode.driverdata = NULL;
SDL_AddDisplayMode(display, &mode);
}
jt++;
} while (1);
} else {
/* Add this display mode as is in case if it is non-generic */
/* But go through the each refresh rate, supported by gf */
jt = 0;
do {
if (modeinfo.refresh[jt] != 0) {
mode.w = modeinfo.xres;
mode.h = modeinfo.yres;
mode.refresh_rate = modeinfo.refresh[jt];
mode.format =
qnxgf_gf_to_sdl_pixelformat(modeinfo.
primary_format);
mode.driverdata = NULL;
SDL_AddDisplayMode(display, &mode);
/* If mode is RGBA8888, add the same mode as RGBx888 */
if (modeinfo.primary_format == GF_FORMAT_BGRA8888) {
mode.w = modeinfo.xres;
mode.h = modeinfo.yres;
mode.refresh_rate = modeinfo.refresh[jt];
mode.format = SDL_PIXELFORMAT_RGB888;
mode.driverdata = NULL;
SDL_AddDisplayMode(display, &mode);
}
/* If mode is RGBA1555, add the same mode as RGBx555 */
if (modeinfo.primary_format ==
GF_FORMAT_PACK_ARGB1555) {
mode.w = modeinfo.xres;
mode.h = modeinfo.yres;
mode.refresh_rate = modeinfo.refresh[jt];
mode.format = SDL_PIXELFORMAT_RGB555;
mode.driverdata = NULL;
SDL_AddDisplayMode(display, &mode);
}
jt++;
} else {
break;
}
} while (1);
}
} else {
if (status == GF_ERR_PARM) {
/* out of available modes, all are listed */
break;
}
/* Error occured during mode listing */
break;
}
it++;
} while (1);
}
int
qnxgf_setdisplaymode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
{
SDL_DisplayData *didata = (SDL_DisplayData *) display->driverdata;
uint32_t refresh_rate = 0;
int status;
/* 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) {
uint32_t it;
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 < display->num_display_modes; it++) {
if ((display->display_modes[it].w == mode->w) &&
(display->display_modes[it].h == mode->h) &&
(display->display_modes[it].format == mode->format))
{
/* Find the lowest refresh rate available */
if (tempmode.refresh_rate >
display->display_modes[it].refresh_rate) {
tempmode = display->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) {
uint32_t it;
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 < display->num_display_modes; it++) {
if ((display->display_modes[it].w == mode->w) &&
(display->display_modes[it].h == mode->h) &&
(display->display_modes[it].format == mode->format))
{
/* Find the lowest refresh rate available */
if (tempmode.refresh_rate >
display->display_modes[it].refresh_rate) {
tempmode = display->display_modes[it];
}
/* Check if requested refresh rate found */
if (refresh_rate ==
display->display_modes[it].refresh_rate) {
tempmode = display->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;
}
}
/* Free main surface */
if (didata->surface[0] != NULL) {
gf_surface_free(didata->surface[0]);
didata->surface[0] = NULL;
}
/* Free back surface */
if (didata->surface[1] != NULL) {
gf_surface_free(didata->surface[1]);
didata->surface[1] = NULL;
}
/* Free second back surface */
if (didata->surface[2] != NULL) {
gf_surface_free(didata->surface[2]);
didata->surface[2] = NULL;
}
/* Detach layer before switch to new graphics mode */
if (didata->layer_attached == SDL_TRUE) {
/* Disable layer if hardware supports this */
gf_layer_disable(didata->layer);
/* Detach from layer, free it for others */
gf_layer_detach(didata->layer);
/* Mark it as detached */
didata->layer_attached = SDL_FALSE;
}
/* Set new display video mode */
status =
gf_display_set_mode(didata->display, mode->w, mode->h, refresh_rate,
qnxgf_sdl_to_gf_pixelformat(mode->format), 0);
if (status != GF_ERR_OK) {
/* Display mode/resolution switch has been failed */
SDL_SetError("GF: Mode is not supported by graphics driver");
return -1;
} else {
didata->current_mode = *mode;
didata->current_mode.refresh_rate = refresh_rate;
}
/* Attach to main display layer */
status =
gf_layer_attach(&didata->layer, didata->display,
didata->display_info.main_layer_index, 0);
if (status != GF_ERR_OK) {
SDL_SetError("GF: Couldn't attach to main layer, it could be busy");
/* Failed to attach to main displayable layer */
return -1;
}
/* Mark main display layer is attached */
didata->layer_attached = SDL_TRUE;
/* Set layer source and destination viewports */
gf_layer_set_src_viewport(didata->layer, 0, 0, mode->w - 1, mode->h - 1);
gf_layer_set_dst_viewport(didata->layer, 0, 0, mode->w - 1, mode->h - 1);
/* Create main visible on display surface */
status =
gf_surface_create_layer(&didata->surface[0], &didata->layer, 1, 0,
mode->w, mode->h,
qnxgf_sdl_to_gf_pixelformat(mode->format),
NULL,
GF_SURFACE_CREATE_2D_ACCESSIBLE |
GF_SURFACE_CREATE_3D_ACCESSIBLE |
GF_SURFACE_CREATE_SHAREABLE);
if (status != GF_ERR_OK) {
gf_layer_disable(didata->layer);
gf_layer_detach(didata->layer);
didata->layer_attached = SDL_FALSE;
SDL_SetError
("GF: Can't create main layer surface at modeswitch (%d)\n",
status);
return -1;
}
/* Set just created surface as main visible on the layer */
gf_layer_set_surfaces(didata->layer, &didata->surface[0], 1);
/* Update layer parameters */
status = gf_layer_update(didata->layer, GF_LAYER_UPDATE_NO_WAIT_IDLE);
if (status != GF_ERR_OK) {
/* Free main surface */
gf_surface_free(didata->surface[0]);
didata->surface[0] = NULL;
/* Detach layer */
gf_layer_disable(didata->layer);
gf_layer_detach(didata->layer);
didata->layer_attached = SDL_FALSE;
SDL_SetError("GF: Can't update layer parameters\n");
return -1;
}
/* Restore cursor if it was visible */
if (didata->cursor_visible == SDL_TRUE) {
gf_cursor_set(didata->display, 0, &didata->cursor);
gf_cursor_enable(didata->display, 0);
}
/* Enable layer in case if hardware supports layer enable/disable */
gf_layer_enable(didata->layer);
return 0;
}
int
qnxgf_setdisplaygammaramp(_THIS, SDL_VideoDisplay * display, Uint16 * ramp)
{
SDL_DisplayData *didata = (SDL_DisplayData *) display->driverdata;
int status;
/* Setup gamma ramp, for each color channel */
status =
gf_display_set_color_lut16(didata->display, (uint16_t *) ramp,
(uint16_t *) ramp + 256,
(uint16_t *) ramp + 512);
if (status != GF_ERR_OK) {
/* Setting display gamma ramp operation has been failed */
return -1;
}
return 0;
}
int
qnxgf_getdisplaygammaramp(_THIS, SDL_VideoDisplay * display, Uint16 * ramp)
{
/* TODO: We need to return previous gamma set */
/* Also we need some initial fake gamma to return */
SDL_Unsupported();
return -1;
}
int
qnxgf_createwindow(_THIS, SDL_Window * window)
{
SDL_VideoData *gfdata = (SDL_VideoData *) _this->driverdata;
SDL_VideoDisplay *display = window->display;
SDL_DisplayData *didata = (SDL_DisplayData *) display->driverdata;
SDL_WindowData *wdata;
int32_t status;
/* QNX GF supports fullscreen window modes only */
if ((window->flags & SDL_WINDOW_FULLSCREEN) != SDL_WINDOW_FULLSCREEN) {
uint32_t it;
SDL_DisplayMode mode;
/* Clear display mode structure */
SDL_memset(&mode, 0x00, sizeof(SDL_DisplayMode));
mode.refresh_rate = 0x0000FFFF;
/* Check if window width and height matches one of our modes */
for (it = 0; it < display->num_display_modes; it++) {
if ((display->display_modes[it].w == window->w) &&
(display->display_modes[it].h == window->h) &&
(display->display_modes[it].format ==
display->desktop_mode.format)) {
/* Find the lowest refresh rate available */
if (mode.refresh_rate >
display->display_modes[it].refresh_rate) {
mode = display->display_modes[it];
}
}
}
/* Check if end of display list has been reached */
if (mode.refresh_rate == 0x0000FFFF) {
SDL_SetError("GF: Desired video mode is not supported");
/* Failed to create new window */
return -1;
} else {
/* Tell to the caller that mode will be fullscreen */
window->flags |= SDL_WINDOW_FULLSCREEN;
/* Setup fullscreen mode, bpp used from desktop mode in this case */
status = qnxgf_setdisplaymode(_this, &mode);
if (status != 0) {
/* Failed to swith fullscreen video mode */
return -1;
}
}
}
/* Setup our own window decorations and states, which are depend on fullscreen mode */
window->flags |= SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS |
SDL_WINDOW_MAXIMIZED | SDL_WINDOW_INPUT_GRABBED |
SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_MOUSE_FOCUS;
window->flags &= ~(SDL_WINDOW_RESIZABLE | SDL_WINDOW_MINIMIZED);
/* Ignore any window position settings */
window->x = SDL_WINDOWPOS_UNDEFINED;
window->y = SDL_WINDOWPOS_UNDEFINED;
/* Allocate window internal data */
wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
if (wdata == NULL) {
SDL_OutOfMemory();
return -1;
}
/* Setup driver data for this window */
window->driverdata = wdata;
/* Check if window must support OpenGL ES rendering */
if ((window->flags & SDL_WINDOW_OPENGL) == SDL_WINDOW_OPENGL) {
#if defined(SDL_VIDEO_OPENGL_ES)
EGLBoolean initstatus;
/* Mark this window as OpenGL ES compatible */
wdata->uses_gles = SDL_TRUE;
/* Create connection to OpenGL ES */
if (gfdata->egldisplay == EGL_NO_DISPLAY) {
gfdata->egldisplay = eglGetDisplay(gfdata->gfdev);
if (gfdata->egldisplay == EGL_NO_DISPLAY) {
SDL_SetError("GF: Can't get connection to OpenGL ES");
return -1;
}
/* Initialize OpenGL ES library, ignore EGL version */
initstatus = eglInitialize(gfdata->egldisplay, NULL, NULL);
if (initstatus != EGL_TRUE) {
SDL_SetError("GF: Can't init OpenGL ES library");
return -1;
}
}
/* Increment GL ES reference count usage */
gfdata->egl_refcount++;
#else
SDL_SetError("GF: OpenGL ES support is not compiled in");
return -1;
#endif /* SDL_VIDEO_OPENGL_ES */
}
/* Enable mouse event collecting */
hiddi_enable_mouse();
/* By default last created window got a input focus */
SDL_SetKeyboardFocus(0, window);
SDL_SetMouseFocus(0, window);
/* Window has been successfully created */
return 0;
}
int
qnxgf_createwindowfrom(_THIS, SDL_Window * window, const void *data)
{
/* Failed to create window from another window */
return -1;
}
void
qnxgf_setwindowtitle(_THIS, SDL_Window * window)
{
}
void
qnxgf_setwindowicon(_THIS, SDL_Window * window, SDL_Surface * icon)
{
}
void
qnxgf_setwindowposition(_THIS, SDL_Window * window)
{
}
void
qnxgf_setwindowsize(_THIS, SDL_Window * window)
{
}
void
qnxgf_showwindow(_THIS, SDL_Window * window)
{
}
void
qnxgf_hidewindow(_THIS, SDL_Window * window)
{
}
void
qnxgf_raisewindow(_THIS, SDL_Window * window)
{
}
void
qnxgf_maximizewindow(_THIS, SDL_Window * window)
{
}
void
qnxgf_minimizewindow(_THIS, SDL_Window * window)
{
}
void
qnxgf_restorewindow(_THIS, SDL_Window * window)
{
}
void
qnxgf_setwindowgrab(_THIS, SDL_Window * window)
{
}
void
qnxgf_destroywindow(_THIS, SDL_Window * window)
{
SDL_VideoData *gfdata = (SDL_VideoData *) _this->driverdata;
SDL_DisplayData *didata =
(SDL_DisplayData *) window->display->driverdata;
SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
if (wdata != NULL) {
#if defined(SDL_VIDEO_OPENGL_ES)
/* Destroy OpenGL ES surface if it was created */
if (wdata->gles_surface != EGL_NO_SURFACE) {
eglDestroySurface(gfdata->egldisplay, wdata->gles_surface);
}
/* Free any 3D target if it was created before */
if (wdata->target_created == SDL_TRUE) {
gf_3d_target_free(wdata->target);
wdata->target_created == SDL_FALSE;
}
gfdata->egl_refcount--;
if (gfdata->egl_refcount == 0) {
/* Terminate connection to OpenGL ES */
if (gfdata->egldisplay != EGL_NO_DISPLAY) {
eglTerminate(gfdata->egldisplay);
gfdata->egldisplay = EGL_NO_DISPLAY;
}
}
#endif /* SDL_VIDEO_OPENGL_ES */
}
}
/*****************************************************************************/
/* SDL Window Manager function */
/*****************************************************************************/
SDL_bool
qnxgf_getwindowwminfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
{
/* QNX GF do not operates at window level, this means we are have no */
/* Window Manager available, no specific data in SDL_SysWMinfo too */
if (info->version.major <= SDL_MAJOR_VERSION) {
return SDL_TRUE;
} else {
SDL_SetError("Application not compiled with SDL %d.%d\n",
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
return SDL_FALSE;
}
/* Failed to get window manager information */
return SDL_FALSE;
}
/*****************************************************************************/
/* SDL OpenGL/OpenGL ES functions */
/*****************************************************************************/
int
qnxgf_gl_loadlibrary(_THIS, const char *path)
{
#if defined(SDL_VIDEO_OPENGL_ES)
/* 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("GF: 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("GF: OpenGL ES support is not compiled in");
return -1;
#endif /* SDL_VIDEO_OPENGL_ES */
}
void *
qnxgf_gl_getprocaddres(_THIS, const char *proc)
{
#if defined(SDL_VIDEO_OPENGL_ES)
void *function_address;
/* 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("GF: Cannot locate OpenGL ES function name");
return NULL;
#else
SDL_SetError("GF: OpenGL ES support is not compiled in");
return NULL;
#endif /* SDL_VIDEO_OPENGL_ES */
}
void
qnxgf_gl_unloadlibrary(_THIS)
{
#if defined(SDL_VIDEO_OPENGL_ES)
/* 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("GF: OpenGL ES support is not compiled in");
return;
#endif /* SDL_VIDEO_OPENGL_ES */
}
SDL_GLContext
qnxgf_gl_createcontext(_THIS, SDL_Window * window)
{
#if defined(SDL_VIDEO_OPENGL_ES)
SDL_VideoData *gfdata = (SDL_VideoData *) _this->driverdata;
SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
SDL_DisplayData *didata =
(SDL_DisplayData *) window->display->driverdata;
EGLBoolean status;
int32_t gfstatus;
EGLint configs;
uint32_t surfaces;
uint32_t attr_pos;
EGLint attr_value;
EGLint cit;
/* Choose buffeingr scheme */
if (!_this->gl_config.double_buffer) {
surfaces = 1;
} else {
surfaces = 2;
}
/* If driver has no support of video memory allocation, then */
/* disable double buffering, use single buffer present copy */
if ((didata->caps & SDL_GF_VIDEOMEMORY) != SDL_GF_VIDEOMEMORY) {
surfaces = 1;
}
/* Free main surface */
if (didata->surface[0] != NULL) {
gf_surface_free(didata->surface[0]);
didata->surface[0] = NULL;
}
/* Free back surface */
if (didata->surface[1] != NULL) {
gf_surface_free(didata->surface[1]);
didata->surface[1] = NULL;
}
/* Free second back surface */
if (didata->surface[2] != NULL) {
gf_surface_free(didata->surface[2]);
didata->surface[2] = NULL;
}
/* Detach layer before switch to new graphics mode */
if (didata->layer_attached == SDL_TRUE) {
/* Disable layer if hardware supports this */
gf_layer_disable(didata->layer);
/* Detach from layer, free it for others */
gf_layer_detach(didata->layer);
/* Mark it as detached */
didata->layer_attached = SDL_FALSE;
}
/* Attach to main display layer */
gfstatus =
gf_layer_attach(&didata->layer, didata->display,
didata->display_info.main_layer_index, 0);
if (gfstatus != GF_ERR_OK) {
SDL_SetError("GF: Couldn't attach to main layer, it could be busy");
/* Failed to attach to main displayable layer */
return NULL;
}
/* Mark main display layer is attached */
didata->layer_attached = SDL_TRUE;
/* Set layer source and destination viewport */
gf_layer_set_src_viewport(didata->layer, 0, 0, didata->current_mode.w - 1,
didata->current_mode.h - 1);
gf_layer_set_dst_viewport(didata->layer, 0, 0, didata->current_mode.w - 1,
didata->current_mode.h - 1);
/* Create main visible on display surface */
gfstatus =
gf_surface_create_layer(&didata->surface[0], &didata->layer, 1, 0,
didata->current_mode.w,
didata->current_mode.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) {
gf_layer_disable(didata->layer);
gf_layer_detach(didata->layer);
didata->layer_attached = SDL_FALSE;
SDL_SetError("GF: Can't create main layer surface at glctx (%d)\n",
gfstatus);
return NULL;
}
/* Set just created surface as main visible on the layer */
// gf_layer_set_surfaces(didata->layer, &didata->surface[0], 1);
if (surfaces > 1) {
/* Create back display surface */
gfstatus =
gf_surface_create_layer(&didata->surface[1], &didata->layer, 1, 0,
didata->current_mode.w,
didata->current_mode.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) {
gf_surface_free(didata->surface[0]);
gf_layer_disable(didata->layer);
gf_layer_detach(didata->layer);
didata->layer_attached = SDL_FALSE;
SDL_SetError
("GF: Can't create main layer surface at glctx (%d)\n",
gfstatus);
return NULL;
}
}
/* Update layer parameters */
gfstatus = gf_layer_update(didata->layer, GF_LAYER_UPDATE_NO_WAIT_IDLE);
if (gfstatus != GF_ERR_OK) {
/* Free main and back surfaces */
gf_surface_free(didata->surface[1]);
didata->surface[1] = NULL;
gf_surface_free(didata->surface[0]);
didata->surface[0] = NULL;
/* Detach layer */
gf_layer_disable(didata->layer);
gf_layer_detach(didata->layer);
didata->layer_attached = SDL_FALSE;
SDL_SetError("GF: Can't update layer parameters\n");
return NULL;
}
/* Enable layer in case if hardware supports layer enable/disable */
gf_layer_enable(didata->layer);
/* 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;
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;
}
wdata->gles_attributes[attr_pos++] = EGL_DEPTH_SIZE;
if (_this->gl_config.depth_size) {
wdata->gles_attributes[attr_pos++] = _this->gl_config.depth_size;
} else {
wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
}
if (_this->gl_config.buffer_size) {
wdata->gles_attributes[attr_pos++] = EGL_BUFFER_SIZE;
wdata->gles_attributes[attr_pos++] = _this->gl_config.buffer_size;
}
if (_this->gl_config.stencil_size) {
wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
wdata->gles_attributes[attr_pos++] = _this->gl_config.stencil_size;
}
/* 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(gfdata->egldisplay, wdata->gles_attributes,
wdata->gles_configs, SDL_VIDEO_GF_OPENGLES_CONFS,
&configs);
if (status != EGL_TRUE) {
SDL_SetError("GF: 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;
static const 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 data set 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;
/* exit from stencil loop */
jt = 0;
}
/* Don't care about antialiasing */
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(gfdata->egldisplay,
wdata->gles_attributes,
wdata->gles_configs,
SDL_VIDEO_GF_OPENGLES_CONFS, &configs);
if (status != EGL_TRUE) {
SDL_SetError
("GF: 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("GF: 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;
EGLint cur_depth;
EGLint cur_stencil;
stencil_found = 0;
depth_found = 0;
if (_this->gl_config.stencil_size) {
status =
eglGetConfigAttrib(gfdata->egldisplay,
wdata->gles_configs[cit], EGL_STENCIL_SIZE,
&cur_stencil);
if (status == EGL_TRUE) {
if (attr_value != 0) {
stencil_found = 1;
}
}
} else {
stencil_found = 1;
}
if (_this->gl_config.depth_size) {
status =
eglGetConfigAttrib(gfdata->egldisplay,
wdata->gles_configs[cit], EGL_DEPTH_SIZE,
&cur_depth);
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)) {
/* Store last satisfied configuration id */
wdata->gles_config = cit;
if (cur_depth==_this->gl_config.depth_size)
{
/* Exact match on depth bits */
if (!_this->gl_config.stencil_size)
{
/* Stencil is not required */
break;
}
else
{
if (cur_stencil==_this->gl_config.stencil_size)
{
/* Exact match on stencil bits */
break;
}
}
}
}
}
/* If best could not be found, use first or last satisfied */
if ((cit == configs) && (wdata->gles_config==0)) {
cit = 0;
wdata->gles_config = cit;
}
/* Create OpenGL ES context */
wdata->gles_context =
eglCreateContext(gfdata->egldisplay,
wdata->gles_configs[wdata->gles_config],
EGL_NO_CONTEXT, NULL);
if (wdata->gles_context == EGL_NO_CONTEXT) {
SDL_SetError("GF: OpenGL ES context creation has been failed");
return NULL;
}
/* Free any 3D target if it was created before */
if (wdata->target_created == SDL_TRUE) {
gf_3d_target_free(wdata->target);
wdata->target_created == SDL_FALSE;
}
/* Create surface(s) target for OpenGL ES */
gfstatus =
gf_3d_target_create(&wdata->target, didata->layer,
&didata->surface[0], surfaces,
didata->current_mode.w, didata->current_mode.h,
qnxgf_sdl_to_gf_pixelformat(didata->current_mode.
format));
if (gfstatus != GF_ERR_OK) {
/* Destroy just created context */
eglDestroyContext(gfdata->egldisplay, wdata->gles_context);
wdata->gles_context = EGL_NO_CONTEXT;
/* Mark 3D target as unallocated */
wdata->target_created = SDL_FALSE;
SDL_SetError("GF: OpenGL ES target could not be created");
return NULL;
} else {
wdata->target_created = SDL_TRUE;
}
/* Create target rendering surface on whole screen */
wdata->gles_surface =
eglCreateWindowSurface(gfdata->egldisplay,
wdata->gles_configs[wdata->gles_config],
wdata->target, NULL);
if (wdata->gles_surface == EGL_NO_SURFACE) {
/* Destroy 3d target */
gf_3d_target_free(wdata->target);
wdata->target_created = SDL_FALSE;
/* Destroy OpenGL ES context */
eglDestroyContext(gfdata->egldisplay, wdata->gles_context);
wdata->gles_context = EGL_NO_CONTEXT;
SDL_SetError("GF: OpenGL ES surface could not be created");
return NULL;
}
/* Make just created context current */
status =
eglMakeCurrent(gfdata->egldisplay, wdata->gles_surface,
wdata->gles_surface, wdata->gles_context);
if (status != EGL_TRUE) {
/* Destroy OpenGL ES surface */
eglDestroySurface(gfdata->egldisplay, wdata->gles_surface);
/* Destroy 3d target */
gf_3d_target_free(wdata->target);
wdata->target_created = SDL_FALSE;
/* Destroy OpenGL ES context */
eglDestroyContext(gfdata->egldisplay, wdata->gles_context);
wdata->gles_context = EGL_NO_CONTEXT;
/* Failed to set current GL ES context */
SDL_SetError("GF: 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_GF_ACCELERATED_3D) == SDL_GF_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(gfdata->egldisplay,
wdata->gles_configs[wdata->gles_config],
EGL_SAMPLES, &attr_value);
if (status == EGL_TRUE) {
_this->gl_config.multisamplesamples = attr_value;
}
status =
eglGetConfigAttrib(gfdata->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(gfdata->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(gfdata->egldisplay,
wdata->gles_configs[wdata->gles_config],
EGL_STENCIL_SIZE, &attr_value);
if (status == EGL_TRUE) {
_this->gl_config.stencil_size = attr_value;
}
/* Restore cursor if it was visible */
if (didata->cursor_visible == SDL_TRUE) {
gf_cursor_set(didata->display, 0, &didata->cursor);
gf_cursor_enable(didata->display, 0);
}
/* GL ES context was successfully created */
return wdata->gles_context;
#else
SDL_SetError("GF: OpenGL ES support is not compiled in");
return NULL;
#endif /* SDL_VIDEO_OPENGL_ES */
}
int
qnxgf_gl_makecurrent(_THIS, SDL_Window * window, SDL_GLContext context)
{
#if defined(SDL_VIDEO_OPENGL_ES)
SDL_VideoData *gfdata = (SDL_VideoData *) _this->driverdata;
SDL_WindowData *wdata;
EGLBoolean status;
if ((window == NULL) && (context == NULL)) {
status =
eglMakeCurrent(gfdata->egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT);
if (status != EGL_TRUE) {
/* Failed to set current GL ES context */
SDL_SetError("GF: Can't set OpenGL ES context");
return -1;
}
} else {
wdata = (SDL_WindowData *) window->driverdata;
status =
eglMakeCurrent(gfdata->egldisplay, wdata->gles_surface,
wdata->gles_surface, wdata->gles_context);
if (status != EGL_TRUE) {
/* Failed to set current GL ES context */
SDL_SetError("GF: Can't set OpenGL ES context");
return -1;
}
}
return 0;
#else
SDL_SetError("GF: OpenGL ES support is not compiled in");
return -1;
#endif /* SDL_VIDEO_OPENGL_ES */
}
int
qnxgf_gl_setswapinterval(_THIS, int interval)
{
#if defined(SDL_VIDEO_OPENGL_ES)
SDL_VideoData *gfdata = (SDL_VideoData *) _this->driverdata;
EGLBoolean status;
/* Check if OpenGL ES connection has been initialized */
if (gfdata->egldisplay != EGL_NO_DISPLAY) {
/* Set swap OpenGL ES interval */
status = eglSwapInterval(gfdata->egldisplay, interval);
if (status == EGL_TRUE) {
/* Return success to upper level */
gfdata->swapinterval = interval;
return 0;
}
}
/* Failed to set swap interval */
SDL_SetError("GF: Cannot set swap interval");
return -1;
#else
SDL_SetError("GF: OpenGL ES support is not compiled in");
return -1;
#endif /* SDL_VIDEO_OPENGL_ES */
}
int
qnxgf_gl_getswapinterval(_THIS)
{
#if defined(SDL_VIDEO_OPENGL_ES)
SDL_VideoData *gfdata = (SDL_VideoData *) _this->driverdata;
/* Return default swap interval value */
return gfdata->swapinterval;
#else
SDL_SetError("GF: OpenGL ES support is not compiled in");
return -1;
#endif /* SDL_VIDEO_OPENGL_ES */
}
void
qnxgf_gl_swapwindow(_THIS, SDL_Window * window)
{
#if defined(SDL_VIDEO_OPENGL_ES)
SDL_VideoData *gfdata = (SDL_VideoData *) _this->driverdata;
SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
/* Finish all drawings */
glFinish();
/* Swap buffers */
eglSwapBuffers(gfdata->egldisplay, wdata->gles_surface);
#else
SDL_SetError("GF: OpenGL ES support is not compiled in");
return;
#endif /* SDL_VIDEO_OPENGL_ES */
}
void
qnxgf_gl_deletecontext(_THIS, SDL_GLContext context)
{
#if defined(SDL_VIDEO_OPENGL_ES)
SDL_VideoData *gfdata = (SDL_VideoData *) _this->driverdata;
EGLBoolean status;
/* Check if OpenGL ES connection has been initialized */
if (gfdata->egldisplay != EGL_NO_DISPLAY) {
if (context != EGL_NO_CONTEXT) {
status = eglDestroyContext(gfdata->egldisplay, context);
if (status != EGL_TRUE) {
/* Error during OpenGL ES context destroying */
SDL_SetError("GF: OpenGL ES context destroy error");
return;
}
}
}
return;
#else
SDL_SetError("GF: OpenGL ES support is not compiled in");
return;
#endif /* SDL_VIDEO_OPENGL_ES */
}
/*****************************************************************************/
/* SDL Event handling function */
/*****************************************************************************/
void
qnxgf_pumpevents(_THIS)
{
}
/*****************************************************************************/
/* SDL screen saver related functions */
/*****************************************************************************/
void
qnxgf_suspendscreensaver(_THIS)
{
/* There is no screensaver in pure console, it may exist when running */
/* GF under Photon, but I do not know, how to disable screensaver */
}
/* vi: set ts=4 sw=4 expandtab: */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
QNX Graphics Framework SDL driver
Copyright (C) 2009 Mike Gorchak
(mike@malva.ua, lestat@i.com.ua)
*/
#ifndef __SDL_QNXGF_H__
#define __SDL_QNXGF_H__
#include "../SDL_sysvideo.h"
#include <gf/gf.h>
#include <gf/gf3d.h>
#if defined(SDL_VIDEO_OPENGL_ES)
#include <GLES/egl.h>
#endif /* SDL_VIDEO_OPENGL_ES */
typedef struct SDL_VideoData
{
gf_dev_t gfdev; /* GF device handle */
gf_dev_info_t gfdev_info; /* GF device information */
SDL_bool gfinitialized; /* GF device initialization status */
#if defined(SDL_VIDEO_OPENGL_ES)
EGLDisplay egldisplay; /* OpenGL ES display connection */
uint32_t egl_refcount; /* OpenGL ES reference count */
uint32_t swapinterval; /* OpenGL ES default swap interval */
#endif /* SDL_VIDEO_OPENGL_ES */
} SDL_VideoData;
#define SDL_VIDEO_GF_DEVICENAME_MAX 257
#define SDL_VIDEO_GF_MAX_CURSOR_SIZE 128
typedef struct SDL_DisplayData
{
gf_display_info_t display_info; /* GF display information */
gf_display_t display; /* GF display handle */
uint32_t custom_refresh; /* Custom refresh rate for all modes */
SDL_DisplayMode current_mode; /* Current video mode */
uint8_t description[SDL_VIDEO_GF_DEVICENAME_MAX];
/* Device description */
uint32_t caps; /* Device capabilities */
SDL_bool layer_attached; /* Layer attach status */
gf_layer_t layer; /* Graphics layer to which attached */
gf_surface_t surface[3]; /* Visible surface on the display */
SDL_bool cursor_visible; /* SDL_TRUE if cursor visible */
gf_cursor_t cursor; /* Cursor shape which was set last */
} SDL_DisplayData;
/* Maximum amount of OpenGL ES framebuffer configurations */
#define SDL_VIDEO_GF_OPENGLES_CONFS 32
typedef struct SDL_WindowData
{
SDL_bool uses_gles; /* true if window support OpenGL ES */
#if defined(SDL_VIDEO_OPENGL_ES)
gf_3d_target_t target; /* OpenGL ES window target */
SDL_bool target_created; /* GF 3D target is created if true */
EGLConfig gles_configs[SDL_VIDEO_GF_OPENGLES_CONFS];
/* OpenGL ES framebuffer confs */
EGLint gles_config; /* Config index in the array of cfgs */
EGLContext gles_context; /* OpenGL ES context */
EGLint gles_attributes[256]; /* OpenGL ES attributes for context */
EGLSurface gles_surface; /* OpenGL ES target rendering surface */
#endif /* SDL_VIDEO_OPENGL_ES */
} SDL_WindowData;
typedef struct SDL_GLDriverData
{
#if defined(SDL_VIDEO_OPENGL_ES)
#endif /* SDL_VIDEO_OPENGL_ES */
} SDL_GLDriverData;
/****************************************************************************/
/* Low level GF graphics driver capabilities */
/****************************************************************************/
typedef struct GF_DeviceCaps
{
uint8_t *name;
uint32_t caps;
} GF_DeviceCaps;
#define SDL_GF_UNACCELERATED 0x00000000 /* driver is unaccelerated */
#define SDL_GF_ACCELERATED 0x00000001 /* driver is accelerated */
#define SDL_GF_NOLOWRESOLUTION 0x00000000 /* no modes below 640x480 */
#define SDL_GF_LOWRESOLUTION 0x00000002 /* support modes <640x480 */
#define SDL_GF_UNACCELERATED_3D 0x00000000 /* software OpenGL ES */
#define SDL_GF_ACCELERATED_3D 0x00000004 /* hardware acc. OpenGL ES */
#define SDL_GF_NOVIDEOMEMORY 0x00000000 /* no video memory alloc. */
#define SDL_GF_VIDEOMEMORY 0x00000008 /* has video memory alloc. */
/****************************************************************************/
/* SDL_VideoDevice functions declaration */
/****************************************************************************/
/* Display and window functions */
int qnxgf_videoinit(_THIS);
void qnxgf_videoquit(_THIS);
void qnxgf_getdisplaymodes(_THIS);
int qnxgf_setdisplaymode(_THIS, SDL_DisplayMode * mode);
int qnxgf_setdisplaygammaramp(_THIS, Uint16 * ramp);
int qnxgf_getdisplaygammaramp(_THIS, Uint16 * ramp);
int qnxgf_createwindow(_THIS, SDL_Window * window);
int qnxgf_createwindowfrom(_THIS, SDL_Window * window, const void *data);
void qnxgf_setwindowtitle(_THIS, SDL_Window * window);
void qnxgf_setwindowicon(_THIS, SDL_Window * window, SDL_Surface * icon);
void qnxgf_setwindowposition(_THIS, SDL_Window * window);
void qnxgf_setwindowsize(_THIS, SDL_Window * window);
void qnxgf_showwindow(_THIS, SDL_Window * window);
void qnxgf_hidewindow(_THIS, SDL_Window * window);
void qnxgf_raisewindow(_THIS, SDL_Window * window);
void qnxgf_maximizewindow(_THIS, SDL_Window * window);
void qnxgf_minimizewindow(_THIS, SDL_Window * window);
void qnxgf_restorewindow(_THIS, SDL_Window * window);
void qnxgf_setwindowgrab(_THIS, SDL_Window * window);
void qnxgf_destroywindow(_THIS, SDL_Window * window);
/* Window manager function */
SDL_bool qnxgf_getwindowwminfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo *info);
/* OpenGL/OpenGL ES functions */
int qnxgf_gl_loadlibrary(_THIS, const char *path);
void *qnxgf_gl_getprocaddres(_THIS, const char *proc);
void qnxgf_gl_unloadlibrary(_THIS);
SDL_GLContext qnxgf_gl_createcontext(_THIS, SDL_Window * window);
int qnxgf_gl_makecurrent(_THIS, SDL_Window * window, SDL_GLContext context);
int qnxgf_gl_setswapinterval(_THIS, int interval);
int qnxgf_gl_getswapinterval(_THIS);
void qnxgf_gl_swapwindow(_THIS, SDL_Window * window);
void qnxgf_gl_deletecontext(_THIS, SDL_GLContext context);
/* Event handling function */
void qnxgf_pumpevents(_THIS);
/* Screen saver related function */
void qnxgf_suspendscreensaver(_THIS);
#endif /* __SDL_QNXGF_H__ */
/* vi: set ts=4 sw=4 expandtab: */
...@@ -116,10 +116,6 @@ main(int argc, char *argv[]) ...@@ -116,10 +116,6 @@ main(int argc, char *argv[])
/* you may want to change these according to the platform */ /* you may want to change these according to the platform */
video_w = 320; video_w = 320;
video_h = 480; video_h = 480;
#ifdef __QNXNTO__
video_w = 480;
video_h = 640;
#endif /* __QNXNTO__ */
if (argv[1]) { if (argv[1]) {
gl_library = argv[1]; gl_library = argv[1];
...@@ -151,12 +147,7 @@ main(int argc, char *argv[]) ...@@ -151,12 +147,7 @@ main(int argc, char *argv[])
pixels[3 * i + 2] = rand() % 250 - 125; pixels[3 * i + 2] = rand() % 250 - 125;
} }
#ifdef __QNXNTO__
f.glViewport(0, 0, video_h, video_w);
#else
f.glViewport(0, 0, video_w, video_h); f.glViewport(0, 0, video_w, video_h);
#endif /* __QNXNTO__ */
f.glMatrixMode(GL_PROJECTION); f.glMatrixMode(GL_PROJECTION);
f.glLoadIdentity(); f.glLoadIdentity();
f.glOrthof(-100, 100, -100, 100, -500, 500); f.glOrthof(-100, 100, -100, 100, -500, 500);
......
...@@ -10,11 +10,7 @@ ...@@ -10,11 +10,7 @@
#endif #endif
#define DEFAULT_PTSIZE 30 #define DEFAULT_PTSIZE 30
#ifdef __QNXNTO__ #define DEFAULT_FONT "/System/Library/Fonts/华文细黑.ttf"
#define DEFAULT_FONT "/usr/photon/font_repository/tt0003m_.ttf"
#else
#define DEFAULT_FONT "/System/Library/Fonts/华文细黑.ttf"
#endif
#define MAX_TEXT_LENGTH 256 #define MAX_TEXT_LENGTH 256
SDL_Surface *screen; SDL_Surface *screen;
...@@ -28,36 +24,36 @@ SDL_Color textColor = { 0, 0, 0 }; ...@@ -28,36 +24,36 @@ SDL_Color textColor = { 0, 0, 0 };
char text[MAX_TEXT_LENGTH], markedText[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; char text[MAX_TEXT_LENGTH], markedText[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
int cursor = 0; int cursor = 0;
size_t utf8_length(unsigned char c) size_t utf8_length(unsigned char c)
{ {
c = (unsigned char)(0xff & c); c = (unsigned char)(0xff & c);
if (c < 0x80) if (c < 0x80)
return 1; return 1;
else if ((c >> 5) ==0x6) else if ((c >> 5) ==0x6)
return 2; return 2;
else if ((c >> 4) == 0xe) else if ((c >> 4) == 0xe)
return 3; return 3;
else if ((c >> 3) == 0x1e) else if ((c >> 3) == 0x1e)
return 4; return 4;
else else
return 0; return 0;
} }
char *utf8_next(char *p) char *utf8_next(char *p)
{ {
size_t len = utf8_length(*p); size_t len = utf8_length(*p);
size_t i = 0; size_t i = 0;
if (!len) if (!len)
return 0; return 0;
for (; i < len; ++i) for (; i < len; ++i)
{ {
++p; ++p;
if (!*p) if (!*p)
return 0; return 0;
} }
return p; return p;
} }
char *utf8_advance(char *p, size_t distance) char *utf8_advance(char *p, size_t distance)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment