2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
10 **************************************************************************/
12 #include "Dispatch.hh"
16 #include "Settings.hh"
28 Video::Video(const Attributes
& attribs
) :
36 Error error
= Backend::getError();
37 if (error
) error
.raise();
42 setFull(mAttribs
.fullscreen
);
43 setResizable(mAttribs
.resizable
);
44 setOpenGLAttributes();
45 setCaption(mAttribs
.caption
);
47 setCursorVisible(mAttribs
.cursorVisible
);
48 setCursorGrab(mAttribs
.cursorGrab
);
49 setVideoMode(mAttribs
.mode
);
51 if (!gCurrentVideo
) makeCurrent();
54 void Video::recreateContext()
56 SDL_FreeSurface(mContext
);
58 setVideoMode(mAttribs
.mode
);
61 void Video::setOpenGLAttributes()
63 SDL_GL_SetAttribute(SDL_GL_RED_SIZE
,
64 mAttribs
.colorBuffer
[0]);
65 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE
,
66 mAttribs
.colorBuffer
[1]);
67 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE
,
68 mAttribs
.colorBuffer
[2]);
69 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE
,
70 mAttribs
.colorBuffer
[3]);
71 SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE
,
72 mAttribs
.frameBuffer
);
73 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER
,
74 mAttribs
.doubleBuffer
);
75 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE
,
76 mAttribs
.depthBuffer
);
77 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE
,
78 mAttribs
.stencilBuffer
);
79 SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE
,
80 mAttribs
.accumBuffer
[0]);
81 SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE
,
82 mAttribs
.accumBuffer
[1]);
83 SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE
,
84 mAttribs
.accumBuffer
[2]);
85 SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE
,
86 mAttribs
.accumBuffer
[3]);
87 SDL_GL_SetAttribute(SDL_GL_STEREO
,
89 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS
,
90 mAttribs
.multisampleBuffers
);
91 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES
,
92 mAttribs
.multisampleSamples
);
93 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL
,
94 mAttribs
.swapControl
);
95 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL
,
96 mAttribs
.hardwareOnly
);
102 SDL_FreeSurface(mContext
);
104 if (gCurrentVideo
== this) gCurrentVideo
= 0;
108 void Video::setVideoMode(const int mode
[3])
110 if (mode
!= mAttribs
.mode
|| !mContext
)
112 if (mContext
) SDL_FreeSurface(mContext
);
114 mContext
= SDL_SetVideoMode(mode
[0], mode
[1], mode
[2],
115 SDL_OPENGL
| mFlags
);
119 mAttribs
.mode
[0] = mode
[0];
120 mAttribs
.mode
[1] = mode
[1];
121 mAttribs
.mode
[2] = mode
[2];
123 #if !defined(linux) && !defined(__linux) && !defined(__linux__)
124 logInfo("video context recreated");
125 Dispatch::global().dispatch("video.newcontext");
128 else Error(Error::SDL_VIDEOMODE
).raise();
132 Video::Attributes
Video::attributes() const
138 void Video::resize(int width
, int height
)
140 int mode
[] = {width
, height
, mAttribs
.mode
[2]};
144 bool Video::iconify()
146 return SDL_WM_IconifyWindow();
150 void Video::setCaption(const std::string
& caption
)
152 mAttribs
.caption
= caption
;
153 SDL_WM_SetCaption(caption
.c_str(), 0);
156 void Video::setIcon()
158 if (mAttribs
.icon
!= "")
160 Image
icon(mAttribs
.icon
);
165 std::string
Video::getCaption() const
167 return mAttribs
.caption
;
170 const std::string
& Video::getIcon() const
172 return mAttribs
.icon
;
176 void Video::setFull(bool full
)
178 if (full
!= isFull() || !mContext
)
182 mFlags
^= SDL_FULLSCREEN
;
184 #if defined(linux) || defined(__linux) || defined(__linux__)
185 if (SDL_WM_ToggleFullScreen(mContext
) == 0)
191 if (full
) mFlags
|= SDL_FULLSCREEN
;
192 else mFlags
&= ~SDL_FULLSCREEN
;
197 void Video::toggleFull()
202 bool Video::isFull() const
204 return mFlags
& SDL_FULLSCREEN
;
208 void Video::setCursorVisible(bool hasCursor
)
210 SDL_ShowCursor(hasCursor
? SDL_ENABLE
: SDL_DISABLE
);
213 void Video::toggleCursorVisible()
215 setCursorVisible(!isCursorVisible());
218 bool Video::isCursorVisible() const
220 return (SDL_ShowCursor(SDL_QUERY
) == SDL_ENABLE
);
224 void Video::setResizable(bool resizable
)
226 if (resizable
!= isResizable() || !mContext
)
230 mFlags
^= SDL_RESIZABLE
;
235 if (resizable
) mFlags
|= SDL_RESIZABLE
;
236 else mFlags
&= ~SDL_RESIZABLE
;
241 void Video::toggleResizable()
243 setResizable(!isResizable());
246 bool Video::isResizable() const
248 return mFlags
& SDL_RESIZABLE
;
252 bool Video::isCursorGrab() const
254 return (SDL_WM_GrabInput(SDL_GRAB_QUERY
) == SDL_GRAB_ON
);
257 void Video::toggleCursorGrab()
259 setCursorGrab(!isCursorGrab());
262 void Video::setCursorGrab(bool cursorGrab
)
264 SDL_WM_GrabInput(cursorGrab
? SDL_GRAB_ON
: SDL_GRAB_OFF
);
270 SDL_GL_SwapBuffers();
274 int Video::getWidth() const
279 int Video::getHeight() const
285 void Video::makeCurrent() const
287 gCurrentVideo
= const_cast<Video
*>(this);
291 Video::Attributes::Attributes()
296 Video::Attributes::Attributes(const Settings
& settings
)
300 std::vector
<int> colors
;
301 settings
.get("colorbuffers", colors
);
302 if (colors
.size() > 0) colorBuffer
[0] = colors
[0];
303 if (colors
.size() > 1) colorBuffer
[1] = colors
[1];
304 if (colors
.size() > 2) colorBuffer
[2] = colors
[2];
305 if (colors
.size() > 3) colorBuffer
[3] = colors
[3];
307 settings
.get("framebuffer", frameBuffer
);
308 settings
.get("doublebuffer", doubleBuffer
);
309 settings
.get("depthbuffer", depthBuffer
);
310 settings
.get("stencilbuffer", stencilBuffer
);
312 std::vector
<int> accum
;
313 settings
.get("accumbuffers", accum
);
314 if (accum
.size() > 0) accumBuffer
[0] = accum
[0];
315 if (accum
.size() > 1) accumBuffer
[1] = accum
[1];
316 if (accum
.size() > 2) accumBuffer
[2] = accum
[2];
317 if (accum
.size() > 3) accumBuffer
[3] = accum
[3];
319 settings
.get("stereo", stereo
);
320 settings
.get("multiesamplebuffers", multisampleBuffers
);
321 settings
.get("multiesamplesamples", multisampleSamples
);
322 settings
.get("swapcontrol", swapControl
);
323 settings
.get("hardwareonly", hardwareOnly
);
325 if (!settings
.get("caption", caption
))
327 caption
= "Untitled";
329 settings
.get("icon", icon
);
331 settings
.get("fullscreen", fullscreen
);
332 settings
.get("resizable", resizable
);
333 settings
.get("showcursor", cursorVisible
);
334 settings
.get("grab", cursorGrab
);
336 std::vector
<int> dimensions
;
337 settings
.get("videomode", dimensions
);
338 if (dimensions
.size() > 1)
340 mode
[0] = dimensions
[0];
341 mode
[1] = dimensions
[1];
343 else if (fullscreen
&& Backend::isInitialized())
345 SDL_Rect
** modes
= SDL_ListModes(NULL
,
346 SDL_FULLSCREEN
| SDL_HWSURFACE
);
348 if (modes
== (SDL_Rect
**)0)
350 Mf::logError("no native video mode");
352 else if (modes
== (SDL_Rect
**)-1)
354 Mf::logWarning("any resolution allowed; "
355 "choosing default 800x600");
361 mode
[0] = (*modes
)->w
;
362 mode
[1] = (*modes
)->h
;
363 Mf::logInfo
<< "choosing native resolution "
364 << mode
[0] << "x" << mode
[1] << std::endl
;
367 if (dimensions
.size() > 2) mode
[2] = dimensions
[2];
370 void Video::Attributes::init()
372 // set some sane GL and window defaults (see SDL_video.c:217)
386 multisampleBuffers
= 0;
387 multisampleSamples
= 0;
389 hardwareOnly
= false;
395 cursorVisible
= true;
400 Video
* Video::gCurrentVideo
= 0; // most recently instantiated instance