Skip to content

Instantly share code, notes, and snippets.

@mattvchandler
Created July 9, 2015 22:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattvchandler/6f847d165e3abce7756d to your computer and use it in GitHub Desktop.
Save mattvchandler/6f847d165e3abce7756d to your computer and use it in GitHub Desktop.
SFML and gtkmm regression test
// test.cpp
// test for SFML embedded in gtkmm window problems
// Based on example from SFML github wiki: https://github.com/LaurentGomila/SFML/wiki/Source%3A-GTK-SFMLWidget
// - changed to use SFML window instead of RenderWindow, cleaned up, and tweaked substantially
// Copyright 2015 Matthew Chandler
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <iostream>
#include <SFML/Window.hpp>
#include <SFML/OpenGL.hpp>
#include <gtkmm/application.h>
#include <gtkmm/widget.h>
#include <gtkmm/window.h>
#include <gdkmm/general.h>
#if defined(SFML_SYSTEM_WINDOWS)
#include <gdk/gdkwin32.h>
#define GET_WINDOW_HANDLE_FROM_GDK GDK_WINDOW_HWND
#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
#include <gdk/gdkx.h>
#define GET_WINDOW_HANDLE_FROM_GDK GDK_WINDOW_XID
#else
#error Unsupported Operating System
#endif
class SFMLWidget: public Gtk::Widget
{
public:
SFMLWidget()
{
set_size_request(800, 600);
set_has_window(false);
}
void invalidate()
{
if(_gdk_window)
{
_gdk_window->invalidate(true);
}
}
sf::Window sf_win;
virtual void on_size_allocate(Gtk::Allocation & allocation)
{
this->set_allocation(allocation);
if(_gdk_window)
{
_gdk_window->move_resize(allocation.get_x(),
allocation.get_y(),
allocation.get_width(),
allocation.get_height());
sf_win.setSize(sf::Vector2u(allocation.get_width(),
allocation.get_height()));
std::cout<<"Resized to "<<allocation.get_width()<<","<<allocation.get_height()<<std::endl;
}
}
virtual void on_realize()
{
Gtk::Widget::on_realize();
if(!_gdk_window)
{
GdkWindowAttr attributes;
memset(&attributes, 0, sizeof(attributes));
Gtk::Allocation allocation = get_allocation();
attributes.x = allocation.get_x();
attributes.y = allocation.get_y();
attributes.width = allocation.get_width();
attributes.height = allocation.get_height();
attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK;
attributes.window_type = GDK_WINDOW_CHILD;
attributes.wclass = GDK_INPUT_OUTPUT;
_gdk_window = Gdk::Window::create(get_window(), &attributes,
GDK_WA_X | GDK_WA_Y);
set_has_window(true);
set_window(_gdk_window);
unset_background_color();
set_double_buffered(false);
_gdk_window->set_user_data(gobj());
sf::ContextSettings request(24, 8, 4, 3, 0);
sf_win.create(static_cast<sf::WindowHandle>(GET_WINDOW_HANDLE_FROM_GDK(_gdk_window->gobj())),
request);
std::cout<<"requested depth "<<request.depthBits<<
" sten: "<<request.stencilBits<<" AA: "<<request.antialiasingLevel<<
" GL vers: "<<request.majorVersion<<"."<<request.minorVersion<<std::endl;
sf::ContextSettings created = sf_win.getSettings();
std::cout<<"recieved depth "<<created.depthBits<<
" sten: "<<created.stencilBits<<" AA: "<<created.antialiasingLevel<<
" GL vers: "<<created.majorVersion<<"."<<created.minorVersion<<std::endl;
}
}
virtual void on_unrealize()
{
_gdk_window.clear();
Gtk::Widget::on_unrealize();
}
Glib::RefPtr<Gdk::Window> _gdk_window;
};
class Main_win: public Gtk::Window
{
public:
Main_win()
{
add(sf_widget);
show_all_children();
signal_draw().connect(sigc::mem_fun(this, &Main_win::draw));
}
bool draw(const Cairo::RefPtr<Cairo::Context> &)
{
glClearColor(0.0f, 1.0f, 0.0f, 1.0f); // cleared to green to make resize bug obvious
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
sf_widget.sf_win.display();
return true;
}
SFMLWidget sf_widget;
};
int main(int argc, char * argv[])
{
Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.test.test", Gio::APPLICATION_NON_UNIQUE);
Main_win gtk_window;
return app->run(gtk_window);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment