1
Window / [SFML2] Missing call to XInitThreads?
« on: September 09, 2010, 10:15:45 am »
Thanks for your answer, I'll see want I can do without it.
This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
#include <iostream>
#include <SFML/Window.hpp>
#include <X11/Xlib.h>
sf::Mutex mutex;
class EventLoopThread : public sf::Thread
{
public:
EventLoopThread(sf::Window* w)
: win_(w)
{
}
private:
void Run()
{
sf::Context context;
sf::Event event;
while (true)
{
mutex.Lock();
std::cout << "[thread 1] display start" << std::endl;
win_->SetActive(true);
win_->Display();
win_->SetActive(false);
std::cout << "[thread 1] display end" << std::endl;
mutex.Unlock();
}
}
sf::Window* win_;
};
int main()
{
sf::Window window(sf::VideoMode(100, 100), "SFML window");
EventLoopThread th(&window);
th.Launch();
while (window.IsOpened())
{
mutex.Lock();
std::cout << "[thread 0] display start" << std::endl;
window.SetActive(true);
window.Display();
window.SetActive(false);
std::cout << "[thread 0] display end" << std::endl;
mutex.Unlock();
}
}
The XInitThreads function initializes Xlib support for concurrent threads. This function must
be the first Xlib function a multi-threaded program calls, and it must complete before any other
Xlib call is made. This function returns a nonzero status if initialization was successful; other-
wise, it returns zero. On systems that do not support threads, this function always returns zero.
It is only necessary to call this function if multiple threads might use Xlib concurrently. If all
calls to Xlib functions are protected by some other access mechanism (for example, a mutual
exclusion lock in a toolkit or through explicit client programming), Xlib thread initialization is
not required. It is recommended that single-threaded programs not call this function.
#include <iostream>
#include <SFML/Window.hpp>
#include <X11/Xlib.h>
class EventLoopThread : public sf::Thread
{
public:
EventLoopThread(sf::Window* w)
: win_(w)
{
}
private:
void Run()
{
sf::Event event;
while (true)
{
win_->WaitEvent(event);
}
}
sf::Window* win_;
};
int main()
{
//XInitThreads(); // Deadlock without this call
// Declare and create a new window
sf::Window window(sf::VideoMode(100, 100), "SFML window");
EventLoopThread th(&window);
th.Launch();
// Activate the window for OpenGL rendering
window.SetActive();
unsigned f = 0;
// The main loop - ends as soon as the window is closed
while (window.IsOpened())
{
// OpenGL drawing commands go here...
std::cout << f << " display start" << std::endl;
// End the current frame and display its contents on screen
window.Display();
std::cout << "display end" << std::endl;
f++;
}
}
It's not a problem, it's how SFML 2 work. You have to create an OpenGL context in threads other than the main one if no window is active. That's why the sf::Context class exists.
bool GlContext::SetActive(bool active)
{
if (active)
{
// Activate the context
if (MakeCurrent())
{
// If this is the first context to be activated on this thread, make
// it the reference context for the whole thread
if (!threadContext)
threadContext = this;
return true;
}
}
else
{
// Deactivate the context
if (threadContext && (threadContext != this))
{
// To deactivate the context, we actually activate another one
// so that we make sure that there is always an active context
// for subsequent graphics operations
return threadContext->SetActive(true);
}
}
// If we got there then something failed
return false;
}
SFML is made for real-time applications that are refreshed contiuously, I can't find how this kind of event would be used in this context. But I'm sure you have a good example to tell me
// Expose
case Expose :
{
Event event;
event.Type = Event::GainedFocus;
PushEvent(event);
break;
}