Implement initial Wayland support
[freeglut] / src / wayland / fg_init_wl.c
1 /*
2  * fg_init_wl.c
3  *
4  * Various freeglut Wayland initialization functions.
5  *
6  * Copyright (c) 2015 Manuel Bachmann. All Rights Reserved.
7  * Written by Manuel Bachmann, <tarnyko@tarnyko.net>
8  * Creation date: Tue Mar 17, 2015
9  *
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:
16  *
17  * The above copyright notice and this permission notice shall be included
18  * in all copies or substantial portions of the Software.
19  *
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.
26  */
27
28 #define FREEGLUT_BUILDING_LIB
29 #include <string.h>
30 #include <GL/freeglut.h>
31 #include "fg_internal.h"
32 #include "egl/fg_init_egl.h"
33
34 void fgPlatformInitialiseInputDevices( void );
35 void fgPlatformCloseInputDevices( void );
36
37
38 static void fghRegistryGlobal( void* data,
39                                struct wl_registry* registry,
40                                uint32_t id,
41                                const char* interface,
42                                uint32_t version )
43 {
44     SFG_PlatformDisplay* pDisplay = data;
45
46     if ( ! strcmp( interface, "wl_compositor" ) )
47       pDisplay->compositor = wl_registry_bind ( registry, id,
48                                                 &wl_compositor_interface, 1 );
49     else if ( ! strcmp( interface, "wl_shell" ) )
50       pDisplay->shell = wl_registry_bind ( registry, id,
51                                            &wl_shell_interface, 1 );
52     else if ( ! strcmp( interface, "wl_seat" ) )
53       pDisplay->seat = wl_registry_bind ( registry, id,
54                                           &wl_seat_interface, 1 );
55     else if ( ! strcmp( interface, "wl_shm" ) )
56       pDisplay->shm = wl_registry_bind ( registry, id,
57                                          &wl_shm_interface, 1 );
58 }
59 static void fghRegistryGlobalRemove( void* data,
60                                      struct wl_registry* registry,
61                                      uint32_t id )
62 {
63 }
64 static const struct wl_registry_listener fghRegistryListener =
65 {
66     fghRegistryGlobal,
67     fghRegistryGlobalRemove
68 };
69
70
71 static void fghInitialiseCursorTheme(void)
72 {
73     fgDisplay.pDisplay.cursor_theme = wl_cursor_theme_load (
74                                         "default", 32,
75                                         fgDisplay.pDisplay.shm );
76 };
77
78 void fgPlatformInitialize( const char* displayName )
79 {
80     fgDisplay.pDisplay.display = wl_display_connect( NULL );
81
82     if( fgDisplay.pDisplay.display == NULL )
83         fgError( "failed to connect to a Wayland compositor" );
84
85     fgDisplay.pDisplay.registry = wl_display_get_registry(
86                                     fgDisplay.pDisplay.display );
87     wl_registry_add_listener( fgDisplay.pDisplay.registry,
88                               &fghRegistryListener,
89                               &fgDisplay.pDisplay );
90     wl_display_roundtrip( fgDisplay.pDisplay.display );
91
92     if( fgDisplay.pDisplay.compositor == NULL ||
93         fgDisplay.pDisplay.shell == NULL ||
94         fgDisplay.pDisplay.seat == NULL ||
95         fgDisplay.pDisplay.shm == NULL )
96           fgError( "failed to discover all needed compositor interfaces" );
97
98     fghInitialiseCursorTheme();
99
100     fghPlatformInitializeEGL();
101
102     /* Get start time */
103     fgState.Time = fgSystemTime();
104
105     fgState.Initialised = GL_TRUE;
106
107     atexit(fgDeinitialize);
108
109     /* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */
110     fgPlatformInitialiseInputDevices();
111 }
112
113
114 void fgPlatformDeinitialiseInputDevices ( void )
115 {
116     fgPlatformCloseInputDevices();
117
118     fgState.InputDevsInitialised = GL_FALSE;
119 }
120
121
122 void fgPlatformCloseDisplay ( void )
123 {
124     wl_cursor_theme_destroy( fgDisplay.pDisplay.cursor_theme );
125
126     wl_shm_destroy( fgDisplay.pDisplay.shm );
127     wl_seat_destroy( fgDisplay.pDisplay.seat );
128     wl_shell_destroy( fgDisplay.pDisplay.shell );
129     wl_compositor_destroy( fgDisplay.pDisplay.compositor );
130     wl_registry_destroy( fgDisplay.pDisplay.registry );
131
132     wl_display_disconnect( fgDisplay.pDisplay.display );
133 }
134