#include "xlib.h" #include s48_value scx_enter_error_code(int code) { s48_value v = S48_SHARED_BINDING_REF(s48_get_imported_binding("scx-error-codes")); if (code < S48_VECTOR_LENGTH(v)) return S48_VECTOR_REF(v, code); else return s48_enter_integer(code); // Extension Errors } s48_value scx_extract_error_code(s48_value code) { if (S48_RECORD_P(code)) { s48_value t = S48_SHARED_BINDING_REF(s48_get_imported_binding("scx-error-code")); return s48_extract_integer(s48_checked_record_ref(code, 1, t)); } else return s48_extract_integer(code); } s48_value scx_enter_x_error(XErrorEvent* xe) { s48_value e = s48_make_record(s48_get_imported_binding("scx-x-error")); char s[1024]; S48_DECLARE_GC_PROTECT(1); S48_GC_PROTECT_1(e); S48_RECORD_SET(e, 0, scx_enter_display(xe->display)); S48_RECORD_SET(e, 1, s48_enter_integer(xe->serial)); S48_RECORD_SET(e, 2, scx_enter_error_code(xe->error_code)); S48_RECORD_SET(e, 3, s48_enter_integer(xe->request_code)); S48_RECORD_SET(e, 4, s48_enter_integer(xe->minor_code)); S48_RECORD_SET(e, 5, s48_enter_integer(xe->resourceid)); XGetErrorText(xe->display, xe->error_code, s, 1023); S48_RECORD_SET(e, 6, s48_enter_string(s)); S48_GC_UNPROTECT(); return e; } void scx_extract_x_error(s48_value e, XErrorEvent* xe) { s48_check_record_type(e, s48_get_imported_binding("scx-x-error")); xe->type = 1; xe->display = scx_extract_display(S48_RECORD_REF(e, 0)); xe->serial = s48_extract_integer(S48_RECORD_REF(e, 1)); xe->error_code = scx_extract_error_code(S48_RECORD_REF(e, 2)); xe->request_code = s48_extract_integer(S48_RECORD_REF(e, 3)); xe->minor_code = s48_extract_integer(S48_RECORD_REF(e, 4)); xe->resourceid = s48_extract_integer(S48_RECORD_REF(e, 5)); } /* Default error handlers of the Xlib */ extern int _XDefaultIOError(); extern int _XDefaultError(); static s48_value internal_x_error_handler_binding = S48_FALSE; static int error_handler_wrapper(Display* dpy, XErrorEvent* e) { char handled = 0; if ((internal_x_error_handler_binding != S48_FALSE) && (S48_SHARED_BINDING_REF(internal_x_error_handler_binding) != S48_FALSE)){ s48_value v = s48_call_scheme(S48_SHARED_BINDING_REF(internal_x_error_handler_binding), 2, scx_enter_display(dpy), scx_enter_x_error(e)); handled = (v != S48_FALSE); } if (!handled) _XDefaultError(dpy, e); return 0; } s48_value scx_Get_Error_Text(s48_value display, s48_value code) { char buf[1024]; XGetErrorText(scx_extract_display(display), scx_extract_error_code(code), buf, 1024); buf[1023] = 0; return s48_enter_string(buf); } s48_value scx_Get_Error_Database_Text(s48_value display, s48_value name, s48_value message, s48_value def) { char buf[1024]; XGetErrorDatabaseText(scx_extract_display(display), s48_extract_string(name), s48_extract_string(message), s48_extract_string(def), buf, 1024); buf[1023] = 0; return s48_enter_string(buf); } s48_value internal_x_fatal_error_handler_binding = S48_FALSE; static int fatal_error_handler_wrapper(Display* d) { // call the scheme-func internal-x-fatal-error-handler, which does the rest. if ((internal_x_fatal_error_handler_binding != S48_FALSE) && (S48_SHARED_BINDING_REF(internal_x_fatal_error_handler_binding) != S48_FALSE)) s48_call_scheme(S48_SHARED_BINDING_REF( internal_x_fatal_error_handler_binding), 1, scx_enter_display(d)); // In case the scheme error handler does not exit (or none exists): _XDefaultIOError (d); // And if even the default handler does not exit: exit(1); /*NOTREACHED*/ return 0; } void scx_init_error() { S48_GC_PROTECT_GLOBAL(internal_x_error_handler_binding); S48_GC_PROTECT_GLOBAL(internal_x_fatal_error_handler_binding); S48_EXPORT_FUNCTION(scx_Get_Error_Text); S48_EXPORT_FUNCTION(scx_Get_Error_Database_Text); internal_x_fatal_error_handler_binding = s48_get_imported_binding("internal-x-fatal-error-handler"); internal_x_error_handler_binding = s48_get_imported_binding("internal-x-error-handler"); (void)XSetIOErrorHandler(fatal_error_handler_wrapper); (void)XSetErrorHandler(error_handler_wrapper); }