1 /***********************************************************************
2 created:    21/7/2015
3 author:     Yaron Cohen-Tal
4 *************************************************************************/
5 /***************************************************************************
6 *   Copyright (C) 2004 - 2015 Paul D Turner & The CEGUI Development Team
7 *
8 *   Permission is hereby granted, free of charge, to any person obtaining
9 *   a copy of this software and associated documentation files (the
10 *   "Software"), to deal in the Software without restriction, including
11 *   without limitation the rights to use, copy, modify, merge, publish,
12 *   distribute, sublicense, and/or sell copies of the Software, and to
13 *   permit persons to whom the Software is furnished to do so, subject to
14 *   the following conditions:
15 *
16 *   The above copyright notice and this permission notice shall be
17 *   included in all copies or substantial portions of the Software.
18 *
19 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 *   OTHER DEALINGS IN THE SOFTWARE.
26 ***************************************************************************/
27 #include "CEGuiGLFWSharedBase.h"
28 #include "SamplesFrameworkBase.h"
29 #include "CEGUI/CEGUI.h"
30 
31 #include <stdexcept>
32 #include <sstream>
33 
34 //----------------------------------------------------------------------------//
run()35 void CEGuiGLFWSharedBase::run()
36 {
37     // Input callbacks of glfw for CEGUI
38     glfwSetKeyCallback(glfwKeyCallback);
39     glfwSetCharCallback(glfwCharCallback);
40     glfwSetMouseButtonCallback(glfwMouseButtonCallback);
41     glfwSetMouseWheelCallback(glfwMouseWheelCallback);
42     glfwSetMousePosCallback(glfwMousePosCallback);
43 
44     //Window callbacks
45     glfwSetWindowCloseCallback(glfwWindowCloseCallback);
46     glfwSetWindowSizeCallback(glfwWindowResizeCallback);
47     d_windowSized = false; //The resize callback is being called immediately after setting it in this version of glfw
48     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
49 
50     // set starting time
51     d_frameTime = glfwGetTime();
52 
53     while (!d_sampleApp->isQuitting() &&
54         glfwGetWindowParam(GLFW_OPENED))
55     {
56         if (d_windowSized)
57         {
58             d_windowSized = false;
59             CEGUI::System::getSingleton().
60                 notifyDisplaySizeChanged(
61                 CEGUI::Sizef(static_cast<float>(d_newWindowWidth),
62                 static_cast<float>(d_newWindowHeight)));
63         }
64 
65         drawFrame();
66     }
67 }
68 
69 //----------------------------------------------------------------------------//
endRendering()70 void CEGuiGLFWSharedBase::endRendering()
71 {
72     glfwSwapBuffers();
73 }
74 
75 //----------------------------------------------------------------------------//
createGLFWWindow()76 void CEGuiGLFWSharedBase::createGLFWWindow()
77 {
78     if (glfwOpenWindow(s_defaultWindowWidth, s_defaultWindowHeight, 0, 0, 0, 0,
79           24, 8, GLFW_WINDOW) != GL_TRUE)
80     {
81         CEGUI_THROW(RendererException("Failed to open GLFW window."));
82         glfwTerminate();
83     }
84     glfwEnable (GLFW_KEY_REPEAT);
85 }
86 
87 //----------------------------------------------------------------------------//
setGLFWAppConfiguration()88 void CEGuiGLFWSharedBase::setGLFWAppConfiguration()
89 {
90     glfwSetWindowTitle(d_windowTitle);
91 
92     //Deactivate VSYNC
93     glfwSwapInterval(0);
94 
95     // Disable the mouse position in Non_Debug mode
96 #ifndef DEBUG
97     glfwDisable(GLFW_MOUSE_CURSOR);
98 #endif
99     // Clear Errors by GLFW, even if Setup is correct.
100     glGetError();
101 }
102 
103 //----------------------------------------------------------------------------//
glfwWindowCloseCallback(void)104 int CEGuiGLFWSharedBase::glfwWindowCloseCallback(void)
105 {
106     d_sampleApp->setQuitting(true);
107     return GL_TRUE;
108 }
109 
110 //----------------------------------------------------------------------------//
glfwWindowResizeCallback(int w,int h)111 void CEGuiGLFWSharedBase::glfwWindowResizeCallback(int w, int h)
112 {
113     // We cache this in order to minimise calls to notifyDisplaySizeChanged,
114     // which happens in the main loop whenever d_windowSized is set to true.
115     d_windowSized = true;
116     d_newWindowWidth = w;
117     d_newWindowHeight = h;
118 }
119 
120 //----------------------------------------------------------------------------//
GlfwToCeguiKey(int glfwKey)121 CEGUI::Key::Scan CEGuiGLFWSharedBase::GlfwToCeguiKey(int glfwKey)
122 {
123     switch(glfwKey)
124     {
125     case GLFW_KEY_ESC       : return CEGUI::Key::Escape;
126     case GLFW_KEY_F1        : return CEGUI::Key::F1;
127     case GLFW_KEY_F2        : return CEGUI::Key::F2;
128     case GLFW_KEY_F3        : return CEGUI::Key::F3;
129     case GLFW_KEY_F4        : return CEGUI::Key::F4;
130     case GLFW_KEY_F5        : return CEGUI::Key::F5;
131     case GLFW_KEY_F6        : return CEGUI::Key::F6;
132     case GLFW_KEY_F7        : return CEGUI::Key::F7;
133     case GLFW_KEY_F8        : return CEGUI::Key::F8;
134     case GLFW_KEY_F9        : return CEGUI::Key::F9;
135     case GLFW_KEY_F10       : return CEGUI::Key::F10;
136     case GLFW_KEY_F11       : return CEGUI::Key::F11;
137     case GLFW_KEY_F12       : return CEGUI::Key::F12;
138     case GLFW_KEY_F13       : return CEGUI::Key::F13;
139     case GLFW_KEY_F14       : return CEGUI::Key::F14;
140     case GLFW_KEY_F15       : return CEGUI::Key::F15;
141     case GLFW_KEY_UP        : return CEGUI::Key::ArrowUp;
142     case GLFW_KEY_DOWN      : return CEGUI::Key::ArrowDown;
143     case GLFW_KEY_LEFT      : return CEGUI::Key::ArrowLeft;
144     case GLFW_KEY_RIGHT     : return CEGUI::Key::ArrowRight;
145     case GLFW_KEY_LSHIFT    : return CEGUI::Key::LeftShift;
146     case GLFW_KEY_RSHIFT    : return CEGUI::Key::RightShift;
147     case GLFW_KEY_LCTRL     : return CEGUI::Key::LeftControl;
148     case GLFW_KEY_RCTRL     : return CEGUI::Key::RightControl;
149     case GLFW_KEY_LALT      : return CEGUI::Key::LeftAlt;
150     case GLFW_KEY_RALT      : return CEGUI::Key::RightAlt;
151     case GLFW_KEY_TAB       : return CEGUI::Key::Tab;
152     case GLFW_KEY_ENTER     : return CEGUI::Key::Return;
153     case GLFW_KEY_BACKSPACE : return CEGUI::Key::Backspace;
154     case GLFW_KEY_INSERT    : return CEGUI::Key::Insert;
155     case GLFW_KEY_DEL       : return CEGUI::Key::Delete;
156     case GLFW_KEY_PAGEUP    : return CEGUI::Key::PageUp;
157     case GLFW_KEY_PAGEDOWN  : return CEGUI::Key::PageDown;
158     case GLFW_KEY_HOME      : return CEGUI::Key::Home;
159     case GLFW_KEY_END       : return CEGUI::Key::End;
160     case GLFW_KEY_KP_ENTER  : return CEGUI::Key::NumpadEnter;
161     default                 : return CEGUI::Key::Unknown;
162     }
163 }
164 
165 //----------------------------------------------------------------------------//
glfwKeyCallback(int key,int action)166 void GLFWCALL CEGuiGLFWSharedBase::glfwKeyCallback(int key, int action)
167 {
168     CEGUI::Key::Scan ceguiKey = GlfwToCeguiKey(key);
169 
170     if(action == GLFW_PRESS)
171         d_sampleApp->injectKeyDown(ceguiKey);
172     else if (action == GLFW_RELEASE)
173         d_sampleApp->injectKeyUp(ceguiKey);
174 }
175 
176 //----------------------------------------------------------------------------//
glfwCharCallback(int character,int action)177 void GLFWCALL CEGuiGLFWSharedBase::glfwCharCallback(int character, int action)
178 {
179     if(action == GLFW_PRESS)
180         d_sampleApp->injectChar(character);
181 }
182 
183 //----------------------------------------------------------------------------//
glfwMouseButtonCallback(int key,int action)184 void GLFWCALL CEGuiGLFWSharedBase::glfwMouseButtonCallback(int key, int action)
185 {
186     CEGUI::MouseButton ceguiMouseButton = GlfwToCeguiMouseButton(key);
187 
188     if(action == GLFW_PRESS)
189         d_sampleApp->injectMouseButtonDown(ceguiMouseButton);
190     else if (action == GLFW_RELEASE)
191         d_sampleApp->injectMouseButtonUp(ceguiMouseButton);
192 }
193 
194 //----------------------------------------------------------------------------//
glfwMouseWheelCallback(int position)195 void GLFWCALL CEGuiGLFWSharedBase::glfwMouseWheelCallback(int position)
196 {
197     static int lastPosition = 0;
198     d_sampleApp->injectMouseWheelChange(static_cast<float>(position - lastPosition));
199     lastPosition = position;
200 }
201 
202 //----------------------------------------------------------------------------//
glfwMousePosCallback(int x,int y)203 void GLFWCALL CEGuiGLFWSharedBase::glfwMousePosCallback(int x, int y)
204 {
205     if (!d_mouseDisableCalled)
206     {
207         // if cursor didn't leave the window nothing changes
208         d_sampleApp->injectMousePosition(static_cast<float>(x), static_cast<float>(y));
209     }
210     else
211     {
212         // if the cursor left the window, we need to use the saved position
213         // because glfw beams the cursor to the middle of the window if
214         // the cursor is disabled
215         d_sampleApp->injectMousePosition(static_cast<float>(d_oldMousePosX), static_cast<float>(d_oldMousePosY));
216         glfwSetMousePos(static_cast<int>(d_oldMousePosX), static_cast<int>(d_oldMousePosY));
217         d_mouseDisableCalled = false;
218     }
219 
220 #ifndef DEBUG
221     if (x < 0 || y < 0
222         || x > d_newWindowWidth
223         || y > d_newWindowHeight)
224     {
225         // show cursor
226         glfwEnable(GLFW_MOUSE_CURSOR);
227 
228         // move the cursor to the position where it left the window
229         glfwSetMousePos(x, y);
230 
231         // "note down" that the cursor left the window
232         d_mouseLeftWindow = true;
233     }
234     else
235     {
236         if (d_mouseLeftWindow)
237         {
238             // get cursor position to restore afterwards
239             int mouse_x_int(0);
240             int mouse_y_int(0);
241             glfwGetMousePos(&mouse_x_int, &mouse_y_int);
242             d_oldMousePosX = mouse_x_int;
243             d_oldMousePosY = mouse_y_int;
244 
245             // we need to inject the previous cursor position because
246             // glfw moves the cursor to the centre of the render
247             // window if it gets disabled. therefore notify the
248             // next MousePosCallback invocation of the "mouse disabled" event.
249             d_mouseDisableCalled = true;
250 
251             // disable cursor
252             glfwDisable(GLFW_MOUSE_CURSOR);
253 
254             // "note down" that the cursor is back in the render window
255             d_mouseLeftWindow = false;
256         }
257     }
258 #endif
259 }
260 
261 //----------------------------------------------------------------------------//
262 
263