Made glutGet, for window width and height, return width and height determined by device rotation Now handles keyboard open/close (along wit device rotation while the keyboard is open) and resize The "back" operation now returns an ESCAPE key

git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1671 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
dcnieho 2014-01-24 10:34:17 +00:00
parent eb835cc833
commit d8f19f2481
6 changed files with 198 additions and 30 deletions

View File

@ -128,7 +128,6 @@ ELSEIF(ANDROID OR BLACKBERRY)
src/android/fg_gamemode_android.c src/android/fg_gamemode_android.c
src/android/fg_joystick_android.c src/android/fg_joystick_android.c
src/android/fg_spaceball_android.c src/android/fg_spaceball_android.c
src/android/fg_structure_android.c
) )
IF(ANDROID) IF(ANDROID)
LIST(APPEND FREEGLUT_SRCS LIST(APPEND FREEGLUT_SRCS
@ -141,6 +140,7 @@ ELSEIF(ANDROID OR BLACKBERRY)
src/android/fg_main_android.h src/android/fg_main_android.h
src/android/fg_runtime_android.c src/android/fg_runtime_android.c
src/android/fg_state_android.c src/android/fg_state_android.c
src/android/fg_structure_android.c
src/android/fg_window_android.c src/android/fg_window_android.c
) )
ELSE() ELSE()
@ -150,6 +150,7 @@ ELSEIF(ANDROID OR BLACKBERRY)
src/x11/fg_input_devices_x11.c src/x11/fg_input_devices_x11.c
src/blackberry/fg_main_blackberry.c src/blackberry/fg_main_blackberry.c
src/blackberry/fg_state_blackberry.c src/blackberry/fg_state_blackberry.c
src/blackberry/fg_structure_blackberry.c
src/blackberry/fg_window_blackberry.c src/blackberry/fg_window_blackberry.c
) )
ENDIF() ENDIF()

View File

@ -34,6 +34,7 @@
#include "egl/fg_internal_egl.h" #include "egl/fg_internal_egl.h"
#include <screen/screen.h> #include <screen/screen.h>
#include <bps/event.h> #include <bps/event.h>
#include <bps/navigator.h>
/* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */ /* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */
/* The structure used by display initialization in freeglut_init.c */ /* The structure used by display initialization in freeglut_init.c */
@ -115,6 +116,9 @@ struct tagSFG_PlatformWindowState
{ {
int newWidth; int newWidth;
int newHeight; int newHeight;
int originalRotation;
navigator_window_state_t windowState;
GLboolean windowCovered;
}; };
/* Menu font and color definitions */ /* Menu font and color definitions */

View File

