4 * Window management methods for Wayland
6 * Copyright (c) 2015 Manuel Bachmann. All Rights Reserved.
7 * Written by Manuel Bachmann, <tarnyko@tarnyko.net>
8 * Creation date: Tue Mar 17, 2015
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * MANUEL BACHMANN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #define FREEGLUT_BUILDING_LIB
29 #include <GL/freeglut.h>
30 #include "../fg_internal.h"
31 #include "egl/fg_window_egl.h"
32 #define fghCreateNewContext fghCreateNewContextEGL
34 extern void fghOnReshapeNotify( SFG_Window *window, int width, int height, GLboolean forceNotify );
35 void fgPlatformReshapeWindow( SFG_Window *window, int width, int height );
36 void fgPlatformIconifyWindow( SFG_Window *window );
39 static void fghShSurfacePing( void* data,
40 struct wl_shell_surface* shsurface,
43 wl_shell_surface_pong( shsurface, serial );
45 static void fghShSurfaceConfigure( void* data,
46 struct wl_shell_surface* shsurface,
48 int32_t width, int32_t height )
50 SFG_Window* window = data;
51 fgPlatformReshapeWindow( window, width, height );
53 static const struct wl_shell_surface_listener fghShSurfaceListener =
56 fghShSurfaceConfigure,
61 static int fghToggleFullscreen(void)
63 SFG_Window* win = fgStructure.CurrentWindow;
65 if ( ! win->State.IsFullscreen )
67 win->State.pWState.OldWidth = win->State.Width;
68 win->State.pWState.OldHeight = win->State.Height;
69 wl_shell_surface_set_fullscreen( win->Window.pContext.shsurface,
70 WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
75 fgPlatformReshapeWindow( win, win->State.pWState.OldWidth,
76 win->State.pWState.OldHeight );
77 wl_shell_surface_set_toplevel( win->Window.pContext.shsurface );
83 void fgPlatformOpenWindow( SFG_Window* window, const char* title,
84 GLboolean positionUse, int x, int y,
85 GLboolean sizeUse, int w, int h,
86 GLboolean gameMode, GLboolean isSubWindow )
88 /* Save the display mode if we are creating a menu window */
89 if( window->IsMenu && ( ! fgStructure.MenuContext ) )
90 fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB ;
92 fghChooseConfig( &window->Window.pContext.egl.Config );
94 if( ! window->Window.pContext.egl.Config )
97 * The "fghChooseConfig" returned a null meaning that the visual
98 * context is not available.
99 * Try a couple of variations to see if they will work.
101 if( fgState.DisplayMode & GLUT_MULTISAMPLE )
103 fgState.DisplayMode &= ~GLUT_MULTISAMPLE ;
104 fghChooseConfig( &window->Window.pContext.egl.Config );
105 fgState.DisplayMode |= GLUT_MULTISAMPLE;
109 FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.pContext.egl.Config != NULL,
110 "EGL configuration with necessary capabilities "
111 "not found", "fgOpenWindow" );
114 x = y = -1; /* default window position */
116 w = h = 300; /* default window size */
118 /* Create the cursor */
119 window->Window.pContext.cursor = wl_cursor_theme_get_cursor(
120 fgDisplay.pDisplay.cursor_theme,
122 window->Window.pContext.cursor_surface = wl_compositor_create_surface(
123 fgDisplay.pDisplay.compositor );
125 /* Create the main surface */
126 window->Window.pContext.surface = wl_compositor_create_surface(
127 fgDisplay.pDisplay.compositor );
129 /* Create the shell surface with respects to the parent/child tree */
130 window->Window.pContext.shsurface = wl_shell_get_shell_surface(
131 fgDisplay.pDisplay.shell,
132 window->Window.pContext.surface );
133 wl_shell_surface_add_listener( window->Window.pContext.shsurface,
134 &fghShSurfaceListener, window );
137 wl_shell_surface_set_title( window->Window.pContext.shsurface, title );
141 window->State.IsFullscreen = GL_TRUE;
142 wl_shell_surface_set_fullscreen( window->Window.pContext.shsurface,
143 WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
146 else if( !isSubWindow && !window->IsMenu )
148 wl_shell_surface_set_toplevel( window->Window.pContext.shsurface );
152 wl_shell_surface_set_transient( window->Window.pContext.shsurface,
153 window->Parent->Window.pContext.surface,
157 /* Create the Wl_EGL_Window */
158 window->Window.Context = fghCreateNewContext( window );
159 window->Window.pContext.egl_window = wl_egl_window_create(
160 window->Window.pContext.surface,
162 window->Window.pContext.egl.Surface = eglCreateWindowSurface(
163 fgDisplay.pDisplay.egl.Display,
164 window->Window.pContext.egl.Config,
165 (EGLNativeWindowType)window->Window.pContext.egl_window,
167 eglMakeCurrent( fgDisplay.pDisplay.egl.Display, window->Window.pContext.egl.Surface,
168 window->Window.pContext.egl.Surface, window->Window.Context );
170 window->Window.pContext.pointer_button_pressed = GL_FALSE;
175 * Request a window resize
177 void fgPlatformReshapeWindow( SFG_Window *window, int width, int height )
179 fghOnReshapeNotify(window, width, height, GL_FALSE);
181 if( window->Window.pContext.egl_window )
182 wl_egl_window_resize( window->Window.pContext.egl_window,
183 width, height, 0, 0 );
188 * Closes a window, destroying the frame and OpenGL context
190 void fgPlatformCloseWindow( SFG_Window* window )
192 fghPlatformCloseWindowEGL(window);
194 if ( window->Window.pContext.egl_window )
195 wl_egl_window_destroy( window->Window.pContext.egl_window );
196 if ( window->Window.pContext.shsurface )
197 wl_shell_surface_destroy( window->Window.pContext.shsurface );
198 if ( window->Window.pContext.surface )
199 wl_surface_destroy( window->Window.pContext.surface );
200 if ( window->Window.pContext.cursor_surface )
201 wl_surface_destroy( window->Window.pContext.cursor_surface );
206 * This function re-creates the window assets if they
207 * have been destroyed
209 void fgPlatformShowWindow( SFG_Window *window )
211 if ( ! window->Window.pContext.egl_window ||
212 ! window->Window.pContext.shsurface ||
213 ! window->Window.pContext.surface)
215 fgPlatformCloseWindow( window );
216 fgPlatformOpenWindow( window, "", /* TODO : save the title for further use */
217 GL_TRUE, window->State.Xpos, window->State.Ypos,
218 GL_TRUE, window->State.Width, window->State.Height,
219 (GLboolean)(window->State.IsFullscreen ? GL_TRUE : GL_FALSE),
220 (GLboolean)(window->Parent ? GL_TRUE : GL_FALSE) );
224 /* TODO : support this once we start using xdg-shell
226 * xdg_surface_present( window->Window.pContext.shsurface, 0 );
227 * INVOKE_WCB( *window, WindowStatus, ( GLUT_FULLY_RETAINED ) );
228 * window->State.Visible = GL_TRUE;
230 fgWarning( "glutShownWindow(): function unsupported for an already existing"
231 " window under Wayland" );
236 * This function hides the specified window
238 void fgPlatformHideWindow( SFG_Window *window )
240 fgPlatformIconifyWindow( window );
244 * Iconify the specified window (top-level windows only)
246 void fgPlatformIconifyWindow( SFG_Window *window )
248 /* TODO : support this once we start using xdg-shell
250 * xdg_surface_set_minimized( window->Window.pContext.shsurface );
251 * INVOKE_WCB( *window, WindowStatus, ( GLUT_HIDDEN ) );
252 * window->State.Visible = GL_FALSE;
254 fgWarning( "glutIconifyWindow(): function unsupported under Wayland" );
258 * Set the current window's title
260 void fgPlatformGlutSetWindowTitle( const char* title )
262 SFG_Window* win = fgStructure.CurrentWindow;
263 wl_shell_surface_set_title( win->Window.pContext.shsurface, title );
267 * Set the current window's iconified title
269 void fgPlatformGlutSetIconTitle( const char* title )
271 fgPlatformGlutSetWindowTitle( title );
275 * Change the specified window's position
277 void fgPlatformPositionWindow( SFG_Window *window, int x, int y )
279 /* pointless under Wayland */
280 fgWarning( "glutPositionWindow(): function unsupported under Wayland" );
284 * Lowers the specified window (by Z order change)
286 void fgPlatformPushWindow( SFG_Window *window )
288 /* pointless under Wayland */
289 fgWarning( "glutPushWindow(): function unsupported under Wayland" );
293 * Raises the specified window (by Z order change)
295 void fgPlatformPopWindow( SFG_Window *window )
297 /* pointless under Wayland */
298 fgWarning( "glutPopWindow(): function unsupported under Wayland" );
302 * Toggle the window's full screen state.
304 void fgPlatformFullScreenToggle( SFG_Window *win )
306 if(fghToggleFullscreen() != -1) {
307 win->State.IsFullscreen = !win->State.IsFullscreen;