error.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include "xlib.h"
  2. #include <stdio.h>
  3. s48_ref_t scx_error_code_binding = NULL;
  4. s48_ref_t scx_error_codes_binding = NULL;
  5. s48_ref_t scx_enter_error_code(s48_call_t call, int code) {
  6. s48_ref_t v = s48_shared_binding_ref_2(call, scx_error_codes_binding);
  7. if (code < s48_vector_length_2(call, v))
  8. return s48_vector_ref_2(call, v, code);
  9. else
  10. return s48_enter_long_2(call, code); /* Extension Errors */
  11. }
  12. long scx_extract_error_code(s48_call_t call, s48_ref_t code) {
  13. if (s48_record_p_2(call, code))
  14. return s48_extract_long_2(call, s48_checked_record_ref_2(call, code, 1,
  15. scx_error_code_binding));
  16. else
  17. return s48_extract_long_2(call, code);
  18. }
  19. s48_ref_t scx_x_error_binding = NULL;
  20. s48_ref_t scx_enter_x_error(s48_call_t call, XErrorEvent* xe) {
  21. s48_ref_t e = s48_make_record_2(call, scx_x_error_binding);
  22. char s[1024];
  23. s48_record_set_2(call, e, 0, scx_enter_display(call, scx_get_display_bundle(call, xe->display)));
  24. s48_record_set_2(call, e, 1, s48_enter_long_2(call, xe->serial));
  25. s48_record_set_2(call, e, 2, scx_enter_error_code(call, xe->error_code));
  26. s48_record_set_2(call, e, 3, s48_enter_long_2(call, xe->request_code));
  27. s48_record_set_2(call, e, 4, s48_enter_long_2(call, xe->minor_code));
  28. s48_record_set_2(call, e, 5, s48_enter_long_2(call, xe->resourceid));
  29. XGetErrorText(xe->display, xe->error_code, s, 1023);
  30. s48_record_set_2(call, e, 6, s48_enter_string(call, s));
  31. return e;
  32. }
  33. void scx_extract_x_error(s48_call_t call, s48_ref_t e, XErrorEvent* xe) {
  34. s48_check_record_type_2(call, e, scx_x_error_binding);
  35. xe->type = 1;
  36. xe->display = scx_extract_display(call, s48_record_ref_2(call, e, 0));
  37. xe->serial = s48_extract_long_2(call, s48_record_ref_2(call, e, 1));
  38. xe->error_code = scx_extract_error_code(call, s48_record_ref_2(call, e, 2));
  39. xe->request_code = s48_extract_long_2(call, s48_record_ref_2(call, e, 3));
  40. xe->minor_code = s48_extract_long_2(call, s48_record_ref_2(call, e, 4));
  41. xe->resourceid = s48_extract_long_2(call, s48_record_ref_2(call, e, 5));
  42. }
  43. /* Default error handlers of the Xlib */
  44. extern int _XDefaultIOError();
  45. extern int _XDefaultError();
  46. static s48_ref_t internal_x_error_handler_binding = NULL;
  47. static int error_handler_wrapper(Display* dpy, XErrorEvent* e) {
  48. s48_call_t call = s48_get_current_call();
  49. char handled = 0;
  50. if ((!s48_false_p_2(call, internal_x_error_handler_binding)) &&
  51. (!s48_false_p_2(call,
  52. s48_shared_binding_ref_2(call,
  53. internal_x_error_handler_binding)))){
  54. s48_ref_t v =
  55. s48_false_2(call), display = s48_false_2(call), err = s48_false_2(call);
  56. display = scx_enter_display(call, scx_get_display_bundle(call, dpy));
  57. err = scx_enter_x_error(call, e);
  58. v = s48_call_scheme_2(call,
  59. s48_shared_binding_ref_2(call, internal_x_error_handler_binding),
  60. 2, display, err);
  61. handled = (!s48_false_p_2(call, v));
  62. }
  63. if (!handled)
  64. _XDefaultError(dpy, e);
  65. return 0;
  66. }
  67. s48_ref_t scx_Get_Error_Text(s48_call_t call, s48_ref_t display, s48_ref_t code) {
  68. char buf[1024];
  69. XGetErrorText(scx_extract_display(call, display),
  70. scx_extract_error_code(call, code),
  71. buf, 1024);
  72. buf[1023] = 0;
  73. return s48_enter_string(call, buf);
  74. }
  75. s48_ref_t scx_Get_Error_Database_Text(s48_call_t call, s48_ref_t display,
  76. s48_ref_t name, s48_ref_t message, s48_ref_t def) {
  77. char buf[1024];
  78. XGetErrorDatabaseText(scx_extract_display(call, display),
  79. s48_extract_string(call, name),
  80. s48_extract_string(call, message),
  81. s48_extract_string(call, def),
  82. buf, 1024);
  83. buf[1023] = 0;
  84. return s48_enter_string(call, buf);
  85. }
  86. s48_ref_t internal_x_fatal_error_handler_binding = NULL;
  87. static int fatal_error_handler_wrapper(Display* d) {
  88. s48_call_t call = s48_get_current_call();
  89. /* call the scheme-func internal-x-fatal-error-handler, which does
  90. the rest. */
  91. if ((!s48_false_p_2(call, internal_x_fatal_error_handler_binding)) &&
  92. (!s48_false_p_2(call, s48_shared_binding_ref_2(call,
  93. internal_x_fatal_error_handler_binding))))
  94. s48_call_scheme_2(call, s48_shared_binding_ref_2(
  95. call, internal_x_fatal_error_handler_binding),
  96. 1, scx_enter_display(call, scx_get_display_bundle(call, d)));
  97. /* In case the scheme error handler does not exit (or none exists): */
  98. _XDefaultIOError (d);
  99. /* And if even the default handler does not exit: */
  100. exit(1);
  101. /*NOTREACHED*/
  102. return 0;
  103. }
  104. void scx_init_error() {
  105. scx_error_code_binding = s48_get_imported_binding_2("scx-error-code");
  106. scx_error_codes_binding = s48_get_imported_binding_2("scx-error-codes");
  107. scx_x_error_binding = s48_get_imported_binding_2("scx-x-error");
  108. S48_EXPORT_FUNCTION(scx_Get_Error_Text);
  109. S48_EXPORT_FUNCTION(scx_Get_Error_Database_Text);
  110. internal_x_fatal_error_handler_binding =
  111. s48_get_imported_binding_2("internal-x-fatal-error-handler");
  112. internal_x_error_handler_binding =
  113. s48_get_imported_binding_2("internal-x-error-handler");
  114. (void)XSetIOErrorHandler(fatal_error_handler_wrapper);
  115. (void)XSetErrorHandler(error_handler_wrapper);
  116. }