@ -40,6 +40,7 @@
#include <bps/event.h> #include <bps/event.h>
#include <bps/screen.h> #include <bps/screen.h>
#include <bps/navigator.h> #include <bps/navigator.h>
#include <bps/virtualkeyboard.h>
extern void fghOnReshapeNotify(SFG_Window *window, int width, int height, GLboolean forceNotify); extern void fghOnReshapeNotify(SFG_Window *window, int width, int height, GLboolean forceNotify);
extern void fghOnPositionNotify(SFG_Window *window, int x, int y, GLboolean forceNotify); extern void fghOnPositionNotify(SFG_Window *window, int x, int y, GLboolean forceNotify);
@ -53,9 +54,12 @@ extern void fgPlatformIconifyWindow( SFG_Window *window );
extern void fgPlatformShowWindow( SFG_Window *window ); extern void fgPlatformShowWindow( SFG_Window *window );
extern void fgPlatformMainLoopPostWork ( void ); extern void fgPlatformMainLoopPostWork ( void );
extern void fgPlatformRotateWindow( SFG_Window *window, int rotation ); extern void fgPlatformRotateWindow( SFG_Window *window, int rotation );
extern void fgPlatformFlushCommands ( void );
static struct touchscreen touchscreen; static struct touchscreen touchscreen;
#define ESCAPE_BUTTON_KEY 0x001B
unsigned int key_special(int qnxKeycode) unsigned int key_special(int qnxKeycode)
{ {
switch(qnxKeycode) { switch(qnxKeycode) {
@ -135,7 +139,7 @@ unsigned char key_ascii(int qnxKeycode)
case KEYCODE_RETURN: case KEYCODE_RETURN:
return 0x000A; return 0x000A;
case KEYCODE_ESCAPE: case KEYCODE_ESCAPE:
return 0x001B; return ESCAPE_BUTTON_KEY;
} }
} }
return qnxKeycode; return qnxKeycode;
@ -161,7 +165,6 @@ fg_time_t fgPlatformSystemTime ( void )
*/ */
void fgPlatformSleepForEvents( fg_time_t msec ) void fgPlatformSleepForEvents( fg_time_t msec )
{ {
//XXX: Is this right? Is there a more direct way to access the context?
if(fgStructure.CurrentWindow && fgDisplay.pDisplay.event == NULL && bps_get_event(&fgDisplay.pDisplay.event, (int)msec) != BPS_SUCCESS) { if(fgStructure.CurrentWindow && fgDisplay.pDisplay.event == NULL && bps_get_event(&fgDisplay.pDisplay.event, (int)msec) != BPS_SUCCESS) {
LOGW("BPS couldn't get event"); LOGW("BPS couldn't get event");
} }
@ -265,6 +268,57 @@ int fgPlatformGetModifiers (int mod)
((mod & KEYMOD_ALT) ? GLUT_ACTIVE_ALT : 0)); ((mod & KEYMOD_ALT) ? GLUT_ACTIVE_ALT : 0));
} }
void fgPlatformHandleKeyboardHeight(SFG_Window* window, int height)
{
int size[2];
int screenHeight;
int nScreenHeight = -1;
screenHeight = glutGet(GLUT_WINDOW_HEIGHT); //Using this takes rotation into account
if(height == 0) {
nScreenHeight = screenHeight;
}
else if(!screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_POSITION, size)) {
/* Calculate the new screen size */ //XXX Make sure to use display size instead of screen size
nScreenHeight = ((size[1] + screenHeight) - height) - size[1];
}
if(nScreenHeight != -1) {
/* If nScreenHeight is less then zero then window is covered. If nScreenHeight == height, then no change in size. Else, change in size */
int screenWidth = glutGet(GLUT_WINDOW_WIDTH);
if(nScreenHeight < 0) {
LOGI("fgPlatformHandleKeyboardHeight: Covered window state");
window->State.Visible = GL_FALSE;
window->State.pWState.windowCovered = GL_TRUE;
INVOKE_WCB(*window, WindowStatus, (GLUT_FULLY_COVERED));
fghOnReshapeNotify(window, screenWidth, 0, GL_FALSE);
} else {
if(window->State.pWState.windowCovered == GL_TRUE) {
LOGI("fgPlatformHandleKeyboardHeight: Resetting window state");
/* Reset window status if it was previously covered */
switch(window->State.pWState.windowState) {
case NAVIGATOR_WINDOW_FULLSCREEN:
window->State.Visible = GL_TRUE;
INVOKE_WCB(*window, WindowStatus, (GLUT_FULLY_RETAINED));
break;
case NAVIGATOR_WINDOW_THUMBNAIL:
window->State.Visible = GL_TRUE;
INVOKE_WCB(*window, WindowStatus, (GLUT_PARTIALLY_RETAINED));
break;
case NAVIGATOR_WINDOW_INVISIBLE:
window->State.Visible = GL_FALSE;
INVOKE_WCB(*window, WindowStatus, (GLUT_HIDDEN));
break;
}
window->State.pWState.windowCovered = GL_FALSE;
}
fghOnReshapeNotify(window, screenWidth, nScreenHeight, GL_FALSE);
}
}
}
void fgPlatformProcessSingleEvent ( void ) void fgPlatformProcessSingleEvent ( void )
{ {
if(fgStructure.CurrentWindow == NULL) { if(fgStructure.CurrentWindow == NULL) {
@ -345,7 +399,7 @@ void fgPlatformProcessSingleEvent ( void )
LOGI("fgPlatformProcessSingleEvent: SCREEN_EVENT_POINTER: Buttons: 0x%X, X: %d, Y: %d, Wheel: %d, Mod: 0x%X", SLOG2_FA_SIGNED(buttons), SLOG2_FA_SIGNED(position[0]), SLOG2_FA_SIGNED(position[1]), SLOG2_FA_SIGNED(wheel), SLOG2_FA_SIGNED(mod)); LOGI("fgPlatformProcessSingleEvent: SCREEN_EVENT_POINTER: Buttons: 0x%X, X: %d, Y: %d, Wheel: %d, Mod: 0x%X", SLOG2_FA_SIGNED(buttons), SLOG2_FA_SIGNED(position[0]), SLOG2_FA_SIGNED(position[1]), SLOG2_FA_SIGNED(wheel), SLOG2_FA_SIGNED(mod));
//XXX Should multitouch be handled? //XXX Is multitouch be handled in a good way?
/* Remember the current modifiers state so user can query it from their callback */ /* Remember the current modifiers state so user can query it from their callback */
fgState.Modifiers = fgPlatformGetModifiers(mod); fgState.Modifiers = fgPlatformGetModifiers(mod);
@ -499,28 +553,37 @@ void fgPlatformProcessSingleEvent ( void )
case NAVIGATOR_WINDOW_STATE: case NAVIGATOR_WINDOW_STATE:
{ {
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE"); LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE");
/* Covered only happens due to keyboard. When the app is minimized, the keyboard is closed.
When the keyboard is open, and the app is fullscreened, the keyboard is also closed.
If a window is covered and the app is minimized, the state will be set and the keyboard event
will adjust the screen size and change window status. */
navigator_window_state_t state = navigator_event_get_window_state(fgDisplay.pDisplay.event); navigator_window_state_t state = navigator_event_get_window_state(fgDisplay.pDisplay.event);
switch (state) if(window->State.pWState.windowCovered == GL_FALSE)
{ {
case NAVIGATOR_WINDOW_FULLSCREEN: switch (state)
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_FULLSCREEN"); {
window->State.Visible = GL_TRUE; case NAVIGATOR_WINDOW_FULLSCREEN:
INVOKE_WCB(*window, WindowStatus, (GLUT_FULLY_RETAINED)); LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_FULLSCREEN");
break; window->State.Visible = GL_TRUE;
case NAVIGATOR_WINDOW_THUMBNAIL: INVOKE_WCB(*window, WindowStatus, (GLUT_FULLY_RETAINED));
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_THUMBNAIL"); break;
window->State.Visible = GL_TRUE; case NAVIGATOR_WINDOW_THUMBNAIL:
INVOKE_WCB(*window, WindowStatus, (GLUT_PARTIALLY_RETAINED)); LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_THUMBNAIL");
break; window->State.Visible = GL_TRUE;
case NAVIGATOR_WINDOW_INVISIBLE: INVOKE_WCB(*window, WindowStatus, (GLUT_PARTIALLY_RETAINED));
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_INVISIBLE"); break;
window->State.Visible = GL_FALSE; case NAVIGATOR_WINDOW_INVISIBLE:
INVOKE_WCB(*window, WindowStatus, (GLUT_HIDDEN)); //XXX Should this be GLUT_FULLY_COVERED? LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_INVISIBLE");
break; window->State.Visible = GL_FALSE;
default: INVOKE_WCB(*window, WindowStatus, (GLUT_HIDDEN));
LOGW("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE unknown: 0x%X", SLOG2_FA_SIGNED(state)); break;
break; default:
LOGW("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE unknown: 0x%X", SLOG2_FA_SIGNED(state));
break;
}
} }
window->State.pWState.windowState = state;
break; break;
} }
@ -563,8 +626,11 @@ void fgPlatformProcessSingleEvent ( void )
case NAVIGATOR_ORIENTATION: case NAVIGATOR_ORIENTATION:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION"); LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION");
/* NAVIGATOR_ORIENTATION occurs before NAVIGATOR_KEYBOARD_POSITION */
/* Rotate and resize the window */ /* Rotate and resize the window */
fgPlatformRotateWindow(window, navigator_event_get_orientation_angle(fgDisplay.pDisplay.event)); fgPlatformRotateWindow(window, navigator_event_get_orientation_angle(fgDisplay.pDisplay.event));
fgPlatformFlushCommands();
fghOnReshapeNotify(window, window->State.pWState.newWidth, window->State.pWState.newHeight, GL_FALSE); fghOnReshapeNotify(window, window->State.pWState.newWidth, window->State.pWState.newHeight, GL_FALSE);
/* Reset sizes */ /* Reset sizes */
@ -576,7 +642,9 @@ void fgPlatformProcessSingleEvent ( void )
break; break;
case NAVIGATOR_BACK: case NAVIGATOR_BACK:
/* XXX Should this be a Special/SpecialUp event? */ LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_BACK");
INVOKE_WCB(*window, Keyboard, (ESCAPE_BUTTON_KEY, window->State.MouseX, window->State.MouseY));
INVOKE_WCB(*window, KeyboardUp, (ESCAPE_BUTTON_KEY, window->State.MouseX, window->State.MouseY));
break; break;
case NAVIGATOR_WINDOW_ACTIVE: case NAVIGATOR_WINDOW_ACTIVE:
@ -591,17 +659,52 @@ void fgPlatformProcessSingleEvent ( void )
case NAVIGATOR_ORIENTATION_DONE: case NAVIGATOR_ORIENTATION_DONE:
case NAVIGATOR_ORIENTATION_RESULT: case NAVIGATOR_ORIENTATION_RESULT:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_DONE\NAVIGATOR_ORIENTATION_RESULT"); LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_DONE/NAVIGATOR_ORIENTATION_RESULT");
break; break;
case NAVIGATOR_KEYBOARD_STATE: case NAVIGATOR_KEYBOARD_STATE:
/* XXX Should something be done with this? */ {
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_KEYBOARD_STATE");
navigator_keyboard_state_t state = navigator_event_get_keyboard_state(fgDisplay.pDisplay.event);
switch (state)
{
case NAVIGATOR_KEYBOARD_CLOSED:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_KEYBOARD_STATE-NAVIGATOR_KEYBOARD_CLOSED");
/* NAVIGATOR_KEYBOARD_POSITION only occurs on open, so on keyboard close we need to reset the keyboard height */
fgPlatformHandleKeyboardHeight(window, 0);
break;
case NAVIGATOR_KEYBOARD_OPENING:
case NAVIGATOR_KEYBOARD_OPENED:
case NAVIGATOR_KEYBOARD_CLOSING:
break;
case NAVIGATOR_KEYBOARD_UNRECOGNIZED:
LOGW("fgPlatformProcessSingleEvent: NAVIGATOR_KEYBOARD_STATE-NAVIGATOR_KEYBOARD_UNRECOGNIZED");
break;
default:
LOGW("fgPlatformProcessSingleEvent: NAVIGATOR_KEYBOARD_STATE unknown: 0x%X", SLOG2_FA_SIGNED(state));
break;
}
break; break;
}
case NAVIGATOR_KEYBOARD_POSITION: case NAVIGATOR_KEYBOARD_POSITION:
/* TODO Invoke resize with the modified screen size (((y + height) - keyboardPos) - y). {
* If result is less then zero then window is covered. If == height, then no change in size. Else, change in size */ /* Occurs only when keyboard has opened or resizes */
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_KEYBOARD_POSITION");
int keyboardOffset = navigator_event_get_keyboard_position(fgDisplay.pDisplay.event);
if(keyboardOffset == BPS_FAILURE) {
LOGW("fgPlatformProcessSingleEvent: NAVIGATOR_KEYBOARD_POSITION: getting keyboard offset failed");
} else {
/* keyboardOffset is the offset from the top of the screen to the top of the keyboard, AKA the size of the uncovered screen
We want the height of the keyboard. So instead of determining the orientation, getting the right display size, and subtracting;
we just get the keyboard height which may be slower but easier to understand and work with */
virtualkeyboard_get_height(&keyboardOffset);
fgPlatformHandleKeyboardHeight(window, keyboardOffset);
}
break; break;
}
case NAVIGATOR_DEVICE_LOCK_STATE: case NAVIGATOR_DEVICE_LOCK_STATE:
break; break;
@ -614,7 +717,7 @@ void fgPlatformProcessSingleEvent ( void )
case NAVIGATOR_APP_STATE: case NAVIGATOR_APP_STATE:
/* Can do the same as NAVIGATOR_WINDOW_ACTIVE/NAVIGATOR_WINDOW_INACTIVE but /* Can do the same as NAVIGATOR_WINDOW_ACTIVE/NAVIGATOR_WINDOW_INACTIVE but
seems less likely to work when the app comes to the foreground. Might be a bug */ seems like it doesn't work when the app comes to the foreground. Might be a bug */
break; break;
case NAVIGATOR_ORIENTATION_SIZE: case NAVIGATOR_ORIENTATION_SIZE:

