Implement initial Wayland support
[freeglut] / src / wayland / fg_cursor_wl.c
1 /*
2  * fg_cursor_wl.c
3  *
4  * The Wayland-specific mouse cursor related stuff.
5  *
6  * Copyright (c) 2015 Manuel Bachmann. All Rights Reserved.
7  * Written by Manuel Bachmann, <tarnyko@tarnyko.net>
8  * Creation date: Thur Mar 19, 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 <string.h>
29 #include <GL/freeglut.h>
30 #include "../fg_internal.h"
31
32 /*
33  * Note: The arrangement of the table below depends on the fact that
34  * the "normal" GLUT_CURSOR_* values start a 0 and are consecutive.
35  */ 
36 static char* cursorList[] = {
37     "UNSUPPORTED",          /* GLUT_CURSOR_RIGHT_ARROW */
38     "left_ptr",             /* GLUT_CURSOR_LEFT_ARROW */
39     "hand1",                /* GLUT_CURSOR_INFO */
40     "UNSUPPORTED",          /* GLUT_CURSOR_DESTROY */
41     "UNSUPPORTED",          /* GLUT_CURSOR_HELP */
42     "UNSUPPORTED",          /* GLUT_CURSOR_CYCLE */
43     "UNSUPPORTED",          /* GLUT_CURSOR_SPRAY */
44     "watch",                /* GLUT_CURSOR_WAIT */
45     "xterm",                /* GLUT_CURSOR_TEXT */
46     "grabbing",             /* GLUT_CURSOR_CROSSHAIR */
47     "UNSUPPORTED",          /* GLUT_CURSOR_UP_DOWN */
48     "UNSUPPORTED",          /* GLUT_CURSOR_LEFT_RIGHT */
49     "top_side",             /* GLUT_CURSOR_TOP_SIDE */
50     "bottom_side",          /* GLUT_CURSOR_BOTTOM_SIDE */
51     "left_side",            /* GLUT_CURSOR_LEFT_SIDE */
52     "right_side",           /* GLUT_CURSOR_RIGHT_SIDE */
53     "top_left_corner",      /* GLUT_CURSOR_TOP_LEFT_CORNER */
54     "top_right_corner",     /* GLUT_CURSOR_TOP_RIGHT_CORNER */
55     "bottom_right_corner",  /* GLUT_CURSOR_BOTTOM_RIGHT_CORNER */
56     "bottom_left_corner"    /* GLUT_CURSOR_BOTTOM_LEFT_CORNER */
57 };
58
59 void fgPlatformSetCursor ( SFG_Window *window, int cursorID )
60 {
61     /*
62      * XXX FULL_CROSSHAIR demotes to plain CROSSHAIR. Old GLUT allows
63      * for this, but if there is a system that easily supports a full-
64      * window (or full-screen) crosshair, we might consider it.
65      */
66     int cursorIDToUse =
67         ( cursorID == GLUT_CURSOR_FULL_CROSSHAIR ) ? GLUT_CURSOR_CROSSHAIR : cursorID;
68
69     char* cursor;
70
71     if( ( cursorIDToUse >= 0 ) &&
72         ( cursorIDToUse < sizeof( cursorList ) / sizeof( cursorList[0] ) ) ) {
73
74         cursor = cursorList[cursorIDToUse];
75
76         /* if the type is UNSUPPORTED, fall back to GLUT_CURSOR_LEFT_ARROW */
77         if ( ! strcmp( cursor, "UNSUPPORTED" ) )
78         {
79             fgWarning( "glutSetCursor(): cursor type unsupported under Wayland : %d",
80                        cursorIDToUse );
81             cursor = "left_ptr";
82         }
83     } else {
84         switch( cursorIDToUse )
85         {
86         case GLUT_CURSOR_NONE:
87         case GLUT_CURSOR_INHERIT:
88             cursor = NULL;
89             break;
90
91         default:
92             fgError( "Unknown cursor type: %d", cursorIDToUse );
93             return;
94         }
95     }
96
97     if ( cursorIDToUse == GLUT_CURSOR_INHERIT ) {
98         if( window->Parent )
99           window->Window.pContext.cursor =
100             window->Parent->Window.pContext.cursor;
101     } else {
102         window->Window.pContext.cursor = wl_cursor_theme_get_cursor(
103                                            fgDisplay.pDisplay.cursor_theme,
104                                            cursor );
105         if ( ! window->Window.pContext.cursor )
106           fgError( "Failed to create cursor" );
107     }
108 }
109
110
111 void fgPlatformWarpPointer ( int x, int y )
112 {
113     /* unsupported under Wayland */
114     fgWarning( "glutWarpPointer(): function unsupported under Wayland" );
115 }
116
117 void fghPlatformGetCursorPos(const SFG_Window *window, GLboolean client, SFG_XYUse *mouse_pos)
118 {
119     /* Get current pointer location relative to top-left of client area of window (if client is true and window is not NULL)
120      * We cannot get current pointer location in screen coordinates under Wayland, so inform the user and return -1 is this case
121      */
122
123     if (client && window)
124     {
125         mouse_pos->X = window->State.MouseX;
126         mouse_pos->Y = window->State.MouseY;
127     }
128     else
129     {
130         fgWarning( "glutGetCursorPos(): cannot get screen position under Wayland" );
131         mouse_pos->X = -1;
132         mouse_pos->Y = -1;
133     }
134
135     mouse_pos->Use = GL_TRUE;
136 }
137