OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4WindowSDL.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2010-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 
17 /* A wrapper class to OS dependent event and window interfaces, SDL version */
18 
19 #include "C4Include.h"
20 #include "platform/C4Window.h"
21 
22 #include "game/C4Application.h"
23 #include "graphics/C4DrawGL.h"
24 #include "editor/C4Console.h"
26 #include "gui/C4Gui.h"
27 #include "platform/StdFile.h"
28 #include "lib/StdBuf.h"
29 
30 #include "C4Version.h"
31 #include "lib/C4Rect.h"
32 #include "config/C4Config.h"
33 
34 #ifdef SDL_VIDEO_DRIVER_X11
35 #include <X11/Xlib.h>
36 #include <X11/Xutil.h>
37 #include <SDL_syswm.h>
38 #endif
39 
40 /* C4Window */
41 
43  Active(false), pSurface(0), eKind(W_Fullscreen), window(nullptr)
44 #ifdef WITH_QT_EDITOR
45 , glwidget(nullptr)
46 #endif
47 {
48 }
49 
51 {
52  Clear();
53 }
54 
55 static void SetMultisamplingAttributes(int samples)
56 {
57  SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, samples > 0 ? 1 : 0);
58  SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples);
59 }
60 
61 C4Window * C4Window::Init(WindowKind windowKind, C4AbstractApp * pApp, const char * Title, const C4Rect * size)
62 {
63  eKind = windowKind;
64 #ifdef WITH_QT_EDITOR
65  if (windowKind == W_Viewport)
66  {
67  // embed into editor: Viewport widget creation handled by C4ConsoleQt
68  ::Console.AddViewport(static_cast<C4ViewportWindow *>(this));
69  return this;
70  }
71 #endif
72 /* SDL_GL_MULTISAMPLEBUFFERS,
73  SDL_GL_MULTISAMPLESAMPLES,*/
74  SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
75  SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
76  SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
77  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 8);
78  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, /*REQUESTED_GL_CTX_MAJOR*/ 3);
79  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, /*REQUESTED_GL_CTX_MINOR*/ 2);
80  SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, (Config.Graphics.DebugOpenGL ? SDL_GL_CONTEXT_DEBUG_FLAG : 0));
81  SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
82  SetMultisamplingAttributes(Config.Graphics.MultiSampling);
83  uint32_t flags = SDL_WINDOW_OPENGL;
84  if (windowKind == W_Fullscreen && size->Wdt == -1)
85  flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
86  else if (windowKind == W_Fullscreen && !Config.Graphics.Windowed)
87  flags |= SDL_WINDOW_FULLSCREEN;
88  window = SDL_CreateWindow(Title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, size->Wdt, size->Hgt, flags);
89  if (!window)
90  {
91  Log(SDL_GetError());
92  return 0;
93  }
94  SDL_SetWindowData(window, "C4Window", this);
95  Active = true;
96  SDL_ShowCursor(SDL_DISABLE);
97  return this;
98 }
99 
101 {
102  // TODO: Is there some way to do this without requiring a restart?
103  // Maybe re-call SDL_SetVideoMode?
104  C4GUI::TheScreen.ShowMessage(LoadResStr("IDS_CTL_ANTIALIASING_RESTART_MSG"), LoadResStr("IDS_CTL_ANTIALIASING_RESTART_TITLE"), C4GUI::Ico_Notify);
105  return true;
106 }
107 
108 void C4Window::Clear()
109 {
110  if (window) SDL_DestroyWindow(window);
111  window = nullptr;
112 
113 #ifdef WITH_QT_EDITOR
114  if (eKind == W_Viewport)
115  {
116  // embed into editor: Viewport widget creation handled by C4ConsoleQt
117  ::Console.RemoveViewport(static_cast<C4ViewportWindow *>(this));
118  }
119 #endif
120 }
121 
122 void C4Window::EnumerateMultiSamples(std::vector<int>& samples) const
123 {
124  int max_samples;
125  glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
126  samples.clear();
127  for (int s = 2; s <= max_samples; s *= 2)
128  {
129  // Not all multisampling options seem to work. Verify by creating a hidden window.
130  SetMultisamplingAttributes(s);
131  SDL_Window *wnd = SDL_CreateWindow("OpenClonk Test Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 100, 100, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
132  if (wnd)
133  {
134  SDL_DestroyWindow(wnd);
135  samples.push_back(s);
136  }
137  else
138  break;
139  }
140  SetMultisamplingAttributes(Config.Graphics.MultiSampling);
141 }
142 
143 bool C4Window::StorePosition(const char *, const char *, bool) { return true; }
144 
145 bool C4Window::RestorePosition(const char *, const char *, bool) { return true; }
146 
147 // Window size is automatically managed by C4AbstractApp's display mode management.
148 // Just remember the size for others to query.
149 
150 bool C4Window::GetSize(C4Rect * pRect)
151 {
152  pRect->x = pRect->y = 0;
153  SDL_GL_GetDrawableSize(window, &pRect->Wdt, &pRect->Hgt);
154  return true;
155 }
156 
157 void C4Window::SetSize(unsigned int X, unsigned int Y)
158 {
159  SDL_SetWindowSize(window, X, Y);
160 }
161 
162 void C4Window::SetTitle(const char * Title)
163 {
164  SDL_SetWindowTitle(window, Title);
165 }
166 
168 {
169  // just invoke directly
170  PerformUpdate();
171 }
172 
173 static void SetUrgencyHint(SDL_Window *window, bool urgency_hint)
174 {
175 #ifdef SDL_VIDEO_DRIVER_X11
176  SDL_SysWMinfo wminfo;
177  SDL_VERSION(&wminfo.version);
178  if (!SDL_GetWindowWMInfo(window, &wminfo))
179  {
180  LogF("FlashWindow SDL: %s", SDL_GetError());
181  return;
182  }
183 
184  if (wminfo.subsystem == SDL_SYSWM_X11)
185  {
186  auto x11 = wminfo.info.x11;
187  XWMHints *wmhints = XGetWMHints(x11.display, x11.window);
188  if (wmhints == nullptr)
189  wmhints = XAllocWMHints();
190  // Set the window's urgency hint.
191  if (urgency_hint)
192  wmhints->flags |= XUrgencyHint;
193  else
194  wmhints->flags &= ~XUrgencyHint;
195  XSetWMHints(x11.display, x11.window, wmhints);
196  XFree(wmhints);
197  }
198 #endif
199 }
200 
202 {
203  SetUrgencyHint(window, true);
204 }
205 
206 void C4Window::GrabMouse(bool grab)
207 {
208  SDL_SetWindowGrab(window, grab ? SDL_TRUE : SDL_FALSE);
209 }
210 
211 void C4Window::HandleSDLEvent(SDL_WindowEvent &e)
212 {
213  switch (e.event)
214  {
215  case SDL_WINDOWEVENT_FOCUS_GAINED:
216  SetUrgencyHint(window, false);
217  break;
218  case SDL_WINDOWEVENT_RESIZED:
219  case SDL_WINDOWEVENT_SIZE_CHANGED:
220  Application.OnResolutionChanged(e.data1, e.data2);
221  break;
222  default:
223  // We don't care about most events. We should care about more, though.
224  break;
225  }
226 }
bool StorePosition(const char *szWindowName, const char *szSubKey, bool fStoreSize=true)
int32_t DebugOpenGL
Definition: C4Config.h:118
int32_t MultiSampling
Definition: C4Config.h:116
C4Config Config
Definition: C4Config.cpp:837
void GrabMouse(bool grab)
Definition: C4AppT.cpp:105
bool GetSize(C4Rect *pRect)
Definition: C4AppT.cpp:106
C4Console Console
Definition: C4Globals.cpp:45
virtual void OnResolutionChanged(unsigned int iXRes, unsigned int iYRes)
void FlashWindow()
Definition: C4AppMac.mm:75
int32_t Windowed
Definition: C4Config.h:107
void SetTitle(const char *Title)
Definition: C4AppT.cpp:112
Definition: C4Rect.h:29
virtual void EnumerateMultiSamples(std::vector< int > &samples) const
Definition: C4AppT.cpp:103
virtual void PerformUpdate()
Definition: C4App.cpp:85
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
virtual bool ReInit(C4AbstractApp *pApp)
Definition: C4AppT.cpp:108
C4ConfigGraphics Graphics
Definition: C4Config.h:254
int32_t Wdt
Definition: C4Rect.h:32
void SetSize(unsigned int cx, unsigned int cy)
Definition: C4AppT.cpp:111
int32_t y
Definition: C4Rect.h:32
void AddViewport(C4ViewportWindow *cvp)
Definition: C4ConsoleGUI.h:111
virtual ~C4Window()
Definition: C4AppT.cpp:102
WindowKind eKind
Definition: C4Window.h:280
bool RestorePosition(const char *szWindowName, const char *szSubKey, bool fHidden=false)
Definition: C4AppT.cpp:109
int32_t x
Definition: C4Rect.h:32
bool ShowMessage(const char *szMessage, const char *szCaption, Icons icoIcon, int32_t *piConfigDontShowAgainSetting=nullptr)
void RemoveViewport(C4ViewportWindow *cvp)
Definition: C4ConsoleGUI.h:112
virtual void RequestUpdate()
Definition: C4AppT.cpp:110
bool Active
Definition: C4Window.h:278
bool Log(const char *szMessage)
Definition: C4Log.cpp:195
virtual C4Window * Init(WindowKind windowKind, C4AbstractApp *pApp, const char *Title, const C4Rect *size)
Definition: C4AppT.cpp:107
#define X(sdl, oc)
int32_t Hgt
Definition: C4Rect.h:32
virtual void Clear()
Definition: C4AppT.cpp:100
Screen TheScreen
Definition: C4Gui.cpp:1057
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:253
#define s
C4Application Application
Definition: C4Globals.cpp:44
C4Window()
Definition: C4AppT.cpp:101