View File

@ -102,8 +102,18 @@ int fgPlatformGlutGet ( GLenum eWhat )
if ( fgStructure.CurrentWindow == NULL ) if ( fgStructure.CurrentWindow == NULL )
return 0; return 0;
int size[2]; int size[2];
int orientation;
if ( screen_get_window_property_iv(fgStructure.CurrentWindow->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size) != 0 ) if ( screen_get_window_property_iv(fgStructure.CurrentWindow->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size) != 0 )
return 0; return 0;
if ( screen_get_window_property_iv(fgStructure.CurrentWindow->Window.Handle, SCREEN_PROPERTY_ROTATION, &orientation) != 0 )
return 0;
int orientationDif = abs(orientation - fgStructure.CurrentWindow->State.pWState.originalRotation);
if (orientationDif == 90 || orientationDif == 270) {
/* Swap dim. if screen is rotated */
int tmp = size[0];
size[0] = size[1];
size[1] = tmp;
}
switch ( eWhat ) switch ( eWhat )
{ {
case GLUT_WINDOW_WIDTH: case GLUT_WINDOW_WIDTH:

View File

@ -0,0 +1,40 @@
/*
* fg_structure_blackberry.c
*
* Windows and menus need tree structure
*
* Copyright (C) 2012 Sylvain Beucler
* Copyright (C) 2013 Vincent Simonetti
*
* 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
* PAWEL W. OLSZTA 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 <GL/freeglut.h>
#include "fg_internal.h"
#include "egl/fg_structure_egl.h"
/**
* Initialize default platform-specific fields in SFG_Window
*/
void fgPlatformCreateWindow ( SFG_Window *window )
{
fghPlatformCreateWindowEGL(window);
memset(&(window->State.pWState), 0, sizeof(SFG_PlatformWindowState));
window->State.pWState.windowCovered = GL_FALSE;
}

View File

@ -159,6 +159,7 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
fgError("Could not set window rotation"); fgError("Could not set window rotation");
return; return;
} }
window->State.pWState.originalRotation = orientation;
/* Set buffer sizes */ /* Set buffer sizes */
if (screen_set_window_property_iv(sWindow, SCREEN_PROPERTY_BUFFER_SIZE, value)) { if (screen_set_window_property_iv(sWindow, SCREEN_PROPERTY_BUFFER_SIZE, value)) {
@ -189,9 +190,18 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
window->State.Visible = GL_TRUE; window->State.Visible = GL_TRUE;
} }
void fgPlatformFlushCommands()
{
if(screen_flush_context(fgDisplay.pDisplay.screenContext, 0)) {
fgWarning("Could not flush screen context");
}
}
void fgPlatformRotateWindow(SFG_Window* window, int rotation) void fgPlatformRotateWindow(SFG_Window* window, int rotation)
{ {
screen_set_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_ROTATION, &rotation); if(screen_set_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_ROTATION, &rotation)) {
fgWarning("Could not set window rotation");
}
} }
/* /*