141 lines
4.7 KiB
C
141 lines
4.7 KiB
C
#include "xlib.h"
|
|
#include <stdio.h>
|
|
|
|
s48_value scx_error_code_binding = S48_FALSE;
|
|
s48_value scx_error_codes_binding = S48_FALSE;
|
|
|
|
s48_value scx_enter_error_code(int code) {
|
|
s48_value v = S48_SHARED_BINDING_REF(scx_error_codes_binding);
|
|
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))
|
|
return s48_extract_integer(s48_checked_record_ref(code, 1,
|
|
scx_error_code_binding));
|
|
else
|
|
return s48_extract_integer(code);
|
|
}
|
|
|
|
s48_value scx_x_error_binding = S48_FALSE;
|
|
|
|
s48_value scx_enter_x_error(XErrorEvent* xe) {
|
|
s48_value e = s48_make_record(scx_x_error_binding);
|
|
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_DECLARE_GC_PROTECT_1(e);
|
|
s48_check_record_type(e, scx_x_error_binding);
|
|
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));
|
|
S48_GC_UNPROTECT();
|
|
}
|
|
|
|
/* 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_FALSE, display = S48_FALSE, err = S48_FALSE;
|
|
S48_DECLARE_GC_PROTECT_3(v, display, err);
|
|
display = scx_enter_display(dpy);
|
|
err = scx_enter_x_error(e);
|
|
v =
|
|
s48_call_scheme(S48_SHARED_BINDING_REF(internal_x_error_handler_binding),
|
|
2, display, err);
|
|
handled = (v != S48_FALSE);
|
|
S48_GC_UNPROTECT();
|
|
}
|
|
if (!handled)
|
|
_XDefaultError(dpy, e);
|
|
return 0;
|
|
}
|
|
|
|
s48_value scx_Get_Error_Text(s48_value display, s48_value code) {
|
|
char buf[1024];
|
|
S48_DECLARE_GC_PROTECT_2(display, code);
|
|
XGetErrorText(scx_extract_display(display), scx_extract_error_code(code),
|
|
buf, 1024);
|
|
buf[1023] = 0;
|
|
S48_GC_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];
|
|
S48_DECLARE_GC_PROTECT_4(display, name, message, def);
|
|
XGetErrorDatabaseText(scx_extract_display(display),
|
|
s48_extract_string(name),
|
|
s48_extract_string(message),
|
|
s48_extract_string(def),
|
|
buf, 1024);
|
|
buf[1023] = 0;
|
|
S48_GC_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() {
|
|
SCX_PRO_IMP(scx_error_code_binding, "scx-error-code");
|
|
SCX_PRO_IMP(scx_error_codes_binding, "scx-error-codes");
|
|
SCX_PRO_IMP(scx_x_error_binding, "scx-x-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);
|
|
}
|