--- /dev/null
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#include <stdexcept>
+
+#include "serializable.hh"
+#include "settings.hh"
+
+#include "video.hh"
+
+
+namespace dc {
+
+
+video::video()
+{
+ std::string caption;
+ if (settings::instance().get("video.caption", caption))
+ {
+ init(attribs_, caption);
+ }
+ else
+ {
+ init(attribs_, "Untitled");
+ }
+}
+
+video::video(const attributes& attribs, const std::string& caption)
+{
+ init(attribs, caption);
+}
+
+video::video(const attributes& attribs)
+{
+ std::string caption;
+ if (settings::instance().get("video.caption", caption))
+ {
+ init(attribs, caption);
+ }
+ else
+ {
+ init(attribs, "Untitled");
+ }
+}
+
+video::video(const std::string& caption)
+{
+ init(attribs_, caption);
+}
+
+void video::init(const attributes& attribs, const std::string& caption)
+{
+ context_ = 0;
+ flags_ = 0;
+ attribs_ = attribs;
+
+ setFull(attribs.fullscreen);
+ setResizable(attribs.resizable);
+ setOpenGLAttributes();
+ setCaption(caption);
+ setCursorVisible(attribs.cursorVisible);
+ setCursorGrab(attribs.cursorGrab);
+ setVideoMode(attribs.mode);
+}
+
+void video::recreateContext()
+{
+ SDL_FreeSurface(context_);
+ context_ = 0;
+ setVideoMode(attribs_.mode);
+}
+
+void video::setOpenGLAttributes()
+{
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, attribs_.colorBuffer[0]);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, attribs_.colorBuffer[1]);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, attribs_.colorBuffer[2]);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, attribs_.colorBuffer[3]);
+ SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, attribs_.frameBuffer);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, attribs_.doubleBuffer);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, attribs_.depthBuffer);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, attribs_.stencilBuffer);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, attribs_.accumBuffer[0]);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, attribs_.accumBuffer[1]);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, attribs_.accumBuffer[2]);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, attribs_.accumBuffer[3]);
+ SDL_GL_SetAttribute(SDL_GL_STEREO, attribs_.stereo);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, attribs_.multisampleBuffers);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, attribs_.multisampleSamples);
+ SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, attribs_.swapControl);
+ SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, attribs_.hardwareonly);
+}
+
+
+video::~video()
+{
+ SDL_FreeSurface(context_);
+}
+
+
+void video::setVideoMode(const long mode[3])
+{
+ if (mode != attribs_.mode || !context_)
+ {
+ if (context_) SDL_FreeSurface(context_);
+
+ context_ = SDL_SetVideoMode(mode[0], mode[1], mode[2],
+ SDL_OPENGL | flags_);
+
+ if (context_)
+ {
+ attribs_.mode[0] = mode[0];
+ attribs_.mode[1] = mode[1];
+ attribs_.mode[2] = mode[2];
+ }
+ else throw std::runtime_error(SDL_GetError());
+ }
+}
+
+video::attributes video::getAttributes() const
+{
+ return attribs_;
+}
+
+
+void video::resize(int width, int height)
+{
+ long mode[] = {width, height, attribs_.mode[2]};
+ setVideoMode(mode);
+}
+
+bool video::iconify()
+{
+ return SDL_WM_IconifyWindow();
+}
+
+
+void video::setCaption(const std::string& caption)
+{
+ SDL_WM_SetCaption(caption.c_str(), 0);
+}
+
+std::string video::getCaption() const
+{
+ char* str;
+ SDL_WM_GetCaption(&str, 0);
+ return std::string(str);
+}
+
+
+void video::setFull(bool full)
+{
+ if (full != isFull() || !context_)
+ {
+ if (context_)
+ {
+ flags_ ^= SDL_FULLSCREEN;
+
+#if defined(linux) || defined(__linux) || defined(__linux__)
+ if (SDL_WM_ToggleFullScreen(context_) == 0)
+#endif
+ recreateContext();
+ }
+ else
+ {
+ if (full) flags_ |= SDL_FULLSCREEN;
+ else flags_ &= ~SDL_FULLSCREEN;
+ }
+ }
+}
+
+void video::toggleFull()
+{
+ setFull(!isFull());
+}
+
+bool video::isFull() const
+{
+ return flags_ & SDL_FULLSCREEN;
+}
+
+
+void video::setCursorVisible(bool hasCursor)
+{
+ SDL_ShowCursor(hasCursor? SDL_ENABLE : SDL_DISABLE);
+}
+
+void video::toggleCursorVisible()
+{
+ setCursorVisible(!isCursorVisible());
+}
+
+bool video::isCursorVisible() const
+{
+ return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE);
+}
+
+
+void video::setResizable(bool resizable)
+{
+ if (resizable != isResizable() || !context_)
+ {
+ if (context_)
+ {
+ flags_ ^= SDL_RESIZABLE;
+ recreateContext();
+ }
+ else
+ {
+ if (resizable) flags_ |= SDL_RESIZABLE;
+ else flags_ &= ~SDL_RESIZABLE;
+ }
+ }
+}
+
+void video::toggleResizable()
+{
+ setResizable(!isResizable());
+}
+
+bool video::isResizable() const
+{
+ return flags_ & SDL_RESIZABLE;
+}
+
+
+bool video::isCursorGrab() const
+{
+ return (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON);
+}
+
+void video::toggleCursorGrab()
+{
+ setCursorGrab(!isCursorGrab());
+}
+
+void video::setCursorGrab(bool cursorGrab)
+{
+ SDL_WM_GrabInput(cursorGrab? SDL_GRAB_ON : SDL_GRAB_OFF);
+}
+
+
+void video::makeActive()
+{
+ // NOP until the day SDL supports more than only one window.
+ // Still waiting...
+}
+
+void video::swap()
+{
+ SDL_GL_SwapBuffers();
+}
+
+
+video::attributes::attributes()
+{
+ // Set some sane GL and window defaults (see SDL_video.c:217)
+ colorBuffer[0] = 3;
+ colorBuffer[1] = 3;
+ colorBuffer[2] = 2;
+ colorBuffer[3] = 0;
+ frameBuffer = 0;
+ doubleBuffer = true;
+ depthBuffer = 16;
+ stencilBuffer = 0;
+ accumBuffer[0] = 0;
+ accumBuffer[1] = 0;
+ accumBuffer[2] = 0;
+ accumBuffer[3] = 0;
+ stereo = false;
+ multisampleBuffers = 0;
+ multisampleSamples = 0;
+ swapControl = false;
+ hardwareonly = false;
+ mode[0] = 640;
+ mode[1] = 480;
+ mode[2] = 0;
+ fullscreen = false;
+ resizable = false;
+ cursorVisible = true;
+ cursorGrab = false;
+
+ std::vector<serializable_ptr> colors;
+ settings::instance().get("video.colorbuffers", colors);
+ if (colors.size() > 0) colors[0]->get(colorBuffer[0]);
+ if (colors.size() > 1) colors[1]->get(colorBuffer[1]);
+ if (colors.size() > 2) colors[2]->get(colorBuffer[2]);
+ if (colors.size() > 3) colors[3]->get(colorBuffer[3]);
+
+ settings::instance().get("video.framebuffer", frameBuffer);
+ settings::instance().get("video.doublebuffer", doubleBuffer);
+ settings::instance().get("video.depthbuffer", depthBuffer);
+ settings::instance().get("video.stencilbuffer", stencilBuffer);
+
+ std::vector<serializable_ptr> accum;
+ settings::instance().get("video.accumbuffers", accum);
+ if (accum.size() > 0) accum[0]->get(accumBuffer[0]);
+ if (accum.size() > 1) accum[1]->get(accumBuffer[1]);
+ if (accum.size() > 2) accum[2]->get(accumBuffer[2]);
+ if (accum.size() > 3) accum[3]->get(accumBuffer[3]);
+
+ settings::instance().get("video.stereo", stereo);
+ settings::instance().get("video.multiesamplebuffers", multisampleBuffers);
+ settings::instance().get("video.multiesamplesamples", multisampleSamples);
+ settings::instance().get("video.swapcontrol", swapControl);
+ settings::instance().get("video.hardwareonly", hardwareonly);
+
+ std::vector<serializable_ptr> dimensions;
+ settings::instance().get("video.mode", dimensions);
+ if (dimensions.size() > 0) dimensions[0]->get(mode[0]);
+ if (dimensions.size() > 1) dimensions[1]->get(mode[1]);
+ if (dimensions.size() > 2) dimensions[2]->get(mode[2]);
+
+ settings::instance().get("video.fullscreen", fullscreen);
+ settings::instance().get("video.resizable", resizable);
+ settings::instance().get("video.cursor", cursorVisible);
+ settings::instance().get("video.grab", cursorGrab);
+}
+
+
+} // namespace dc
+