Added support for rotation so an app can be rotated and FG will resize and manage the window in the background Additional documentation explaining why certain functions are implemented in the manner they are Changed QNX macro to a non deprecated one

git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1670 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
dcnieho 2014-01-24 10:33:57 +00:00
parent b817a1d976
commit eb835cc833
6 changed files with 414 additions and 284 deletions

View File

@ -32,9 +32,6 @@ John Tsiombikas <nuclear@member.fsf.org>
Sylvain Beucler Sylvain Beucler
support for Android, X11/EGL, OpenGL(ES) 2.x, misc fixes support for Android, X11/EGL, OpenGL(ES) 2.x, misc fixes
Vincent Simonetti
support for BlackBerry
Diederick C. Niehorster Diederick C. Niehorster
Chris Marshall Chris Marshall
Clive McCarthy Clive McCarthy
@ -42,4 +39,7 @@ Eero Pajarre
Florian Echtler Florian Echtler
Matti Lehtonen Matti Lehtonen
Vincent Simonetti
support for BlackBerry
...and all the opengl-gamedev-l people that made Pawel start this project :) ...and all the opengl-gamedev-l people that made Pawel start this project :)

View File

@ -119,6 +119,9 @@ IF(WIN32)
ENDIF() ENDIF()
ELSEIF(ANDROID OR BLACKBERRY) ELSEIF(ANDROID OR BLACKBERRY)
# BlackBerry and Android share some similar design concepts and ideas, as with many mobile devices.
# As such, some classes can be shared between the two. XXX: Possibly rename shareable classes to
# a more generic name. *_stub? *_mobile?
LIST(APPEND FREEGLUT_SRCS LIST(APPEND FREEGLUT_SRCS
src/android/fg_cursor_android.c src/android/fg_cursor_android.c
src/android/fg_ext_android.c src/android/fg_ext_android.c

View File

@ -113,7 +113,8 @@ struct tagSFG_PlatformJoystick
typedef struct tagSFG_PlatformWindowState SFG_PlatformWindowState; typedef struct tagSFG_PlatformWindowState SFG_PlatformWindowState;
struct tagSFG_PlatformWindowState struct tagSFG_PlatformWindowState
{ {
char unused; int newWidth;
int newHeight;
}; };
/* Menu font and color definitions */ /* Menu font and color definitions */

View File

@ -52,6 +52,7 @@ extern void fgPlatformHideWindow( SFG_Window *window );
extern void fgPlatformIconifyWindow( SFG_Window *window ); 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 );
static struct touchscreen touchscreen; static struct touchscreen touchscreen;
@ -272,17 +273,14 @@ void fgPlatformProcessSingleEvent ( void )
return; return;
} }
if(fgDisplay.pDisplay.event == NULL)
/* Nothing to do */
return;
int domain; int domain;
do do
{ {
if(fgDisplay.pDisplay.event != NULL) {
SFG_Window* window = fgStructure.CurrentWindow; SFG_Window* window = fgStructure.CurrentWindow;
if (window->Window.Handle != NULL) {
int size[2];
screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size);
fghOnReshapeNotify(window,size[0],size[1],GL_FALSE);
}
domain = bps_event_get_domain(fgDisplay.pDisplay.event); domain = bps_event_get_domain(fgDisplay.pDisplay.event);
if (domain == screen_get_domain()) { if (domain == screen_get_domain()) {
int eventType; int eventType;
@ -546,6 +544,37 @@ void fgPlatformProcessSingleEvent ( void )
/* XXX Open app menu */ /* XXX Open app menu */
break; break;
/* Orientation is a bunch of handshakes.
- First the app get's asked if it wants to rotate (NAVIGATOR_ORIENTATION_CHECK)
- If the app wants to rotate, then it will be told what size it will be after rotate (NAVIGATOR_ORIENTATION_SIZE).
- Once the OS confirms that it's ready to rotate, it tells the app to handle rotation (NAVIGATOR_ORIENTATION).
- Once rotation is complete, the OS tells the app it's done (NAVIGATOR_ORIENTATION_DONE) */
case NAVIGATOR_ORIENTATION_CHECK:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_CHECK");
/* Reset sizes */
window->State.pWState.newWidth = 0;
window->State.pWState.newHeight = 0;
/* Notify that we want to rotate */
navigator_orientation_check_response(fgDisplay.pDisplay.event, true);
break;
case NAVIGATOR_ORIENTATION:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION");
/* Rotate and resize the window */
fgPlatformRotateWindow(window, navigator_event_get_orientation_angle(fgDisplay.pDisplay.event));
fghOnReshapeNotify(window, window->State.pWState.newWidth, window->State.pWState.newHeight, GL_FALSE);
/* Reset sizes */
window->State.pWState.newWidth = 0;
window->State.pWState.newHeight = 0;
/* Done rotating */
navigator_done_orientation(fgDisplay.pDisplay.event);
break;
case NAVIGATOR_BACK: case NAVIGATOR_BACK:
/* XXX Should this be a Special/SpecialUp event? */ /* XXX Should this be a Special/SpecialUp event? */
break; break;
@ -560,9 +589,18 @@ void fgPlatformProcessSingleEvent ( void )
INVOKE_WCB(*window, AppStatus, (GLUT_APPSTATUS_PAUSE)); INVOKE_WCB(*window, AppStatus, (GLUT_APPSTATUS_PAUSE));
break; break;
case NAVIGATOR_ORIENTATION_DONE:
case NAVIGATOR_ORIENTATION_RESULT:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_DONE\NAVIGATOR_ORIENTATION_RESULT");
break;
case NAVIGATOR_KEYBOARD_STATE: case NAVIGATOR_KEYBOARD_STATE:
/* XXX Should something be done with this? */
break;
case NAVIGATOR_KEYBOARD_POSITION: case NAVIGATOR_KEYBOARD_POSITION:
/* TODO Something needs to be done with this. Not sure what */ /* 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 */
break; break;
case NAVIGATOR_DEVICE_LOCK_STATE: case NAVIGATOR_DEVICE_LOCK_STATE:
@ -579,6 +617,14 @@ void fgPlatformProcessSingleEvent ( void )
seems less likely to work when the app comes to the foreground. Might be a bug */ seems less likely to work when the app comes to the foreground. Might be a bug */
break; break;
case NAVIGATOR_ORIENTATION_SIZE:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_SIZE");
/* Get new window size */
window->State.pWState.newWidth = navigator_event_get_orientation_size_width(fgDisplay.pDisplay.event);
window->State.pWState.newHeight = navigator_event_get_orientation_size_height(fgDisplay.pDisplay.event);
break;
case 0: //Doesn't exist in header, but shows up when keyboard shows and resizes case 0: //Doesn't exist in header, but shows up when keyboard shows and resizes
break; break;
@ -587,7 +633,6 @@ void fgPlatformProcessSingleEvent ( void )
break; break;
} }
} }
}
} while(bps_get_event(&fgDisplay.pDisplay.event, 1) == BPS_SUCCESS && fgDisplay.pDisplay.event != NULL); } while(bps_get_event(&fgDisplay.pDisplay.event, 1) == BPS_SUCCESS && fgDisplay.pDisplay.event != NULL);
/* Reset event to reduce chances of triggering something */ /* Reset event to reduce chances of triggering something */
@ -600,7 +645,9 @@ void fgPlatformMainLoopPreliminaryWork ( void )
/* Request navigator events */ /* Request navigator events */
navigator_request_events(0); navigator_request_events(0);
//XXX rotation lock? navigator_rotation_lock(true);
/* Allow rotation */
navigator_rotation_lock(false);
/* Request window events */ /* Request window events */
screen_request_events(fgDisplay.pDisplay.screenContext); screen_request_events(fgDisplay.pDisplay.screenContext);
@ -610,6 +657,7 @@ void fgPlatformMainLoopPostWork ( void )
{ {
LOGI("fgPlatformMainLoopPostWork"); LOGI("fgPlatformMainLoopPostWork");
/* Stop all events */
screen_stop_events(fgDisplay.pDisplay.screenContext); screen_stop_events(fgDisplay.pDisplay.screenContext);
navigator_stop_events(0); navigator_stop_events(0);
@ -623,6 +671,11 @@ void fgPlatformInitWork(SFG_Window* window)
/* Position callback, always at 0,0 */ /* Position callback, always at 0,0 */
fghOnPositionNotify(window, 0, 0, GL_TRUE); fghOnPositionNotify(window, 0, 0, GL_TRUE);
/* Get window size */
int size[2];
screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size);
fghOnReshapeNotify(window, size[0], size[1], GL_FALSE);
/* Size gets notified on window creation with size detection in mainloop above /* Size gets notified on window creation with size detection in mainloop above
* XXX CHECK: does this messages happen too early like on windows, * XXX CHECK: does this messages happen too early like on windows,
* so client code cannot have registered a callback yet and the message * so client code cannot have registered a callback yet and the message

View File

@ -58,11 +58,12 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
fgDisplay.pDisplay.single_native_window = sWindow; fgDisplay.pDisplay.single_native_window = sWindow;
/* Set window properties */ /* Set window properties */
int orientation = atoi(getenv("ORIENTATION"));
int screenFormat = SCREEN_FORMAT_RGBA8888; //XXX Should this be determined by config? int screenFormat = SCREEN_FORMAT_RGBA8888; //XXX Should this be determined by config?
#ifdef GL_ES_VERSION_2_0 #ifdef GL_ES_VERSION_2_0
int screenUsage = SCREEN_USAGE_OPENGL_ES2; int screenUsage = SCREEN_USAGE_OPENGL_ES2 | SCREEN_USAGE_ROTATION;
#elif GL_VERSION_ES_CM_1_0 || GL_VERSION_ES_CL_1_0 || GL_VERSION_ES_CM_1_1 || GL_VERSION_ES_CL_1_1 #elif GL_VERSION_ES_CM_1_0 || GL_VERSION_ES_CL_1_0 || GL_VERSION_ES_CM_1_1 || GL_VERSION_ES_CL_1_1
int screenUsage = SCREEN_USAGE_OPENGL_ES1; int screenUsage = SCREEN_USAGE_OPENGL_ES1 | SCREEN_USAGE_ROTATION;
#endif #endif
#ifndef __X86__ #ifndef __X86__
screenUsage |= SCREEN_USAGE_DISPLAY; // Physical device copy directly into physical display screenUsage |= SCREEN_USAGE_DISPLAY; // Physical device copy directly into physical display
@ -78,8 +79,8 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
return; return;
} }
/* Uncomment when multiple windows are supported
int value[2]; int value[2];
/* Uncomment when multiple windows are supported
if(positionUse) { if(positionUse) {
value[0] = x; value[0] = x;
value[1] = y; value[1] = y;
@ -88,17 +89,83 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
fgError("Could not set window position"); fgError("Could not set window position");
return; return;
} }
} }*/
if(sizeUse) { if(sizeUse) {
/* Uncomment when multiple windows are supported
value[0] = w; value[0] = w;
value[1] = h; value[1] = h;
*/
//TEMP until ^^ is uncommented
if (screen_get_window_property_iv(sWindow, SCREEN_PROPERTY_BUFFER_SIZE, value)) {
screen_destroy_window(sWindow);
fgError("Could not get window mode");
return;
}
} else {
/* From PlatformBlackBerry in GamePlay3d */
screen_display_t display;
if (screen_get_window_property_pv(sWindow, SCREEN_PROPERTY_DISPLAY, (void**)&display)) {
screen_destroy_window(sWindow);
fgError("Could not get window display");
return;
}
screen_display_mode_t displayMode;
if (screen_get_display_property_pv(display, SCREEN_PROPERTY_MODE, (void**)&displayMode)) {
screen_destroy_window(sWindow);
fgError("Could not get display mode");
return;
}
if (screen_get_window_property_iv(sWindow, SCREEN_PROPERTY_BUFFER_SIZE, value)) {
screen_destroy_window(sWindow);
fgError("Could not get window mode");
return;
}
/* Adjust buffer sizes based on rotation */
if ((orientation == 0) || (orientation == 180))
{
if (((displayMode.width > displayMode.height) && (value[0] < value[1])) ||
((displayMode.width < displayMode.height) && (value[0] > value[1])))
{
int tmp = value[1];
value[1] = value[0];
value[0] = tmp;
}
}
else if ((orientation == 90) || (orientation == 270))
{
if (((displayMode.width > displayMode.height) && (value[0] > value[1])) ||
((displayMode.width < displayMode.height) && (value[0] < value[1])))
{
int tmp = value[1];
value[1] = value[0];
value[0] = tmp;
}
}
else
{
screen_destroy_window(sWindow);
fgError("Unexpected rotation angle");
return;
}
}
/* Set rotation if usage allows it */
if (screen_set_window_property_iv(sWindow, SCREEN_PROPERTY_ROTATION, &orientation)) {
screen_destroy_window(sWindow);
fgError("Could not set window rotation");
return;
}
/* 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)) {
screen_destroy_window(sWindow); screen_destroy_window(sWindow);
fgError("Could not set window buffer size"); fgError("Could not set window buffer size");
return; return;
} }
}*/
/* Create window buffers */ /* Create window buffers */
if (screen_create_window_buffers(sWindow, (fgState.DisplayMode & GLUT_DOUBLE) ? 2 : 1)) { if (screen_create_window_buffers(sWindow, (fgState.DisplayMode & GLUT_DOUBLE) ? 2 : 1)) {
@ -108,7 +175,7 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
} }
/* Save window and set state */ /* Save window and set state */
window->Window.Handle = fgDisplay.pDisplay.single_native_window; window->Window.Handle = sWindow;
window->State.WorkMask |= GLUT_INIT_WORK; window->State.WorkMask |= GLUT_INIT_WORK;
window->State.IsFullscreen = GL_TRUE; //XXX Always fullscreen for now window->State.IsFullscreen = GL_TRUE; //XXX Always fullscreen for now
@ -122,6 +189,11 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
window->State.Visible = GL_TRUE; window->State.Visible = GL_TRUE;
} }
void fgPlatformRotateWindow(SFG_Window* window, int rotation)
{
screen_set_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_ROTATION, &rotation);
}
/* /*
* Request a window resize * Request a window resize
*/ */
@ -162,6 +234,7 @@ void fgPlatformHideWindow( SFG_Window *window )
void fgPlatformIconifyWindow( SFG_Window *window ) void fgPlatformIconifyWindow( SFG_Window *window )
{ {
//XXX This is possible via Cascades, but can't seem to find a C-level API //XXX This is possible via Cascades, but can't seem to find a C-level API
//XXX bb::Application::instance()->minimize();
fprintf(stderr, "fgPlatformGlutIconifyWindow: STUB\n"); fprintf(stderr, "fgPlatformGlutIconifyWindow: STUB\n");
} }

View File

@ -45,7 +45,7 @@
#elif defined (__ANDROID__) #elif defined (__ANDROID__)
# define TARGET_HOST_ANDROID 1 # define TARGET_HOST_ANDROID 1
#elif defined (__QNX__) #elif defined (__QNXNTO__)
# define TARGET_HOST_BLACKBERRY 1 # define TARGET_HOST_BLACKBERRY 1
#elif defined(__posix__) || defined(__unix__) || defined(__linux__) || defined(__sun) #elif defined(__posix__) || defined(__unix__) || defined(__linux__) || defined(__sun)