How to use MinGW-w64 with CLion

Update 29.09.2014: As pointed out by Anastasia Kazakova in the comments, CLion’s EAP has received an update which added native support for MinGW-w64!

In the past few days, I’ve seen CLion mentioned on multiple locations including the SFML forum. CLion is a new IDE developed by JetBrains for CMake based projects, it supports multiple languages and can be further extended with plugins. Some might recognize the interface since it’s very similar to JetBrains’ popular Java editor IntelliJ IDEA.

CLion

Personally I haven’t really looked at the IDE in-depth, since JetBrains is the creator of the allegedly awesome ReSharper tool for Visual Studio – which I’ve never used – the IDE itself should provide some pretty decent refactoring capabilities. Last I checked out Qt Creator, I was a bit disappointed at the sluggish CMake integration; this at least seems to work a lot better with CLion. However maybe Qt Creator upped their game since then as well.

This post however shouldn’t really be about introducing/promoting CLion and maybe some or many of you who somehow find this post already know what CLion is, instead this should actually be a short tutorial on how to use a compiler of the MinGW-w64 family with CLion.

Tricking CLion

For whatever reasons the developers at CLion apparently didn’t get the memo, that the original MinGW has been relatively abandoned and most of the user base has moved on to the MinGW-w64 project, which originally was created to develop a 64-bit compiler, but now supports both architectures. As such CLion currently only officially supports the vanilla MinGW. As a MinGW user for many years, the fact that CLion only wanted to recognize the original MinGW as compiler seemed rather odd, since the differences in using either a MinGW or a MinGW-w64 version nearly doesn’t exist. When I ran ProcMon and tracked what in the filesystem CLion accessed, I noticed that it checks for the existence of include/_mingw.h. By providing such a file in your MinGW-w64 directory structure you can trick the compiler into accepting it as MinGW compiler.

How To

Here are the few steps to make it work:

  1. Get your MinGW-w64 compiler installed somewhere.
  2. Create a file with the path [MinGW-w64 dir]/include/_mingw.h and the content shown below.
  3. Point CLion to your [MinGW-w64 dir] and watch how CLion recognizes your MinGW setup.

_mingw.h

#ifndef __MINGW_H

#define __MINGW_H

#define __MINGW32_VERSION           3.20
#define __MINGW32_MAJOR_VERSION     3
#define __MINGW32_MINOR_VERSION     20
#define __MINGW32_PATCHLEVEL        0

#endif /* __MINGW_H */

Disclaimer: CLion is still in an Early Access Program and may change any day. This trick worked for me, but there’s still a chance that it might not work for you.

To end this write up, here’s the introduction video from JetBrains on CLion – it was posted on their blog.

Tutorial: How to change your cursor?

cursorI’ve just published my first tutorial with SFML, okay it’s actually not fully my tutorial since I’ve partially rewritten one from the old section, but expanded it with in my opinion a better solution.
Although you can find the tutorial on the wiki site of SFML, I post it here again.


How to change your cursor?

The cursor is something every computer user is familiar with and in fact is constantly staring at, yet many people don’t even realize anymore that it’s there and changes its shape every so often. Next to the functionality like pointing and clicking the cursor can show many different states and indicate possible actions. For example you’ll get a selection cursor when hovering over a text or a hand shaped cursor could indicate a link etc.

Since SFML is not a framework nor a GUI system providing a native function for changing the mouse cursor doesn’t fit its purpose. Here’s where this tutorial comes in. If you’re making an application or game, you might want to be able to display a different cursor. There are two ways to change your cursor:

  1. You can hide the default cursor and draw a sprite where the cursor should be
  2. You can ask your OS to do it for you. (Windows & Linux)

This tutorial will cover both methods.

What do you need?

You’ll need SFML, an editor and a compiler (obviously these links are only suggestions).
Since I won’t go into details regarding C++ or SFML, the tutorial requires you to have some basic knowledge on both topics.

Hide and Draw

This task is fairly simple, it consists out of three required and one optional tasks:

  1. Use sf::RenderWindow::setMouseCursorVisible(bool) to hide the cursor.
  2. Set the position of the sprite to the position of the mouse.
  3. (optional) Adjust the view to get the correct render position.
  4. Draw the sprite to the screen.

Since it’s so simple there’s not more to talk about and an example shows a possible implementation:

#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "Hidden Cursor");
    window.setMouseCursorVisible(false); // Hide cursor

    sf::View fixed = window.getView(); // Create a fixed view

    // Load image and create sprite
    sf::Texture texture;
    texture.loadFromFile("cursor.png");
    sf::Sprite sprite(texture);

    while(window.isOpen())
    {
        sf::Event event;
        while(window.pollEvent(event))
        {
            if(event.type == sf::Event::Closed)
            {
                window.close();
            }
        }

        sprite.setPosition(static_cast<sf::Vector2f>(sf::Mouse::getPosition(window))); // Set position

        window.clear();
        window.setView(fixed);
        window.draw(sprite);
        window.display();
    }

    return EXIT_SUCCESS;
}

Ask your Operation System (OS)

What are the advantages of using this method over the other?

  • The OS will not duplicate the cursor in memory, because it is a shared resource.
  • The OS will use a cursor that the user is used to. For example on windows 7 the user is not used to having an hour glass, but is familiar with some sort of an animated circle.

Class Prototype

