Index: elec/CrO2/software/Makefile
===================================================================
--- elec/CrO2/software/Makefile	(revision c7b42180dbb79565876daf11c904fa544c18956c)
+++ elec/CrO2/software/Makefile	(revision f9263dd2949eb63851e44991b4ffe2eddd0c432e)
@@ -14,5 +14,5 @@
 
 CC		= g++
-CPPFLAGS	= $(USBFLAGS) -O -Wall -I/usr/include/IUP/ -g
+CPPFLAGS	= $(USBFLAGS) -O -Wall -I/usr/include/IUP/ -g -std=c++0x
 LIBS	= $(USBLIBS) -L/usr/lib/ -mwindows -liup -lcomctl32 -lole32
 
Index: elec/CrO2/software/gui.cpp
===================================================================
--- elec/CrO2/software/gui.cpp	(revision c7b42180dbb79565876daf11c904fa544c18956c)
+++ elec/CrO2/software/gui.cpp	(revision f9263dd2949eb63851e44991b4ffe2eddd0c432e)
@@ -11,55 +11,5 @@
 
 #include <stdint.h>
-#include <iup.h>
 #include <iupcontrols.h>
-
-///////////////////////////////////////////////////////////////////////////////
-// Super awesome extended powerful ultimate deluxe C++ IUP callback system ;)
-
-typedef int (Gui::*Callee)();
-
-class Callback
-{
-	public:
-		static int call(Ihandle* that);
-		static int destroy(Ihandle* that);
-		static void create(Ihandle* handle, const char* name, Gui* self, Callee what);
-
-	private:
-		Callback(Gui* self, Callee what);
-		Callback(); // do not use
-
-		Gui* self;
-		Callee what;
-};
-
-void Callback::create(Ihandle* handle,const char* name, Gui* self, Callee what)
-{
-	Callback* cb = new Callback(self, what);
-	IupSetAttribute(handle, "LCALLBACK", (char*)cb);
-	IupSetCallback(handle, name, Callback::call);
-	IupSetCallback(handle, "LDESTROY_CB", Callback::destroy);
-}
-
-Callback::Callback(Gui* self, Callee what)
-{
-	this->self = self;
-	this->what = what;
-}
-
-int Callback::call(Ihandle* that)
-{
-	Callback* call = (Callback*)IupGetAttribute(that, "LCALLBACK");
-	return ((call->self)->*(call->what))();
-}
-
-int Callback::destroy(Ihandle* that)
-{
-	Callback* call = (Callback*)IupGetAttribute(that, "LCALLBACK");
-	delete call;
-	return IUP_DEFAULT;
-}
-
-///////////////////////////////////////////////////////////////////////////////
 
 	// Start status poller "thread"
@@ -88,10 +38,8 @@
 /* UI */
 
-int menu_exit(Ihandle* that)
+int Gui::menu_exit()
 {
 	return IUP_CLOSE;
 }
-
-
 
 Gui::Gui(int* argc, char*** argv)
@@ -102,8 +50,8 @@
 //	IupControlsOpen();
 
-	IupSetFunction("EXIT", menu_exit);
-
 	Ihandle* menu_open = IupItem("Open", NULL);
-	Callback::create(menu_open, "ACTION", this, &Gui::menu_open);
+	Ihandle* menu_exit = IupItem("Exit", NULL);
+	Callback<Gui>::create(menu_open, "ACTION", this, &Gui::menu_open);
+	Callback<Gui>::create(menu_exit, "ACTION", this, &Gui::menu_exit);
 
 	Ihandle* menu = IupMenu(
@@ -111,5 +59,5 @@
 			IupMenu(
 				menu_open,		
-				IupItem("Exit", "EXIT"),
+				menu_exit,
 				NULL
 			)
Index: elec/CrO2/software/gui.h
===================================================================
--- elec/CrO2/software/gui.h	(revision c7b42180dbb79565876daf11c904fa544c18956c)
+++ elec/CrO2/software/gui.h	(revision f9263dd2949eb63851e44991b4ffe2eddd0c432e)
@@ -5,5 +5,7 @@
  */
 
-#include <iup.h>
+#include "iupplusplus.h"
+
+#include <cstdio>
 
 class K5;
@@ -16,4 +18,5 @@
 	private:
 		int menu_open();
+		int menu_exit();
 
 		K5* file;
Index: elec/CrO2/software/iupplusplus.h
===================================================================
--- elec/CrO2/software/iupplusplus.h	(revision f9263dd2949eb63851e44991b4ffe2eddd0c432e)
+++ elec/CrO2/software/iupplusplus.h	(revision f9263dd2949eb63851e44991b4ffe2eddd0c432e)
@@ -0,0 +1,47 @@
+/* CrO2 datassette emulator
+ * Copyright 2012, Adrien Destugues <pulkomandy@pulkomandy.ath.cx>
+ *
+ * Distributed under the terms of the MIT licence.
+ */
+
+#include <iup.h>
+
+template<class Handler, typename... Args> class Callback
+{
+	typedef int(Handler::*T)(Args... args);
+
+	public:
+		static int destroy(Ihandle* that)
+		{
+			Callback* call = (Callback*)IupGetAttribute(that, "LCALLBACK");
+			delete call;
+			return IUP_DEFAULT;
+		}
+
+		static void create(Ihandle* handle, const char* name, Handler* self, T what)
+		{
+			Callback* cb = new Callback(self, what);
+			IupSetAttribute(handle, "LCALLBACK", (char*)cb);
+			IupSetCallback(handle, name, (Icallback)Callback::call);
+			IupSetCallback(handle, "LDESTROY_CB", Callback::destroy);
+		}
+
+		static int call(Ihandle* that, Args... args)
+		{
+			Callback* call = (Callback*)IupGetAttribute(that, "LCALLBACK");
+			return ((call->self)->*(call->what))(args...);
+		}
+
+	private:
+		Callback(Handler* self, T what)
+		{
+			this->self = self;
+			this->what = what;
+		}
+
+		Callback(); // do not use
+
+		Handler* self;
+		T what;
+};
+
