a1450d11940b47db2bc33fbe6130f8f178a10964
[freeglut] / src / blackberry / fg_window_blackberry.c
1 /*
2  * fg_window_blackberry.c
3  *
4  * Window management methods for BlackBerry
5  *
6  * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
7  * Written by Pawel W. Olszta, <olszta@sourceforge.net>
8  * Copied for Platform code by Evan Felix <karcaw at gmail.com>
9  * Copyright (C) 2012  Sylvain Beucler
10  * Copyright (C) 2013  Vincent Simonetti
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25  * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
26  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28  */
29
30 #define FREEGLUT_BUILDING_LIB
31 #include <GL/freeglut.h>
32 #include "fg_internal.h"
33 #include "egl/fg_window_egl.h"
34 #include <screen/screen.h>
35
36 /*
37  * Opens a window. Requires a SFG_Window object created and attached
38  * to the freeglut structure. OpenGL context is created here.
39  */
40 void fgPlatformOpenWindow( SFG_Window* window, const char* title,
41                            GLboolean positionUse, int x, int y,
42                            GLboolean sizeUse, int w, int h,
43                            GLboolean gameMode, GLboolean isSubWindow )
44 {
45     /* TODO: only one full-screen window possible? */
46     if (fgDisplay.pDisplay.single_native_window != NULL) {
47         fgWarning("You can't have more than one window on BlackBerry");
48         return;
49     }
50
51     /* Create window */
52     screen_window_t sWindow;
53     if (screen_create_window(&sWindow, fgDisplay.pDisplay.screenContext)) {
54         fgError("Could not create window");
55         return;
56     }
57     fgDisplay.pDisplay.single_native_window = sWindow;
58
59     /* Choose config and screen format */
60     fghChooseConfig(&window->Window.pContext.egl.Config);
61     int screenFormat = SCREEN_FORMAT_RGBA8888; //Only SCREEN_FORMAT_RGBA8888 and SCREEN_FORMAT_RGB565 are supported. See fg_window_egl for more info
62     int configAttri;
63 #define EGL_QUERY_COMP(att, comp) (eglGetConfigAttrib(fgDisplay.pDisplay.egl.Display, window->Window.pContext.egl.Config, att, &configAttri) == GL_TRUE && (configAttri comp))
64     if (EGL_QUERY_COMP(EGL_ALPHA_SIZE, <= 0) && EGL_QUERY_COMP(EGL_RED_SIZE, <= 5) &&
65             EGL_QUERY_COMP(EGL_GREEN_SIZE, <= 6) && EGL_QUERY_COMP(EGL_BLUE_SIZE, <= 5)) {
66         screenFormat = SCREEN_FORMAT_RGB565;
67     }
68 #undef EGL_QUERY_COMP
69
70     /* Set window properties */
71     int orientation = atoi(getenv("ORIENTATION"));
72     int screenUsage = SCREEN_USAGE_ROTATION;
73 #ifdef SCREEN_USAGE_OPENGL_ES3
74     if (fgState.MajorVersion >= 3) {
75         screenUsage |= SCREEN_USAGE_OPENGL_ES3;
76     } else
77 #endif
78     if (fgState.MajorVersion >= 2) {
79         screenUsage |= SCREEN_USAGE_OPENGL_ES2;
80     } else {
81         screenUsage |= SCREEN_USAGE_OPENGL_ES1;
82     }
83 #if !defined(__X86__) && !defined(__PLAYBOOK__)
84     screenUsage |= SCREEN_USAGE_DISPLAY; // Physical device copy directly into physical display
85 #endif
86     if (screen_set_window_property_iv(sWindow, SCREEN_PROPERTY_FORMAT, &screenFormat)) {
87         screen_destroy_window(sWindow);
88         fgError("Could not set window format");
89         return;
90     }
91     if (screen_set_window_property_iv(sWindow, SCREEN_PROPERTY_USAGE, &screenUsage)) {
92         screen_destroy_window(sWindow);
93         fgError("Could not set window usage");
94         return;
95     }
96
97     int value[2];
98     /* Uncomment when multiple windows are supported
99     if(positionUse) {
100         value[0] = x;
101         value[1] = y;
102         if (screen_set_window_property_iv(sWindow, SCREEN_PROPERTY_POSITION, value)) {
103             screen_destroy_window(sWindow);
104             fgError("Could not set window position");
105             return;
106         }
107     }*/
108
109     if(sizeUse) {
110         /* Uncomment when multiple windows are supported
111         value[0] = w;
112         value[1] = h;
113         */
114         //TEMP until ^^ is uncommented
115         if (screen_get_window_property_iv(sWindow, SCREEN_PROPERTY_BUFFER_SIZE, value)) {
116             screen_destroy_window(sWindow);
117             fgError("Could not get window mode");
118             return;
119         }
120     } else {
121         /* From PlatformBlackBerry in GamePlay3d */
122         screen_display_t display;
123         if (screen_get_window_property_pv(sWindow, SCREEN_PROPERTY_DISPLAY, (void**)&display)) {
124             screen_destroy_window(sWindow);
125             fgError("Could not get window display");
126             return;
127         }
128
129         screen_display_mode_t displayMode;
130         if (screen_get_display_property_pv(display, SCREEN_PROPERTY_MODE, (void**)&displayMode)) {
131             screen_destroy_window(sWindow);
132             fgError("Could not get display mode");
133             return;
134         }
135
136         if (screen_get_window_property_iv(sWindow, SCREEN_PROPERTY_BUFFER_SIZE, value)) {
137             screen_destroy_window(sWindow);
138             fgError("Could not get window mode");
139             return;
140         }
141
142         /* Adjust buffer sizes based on rotation */
143         if ((orientation == 0) || (orientation == 180))
144         {
145             if (((displayMode.width > displayMode.height) && (value[0] < value[1])) ||
146                 ((displayMode.width < displayMode.height) && (value[0] > value[1])))
147             {
148                 int tmp = value[1];
149                 value[1] = value[0];
150                 value[0] = tmp;
151             }
152         }
153         else if ((orientation == 90) || (orientation == 270))
154         {
155             if (((displayMode.width > displayMode.height) && (value[0] > value[1])) ||
156                 ((displayMode.width < displayMode.height) && (value[0] < value[1])))
157             {
158                 int tmp = value[1];
159                 value[1] = value[0];
160                 value[0] = tmp;
161             }
162         }
163         else
164         {
165             screen_destroy_window(sWindow);
166             fgError("Unexpected rotation angle");
167             return;
168         }
169     }
170
171     /* Set rotation if usage allows it */
172     if (screen_set_window_property_iv(sWindow, SCREEN_PROPERTY_ROTATION, &orientation)) {
173         screen_destroy_window(sWindow);
174         fgError("Could not set window rotation");
175         return;
176     }
177     window->State.pWState.originalRotation = orientation;
178
179     /* Set buffer sizes */
180     if (screen_set_window_property_iv(sWindow, SCREEN_PROPERTY_BUFFER_SIZE, value)) {
181         screen_destroy_window(sWindow);
182         fgError("Could not set window buffer size");
183         return;
184     }
185
186     /* Create window buffers */
187     if (screen_create_window_buffers(sWindow, (fgState.DisplayMode & GLUT_DOUBLE) ? 2 : 1)) {
188         screen_destroy_window(sWindow);
189         fgError("Could not create window buffers");
190         return;
191     }
192
193     /* Save window and set state */
194     window->Window.Handle = sWindow;
195     window->State.WorkMask |= GLUT_INIT_WORK;
196     window->State.IsFullscreen = GL_TRUE; //XXX Always fullscreen for now
197
198     /* Create context */
199     window->Window.Context = EGL_NO_CONTEXT;
200     if( fgState.UseCurrentContext == GL_TRUE )
201         window->Window.Context = eglGetCurrentContext();
202     if( window->Window.Context == EGL_NO_CONTEXT )
203         window->Window.Context = fghCreateNewContextEGL(window);
204
205     /* Create EGL window */
206     fghPlatformOpenWindowEGL(window);
207
208     window->State.Visible = GL_TRUE;
209 }
210
211 void fgPlatformFlushCommands()
212 {
213     if(screen_flush_context(fgDisplay.pDisplay.screenContext, 0)) {
214         fgWarning("Could not flush screen context");
215     }
216 }
217
218 void fgPlatformRotateWindow(SFG_Window* window, int rotation)
219 {
220     if(screen_set_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_ROTATION, &rotation)) {
221         fgWarning("Could not set window rotation");
222     }
223 }
224
225 /*
226  * Request a window resize
227  */
228 void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height )
229 {
230     fprintf(stderr, "fgPlatformReshapeWindow: STUB\n");
231 }
232
233 /*
234  * Closes a window, destroying the frame and OpenGL context
235  */
236 void fgPlatformCloseWindow( SFG_Window* window )
237 {
238     fghPlatformCloseWindowEGL(window);
239
240     screen_destroy_window((screen_window_t)window->Window.Handle);
241 }
242
243 /*
244  * This function makes the specified window visible
245  */
246 void fgPlatformShowWindow( void )
247 {
248     fprintf(stderr, "fgPlatformShowWindow: STUB\n");
249 }
250
251 /*
252  * This function hides the specified window
253  */
254 void fgPlatformHideWindow( SFG_Window *window )
255 {
256     fprintf(stderr, "fgPlatformHideWindow: STUB\n");
257 }
258
259 /*
260  * Iconify the specified window (top-level windows only)
261  */
262 void fgPlatformIconifyWindow( SFG_Window *window )
263 {
264     //XXX This is possible via Cascades, but can't seem to find a C-level API
265     //XXX bb::Application::instance()->minimize();
266     fprintf(stderr, "fgPlatformGlutIconifyWindow: STUB\n");
267 }
268
269 /*
270  * Set the current window's title
271  */
272 void fgPlatformGlutSetWindowTitle( const char* title )
273 {
274     fprintf(stderr, "fgPlatformGlutSetWindowTitle: STUB\n");
275 }
276
277 /*
278  * Set the current window's iconified title
279  */
280 void fgPlatformGlutSetIconTitle( const char* title )
281 {
282     fprintf(stderr, "fgPlatformGlutSetIconTitle: STUB\n");
283 }
284
285 /*
286  * Change the specified window's position
287  */
288 void fgPlatformPositionWindow( SFG_Window *window, int x, int y )
289 {
290     fprintf(stderr, "fgPlatformPositionWindow: STUB\n");
291 }
292
293 /*
294  * Lowers the specified window (by Z order change)
295  */
296 void fgPlatformPushWindow( SFG_Window *window )
297 {
298     fprintf(stderr, "fgPlatformPushWindow: STUB\n");
299 }
300
301 /*
302  * Raises the specified window (by Z order change)
303  */
304 void fgPlatformPopWindow( SFG_Window *window )
305 {
306     fprintf(stderr, "fgPlatformPopWindow: STUB\n");
307 }
308
309 /*
310  * Toggle the window's full screen state.
311  */
312 void fgPlatformFullScreenToggle( SFG_Window *win )
313 {
314     fprintf(stderr, "fgPlatformFullScreenToggle: STUB\n");
315 }