]> git.tdb.fi Git - libs/gui.git/commitdiff
Implement graphical reporting for uncaught exceptions
authorMikko Rasa <tdb@tdb.fi>
Sat, 5 Oct 2013 12:20:18 +0000 (15:20 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 5 Oct 2013 12:20:18 +0000 (15:20 +0300)
source/graphics/cocoa/display.cpp
source/graphics/cocoa/errordialog.cpp [new file with mode: 0644]
source/graphics/cocoa/errordialog.m [new file with mode: 0644]
source/graphics/display.h
source/graphics/errordialog.h [new file with mode: 0644]
source/graphics/windows/display.cpp
source/graphics/windows/errordialog.cpp [new file with mode: 0644]
source/graphics/x11/display.cpp
source/graphics/x11/errordialog.cpp [new file with mode: 0644]

index 5be28cde32f4a7c1ae293e23af292d1bb320c360..c6824b89fb38c66a0240adfebf348b855ac18111 100644 (file)
@@ -11,6 +11,8 @@ namespace Graphics {
 Display::Display(const std::string &):
        priv(new Private)
 {
+       static ErrorDialog err_dlg(0);
+
        priv->display = create_display();
 }
 
diff --git a/source/graphics/cocoa/errordialog.cpp b/source/graphics/cocoa/errordialog.cpp
new file mode 100644 (file)
index 0000000..ec44461
--- /dev/null
@@ -0,0 +1,22 @@
+#include "errordialog.h"
+
+using namespace std;
+
+extern "C" void run_alert(const char *, const char *);
+
+namespace Msp {
+namespace Graphics {
+
+bool ErrorDialog::report_uncaught_exception(const exception &e) const
+{
+       if(Application::get_data())
+       {
+               string type = Debug::demangle(typeid(e).name());
+               run_alert(type.c_str(), e.what());
+               return true;
+       }
+       return false;
+}
+
+} // namespace Graphics
+} // namespace Msp
diff --git a/source/graphics/cocoa/errordialog.m b/source/graphics/cocoa/errordialog.m
new file mode 100644 (file)
index 0000000..2b6b3c6
--- /dev/null
@@ -0,0 +1,16 @@
+#import <Foundation/NSString.h>
+#import <AppKit/NSAlert.h>
+
+// The function gets incorrect linkage without a prototype
+void run_alert(const char *, const char *);
+
+void run_alert(const char *type, const char *what)
+{
+       NSString *message = [[[NSString stringWithUTF8String:type] stringByAppendingString:@": "]
+               stringByAppendingString:[NSString stringWithUTF8String:what]];
+       NSAlert *alert = [NSAlert alertWithMessageText:@"Uncaught exception"
+               defaultButton:nil alternateButton:nil otherButton:nil
+               informativeTextWithFormat:@"%@", message];
+       [alert runModal];
+}
+
index 8d2f61873495bb4056dd276c25f4f6e65e5fa37c..bff17c3ffe69e8a819bf6b9872c77dc8ddab06bc 100644 (file)
@@ -4,6 +4,7 @@
 #include <list>
 #include <stdexcept>
 #include <string>
+#include "errordialog.h"
 #include "monitor.h"
 #include "videomode.h"
 
@@ -22,6 +23,7 @@ private:
        Monitor *primary_monitor;
        std::list<VideoMode> modes;
        Private *priv;
+       ErrorDialog *err_dialog;
 
 public:
        Display(const std::string &disp_name = std::string());
diff --git a/source/graphics/errordialog.h b/source/graphics/errordialog.h
new file mode 100644 (file)
index 0000000..7ece72e
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef MSP_GRAPHICS_ERRORDIALOG_H_
+#define MSP_GRAPHICS_ERRORDIALOG_H_
+
+#include <msp/debug/errorreporter.h>
+
+namespace Msp {
+namespace Graphics {
+
+class Display;
+
+class ErrorDialog: public Debug::ErrorReporter
+{
+private:
+       Display *display;
+
+public:
+       ErrorDialog(Display *d): display(d) { }
+
+       virtual bool report_uncaught_exception(const std::exception &) const;
+};
+
+} // namespace Graphics
+} // namespace Msp
+
+#endif
index 6553a8c692163772ca877e09fa1f26a8d6834271..7b616662ae9e06585c874f4e36c24af027d3f808 100644 (file)
@@ -11,6 +11,8 @@ Display::Display(const string &):
        primary_monitor(0),
        priv(new Private)
 {
+       static ErrorDialog err_dlg(0);
+
        for(unsigned i=0;; ++i)
        {
                DISPLAY_DEVICE adapter_dev;
diff --git a/source/graphics/windows/errordialog.cpp b/source/graphics/windows/errordialog.cpp
new file mode 100644 (file)
index 0000000..5215039
--- /dev/null
@@ -0,0 +1,19 @@
+#include <windows.h>
+#include <typeinfo>
+#include <msp/debug/demangle.h>
+#include "errordialog.h"
+
+using namespace std;
+
+namespace Msp {
+namespace Graphics {
+
+bool ErrorDialog::report_uncaught_exception(const exception &e) const
+{
+       string msg = Debug::demangle(typeid(e).name())+":\n"+e.what();
+       MessageBoxA(0, msg.c_str(), "Uncaught exception", MB_OK|MB_ICONERROR);
+       return false;
+}
+
+} // namespace Graphics
+} // namespace Msp
index 6f677c3048d7a7ee96b1db5f585847490503f7f8..70b77c60ff6239c46041b2821a9c39777f6f0628 100644 (file)
@@ -94,6 +94,8 @@ Display::Display(const string &disp_name):
 
        XSetErrorHandler(x_error_handler);
 
+       err_dialog = new ErrorDialog(this);
+
 #ifdef WITH_XRANDR
        int event_base;
        int error_base;
@@ -200,6 +202,7 @@ Display::~Display()
 {
        XCloseDisplay(priv->display);
        delete priv;
+       delete err_dialog;
 }
 
 void Display::set_mode(const VideoMode &requested_mode, bool exclusive)
diff --git a/source/graphics/x11/errordialog.cpp b/source/graphics/x11/errordialog.cpp
new file mode 100644 (file)
index 0000000..59085b4
--- /dev/null
@@ -0,0 +1,15 @@
+#include "errordialog.h"
+
+using namespace std;
+
+namespace Msp {
+namespace Graphics {
+
+bool ErrorDialog::report_uncaught_exception(const exception &) const
+{
+       // TODO Implement a simple dialog with basic X11 primitives
+       return false;
+}
+
+} // namespace Graphics
+} // namespace Msp