From 5f89d95bd3ce9d96f28b457afe53e68098a8380e Mon Sep 17 00:00:00 2001 From: Rcmaniac25 Date: Fri, 24 Jan 2014 10:34:17 +0000 Subject: [PATCH] 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: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1671 7f0cb862-5218-0410-a997-914c9d46530a --- CMakeLists.txt | 3 +- src/blackberry/fg_internal_blackberry.h | 4 + src/blackberry/fg_main_blackberry.c | 159 ++++++++++++++++++++++++------ src/blackberry/fg_state_blackberry.c | 10 ++ src/blackberry/fg_structure_blackberry.c | 40 ++++++++ src/blackberry/fg_window_blackberry.c | 12 ++- 6 files changed, 198 insertions(+), 30 deletions(-) create mode 100644 src/blackberry/fg_structure_blackberry.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 946ac6d..28bab9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -128,7 +128,6 @@ ELSEIF(ANDROID OR BLACKBERRY) src/android/fg_gamemode_android.c src/android/fg_joystick_android.c src/android/fg_spaceball_android.c - src/android/fg_structure_android.c ) IF(ANDROID) LIST(APPEND FREEGLUT_SRCS @@ -141,6 +140,7 @@ ELSEIF(ANDROID OR BLACKBERRY) src/android/fg_main_android.h src/android/fg_runtime_android.c src/android/fg_state_android.c + src/android/fg_structure_android.c src/android/fg_window_android.c ) ELSE() @@ -150,6 +150,7 @@ ELSEIF(ANDROID OR BLACKBERRY) src/x11/fg_input_devices_x11.c src/blackberry/fg_main_blackberry.c src/blackberry/fg_state_blackberry.c + src/blackberry/fg_structure_blackberry.c src/blackberry/fg_window_blackberry.c ) ENDIF() diff --git a/src/blackberry/fg_internal_blackberry.h b/src/blackberry/fg_internal_blackberry.h index 63cca30..0756219 100644 --- a/src/blackberry/fg_internal_blackberry.h +++ b/src/blackberry/fg_internal_blackberry.h @@ -34,6 +34,7 @@ #include "egl/fg_internal_egl.h" #include #include +#include /* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */ /* The structure used by display initialization in freeglut_init.c */ @@ -115,6 +116,9 @@ struct tagSFG_PlatformWindowState { int newWidth; int newHeight; + int originalRotation; + navigator_window_state_t windowState; + GLboolean windowCovered; }; /* Menu font and color definitions */ diff --git a/src/blackberry/fg_main_blackberry.c b/src/blackberry/fg_main_blackberry.c index 6d2d03c..20c3d1b 100644 --- a/src/blackberry/fg_main_blackberry.c +++ b/src/blackberry/fg_main_blackberry.c @@ -40,6 +40,7 @@ #include #include #include +#include extern void fghOnReshapeNotify(SFG_Window *window, int width, int height, 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 fgPlatformMainLoopPostWork ( void ); extern void fgPlatformRotateWindow( SFG_Window *window, int rotation ); +extern void fgPlatformFlushCommands ( void ); static struct touchscreen touchscreen; +#define ESCAPE_BUTTON_KEY 0x001B + unsigned int key_special(int qnxKeycode) { switch(qnxKeycode) { @@ -135,7 +139,7 @@ unsigned char key_ascii(int qnxKeycode) case KEYCODE_RETURN: return 0x000A; case KEYCODE_ESCAPE: - return 0x001B; + return ESCAPE_BUTTON_KEY; } } return qnxKeycode; @@ -161,7 +165,6 @@ fg_time_t fgPlatformSystemTime ( void ) */ 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) { LOGW("BPS couldn't get event"); } @@ -265,6 +268,57 @@ int fgPlatformGetModifiers (int mod) ((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 ) { 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)); - //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 */ fgState.Modifiers = fgPlatformGetModifiers(mod); @@ -499,28 +553,37 @@ void fgPlatformProcessSingleEvent ( void ) case 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); - switch (state) + if(window->State.pWState.windowCovered == GL_FALSE) { - case NAVIGATOR_WINDOW_FULLSCREEN: - LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_FULLSCREEN"); - window->State.Visible = GL_TRUE; - INVOKE_WCB(*window, WindowStatus, (GLUT_FULLY_RETAINED)); - break; - case NAVIGATOR_WINDOW_THUMBNAIL: - LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_THUMBNAIL"); - window->State.Visible = GL_TRUE; - INVOKE_WCB(*window, WindowStatus, (GLUT_PARTIALLY_RETAINED)); - break; - case NAVIGATOR_WINDOW_INVISIBLE: - LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_INVISIBLE"); - window->State.Visible = GL_FALSE; - INVOKE_WCB(*window, WindowStatus, (GLUT_HIDDEN)); //XXX Should this be GLUT_FULLY_COVERED? - break; - default: - LOGW("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE unknown: 0x%X", SLOG2_FA_SIGNED(state)); - break; + switch (state) + { + case NAVIGATOR_WINDOW_FULLSCREEN: + LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_FULLSCREEN"); + window->State.Visible = GL_TRUE; + INVOKE_WCB(*window, WindowStatus, (GLUT_FULLY_RETAINED)); + break; + case NAVIGATOR_WINDOW_THUMBNAIL: + LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_THUMBNAIL"); + window->State.Visible = GL_TRUE; + INVOKE_WCB(*window, WindowStatus, (GLUT_PARTIALLY_RETAINED)); + break; + case NAVIGATOR_WINDOW_INVISIBLE: + LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_INVISIBLE"); + window->State.Visible = GL_FALSE; + INVOKE_WCB(*window, WindowStatus, (GLUT_HIDDEN)); + break; + default: + LOGW("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE unknown: 0x%X", SLOG2_FA_SIGNED(state)); + break; + } } + window->State.pWState.windowState = state; break; } @@ -563,8 +626,11 @@ void fgPlatformProcessSingleEvent ( void ) case NAVIGATOR_ORIENTATION: LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION"); + /* NAVIGATOR_ORIENTATION occurs before NAVIGATOR_KEYBOARD_POSITION */ + /* Rotate and resize the window */ fgPlatformRotateWindow(window, navigator_event_get_orientation_angle(fgDisplay.pDisplay.event)); + fgPlatformFlushCommands(); fghOnReshapeNotify(window, window->State.pWState.newWidth, window->State.pWState.newHeight, GL_FALSE); /* Reset sizes */ @@ -576,7 +642,9 @@ void fgPlatformProcessSingleEvent ( void ) break; 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; case NAVIGATOR_WINDOW_ACTIVE: @@ -591,17 +659,52 @@ void fgPlatformProcessSingleEvent ( void ) case NAVIGATOR_ORIENTATION_DONE: case NAVIGATOR_ORIENTATION_RESULT: - LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_DONE\NAVIGATOR_ORIENTATION_RESULT"); + LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_DONE/NAVIGATOR_ORIENTATION_RESULT"); break; 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; + } 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; + } case NAVIGATOR_DEVICE_LOCK_STATE: break; @@ -614,7 +717,7 @@ void fgPlatformProcessSingleEvent ( void ) case NAVIGATOR_APP_STATE: /* 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; case NAVIGATOR_ORIENTATION_SIZE: diff --git a/src/blackberry/fg_state_blackberry.c b/src/blackberry/fg_state_blackberry.c index f16aea6..c7991a9 100644 --- a/src/blackberry/fg_state_blackberry.c +++ b/src/blackberry/fg_state_blackberry.c @@ -102,8 +102,18 @@ int fgPlatformGlutGet ( GLenum eWhat ) if ( fgStructure.CurrentWindow == NULL ) return 0; int size[2]; + int orientation; if ( screen_get_window_property_iv(fgStructure.CurrentWindow->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size) != 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 ) { case GLUT_WINDOW_WIDTH: diff --git a/src/blackberry/fg_structure_blackberry.c b/src/blackberry/fg_structure_blackberry.c new file mode 100644 index 0000000..3fe233e --- /dev/null +++ b/src/blackberry/fg_structure_blackberry.c @@ -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 +#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; +} diff --git a/src/blackberry/fg_window_blackberry.c b/src/blackberry/fg_window_blackberry.c index f18512e..0cc14c9 100644 --- a/src/blackberry/fg_window_blackberry.c +++ b/src/blackberry/fg_window_blackberry.c @@ -159,6 +159,7 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, fgError("Could not set window rotation"); return; } + window->State.pWState.originalRotation = orientation; /* Set buffer sizes */ 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; } +void fgPlatformFlushCommands() +{ + if(screen_flush_context(fgDisplay.pDisplay.screenContext, 0)) { + fgWarning("Could not flush screen context"); + } +} + 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"); + } } /* -- 1.7.10.4