2 /*******************************************************************************
4 Copyright (c) 2009, Charles McGarvey
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *******************************************************************************/
29 #include "Dispatch.hh"
33 #include "Settings.hh"
45 Video::Video(const Attributes
& attribs
) :
51 Video::Video(const std::string
& caption
, const std::string
& icon
)
53 mAttribs
.caption
= caption
;
61 Error error
= Backend::getError();
62 if (error
) error
.raise();
67 setFull(mAttribs
.fullscreen
);
68 setResizable(mAttribs
.resizable
);
69 setOpenGLAttributes();
70 setCaption(mAttribs
.caption
);
72 setCursorVisible(mAttribs
.cursorVisible
);
73 setCursorGrab(mAttribs
.cursorGrab
);
74 setVideoMode(mAttribs
.mode
);
79 void Video::recreateContext()
81 SDL_FreeSurface(mContext
);
83 setVideoMode(mAttribs
.mode
);
86 void Video::setOpenGLAttributes()
88 SDL_GL_SetAttribute(SDL_GL_RED_SIZE
, mAttribs
.colorBuffer
[0]);
89 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE
, mAttribs
.colorBuffer
[1]);
90 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE
, mAttribs
.colorBuffer
[2]);
91 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE
, mAttribs
.colorBuffer
[3]);
92 SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE
, mAttribs
.frameBuffer
);
93 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER
, mAttribs
.doubleBuffer
);
94 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE
, mAttribs
.depthBuffer
);
95 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE
, mAttribs
.stencilBuffer
);
96 SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE
, mAttribs
.accumBuffer
[0]);
97 SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE
, mAttribs
.accumBuffer
[1]);
98 SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE
, mAttribs
.accumBuffer
[2]);
99 SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE
, mAttribs
.accumBuffer
[3]);
100 SDL_GL_SetAttribute(SDL_GL_STEREO
, mAttribs
.stereo
);
101 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS
, mAttribs
.multisampleBuffers
);
102 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES
, mAttribs
.multisampleSamples
);
103 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL
, mAttribs
.swapControl
);
104 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL
, mAttribs
.hardwareOnly
);
110 SDL_FreeSurface(mContext
);
112 if (video
== this) video
= 0;
116 void Video::setVideoMode(const long mode
[3])
118 if (mode
!= mAttribs
.mode
|| !mContext
)
120 if (mContext
) SDL_FreeSurface(mContext
);
122 mContext
= SDL_SetVideoMode(mode
[0], mode
[1], mode
[2],
123 SDL_OPENGL
| mFlags
);
127 mAttribs
.mode
[0] = mode
[0];
128 mAttribs
.mode
[1] = mode
[1];
129 mAttribs
.mode
[2] = mode
[2];
131 #if !defined(linux) && !defined(__linux) && !defined(__linux__)
132 logInfo("video context recreated");
133 core
.dispatch("video.newcontext");
136 else Error(Error::SDL_VIDEOMODE
).raise();
140 Video::Attributes
Video::getAttributes() const
146 void Video::resize(int width
, int height
)
148 long mode
[] = {width
, height
, mAttribs
.mode
[2]};
152 bool Video::iconify()
154 return SDL_WM_IconifyWindow();
158 void Video::setCaption(const std::string
& caption
)
160 mAttribs
.caption
= caption
;
161 SDL_WM_SetCaption(caption
.c_str(), 0);
164 void Video::setIcon()
166 if (mAttribs
.icon
!= "")
168 Image
icon(mAttribs
.icon
);
173 std::string
Video::getCaption() const
175 return mAttribs
.caption
;
178 const std::string
& Video::getIcon() const
180 return mAttribs
.icon
;
184 void Video::setFull(bool full
)
186 if (full
!= isFull() || !mContext
)
190 mFlags
^= SDL_FULLSCREEN
;
192 #if defined(linux) || defined(__linux) || defined(__linux__)
193 if (SDL_WM_ToggleFullScreen(mContext
) == 0)
199 if (full
) mFlags
|= SDL_FULLSCREEN
;
200 else mFlags
&= ~SDL_FULLSCREEN
;
205 void Video::toggleFull()
210 bool Video::isFull() const
212 return mFlags
& SDL_FULLSCREEN
;
216 void Video::setCursorVisible(bool hasCursor
)
218 SDL_ShowCursor(hasCursor
? SDL_ENABLE
: SDL_DISABLE
);
221 void Video::toggleCursorVisible()
223 setCursorVisible(!isCursorVisible());
226 bool Video::isCursorVisible() const
228 return (SDL_ShowCursor(SDL_QUERY
) == SDL_ENABLE
);
232 void Video::setResizable(bool resizable
)
234 if (resizable
!= isResizable() || !mContext
)
238 mFlags
^= SDL_RESIZABLE
;
243 if (resizable
) mFlags
|= SDL_RESIZABLE
;
244 else mFlags
&= ~SDL_RESIZABLE
;
249 void Video::toggleResizable()
251 setResizable(!isResizable());
254 bool Video::isResizable() const
256 return mFlags
& SDL_RESIZABLE
;
260 bool Video::isCursorGrab() const
262 return (SDL_WM_GrabInput(SDL_GRAB_QUERY
) == SDL_GRAB_ON
);
265 void Video::toggleCursorGrab()
267 setCursorGrab(!isCursorGrab());
270 void Video::setCursorGrab(bool cursorGrab
)
272 SDL_WM_GrabInput(cursorGrab
? SDL_GRAB_ON
: SDL_GRAB_OFF
);
278 SDL_GL_SwapBuffers();
282 int Video::getWidth() const
287 int Video::getHeight() const
293 Video::Attributes::Attributes()
295 // set some sane GL and window defaults (see SDL_video.c:217)
309 multisampleBuffers
= 0;
310 multisampleSamples
= 0;
312 hardwareOnly
= false;
318 cursorVisible
= true;
321 std::vector
<long> colors
;
322 settings
.get("colorbuffers", colors
);
323 if (colors
.size() > 0) colorBuffer
[0] = colors
[0];
324 if (colors
.size() > 1) colorBuffer
[1] = colors
[1];
325 if (colors
.size() > 2) colorBuffer
[2] = colors
[2];
326 if (colors
.size() > 3) colorBuffer
[3] = colors
[3];
328 settings
.get("framebuffer", frameBuffer
);
329 settings
.get("doublebuffer", doubleBuffer
);
330 settings
.get("depthbuffer", depthBuffer
);
331 settings
.get("stencilbuffer", stencilBuffer
);
333 std::vector
<long> accum
;
334 settings
.get("accumbuffers", accum
);
335 if (accum
.size() > 0) accumBuffer
[0] = accum
[0];
336 if (accum
.size() > 1) accumBuffer
[1] = accum
[1];
337 if (accum
.size() > 2) accumBuffer
[2] = accum
[2];
338 if (accum
.size() > 3) accumBuffer
[3] = accum
[3];
340 settings
.get("stereo", stereo
);
341 settings
.get("multiesamplebuffers", multisampleBuffers
);
342 settings
.get("multiesamplesamples", multisampleSamples
);
343 settings
.get("swapcontrol", swapControl
);
344 settings
.get("hardwareonly", hardwareOnly
);
346 if (!settings
.get("caption", caption
))
348 caption
= "Untitled";
350 settings
.get("icon", icon
);
352 settings
.get("fullscreen", fullscreen
);
353 settings
.get("resizable", resizable
);
354 settings
.get("showcursor", cursorVisible
);
355 settings
.get("grab", cursorGrab
);
357 std::vector
<long> dimensions
;
358 settings
.get("videomode", dimensions
);
359 if (dimensions
.size() > 1)
361 mode
[0] = dimensions
[0];
362 mode
[1] = dimensions
[1];
364 else if (fullscreen
&& Backend::isInitialized())
366 SDL_Rect
** modes
= SDL_ListModes(NULL
, SDL_FULLSCREEN
| SDL_HWSURFACE
);
368 if (modes
== (SDL_Rect
**)0)
370 Mf::logError("no native video mode");
372 else if (modes
== (SDL_Rect
**)-1)
374 Mf::logWarning("any resolution allowed; choosing default 800x600");
380 mode
[0] = (*modes
)->w
;
381 mode
[1] = (*modes
)->h
;
382 Mf::logInfo
<< "choosing native resolution "
383 << mode
[0] << "x" << mode
[1] << std::endl
;
386 if (dimensions
.size() > 2) mode
[2] = dimensions
[2];
395 /** vim: set ts=4 sw=4 tw=80: *************************************************/