Since we have to store the cursor differently for the Linux as for the Windows platform, we’ve introduced an preprocessor switch for the include files and the private class members.

#ifndef STANDARDCURSOR_HPP
#define STANDARDCURSOR_HPP

#include <SFML/System.hpp>
#include <SFML/Window.hpp>

#ifdef SFML_SYSTEM_WINDOWS
    #include <windows.h>
#elif defined(SFML_SYSTEM_LINUX)
    #include <X11/cursorfont.h>
    #include <X11/Xlib.h>
#else
    #error This OS is not yet supported by the cursor library.
#endif

namespace sf
{
    class StandardCursor
    {
    private:
		#ifdef SFML_SYSTEM_WINDOWS

		HCURSOR Cursor; /*Type of the Cursor with Windows*/

		#else

        XID Cursor;
        Display* display;

		#endif
    public:
        enum TYPE{ WAIT, TEXT, NORMAL, HAND /*,...*/ };
        StandardCursor(const TYPE t);
        void set(const sf::WindowHandle& aWindowHandle) const;
        ~StandardCursor();
    };
}

#endif // STANDARDCURSOR_HPP

Class Implementation

Instead of ‘breaking’ the scope with preprocessor statements we’ll define every function twice with a switch for each platform.

#include "StandardCursor.hpp"

#ifdef SFML_SYSTEM_WINDOWS

sf::StandardCursor::StandardCursor(const sf::StandardCursor::TYPE t)
{
    switch(t)
    {
        case sf::StandardCursor::WAIT :
            Cursor = LoadCursor(NULL, IDC_WAIT);
        break;
        case sf::StandardCursor::HAND :
            Cursor = LoadCursor(NULL, IDC_HAND);
        break;
        case sf::StandardCursor::NORMAL :
            Cursor = LoadCursor(NULL, IDC_ARROW);
        break;
        case sf::StandardCursor::TEXT :
            Cursor = LoadCursor(NULL, IDC_IBEAM);
        break;
        //For more cursor options on Windows go here: http://msdn.microsoft.com/en-us/library/ms648391%28v=vs.85%29.aspx
    }
}

void sf::StandardCursor::set(const sf::WindowHandle& aWindowHandle) const
{
	SetClassLongPtr(aWindowHandle, GCLP_HCURSOR, reinterpret_cast<LONG_PTR>(Cursor));
}

sf::StandardCursor::~StandardCursor()
{
	// Nothing to do for destructor : no memory has been allocated (shared ressource principle)
}

#elif defined(SFML_SYSTEM_LINUX)

sf::StandardCursor::StandardCursor(const sf::StandardCursor::TYPE t)
{
    display = XOpenDisplay(NULL);

    switch(t)
    {
        case sf::StandardCursor::WAIT:
            Cursor = XCreateFontCursor(display, XC_watch);
        break;
        case sf::StandardCursor::HAND:
            Cursor = XCreateFontCursor(display, XC_hand1);
        break;
        case sf::StandardCursor::NORMAL:
            Cursor = XCreateFontCursor(display, XC_left_ptr);
        break;
        case sf::StandardCursor::TEXT:
            Cursor = XCreateFontCursor(display, XC_xterm);
        break;
        // For more cursor options on Linux go here: http://www.tronche.com/gui/x/xlib/appendix/b/
    }
}

void sf::StandardCursor::set(const sf::WindowHandle& aWindowHandle) const
{
    XDefineCursor(display, aWindowHandle, Cursor);
    XFlush(display);
}

sf::StandardCursor::~StandardCursor()
{
    XFreeCursor(display, Cursor);
    delete display;
    display = NULL;
}

#else
    #error This OS is not yet supported by the cursor library.
#endif

Cursor Demonstration

This section presents a fully functional demonstration of both cursor changing possibilities.

To get an handle to the window we will use SFML’s sf::Window::getSystemHandle() function and then we will load the cursor with the OS specific implementation.

#include <iostream>
#include <SFML/Graphics.hpp>
#include "StandardCursor.hpp"

int main()
{
	int choice = 0;
	while(choice != 1 && choice != 2)
	{
		std::cout << "t1. Hide the cursor and draw your own." << std::endl;
		std::cout << "t2. Let the OS handle the cursor." << std::endl;
		std::cout << "Choose your cursor behaviour: ";
		std::cin >> choice;
	}

    sf::RenderWindow window(sf::VideoMode(800, 600), "Cursor Demonstration");

	if(choice == 2)
    {
		sf::StandardCursor Cursor(sf::StandardCursor::HAND);
		Cursor.set(window.getSystemHandle());
	}
	else
		window.setMouseCursorVisible(false);

	sf::View fixed = window.getView();
	sf::Texture texture;
	if(!texture.loadFromFile("cursor.png"))
		return EXIT_FAILURE;
	sf::Sprite sprite(texture);

    while(window.isOpen())
    {
		sf::Event event;
		while(window.pollEvent(event))
			if(event.type == sf::Event::Closed)
				window.close();

		window.clear();

		if(choice == 1)
		{
			sprite.setPosition(static_cast<sf::Vector2f>(sf::Mouse::getPosition(window)));
			window.setView(fixed);
			window.draw(sprite);
		}

		window.display();
    }
    return EXIT_SUCCESS;
}

A *.zip file containing both, the code for StandardCursor class and the demonstration and an cursor image, can be obtained through this link: cursor.zip (2.9 KB)