Implement initial Wayland support
[freeglut] / src / wayland / fg_main_wl.c
1 /*
2  * fg_main_wl.c
3  *
4  * The Wayland-specific windows message processing methods.
5  *
6  * Copyright (c) 2015 Manuel Bachmann. All Rights Reserved.
7  * Written by Manuel Bachmann, <tarnyko@tarnyko.net>
8  * Creation date: Sun Mar 22 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 #include <GL/freeglut.h>
29 #include "../fg_internal.h"
30 #include <errno.h>
31 #include <poll.h>
32
33 void fgPlatformFullScreenToggle( SFG_Window *win );
34 void fgPlatformPositionWindow( SFG_Window *window, int x, int y );
35 void fgPlatformReshapeWindow( SFG_Window *window, int width, int height );
36 void fgPlatformPushWindow( SFG_Window *window );
37 void fgPlatformPopWindow( SFG_Window *window );
38 void fgPlatformHideWindow( SFG_Window *window );
39 void fgPlatformIconifyWindow( SFG_Window *window );
40 void fgPlatformShowWindow( SFG_Window *window );
41
42
43 fg_time_t fgPlatformSystemTime( void )
44 {
45 #ifdef CLOCK_MONOTONIC
46     struct timespec now;
47     clock_gettime(CLOCK_MONOTONIC, &now);
48     return now.tv_nsec/1000000 + now.tv_sec*1000;
49 #elif defined(HAVE_GETTIMEOFDAY)
50     struct timeval now;
51     gettimeofday( &now, NULL );
52     return now.tv_usec/1000 + now.tv_sec*1000;
53 #endif
54 }
55
56 void fgPlatformSleepForEvents( fg_time_t msec )
57 {
58     struct pollfd pfd;
59     int err;
60
61     pfd.fd = wl_display_get_fd( fgDisplay.pDisplay.display );
62     pfd.events = POLLIN | POLLERR | POLLHUP;
63
64     wl_display_dispatch_pending( fgDisplay.pDisplay.display );
65     if ( ! wl_display_flush( fgDisplay.pDisplay.display ) )
66     {
67         err = poll( &pfd, 1, msec );
68
69         if( ( -1 == err ) && ( errno != EINTR ) )
70           fgWarning ( "freeglut poll() error: %d", errno );
71     }
72 }
73
74
75 void fgPlatformProcessSingleEvent( void )
76 {
77     SFG_Window *win = fgStructure.CurrentWindow;
78
79     wl_display_dispatch_pending( fgDisplay.pDisplay.display );
80     INVOKE_WCB( *win, Display, ( ) );
81 }
82
83 void fgPlatformMainLoopPreliminaryWork( void )
84 {
85     /* Under Wayland, this is a no-op */
86 }
87
88 void fgPlatformInitWork( SFG_Window* window )
89 {
90     /* Under Wayland, all events happen relative to input handlers
91      * -> this is a no-op
92      */
93      return;
94 }
95
96 void fgPlatformPosResZordWork( SFG_Window* window, unsigned int workMask )
97 {
98     if( workMask & GLUT_FULL_SCREEN_WORK )
99         fgPlatformFullScreenToggle( window );
100     if( workMask & GLUT_POSITION_WORK )
101         fgPlatformPositionWindow( window, window->State.DesiredXpos, window->State.DesiredYpos );
102     if( workMask & GLUT_SIZE_WORK )
103         fgPlatformReshapeWindow ( window, window->State.DesiredWidth, window->State.DesiredHeight );
104     if( workMask & GLUT_ZORDER_WORK )
105     {
106         if( window->State.DesiredZOrder < 0 )
107             fgPlatformPushWindow( window );
108         else
109             fgPlatformPopWindow( window );
110     }
111 }
112
113 void fgPlatformVisibilityWork( SFG_Window* window )
114 {
115     /* Visibility status of window gets updated in the window message handlers above 
116      */
117     SFG_Window *win = window;
118     switch (window->State.DesiredVisibility)
119     {
120     case DesireHiddenState:
121         fgPlatformHideWindow( window );
122         break;
123     case DesireIconicState:
124         /* Call on top-level window */
125         while (win->Parent)
126             win = win->Parent;
127         fgPlatformIconifyWindow( win );
128         break;
129     case DesireNormalState:
130         fgPlatformShowWindow( window );
131         break;
132     }
133 }
134