scx/c/xlib/error.c

139 lines
4.5 KiB
C
Raw Normal View History

2001-05-08 10:21:00 -04:00
#include "xlib.h"
2001-08-29 10:54:05 -04:00
#include <stdio.h>
2001-05-08 10:21:00 -04:00
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));
}
static s48_value internal_error_handler_binding = S48_FALSE;
static int error_handler_wrapper(Display* dpy, XErrorEvent* e) {
s48_call_scheme(internal_error_handler_binding, 2,
scx_enter_display(dpy),
scx_enter_x_error(e));
return 0;
}
s48_value scx_Set_Error_Handler(s48_value fun) {
s48_value maybe_previous = internal_error_handler_binding;
int (*previous)() = NULL;
if (S48_POINTER_P(fun))
previous = XSetErrorHandler(S48_EXTRACT_POINTER(fun));
else if (S48_CLOSURE_P(fun)) {
previous = XSetErrorHandler(&error_handler_wrapper);
internal_error_handler_binding = fun;
} // TODO else error
if (previous == &error_handler_wrapper)
return maybe_previous;
else
return S48_ENTER_POINTER(previous);
}
s48_value scx_Call_C_Error_Handler(s48_value pointer, s48_value display,
s48_value event) {
int (*procedure)() = S48_EXTRACT_POINTER(pointer);
XErrorEvent ev; int result;
scx_extract_x_error(event, &ev);
result = procedure(scx_extract_display(display), &ev);
return s48_enter_integer(result);
}
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);
}
2001-08-29 10:54:05 -04:00
s48_value internal_x_fatal_error_handler_binding = S48_FALSE;
2001-05-08 10:21:00 -04:00
/* Default error handlers of the Xlib */
extern int _XDefaultIOError();
extern int _XDefaultError();
2001-08-29 10:54:05 -04:00
static X_Fatal_Error (Display* d) {
// call the scheme-func internal-x-fatal-error-handler, which does the rest.
s48_call_scheme(S48_SHARED_BINDING_REF(internal_x_fatal_error_handler_binding),
1, scx_enter_display(d));
2001-08-29 10:54:05 -04:00
// In case the scheme error handler does not exit (or none exists):
_XDefaultIOError (d);
// And if event the default handler does not exit:
exit (1);
/*NOTREACHED*/
2001-05-08 10:21:00 -04:00
}
2001-08-29 10:54:05 -04:00
void scx_init_error() {
S48_GC_PROTECT_GLOBAL(internal_error_handler_binding);
2001-08-29 10:54:05 -04:00
S48_GC_PROTECT_GLOBAL(internal_x_fatal_error_handler_binding);
S48_EXPORT_FUNCTION(scx_Set_Error_Handler);
S48_EXPORT_FUNCTION(scx_Call_C_Error_Handler);
S48_EXPORT_FUNCTION(scx_Get_Error_Text);
S48_EXPORT_FUNCTION(scx_Get_Error_Database_Text);
//S48_EXPORT_FUNCTION(scx_Set_IO_Error_Handler); TODO!
2001-08-29 10:54:05 -04:00
internal_x_fatal_error_handler_binding =
s48_get_imported_binding("internal-x-fatal-error-handler");
(void)XSetIOErrorHandler(X_Fatal_Error);
//(void)XSetErrorHandler(X_Error);
2001-05-08 10:21:00 -04:00
}