mirror of https://github.com/axmolengine/axmol.git
1288 lines
40 KiB
C++
1288 lines
40 KiB
C++
/****************************************************************************
|
|
Copyright (c) 2010 cocos2d-x.org
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
****************************************************************************/
|
|
|
|
#include "CCEGLView_qnx.h"
|
|
#include "GLES/gl.h"
|
|
|
|
#include <ctype.h>
|
|
#include <input/screen_helpers.h>
|
|
#include <sys/keycodes.h>
|
|
|
|
#include <bps/bps.h>
|
|
#include <bps/event.h>
|
|
#include <bps/screen.h>
|
|
#include <bps/navigator.h>
|
|
#include <bps/orientation.h>
|
|
#include <bps/virtualkeyboard.h>
|
|
|
|
#include "CCSet.h"
|
|
#include "CCDirector.h"
|
|
#include "CCApplication.h"
|
|
#include "ccMacros.h"
|
|
#include "CCTouch.h"
|
|
#include "CCTouchDispatcher.h"
|
|
#include "CCKeypadDispatcher.h"
|
|
#include "CCIMEDispatcher.h"
|
|
|
|
|
|
using namespace std;
|
|
|
|
NS_CC_BEGIN
|
|
|
|
bool CCEGLView::m_initializedFunctions = false;
|
|
const GLubyte *CCEGLView::m_extensions = 0;
|
|
|
|
PFNGLGENERATEMIPMAPOESPROC CCEGLView::glGenerateMipmapOES = 0;
|
|
PFNGLGENFRAMEBUFFERSOESPROC CCEGLView::glGenFramebuffersOES = 0;
|
|
PFNGLBINDFRAMEBUFFEROESPROC CCEGLView::glBindFramebufferOES = 0;
|
|
PFNGLFRAMEBUFFERTEXTURE2DOESPROC CCEGLView::glFramebufferTexture2DOES = 0;
|
|
PFNGLDELETEFRAMEBUFFERSOESPROC CCEGLView::glDeleteFramebuffersOES = 0;
|
|
PFNGLCHECKFRAMEBUFFERSTATUSOESPROC CCEGLView::glCheckFramebufferStatusOES = 0;
|
|
|
|
enum Orientation
|
|
{
|
|
PORTRAIT,
|
|
LANDSCAPE,
|
|
AUTO
|
|
};
|
|
|
|
static Orientation orientation = LANDSCAPE;
|
|
|
|
static struct {
|
|
EGLint surface_type;
|
|
EGLint red_size;
|
|
EGLint green_size;
|
|
EGLint blue_size;
|
|
EGLint alpha_size;
|
|
EGLint samples;
|
|
EGLint config_id;
|
|
} the_configAttr;
|
|
|
|
#define MAX_TOUCHES 4
|
|
static CCTouch *s_pTouches[MAX_TOUCHES] = { NULL };
|
|
static CCEGLView* s_pInstance = NULL;
|
|
|
|
CCEGLView::CCEGLView()
|
|
: m_pDelegate(NULL), m_pEventHandler(NULL),
|
|
m_fScreenScaleFactor(1.0),
|
|
m_bNotHVGA(false),
|
|
m_isWindowActive(false)
|
|
{
|
|
s_pInstance = this;
|
|
m_eglDisplay = EGL_NO_DISPLAY;
|
|
m_eglContext = EGL_NO_CONTEXT;
|
|
m_eglSurface = EGL_NO_SURFACE;
|
|
m_screenEvent = 0;
|
|
m_screenWindow = 0;
|
|
|
|
strcpy(m_window_group_id, "");
|
|
snprintf(m_window_group_id, sizeof(m_window_group_id), "%d", getpid());
|
|
bps_initialize();
|
|
navigator_request_events(0);
|
|
|
|
navigator_rotation_lock(true);
|
|
|
|
the_configAttr.surface_type = EGL_WINDOW_BIT;
|
|
the_configAttr.red_size = EGL_DONT_CARE;
|
|
the_configAttr.green_size = EGL_DONT_CARE;
|
|
the_configAttr.blue_size = EGL_DONT_CARE;
|
|
the_configAttr.alpha_size = EGL_DONT_CARE;
|
|
the_configAttr.samples = EGL_DONT_CARE;
|
|
the_configAttr.config_id = EGL_DONT_CARE;
|
|
|
|
m_isGLInitialized = initGL();
|
|
|
|
if (m_isGLInitialized)
|
|
initEGLFunctions();
|
|
}
|
|
|
|
CCEGLView::~CCEGLView()
|
|
{
|
|
release();
|
|
}
|
|
|
|
void CCEGLView::initEGLFunctions()
|
|
{
|
|
m_extensions = glGetString(GL_EXTENSIONS);
|
|
|
|
glGenerateMipmapOES = 0;
|
|
glGenFramebuffersOES = 0;
|
|
glBindFramebufferOES = 0;
|
|
glFramebufferTexture2DOES = 0;
|
|
glDeleteFramebuffersOES = 0;
|
|
glCheckFramebufferStatusOES = 0;
|
|
|
|
if (isGLExtension("GL_OES_framebuffer_object"))
|
|
{
|
|
glGenerateMipmapOES = (PFNGLGENERATEMIPMAPOESPROC)eglGetProcAddress("glGenerateMipmapOES");
|
|
glGenFramebuffersOES = (PFNGLGENFRAMEBUFFERSOESPROC)eglGetProcAddress("glGenFramebuffersOES");
|
|
glBindFramebufferOES = (PFNGLBINDFRAMEBUFFEROESPROC)eglGetProcAddress("glBindFramebufferOES");
|
|
glFramebufferTexture2DOES = (PFNGLFRAMEBUFFERTEXTURE2DOESPROC)eglGetProcAddress("glFramebufferTexture2DOES");
|
|
glDeleteFramebuffersOES = (PFNGLDELETEFRAMEBUFFERSOESPROC)eglGetProcAddress("glDeleteFramebuffersOES");
|
|
glCheckFramebufferStatusOES = (PFNGLCHECKFRAMEBUFFERSTATUSOESPROC)eglGetProcAddress("glCheckFramebufferStatusOES");
|
|
}
|
|
|
|
m_initializedFunctions = true;
|
|
}
|
|
|
|
void CCEGLView::setFrameWidthAndHeight(int width, int height)
|
|
{
|
|
m_sSizeInPixel.width = width;
|
|
m_sSizeInPixel.height = height;
|
|
}
|
|
|
|
bool CCEGLView::Create(int width, int height)
|
|
{
|
|
if (width == 0 || height == 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
m_sSizeInPoint.width = width;
|
|
m_sSizeInPoint.height = height;
|
|
|
|
// calculate the factor and the rect of viewport
|
|
m_fScreenScaleFactor = MIN((float)m_sSizeInPixel.width / m_sSizeInPoint.width,
|
|
(float)m_sSizeInPixel.height / m_sSizeInPoint.height);
|
|
|
|
int viewPortW = (int)(m_sSizeInPoint.width * m_fScreenScaleFactor);
|
|
int viewPortH = (int)(m_sSizeInPoint.height * m_fScreenScaleFactor);
|
|
|
|
m_rcViewPort.origin.x = (m_sSizeInPixel.width - viewPortW) / 2;
|
|
m_rcViewPort.origin.y = (m_sSizeInPixel.height - viewPortH) / 2;
|
|
m_rcViewPort.size.width = viewPortW;
|
|
m_rcViewPort.size.height = viewPortH;
|
|
|
|
m_bNotHVGA = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
EGLConfig CCEGLView::chooseConfig(const EGLDisplay &eglDisplay, const char* str)
|
|
{
|
|
EGLConfig config = (EGLConfig)0;
|
|
EGLConfig *configurations;
|
|
EGLint egl_num_configs;
|
|
EGLint val;
|
|
EGLBoolean rc;
|
|
const char *tok;
|
|
EGLint i;
|
|
|
|
if (str != NULL)
|
|
{
|
|
tok = str;
|
|
while (*tok == ' ' || *tok == ',')
|
|
tok++;
|
|
|
|
while (*tok != '\0')
|
|
{
|
|
if (strncmp(tok, "rgba8888", strlen("rgba8888")) == 0)
|
|
{
|
|
the_configAttr.red_size = 8;
|
|
the_configAttr.green_size = 8;
|
|
the_configAttr.blue_size = 8;
|
|
the_configAttr.alpha_size = 8;
|
|
tok += strlen("rgba8888");
|
|
}
|
|
else if (strncmp(tok, "rgba5551", strlen("rgba5551")) == 0)
|
|
{
|
|
the_configAttr.red_size = 5;
|
|
the_configAttr.green_size = 5;
|
|
the_configAttr.blue_size = 5;
|
|
the_configAttr.alpha_size = 1;
|
|
tok += strlen("rgba5551");
|
|
}
|
|
else if (strncmp(tok, "rgba4444", strlen("rgba4444")) == 0)
|
|
{
|
|
the_configAttr.red_size = 4;
|
|
the_configAttr.green_size = 4;
|
|
the_configAttr.blue_size = 4;
|
|
the_configAttr.alpha_size = 4;
|
|
tok += strlen("rgba4444");
|
|
}
|
|
else if (strncmp(tok, "rgb565", strlen("rgb565")) == 0)
|
|
{
|
|
the_configAttr.red_size = 5;
|
|
the_configAttr.green_size = 6;
|
|
the_configAttr.blue_size = 5;
|
|
the_configAttr.alpha_size = 0;
|
|
tok += strlen("rgb565");
|
|
}
|
|
else if (isdigit(*tok))
|
|
{
|
|
val = atoi(tok);
|
|
while (isdigit(*(++tok)));
|
|
if (*tok == 'x')
|
|
{
|
|
the_configAttr.samples = val;
|
|
tok++;
|
|
}
|
|
else
|
|
{
|
|
the_configAttr.config_id = val;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "invalid configuration specifier: ");
|
|
while (*tok != ' ' && *tok != ',' && *tok != '\0')
|
|
fputc(*tok++, stderr);
|
|
|
|
fputc('\n', stderr);
|
|
}
|
|
|
|
while (*tok == ' ' || *tok == ',')
|
|
tok++;
|
|
}
|
|
}
|
|
|
|
rc = eglGetConfigs(eglDisplay, NULL, 0, &egl_num_configs);
|
|
if (rc != EGL_TRUE)
|
|
{
|
|
fprintf(stderr, "eglGetConfigs");
|
|
return config;
|
|
}
|
|
|
|
if (egl_num_configs == 0)
|
|
{
|
|
fprintf(stderr, "eglGetConfigs: could not find a configuration\n");
|
|
return config;
|
|
}
|
|
|
|
configurations = (EGLConfig *)malloc(egl_num_configs * sizeof(*configurations));
|
|
if (configurations == NULL)
|
|
{
|
|
fprintf(stderr, "could not allocate memory for %d EGL configs\n", egl_num_configs);
|
|
return config;
|
|
}
|
|
|
|
rc = eglGetConfigs(eglDisplay, configurations, egl_num_configs, &egl_num_configs);
|
|
if (rc != EGL_TRUE)
|
|
{
|
|
fprintf(stderr, "eglGetConfigs");
|
|
free(configurations);
|
|
return config;
|
|
}
|
|
|
|
for (i = 0; i < egl_num_configs; i++)
|
|
{
|
|
if (the_configAttr.config_id != EGL_DONT_CARE)
|
|
{
|
|
eglGetConfigAttrib(eglDisplay, configurations[i], EGL_CONFIG_ID, &val);
|
|
if (val == the_configAttr.config_id)
|
|
{
|
|
config = configurations[i];
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
eglGetConfigAttrib(eglDisplay, configurations[i], EGL_SURFACE_TYPE, &val);
|
|
if ((val & the_configAttr.surface_type) != the_configAttr.surface_type)
|
|
continue;
|
|
|
|
eglGetConfigAttrib(eglDisplay, configurations[i], EGL_RENDERABLE_TYPE, &val);
|
|
if (!(val & EGL_OPENGL_ES_BIT))
|
|
continue;
|
|
|
|
eglGetConfigAttrib(eglDisplay, configurations[i], EGL_DEPTH_SIZE, &val);
|
|
if (val == 0)
|
|
continue;
|
|
|
|
if (the_configAttr.red_size != EGL_DONT_CARE)
|
|
{
|
|
eglGetConfigAttrib(eglDisplay, configurations[i], EGL_RED_SIZE, &val);
|
|
if (val != the_configAttr.red_size)
|
|
continue;
|
|
}
|
|
|
|
if (the_configAttr.green_size != EGL_DONT_CARE)
|
|
{
|
|
eglGetConfigAttrib(eglDisplay, configurations[i], EGL_GREEN_SIZE, &val);
|
|
if (val != the_configAttr.green_size)
|
|
continue;
|
|
}
|
|
|
|
if (the_configAttr.blue_size != EGL_DONT_CARE)
|
|
{
|
|
eglGetConfigAttrib(eglDisplay, configurations[i], EGL_BLUE_SIZE, &val);
|
|
if (val != the_configAttr.blue_size)
|
|
continue;
|
|
}
|
|
|
|
if (the_configAttr.alpha_size != EGL_DONT_CARE)
|
|
{
|
|
eglGetConfigAttrib(eglDisplay, configurations[i], EGL_ALPHA_SIZE, &val);
|
|
if (val != the_configAttr.alpha_size)
|
|
continue;
|
|
}
|
|
|
|
if (the_configAttr.samples != EGL_DONT_CARE)
|
|
{
|
|
eglGetConfigAttrib(eglDisplay, configurations[i], EGL_SAMPLES, &val);
|
|
if (val != the_configAttr.samples)
|
|
continue;
|
|
}
|
|
|
|
config = configurations[i];
|
|
break;
|
|
}
|
|
|
|
free(configurations);
|
|
|
|
if (config == (EGLConfig)0)
|
|
{
|
|
fprintf(stderr, "eglChooseConfig: could not find a matching configuration\n");
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
int CCEGLView::chooseFormat(const EGLDisplay &eglDisplay, const EGLConfig &config)
|
|
{
|
|
EGLint buffer_bit_depth, alpha_bit_depth;
|
|
|
|
eglGetConfigAttrib(eglDisplay, config, EGL_BUFFER_SIZE, &buffer_bit_depth);
|
|
eglGetConfigAttrib(eglDisplay, config, EGL_ALPHA_SIZE, &alpha_bit_depth);
|
|
|
|
switch (buffer_bit_depth)
|
|
{
|
|
case 32: return SCREEN_FORMAT_RGBA8888;
|
|
case 24: return SCREEN_FORMAT_RGB888;
|
|
case 16:
|
|
{
|
|
switch (alpha_bit_depth)
|
|
{
|
|
case 4: return SCREEN_FORMAT_RGBA4444;
|
|
case 1: return SCREEN_FORMAT_RGBA5551;
|
|
default: return SCREEN_FORMAT_RGB565;
|
|
}
|
|
}
|
|
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
void CCEGLView::printEGLInfo(const EGLConfig &config) const
|
|
{
|
|
int i;
|
|
|
|
fprintf(stderr,"EGL_VENDOR = %s\n", eglQueryString(m_eglDisplay, EGL_VENDOR));
|
|
fprintf(stderr,"EGL_VERSION = %s\n", eglQueryString(m_eglDisplay, EGL_VERSION));
|
|
fprintf(stderr,"EGL_CLIENT_APIS = %s\n", eglQueryString(m_eglDisplay, EGL_CLIENT_APIS));
|
|
fprintf(stderr,"EGL_EXTENSIONS = %s\n\n", eglQueryString(m_eglDisplay, EGL_EXTENSIONS));
|
|
|
|
i = -1;
|
|
eglGetConfigAttrib(m_eglDisplay, config, EGL_CONFIG_ID, &i);
|
|
fprintf(stderr,"EGL_CONFIG_ID = %d\n", i);
|
|
|
|
i = 0;
|
|
eglGetConfigAttrib(m_eglDisplay, config, EGL_RED_SIZE, &i);
|
|
fprintf(stderr,"EGL_RED_SIZE = %d\n", i);
|
|
|
|
i = 0;
|
|
eglGetConfigAttrib(m_eglDisplay, config, EGL_GREEN_SIZE, &i);
|
|
fprintf(stderr,"EGL_GREEN_SIZE = %d\n", i);
|
|
|
|
i = 0;
|
|
eglGetConfigAttrib(m_eglDisplay, config, EGL_BLUE_SIZE, &i);
|
|
fprintf(stderr,"EGL_BLUE_SIZE = %d\n", i);
|
|
|
|
i = 0;
|
|
eglGetConfigAttrib(m_eglDisplay, config, EGL_ALPHA_SIZE, &i);
|
|
fprintf(stderr,"EGL_ALPHA_SIZE = %d\n", i);
|
|
|
|
i = 0;
|
|
eglGetConfigAttrib(m_eglDisplay, config, EGL_DEPTH_SIZE, &i);
|
|
fprintf(stderr,"EGL_DEPTH_SIZE = %d\n", i);
|
|
|
|
i = 0;
|
|
eglGetConfigAttrib(m_eglDisplay, config, EGL_LEVEL, &i);
|
|
fprintf(stderr,"EGL_LEVEL = %d\n", i);
|
|
|
|
i = 0;
|
|
eglGetConfigAttrib(m_eglDisplay, config, EGL_NATIVE_RENDERABLE, &i);
|
|
fprintf(stderr,"EGL_NATIVE_RENDERABLE = %s\n", i ? "EGL_TRUE" : "EGL_FALSE");
|
|
|
|
i = 0;
|
|
eglGetConfigAttrib(m_eglDisplay, config, EGL_NATIVE_VISUAL_TYPE, &i);
|
|
fprintf(stderr,"EGL_NATIVE_VISUAL_TYPE = %d\n", i);
|
|
|
|
i = 0;
|
|
eglGetConfigAttrib(m_eglDisplay, config, EGL_RENDERABLE_TYPE, &i);
|
|
fprintf(stderr,"EGL_RENDERABLE_TYPE = 0x%04x\n", i);
|
|
|
|
i = 0;
|
|
eglGetConfigAttrib(m_eglDisplay, config, EGL_SURFACE_TYPE, &i);
|
|
fprintf(stderr,"EGL_SURFACE_TYPE = 0x%04x\n", i);
|
|
|
|
i = 0;
|
|
eglGetConfigAttrib(m_eglDisplay, config, EGL_TRANSPARENT_TYPE, &i);
|
|
if (i == EGL_TRANSPARENT_RGB)
|
|
{
|
|
fprintf(stderr,"EGL_TRANSPARENT_TYPE = EGL_TRANSPARENT_RGB\n");
|
|
|
|
i = 0;
|
|
eglGetConfigAttrib(m_eglDisplay, config, EGL_TRANSPARENT_RED_VALUE, &i);
|
|
fprintf(stderr,"EGL_TRANSPARENT_RED = 0x%02x\n", i);
|
|
|
|
i = 0;
|
|
eglGetConfigAttrib(m_eglDisplay, config, EGL_TRANSPARENT_GREEN_VALUE, &i);
|
|
fprintf(stderr,"EGL_TRANSPARENT_GREEN = 0x%02x\n", i);
|
|
|
|
i = 0;
|
|
eglGetConfigAttrib(m_eglDisplay, config, EGL_TRANSPARENT_BLUE_VALUE, &i);
|
|
fprintf(stderr,"EGL_TRANSPARENT_BLUE = 0x%02x\n\n", i);
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr,"EGL_TRANSPARENT_TYPE = EGL_NONE\n\n");
|
|
}
|
|
}
|
|
|
|
static void printEglError( GLuint errorCode )
|
|
{
|
|
switch( errorCode )
|
|
{
|
|
case EGL_SUCCESS:
|
|
fprintf( stderr, "EGL_SUCCESS");
|
|
break;
|
|
case EGL_NOT_INITIALIZED:
|
|
fprintf( stderr, ">>EGL_NOT_INITIALIZED");
|
|
break;
|
|
case EGL_BAD_ACCESS:
|
|
fprintf( stderr, ">>EGL_BAD_ACCESS");
|
|
break;
|
|
case EGL_BAD_ALLOC:
|
|
fprintf( stderr, ">>EGL_BAD_ALLOC");
|
|
break;
|
|
case EGL_BAD_ATTRIBUTE:
|
|
fprintf( stderr, ">>EGL_BAD_ATTRIBUTE");
|
|
break;
|
|
case EGL_BAD_CONTEXT:
|
|
fprintf( stderr, ">>EGL_BAD_CONTEXT");
|
|
break;
|
|
case EGL_BAD_CONFIG:
|
|
fprintf( stderr, ">>EGL_BAD_CONFIG");
|
|
break;
|
|
case EGL_BAD_CURRENT_SURFACE:
|
|
fprintf( stderr, ">>EGL_BAD_CURRENT_SURFACE");
|
|
break;
|
|
case EGL_BAD_DISPLAY:
|
|
fprintf( stderr, ">>EGL_BAD_DISPLAY");
|
|
break;
|
|
case EGL_BAD_SURFACE:
|
|
fprintf( stderr, ">>EGL_BAD_SURFACE");
|
|
break;
|
|
case EGL_BAD_MATCH:
|
|
fprintf( stderr, ">>EGL_BAD_MATCH");
|
|
break;
|
|
case EGL_BAD_PARAMETER:
|
|
fprintf( stderr, ">>EGL_BAD_PARAMETER");
|
|
break;
|
|
case EGL_BAD_NATIVE_PIXMAP:
|
|
fprintf( stderr, ">>EGL_BAD_NATIVE_PIXMAP");
|
|
break;
|
|
case EGL_BAD_NATIVE_WINDOW:
|
|
fprintf( stderr, ">>EGL_BAD_NATIVE_WIN i=i+2DOW");
|
|
break;
|
|
case EGL_CONTEXT_LOST:
|
|
fprintf( stderr, ">>EGL_CONTEXT_LOST");
|
|
break;
|
|
default:
|
|
fprintf( stderr, ">>Unknown error");
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool CCEGLView::initDriver()
|
|
{
|
|
int err;
|
|
int egl_ret;
|
|
EGLint majorVersion;
|
|
EGLint minorVersion;
|
|
|
|
// Get EGL display
|
|
m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
|
err = eglGetError();
|
|
if (m_eglDisplay == EGL_NO_DISPLAY || err != EGL_SUCCESS)
|
|
{
|
|
printEglError( err );
|
|
return false;
|
|
}
|
|
|
|
// Initialize EGL
|
|
egl_ret = eglInitialize(m_eglDisplay, &majorVersion, &minorVersion);
|
|
err = eglGetError();
|
|
if ( egl_ret != EGL_TRUE || err != EGL_SUCCESS )
|
|
{
|
|
printEglError( err );
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CCEGLView::createNativeWindow(const EGLConfig &config)
|
|
{
|
|
int usage = SCREEN_USAGE_OPENGL_ES1;
|
|
int transp = SCREEN_TRANSPARENCY_NONE;
|
|
int pos[2] = { 0, 0 };
|
|
int nbuffers = 2;
|
|
EGLint interval = 1;
|
|
int format;
|
|
EGLint err;
|
|
|
|
err = screen_create_context(&m_screenContext, 0);
|
|
if (err)
|
|
{
|
|
fprintf(stderr, "screen_create_context");
|
|
return false;
|
|
}
|
|
|
|
err = screen_create_window(&m_screenWindow, m_screenContext);
|
|
if (err)
|
|
{
|
|
fprintf(stderr, "screen_create_window");
|
|
return false;
|
|
}
|
|
|
|
err = screen_create_window_group(m_screenWindow, m_window_group_id);
|
|
if (err)
|
|
{
|
|
fprintf(stderr, "screen_create_window_group");
|
|
return false;
|
|
}
|
|
format = chooseFormat(m_eglDisplay, config);
|
|
err = screen_set_window_property_iv(m_screenWindow, SCREEN_PROPERTY_FORMAT, &format);
|
|
if (err)
|
|
{
|
|
fprintf(stderr, "screen_set_window_property_iv(SCREEN_PROPERTY_FORMAT)");
|
|
return false;
|
|
}
|
|
|
|
err = screen_set_window_property_iv(m_screenWindow, SCREEN_PROPERTY_USAGE, &usage);
|
|
if (err)
|
|
{
|
|
fprintf(stderr, "screen_set_window_property_iv(SCREEN_PROPERTY_USAGE)");
|
|
return false;
|
|
}
|
|
|
|
if (pos[0] != 0 || pos[1] != 0)
|
|
{
|
|
err = screen_set_window_property_iv(m_screenWindow, SCREEN_PROPERTY_POSITION, pos);
|
|
if (err)
|
|
{
|
|
fprintf(stderr, "screen_set_window_property_iv(SCREEN_PROPERTY_POSITION)");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
err = screen_set_window_property_iv(m_screenWindow, SCREEN_PROPERTY_TRANSPARENCY, &transp);
|
|
if (err)
|
|
{
|
|
fprintf(stderr, "screen_set_window_property_iv(SCREEN_PROPERTY_TRANSPARENCY)");
|
|
return false;
|
|
}
|
|
|
|
err = screen_set_window_property_iv(m_screenWindow, SCREEN_PROPERTY_SWAP_INTERVAL, &interval);
|
|
if (err)
|
|
{
|
|
fprintf(stderr, "screen_set_window_property_iv(SCREEN_PROPERTY_SWAP_INTERVAL)");
|
|
return false;
|
|
}
|
|
|
|
screen_display_t screen_disp;
|
|
int rc = screen_get_window_property_pv(m_screenWindow, SCREEN_PROPERTY_DISPLAY, (void **)&screen_disp);
|
|
if (rc)
|
|
{
|
|
fprintf(stderr, "screen_get_window_property_pv(SCREEN_PROPERTY_DISPLAY)");
|
|
return false;
|
|
}
|
|
|
|
screen_display_mode_t screen_mode;
|
|
rc = screen_get_display_property_pv(screen_disp, SCREEN_PROPERTY_MODE, (void**)&screen_mode);
|
|
if (rc)
|
|
{
|
|
fprintf(stderr, "screen_get_display_property_pv(SCREEN_PROPERTY_MODE)");
|
|
return false;
|
|
}
|
|
|
|
int size[2];
|
|
rc = screen_get_window_property_iv(m_screenWindow, SCREEN_PROPERTY_BUFFER_SIZE, size);
|
|
if (rc)
|
|
{
|
|
fprintf(stderr, "screen_get_window_property_iv(SCREEN_PROPERTY_BUFFER_SIZE)");
|
|
return false;
|
|
}
|
|
|
|
int angle = atoi(getenv("ORIENTATION"));
|
|
int buffer_size[2] = { size[0], size[1] };
|
|
|
|
if ((angle == 0) || (angle == 180))
|
|
{
|
|
if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) ||
|
|
((screen_mode.width < screen_mode.height) && (size[0] > size[1])))
|
|
{
|
|
buffer_size[1] = size[0];
|
|
buffer_size[0] = size[1];
|
|
}
|
|
}
|
|
else if ((angle == 90) || (angle == 270))
|
|
{
|
|
if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) ||
|
|
((screen_mode.width < screen_mode.height && size[0] < size[1])))
|
|
{
|
|
buffer_size[1] = size[0];
|
|
buffer_size[0] = size[1];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "Navigator returned an unexpected orientation angle of %d.\n", angle);
|
|
return false;
|
|
}
|
|
|
|
rc = screen_set_window_property_iv(m_screenWindow, SCREEN_PROPERTY_BUFFER_SIZE, buffer_size);
|
|
if (rc)
|
|
{
|
|
fprintf(stderr, "screen_set_window_property_iv(SCREEN_PROPERTY_BUFFER_SIZE)");
|
|
return false;
|
|
}
|
|
|
|
rc = screen_set_window_property_iv(m_screenWindow, SCREEN_PROPERTY_ROTATION, &angle);
|
|
if (rc)
|
|
{
|
|
fprintf(stderr, "screen_set_window_property_iv(SCREEN_PROPERTY_ROTATION)");
|
|
return false;
|
|
}
|
|
|
|
err = screen_create_window_buffers(m_screenWindow, nbuffers);
|
|
if (err)
|
|
{
|
|
fprintf(stderr, "screen_create_window_buffers");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
#define N_BPS_EVENTS 1
|
|
|
|
bool CCEGLView::initGL()
|
|
{
|
|
EGLConfig config;
|
|
EGLint err;
|
|
|
|
initDriver();
|
|
|
|
config = chooseConfig(m_eglDisplay, "rgb565");
|
|
if (config == (EGLConfig)0)
|
|
{
|
|
fprintf(stderr, "Failed to find config!" );
|
|
return false;
|
|
}
|
|
|
|
// Create EGL rendering context
|
|
m_eglContext = eglCreateContext( m_eglDisplay, config, EGL_NO_CONTEXT, NULL );
|
|
err = eglGetError( );
|
|
if ( m_eglContext == EGL_NO_CONTEXT )
|
|
{
|
|
fprintf(stderr, "Can't create gles2 context!" );
|
|
printEglError( err );
|
|
return false;
|
|
}
|
|
|
|
// printEGLInfo(config);
|
|
|
|
if (!createNativeWindow(config))
|
|
{
|
|
fprintf(stderr, "Unable to create a native window\n");
|
|
return false;
|
|
}
|
|
|
|
// set up the screen events
|
|
err = screen_create_event(&m_screenEvent);
|
|
if (err)
|
|
{
|
|
fprintf(stderr, "screen_create_event");
|
|
return false;
|
|
}
|
|
|
|
#ifdef BPS_EVENTS
|
|
// Request screen events
|
|
screen_request_events(m_screenContext);
|
|
#endif
|
|
|
|
m_eglSurface = eglCreateWindowSurface(m_eglDisplay, config, m_screenWindow, NULL);
|
|
if (m_eglSurface == EGL_NO_SURFACE)
|
|
{
|
|
fprintf(stderr, "Demo Thread Init: can't create surface!" );
|
|
printEglError( err );
|
|
return false;
|
|
}
|
|
|
|
err = eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
|
|
if (err != EGL_TRUE)
|
|
{
|
|
fprintf(stderr, "Demo Thread Init: can't make current!" );
|
|
return false;
|
|
}
|
|
|
|
EGLint width, height;
|
|
|
|
if ((m_eglDisplay == EGL_NO_DISPLAY) || (m_eglSurface == EGL_NO_SURFACE) )
|
|
return EXIT_FAILURE;
|
|
|
|
eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH, &width);
|
|
eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT, &height);
|
|
|
|
m_sSizeInPixel.width = width;
|
|
m_sSizeInPixel.height = height;
|
|
|
|
return true;
|
|
}
|
|
|
|
CCSize CCEGLView::getSize()
|
|
{
|
|
if (m_bNotHVGA)
|
|
{
|
|
CCSize size(m_sSizeInPoint.width, m_sSizeInPoint.height);
|
|
return size;
|
|
}
|
|
else
|
|
{
|
|
CCSize size(m_sSizeInPixel.width, m_sSizeInPixel.height);
|
|
return size;
|
|
}
|
|
}
|
|
|
|
bool CCEGLView::isOpenGLReady()
|
|
{
|
|
return (m_isGLInitialized && m_sSizeInPixel.width != 0 && m_sSizeInPixel.height != 0);
|
|
}
|
|
|
|
bool CCEGLView::isIpad()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
void CCEGLView::release()
|
|
{
|
|
if (!m_eglContext || !m_eglDisplay)
|
|
return;
|
|
#ifdef BPS_EVENTS
|
|
screen_stop_events(m_screenContext);
|
|
#endif
|
|
bps_shutdown();
|
|
|
|
screen_destroy_event(m_screenEvent);
|
|
|
|
eglMakeCurrent(m_eglDisplay, NULL, NULL, NULL);
|
|
eglDestroySurface(m_eglDisplay, m_eglSurface);
|
|
screen_destroy_window(m_screenWindow);
|
|
screen_destroy_context(m_screenContext);
|
|
eglDestroyContext(m_eglDisplay, m_eglContext);
|
|
eglTerminate(m_eglDisplay);
|
|
eglReleaseThread();
|
|
|
|
m_eglDisplay = NULL;
|
|
m_eglContext = NULL;
|
|
m_eglSurface = NULL;
|
|
|
|
m_isGLInitialized = false;
|
|
|
|
exit(0);
|
|
}
|
|
|
|
void CCEGLView::setEventHandler(EventHandler* pHandler)
|
|
{
|
|
m_pEventHandler = pHandler;
|
|
}
|
|
|
|
const char* CCEGLView::getWindowGroupId() const
|
|
{
|
|
return m_window_group_id;
|
|
}
|
|
void CCEGLView::setTouchDelegate(EGLTouchDelegate * pDelegate)
|
|
{
|
|
m_pDelegate = pDelegate;
|
|
}
|
|
|
|
EGLTouchDelegate* CCEGLView::getDelegate(void)
|
|
{
|
|
return m_pDelegate;
|
|
}
|
|
|
|
bool CCEGLView::HandleEvents()
|
|
{
|
|
bps_event_t* event = NULL;
|
|
mtouch_event_t mtouch_event;
|
|
int touch_id = 0;
|
|
int val = 0;
|
|
int rc = 0;
|
|
int domain = 0;
|
|
char buf[4] = {0};
|
|
|
|
for (;;)
|
|
{
|
|
rc = bps_get_event(&event, 1);
|
|
assert(rc == BPS_SUCCESS);
|
|
|
|
#ifdef BPS_EVENTS
|
|
// break if no more events
|
|
if (event == NULL)
|
|
break;
|
|
#else
|
|
if (event != NULL)
|
|
{
|
|
#endif
|
|
if (m_pEventHandler && m_pEventHandler->HandleBPSEvent(event))
|
|
continue;
|
|
|
|
domain = bps_event_get_domain(event);
|
|
|
|
if (domain == navigator_get_domain())
|
|
{
|
|
switch (bps_event_get_code(event))
|
|
{
|
|
case NAVIGATOR_SWIPE_DOWN:
|
|
CCKeypadDispatcher::sharedDispatcher()->dispatchKeypadMSG(kTypeMenuClicked);
|
|
break;
|
|
|
|
case NAVIGATOR_EXIT:
|
|
// exit the application
|
|
// release();
|
|
break;
|
|
|
|
case NAVIGATOR_WINDOW_INACTIVE:
|
|
if(m_isWindowActive)
|
|
{
|
|
CCApplication::sharedApplication().applicationDidEnterBackground();
|
|
m_isWindowActive = false;
|
|
}
|
|
break;
|
|
|
|
case NAVIGATOR_WINDOW_ACTIVE:
|
|
if(!m_isWindowActive)
|
|
{
|
|
CCApplication::sharedApplication().applicationWillEnterForeground();
|
|
m_isWindowActive = true;
|
|
}
|
|
break;
|
|
|
|
case NAVIGATOR_WINDOW_STATE:
|
|
{
|
|
switch(navigator_event_get_window_state(event))
|
|
{
|
|
case NAVIGATOR_WINDOW_FULLSCREEN:
|
|
if(!m_isWindowActive)
|
|
{
|
|
CCApplication::sharedApplication().applicationWillEnterForeground();
|
|
m_isWindowActive = true;
|
|
}
|
|
break;
|
|
case NAVIGATOR_WINDOW_THUMBNAIL:
|
|
if(m_isWindowActive)
|
|
{
|
|
CCApplication::sharedApplication().applicationDidEnterBackground();
|
|
m_isWindowActive = false;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
#ifndef BPS_EVENTS
|
|
// for now handle screen events separately from BPS events
|
|
if (screen_get_event(m_screenContext, m_screenEvent, 0) < 0)
|
|
{
|
|
// we have an error condition in the screen event
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
#else
|
|
else if (domain == screen_get_domain())
|
|
{
|
|
m_screenEvent = screen_event_get_event(event);
|
|
#endif
|
|
rc = screen_get_event_property_iv(m_screenEvent, SCREEN_PROPERTY_TYPE, &val);
|
|
if (rc || val == SCREEN_EVENT_NONE)
|
|
break;
|
|
|
|
switch (val)
|
|
{
|
|
case SCREEN_EVENT_CLOSE:
|
|
fprintf(stderr, "SCREEN CLOSE EVENT!\n");
|
|
break;
|
|
|
|
case SCREEN_EVENT_MTOUCH_RELEASE:
|
|
screen_get_mtouch_event(m_screenEvent, &mtouch_event, 0);
|
|
touch_id = mtouch_event.contact_id;
|
|
|
|
if (m_pDelegate && touch_id < MAX_TOUCHES)
|
|
{
|
|
CCTouch* touch = s_pTouches[touch_id];
|
|
if (touch)
|
|
{
|
|
CCSet set;
|
|
touch->SetTouchInfo(((float)(mtouch_event.x) - m_rcViewPort.origin.x) / m_fScreenScaleFactor,
|
|
((float)(mtouch_event.y) - m_rcViewPort.origin.y) / m_fScreenScaleFactor);
|
|
set.addObject(touch);
|
|
m_pDelegate->touchesEnded(&set, NULL);
|
|
|
|
touch->release();
|
|
for (int i = touch_id; i < MAX_TOUCHES; i++)
|
|
{
|
|
if (i != (MAX_TOUCHES - 1))
|
|
{
|
|
s_pTouches[i] = s_pTouches[i + 1];
|
|
}
|
|
else
|
|
{
|
|
s_pTouches[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case SCREEN_EVENT_MTOUCH_TOUCH:
|
|
screen_get_mtouch_event(m_screenEvent, &mtouch_event, 0);
|
|
touch_id = mtouch_event.contact_id;
|
|
|
|
if (m_pDelegate && touch_id < MAX_TOUCHES)
|
|
{
|
|
CCTouch* touch = s_pTouches[touch_id];
|
|
if (!touch)
|
|
touch = new CCTouch;
|
|
|
|
touch->SetTouchInfo(((float)(mtouch_event.x) - m_rcViewPort.origin.x) / m_fScreenScaleFactor,
|
|
((float)(mtouch_event.y) - m_rcViewPort.origin.y) / m_fScreenScaleFactor);
|
|
s_pTouches[touch_id] = touch;
|
|
|
|
CCSet set;
|
|
set.addObject(touch);
|
|
m_pDelegate->touchesBegan(&set, NULL);
|
|
}
|
|
|
|
break;
|
|
|
|
case SCREEN_EVENT_MTOUCH_MOVE:
|
|
screen_get_mtouch_event(m_screenEvent, &mtouch_event, 0);
|
|
touch_id = mtouch_event.contact_id;
|
|
|
|
if (m_pDelegate && touch_id < MAX_TOUCHES)
|
|
{
|
|
CCTouch* touch = s_pTouches[touch_id];
|
|
if (touch)
|
|
{
|
|
CCSet set;
|
|
touch->SetTouchInfo(((float)(mtouch_event.x) - m_rcViewPort.origin.x) / m_fScreenScaleFactor,
|
|
((float)(mtouch_event.y) - m_rcViewPort.origin.y) / m_fScreenScaleFactor);
|
|
set.addObject(touch);
|
|
m_pDelegate->touchesMoved(&set, NULL);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case SCREEN_EVENT_POINTER:
|
|
{
|
|
int buttons;
|
|
int pair[2];
|
|
static bool mouse_pressed = false;
|
|
|
|
// this is a mouse move event, it is applicable to a device with a usb mouse or simulator
|
|
screen_get_event_property_iv(m_screenEvent, SCREEN_PROPERTY_BUTTONS, &buttons);
|
|
screen_get_event_property_iv(m_screenEvent, SCREEN_PROPERTY_SOURCE_POSITION, pair);
|
|
|
|
if (buttons & SCREEN_LEFT_MOUSE_BUTTON)
|
|
{
|
|
if (mouse_pressed)
|
|
{
|
|
// Left mouse button was released
|
|
if (m_pDelegate && touch_id < MAX_TOUCHES)
|
|
{
|
|
CCTouch* touch = s_pTouches[touch_id];
|
|
if (touch)
|
|
{
|
|
CCSet set;
|
|
touch->SetTouchInfo(((float)(pair[0]) - m_rcViewPort.origin.x) / m_fScreenScaleFactor,
|
|
((float)(pair[1]) - m_rcViewPort.origin.y) / m_fScreenScaleFactor);
|
|
set.addObject(touch);
|
|
m_pDelegate->touchesMoved(&set, NULL);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Left mouse button is pressed
|
|
mouse_pressed = true;
|
|
if (m_pDelegate && touch_id < MAX_TOUCHES)
|
|
{
|
|
CCTouch* touch = s_pTouches[touch_id];
|
|
if (!touch)
|
|
touch = new CCTouch;
|
|
|
|
touch->SetTouchInfo(((float)(pair[0]) - m_rcViewPort.origin.x) / m_fScreenScaleFactor,
|
|
((float)(pair[1]) - m_rcViewPort.origin.y) / m_fScreenScaleFactor);
|
|
s_pTouches[touch_id] = touch;
|
|
|
|
CCSet set;
|
|
set.addObject(touch);
|
|
m_pDelegate->touchesBegan(&set, NULL);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (mouse_pressed)
|
|
{
|
|
if (m_pDelegate && touch_id < MAX_TOUCHES)
|
|
{
|
|
mouse_pressed = false;
|
|
|
|
CCTouch* touch = s_pTouches[touch_id];
|
|
if (touch)
|
|
{
|
|
CCSet set;
|
|
touch->SetTouchInfo(((float)(pair[0]) - m_rcViewPort.origin.x) / m_fScreenScaleFactor,
|
|
((float)(pair[1]) - m_rcViewPort.origin.y) / m_fScreenScaleFactor);
|
|
set.addObject(touch);
|
|
m_pDelegate->touchesEnded(&set, NULL);
|
|
|
|
touch->release();
|
|
for (int i = touch_id; i < MAX_TOUCHES; i++)
|
|
{
|
|
if (i != (MAX_TOUCHES - 1))
|
|
{
|
|
s_pTouches[i] = s_pTouches[i + 1];
|
|
}
|
|
else
|
|
{
|
|
s_pTouches[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SCREEN_EVENT_KEYBOARD:
|
|
screen_get_event_property_iv(m_screenEvent, SCREEN_PROPERTY_KEY_FLAGS, &val);
|
|
if (val & KEY_DOWN)
|
|
{
|
|
screen_get_event_property_iv(m_screenEvent, SCREEN_PROPERTY_KEY_SYM, &val);
|
|
|
|
if (val >= ' ' && val < '~')
|
|
{
|
|
buf[0] = val;
|
|
buf[1]= '\0';
|
|
CCIMEDispatcher::sharedDispatcher()->dispatchInsertText(buf, 1);
|
|
}
|
|
else
|
|
{
|
|
val = val - 0xf000;
|
|
buf[0] = val;
|
|
buf[1]= '\0';
|
|
|
|
switch (val)
|
|
{
|
|
case 8: // backspace
|
|
// CCKeypadDispatcher::sharedDispatcher()->dispatchKeypadMSG(kTypeBackClicked);
|
|
CCIMEDispatcher::sharedDispatcher()->dispatchDeleteBackward();
|
|
break;
|
|
|
|
default:
|
|
CCIMEDispatcher::sharedDispatcher()->dispatchInsertText(buf, 1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void CCEGLView::swapBuffers()
|
|
{
|
|
eglSwapBuffers(m_eglDisplay, m_eglSurface);
|
|
}
|
|
|
|
bool CCEGLView::canSetContentScaleFactor()
|
|
{
|
|
// can scale content?
|
|
return false;
|
|
}
|
|
|
|
void CCEGLView::setContentScaleFactor(float contentScaleFactor)
|
|
{
|
|
m_fScreenScaleFactor = contentScaleFactor;
|
|
}
|
|
|
|
void CCEGLView::setViewPortInPoints(float x, float y, float w, float h)
|
|
{
|
|
if (m_bNotHVGA)
|
|
{
|
|
float factor = m_fScreenScaleFactor / CC_CONTENT_SCALE_FACTOR();
|
|
glViewport( (GLint)(x * factor) + m_rcViewPort.origin.x,
|
|
(GLint)(y * factor) + m_rcViewPort.origin.y,
|
|
(GLint)(w * factor),
|
|
(GLint)(h * factor));
|
|
}
|
|
else
|
|
{
|
|
glViewport( (GLint)x,
|
|
(GLint)y,
|
|
(GLint)w,
|
|
(GLint)h);
|
|
}
|
|
}
|
|
|
|
void CCEGLView::setScissorInPoints(float x, float y, float w, float h)
|
|
{
|
|
if (m_bNotHVGA)
|
|
{
|
|
float factor = m_fScreenScaleFactor / CC_CONTENT_SCALE_FACTOR();
|
|
glScissor( (GLint)(x * factor) + m_rcViewPort.origin.x,
|
|
(GLint)(y * factor) + m_rcViewPort.origin.y,
|
|
(GLint)(w * factor),
|
|
(GLint)(h * factor));
|
|
}
|
|
else
|
|
{
|
|
glScissor( (GLint)x,
|
|
(GLint)y,
|
|
(GLint)w,
|
|
(GLint)h);
|
|
}
|
|
}
|
|
|
|
CCEGLView& CCEGLView::sharedOpenGLView()
|
|
{
|
|
CCAssert(s_pInstance != NULL, "CCEGLView wasn't constructed yet");
|
|
return *s_pInstance;
|
|
}
|
|
|
|
float CCEGLView::getScreenScaleFactor()
|
|
{
|
|
return m_fScreenScaleFactor;
|
|
}
|
|
|
|
CCRect CCEGLView::getViewPort()
|
|
{
|
|
if (m_bNotHVGA)
|
|
{
|
|
return m_rcViewPort;
|
|
}
|
|
else
|
|
{
|
|
CCRect rect(0, 0, 0, 0);
|
|
return rect;
|
|
}
|
|
}
|
|
|
|
bool CCEGLView::isGLExtension(const char *searchName) const
|
|
{
|
|
const GLubyte *start;
|
|
GLubyte *where, *terminator;
|
|
|
|
/* It takes a bit of care to be fool-proof about parsing the
|
|
OpenGL extensions string. Don't be fooled by sub-strings,
|
|
etc. */
|
|
start = m_extensions;
|
|
for (;;)
|
|
{
|
|
where = (GLubyte *) strstr((const char *) start, searchName);
|
|
if (!where)
|
|
break;
|
|
|
|
terminator = where + strlen(searchName);
|
|
if (where == start || *(where - 1) == ' ')
|
|
if (*terminator == ' ' || *terminator == '\0')
|
|
return true;
|
|
|
|
start = terminator;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CCEGLView::showKeyboard()
|
|
{
|
|
int height;
|
|
|
|
virtualkeyboard_get_height(&height);
|
|
|
|
float factor = m_fScreenScaleFactor / CC_CONTENT_SCALE_FACTOR();
|
|
height = (float)height / factor;
|
|
|
|
CCRect rect_begin(0, 0 - height, m_sSizeInPixel.width / factor, height);
|
|
CCRect rect_end(0, 0, m_sSizeInPixel.width / factor, height);
|
|
|
|
CCIMEKeyboardNotificationInfo info;
|
|
info.begin = rect_begin;
|
|
info.end = rect_end;
|
|
info.duration = 0;
|
|
|
|
CCIMEDispatcher::sharedDispatcher()->dispatchKeyboardWillShow(info);
|
|
virtualkeyboard_show();
|
|
CCIMEDispatcher::sharedDispatcher()->dispatchKeyboardDidShow(info);
|
|
}
|
|
|
|
void CCEGLView::hideKeyboard()
|
|
{
|
|
virtualkeyboard_hide();
|
|
}
|
|
|
|
void CCEGLView::setIMEKeyboardState(bool bOpen)
|
|
{
|
|
if (bOpen)
|
|
showKeyboard();
|
|
else
|
|
hideKeyboard();
|
|
}
|
|
|
|
NS_CC_END
|