comparison src/xterm.c @ 26789:03a6016a38bf

(#includes): Allow compilation with only Xaw. (xaw3d_arrow_scroll, xaw3d_pick_top): New variables. (xt_action_hook): Replace XAW3D by XAW. (xaw3d_jump_callback): Renamed to xaw_jump_callback. (xaw_jump_callback): Renamed from xaw3d_jump_callback. Determine epsilon dynamically and don't try to be too clever. (xaw3d_scroll_callback): Renamed to xaw_scroll_callback. (xaw_scroll_callback): Renamed from xaw3d_scroll_callback. Handle both Xaw3d with arrow-scrollbars and with Xaw-style scrollbar (using `ratio'). (x_create_toolkit_scroll_bar): Try to detect which style of Xaw3d scrollbar we have so as to set it up more optimally and to fix xaw3d_arrow_scroll and xaw3d_pick_top. (x_set_toolkit_scroll_bar_thumb): Try to maintain 2 spare pixels at the bottom of the Xaw3d scrollbar, to work around its tendency to refuse shrinking the thumb. Also make sure that `XawScrollbarSetThumb' is not ignored, using a major gross hack. (x_initialize): Init default values for xaw3d_arrow_scroll and xaw3d_pick_top.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Fri, 10 Dec 1999 01:40:21 +0000
parents 346fcfbf7123
children e828d4307ab9
comparison
equal deleted inserted replaced
26788:5e97315b6f11 26789:03a6016a38bf
116 #ifdef USE_TOOLKIT_SCROLL_BARS 116 #ifdef USE_TOOLKIT_SCROLL_BARS
117 #if defined USE_MOTIF 117 #if defined USE_MOTIF
118 #include <Xm/Xm.h> /* for LESSTIF_VERSION */ 118 #include <Xm/Xm.h> /* for LESSTIF_VERSION */
119 #include <Xm/ScrollBar.h> 119 #include <Xm/ScrollBar.h>
120 #include <Xm/ScrollBarP.h> 120 #include <Xm/ScrollBarP.h>
121 #elif defined HAVE_XAW3D 121 #else /* !USE_MOTIF i.e. use Xaw */
122
123 #ifdef HAVE_XAW3D
122 #include <X11/Xaw3d/Simple.h> 124 #include <X11/Xaw3d/Simple.h>
123 #include <X11/Xaw3d/ThreeD.h>
124 #include <X11/Xaw3d/Scrollbar.h> 125 #include <X11/Xaw3d/Scrollbar.h>
125 #define ARROW_SCROLLBAR 126 #define ARROW_SCROLLBAR
126 #include <X11/Xaw3d/ScrollbarP.h> 127 #include <X11/Xaw3d/ScrollbarP.h>
127 #endif /* HAVE_XAW3D */ 128 #else /* !HAVE_XAW3D */
129 #include <X11/Xaw/Simple.h>
130 #include <X11/Xaw/Scrollbar.h>
131 #endif /* !HAVE_XAW3D */
132 #ifndef XtNpickTop
133 #define XtNpickTop "pickTop"
134 #endif /* !XtNpickTop */
135 #endif /* !USE_MOTIF */
128 #endif /* USE_TOOLKIT_SCROLL_BARS */ 136 #endif /* USE_TOOLKIT_SCROLL_BARS */
129 137
130 #endif /* USE_X_TOOLKIT */ 138 #endif /* USE_X_TOOLKIT */
131 139
132 #ifndef USE_X_TOOLKIT 140 #ifndef USE_X_TOOLKIT
7099 7107
7100 /* Last scroll bar part sent in xm_scroll_callback. */ 7108 /* Last scroll bar part sent in xm_scroll_callback. */
7101 7109
7102 static int last_scroll_bar_part; 7110 static int last_scroll_bar_part;
7103 7111
7112 /* Whether this is an Xaw with arrow-scrollbars. This should imply
7113 that movements of 1/20 of the screen size are mapped to up/down. */
7114
7115 static Boolean xaw3d_arrow_scroll;
7116
7117 /* Whether the drag scrolling maintains the mouse at the top of the
7118 thumb. If not, resizing the thumb needs to be done more carefully
7119 to avoid jerkyness. */
7120
7121 static Boolean xaw3d_pick_top;
7122
7104 7123
7105 /* Action hook installed via XtAppAddActionHook when toolkit scroll 7124 /* Action hook installed via XtAppAddActionHook when toolkit scroll
7106 bars are used.. The hoos is responsible for detecting when 7125 bars are used.. The hook is responsible for detecting when
7107 the user ends an interaction with the scroll bar, and generates 7126 the user ends an interaction with the scroll bar, and generates
7108 a `end-scroll' scroll_bar_click' event if so. */ 7127 a `end-scroll' scroll_bar_click' event if so. */
7109 7128
7110 static void 7129 static void
7111 xt_action_hook (widget, client_data, action_name, event, params, 7130 xt_action_hook (widget, client_data, action_name, event, params,
7121 char *end_action; 7140 char *end_action;
7122 7141
7123 #ifdef USE_MOTIF 7142 #ifdef USE_MOTIF
7124 scroll_bar_p = XmIsScrollBar (widget); 7143 scroll_bar_p = XmIsScrollBar (widget);
7125 end_action = "Release"; 7144 end_action = "Release";
7126 #elif defined HAVE_XAW3D 7145 #else /* !USE_MOTIF i.e. use Xaw */
7127 scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass); 7146 scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass);
7128 end_action = "EndScroll"; 7147 end_action = "EndScroll";
7129 #else 7148 #endif /* USE_MOTIF */
7130 #error unknown scroll bar toolkit
7131 #endif /* HAVE_XAW3D */
7132 7149
7133 /* Although LessTif uses XtTimeouts like Xaw3d, the timer hack to 7150 /* Although LessTif uses XtTimeouts like Xaw3d, the timer hack to
7134 let Xt timeouts be processed doesn't work. */ 7151 let Xt timeouts be processed doesn't work. */
7135 if (scroll_bar_p 7152 if (scroll_bar_p
7136 && strcmp (action_name, end_action) == 0 7153 && strcmp (action_name, end_action) == 0
7311 x_send_scroll_bar_event (bar->window, part, portion, whole); 7328 x_send_scroll_bar_event (bar->window, part, portion, whole);
7312 } 7329 }
7313 } 7330 }
7314 7331
7315 7332
7316 #else /* not USE_MOTIF, i.e. XAW3D. */ 7333 #else /* !USE_MOTIF, i.e. Xaw. */
7317 7334
7318 7335
7319 /* Xaw3d scroll bar callback. Invoked when the thumb is dragged. 7336 /* Xaw scroll bar callback. Invoked when the thumb is dragged.
7320 WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the 7337 WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the
7321 scroll bar struct. CALL_DATA is a pointer to a float saying where 7338 scroll bar struct. CALL_DATA is a pointer to a float saying where
7322 the thumb is. */ 7339 the thumb is. */
7323 7340
7324 static void 7341 static void
7325 xaw3d_jump_callback (widget, client_data, call_data) 7342 xaw_jump_callback (widget, client_data, call_data)
7326 Widget widget; 7343 Widget widget;
7327 XtPointer client_data, call_data; 7344 XtPointer client_data, call_data;
7328 { 7345 {
7329 struct scroll_bar *bar = (struct scroll_bar *) client_data; 7346 struct scroll_bar *bar = (struct scroll_bar *) client_data;
7330 float top = *(float *) call_data; 7347 float top = *(float *) call_data;
7331 float shown; 7348 float shown;
7332 int whole, portion; 7349 int whole, portion, height;
7333 int dragging_down_p, part; 7350 int part;
7334 double epsilon = 0.01;
7335 7351
7336 /* Get the size of the thumb, a value between 0 and 1. */ 7352 /* Get the size of the thumb, a value between 0 and 1. */
7337 BLOCK_INPUT; 7353 BLOCK_INPUT;
7338 XtVaGetValues (widget, XtNshown, &shown, NULL); 7354 XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL);
7339 UNBLOCK_INPUT; 7355 UNBLOCK_INPUT;
7340 7356
7341 whole = 10000000; 7357 whole = 10000000;
7342 portion = shown < 1 ? top * whole : 0; 7358 portion = shown < 1 ? top * whole : 0;
7343 dragging_down_p = (INTEGERP (bar->dragging) 7359
7344 && XINT (bar->dragging) < portion); 7360 if (shown < 1 && (abs (top + shown - 1) < 1.0/height))
7345 7361 /* Some derivatives of Xaw refuse to shrink the thumb when you reach
7346 if (shown < 1 7362 the bottom, so we force the scrolling whenever we see that we're
7347 && (abs (top + shown - 1) < epsilon 7363 too close to the bottom (in x_set_toolkit_scroll_bar_thumb
7348 || (dragging_down_p 7364 we try to ensure that we always stay two pixels away from the
7349 && last_scroll_bar_part == scroll_bar_down_arrow))) 7365 bottom). */
7350 part = scroll_bar_down_arrow; 7366 part = scroll_bar_down_arrow;
7351 else 7367 else
7352 part = scroll_bar_handle; 7368 part = scroll_bar_handle;
7353 7369
7354 window_being_scrolled = bar->window; 7370 window_being_scrolled = bar->window;
7356 last_scroll_bar_part = part; 7372 last_scroll_bar_part = part;
7357 x_send_scroll_bar_event (bar->window, part, portion, whole); 7373 x_send_scroll_bar_event (bar->window, part, portion, whole);
7358 } 7374 }
7359 7375
7360 7376
7361 /* Xaw3d scroll bar callback. Invoked for incremental scrolling., 7377 /* Xaw scroll bar callback. Invoked for incremental scrolling.,
7362 i.e. line or page up or down. WIDGET is the Xaw3d scroll bar 7378 i.e. line or page up or down. WIDGET is the Xaw scroll bar
7363 widget. CLIENT_DATA is a pointer to the scroll_bar structure for 7379 widget. CLIENT_DATA is a pointer to the scroll_bar structure for
7364 the scroll bar. CALL_DATA is an integer specifying the action that 7380 the scroll bar. CALL_DATA is an integer specifying the action that
7365 has taken place. It's magnitude is in the range 0..height of the 7381 has taken place. It's magnitude is in the range 0..height of the
7366 scroll bar. Negative values mean scroll towards buffer start. 7382 scroll bar. Negative values mean scroll towards buffer start.
7367 Values < height of scroll bar mean line-wise movement. */ 7383 Values < height of scroll bar mean line-wise movement. */
7368 7384
7369 static void 7385 static void
7370 xaw3d_scroll_callback (widget, client_data, call_data) 7386 xaw_scroll_callback (widget, client_data, call_data)
7371 Widget widget; 7387 Widget widget;
7372 XtPointer client_data, call_data; 7388 XtPointer client_data, call_data;
7373 { 7389 {
7374 struct scroll_bar *bar = (struct scroll_bar *) client_data; 7390 struct scroll_bar *bar = (struct scroll_bar *) client_data;
7375 int position = (int) call_data; 7391 int position = (int) call_data;
7379 /* Get the height of the scroll bar. */ 7395 /* Get the height of the scroll bar. */
7380 BLOCK_INPUT; 7396 BLOCK_INPUT;
7381 XtVaGetValues (widget, XtNheight, &height, NULL); 7397 XtVaGetValues (widget, XtNheight, &height, NULL);
7382 UNBLOCK_INPUT; 7398 UNBLOCK_INPUT;
7383 7399
7384 if (position < 0) 7400 if (abs (position) >= height)
7385 { 7401 part = (position < 0) ? scroll_bar_above_handle : scroll_bar_below_handle;
7386 if (abs (position) < height) 7402
7387 part = scroll_bar_up_arrow; 7403 /* If Xaw3d was compiled with ARROW_SCROLLBAR,
7388 else 7404 it maps line-movement to call_data = max(5, height/20). */
7389 part = scroll_bar_above_handle; 7405 else if (xaw3d_arrow_scroll && abs (position) <= max (5, height / 20))
7390 } 7406 part = (position < 0) ? scroll_bar_up_arrow : scroll_bar_down_arrow;
7391 else 7407 else
7392 { 7408 part = scroll_bar_move_ratio;
7393 if (abs (position) < height)
7394 part = scroll_bar_down_arrow;
7395 else
7396 part = scroll_bar_below_handle;
7397 }
7398 7409
7399 window_being_scrolled = bar->window; 7410 window_being_scrolled = bar->window;
7400 bar->dragging = Qnil; 7411 bar->dragging = Qnil;
7401 last_scroll_bar_part = part; 7412 last_scroll_bar_part = part;
7402 x_send_scroll_bar_event (bar->window, part, 0, 0); 7413 x_send_scroll_bar_event (bar->window, part, position, height);
7403 } 7414 }
7404 7415
7405 7416
7406 #endif /* not USE_MOTIF */ 7417 #endif /* not USE_MOTIF */
7407 7418
7480 /* Set the cursor to an arrow. I didn't find a resource to do that. 7491 /* Set the cursor to an arrow. I didn't find a resource to do that.
7481 And I'm wondering why it hasn't an arrow cursor by default. */ 7492 And I'm wondering why it hasn't an arrow cursor by default. */
7482 XDefineCursor (XtDisplay (widget), XtWindow (widget), 7493 XDefineCursor (XtDisplay (widget), XtWindow (widget),
7483 f->output_data.x->nontext_cursor); 7494 f->output_data.x->nontext_cursor);
7484 7495
7485 #elif defined HAVE_XAW3D 7496 #else /* !USE_MOTIF i.e. use Xaw */
7486 7497
7487 /* Set resources. Create the widget. The background of the 7498 /* Set resources. Create the widget. The background of the
7488 Xaw3d scroll bar widget is a little bit light for my taste. 7499 Xaw3d scroll bar widget is a little bit light for my taste.
7489 We don't alter it here to let users change it according 7500 We don't alter it here to let users change it according
7490 to their taste with `emacs*verticalScrollBar.background: xxx'. */ 7501 to their taste with `emacs*verticalScrollBar.background: xxx'. */
7491 XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac; 7502 XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
7492 XtSetArg (av[ac], XtNorientation, XtorientVertical); ++ac; 7503 XtSetArg (av[ac], XtNorientation, XtorientVertical); ++ac;
7493 XtSetArg (av[ac], XtNcursorName, "left_ptr"); ++ac; 7504 /* For smoother scrolling with Xaw3d -sm */
7494 XtSetArg (av[ac], XtNbeNiceToColormap, True); ++ac; 7505 /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
7506 /* XtSetArg (av[ac], XtNbeNiceToColormap, True); ++ac; */
7495 7507
7496 pixel = f->output_data.x->scroll_bar_foreground_pixel; 7508 pixel = f->output_data.x->scroll_bar_foreground_pixel;
7497 if (pixel != -1) 7509 if (pixel != -1)
7498 { 7510 {
7499 XtSetArg (av[ac], XtNforeground, pixel); 7511 XtSetArg (av[ac], XtNforeground, pixel);
7507 ++ac; 7519 ++ac;
7508 } 7520 }
7509 7521
7510 widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass, 7522 widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass,
7511 f->output_data.x->edit_widget, av, ac); 7523 f->output_data.x->edit_widget, av, ac);
7524
7525 {
7526 char *initial = "";
7527 char *val = initial;
7528 XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val,
7529 XtNpickTop, (XtPointer) &xaw3d_pick_top, NULL);
7530 if (val == initial)
7531 { /* ARROW_SCROLL */
7532 xaw3d_arrow_scroll = True;
7533 /* Isn't that just a personal preference ? -sm */
7534 XtVaSetValues (widget, XtNcursorName, "top_left_arrow", NULL);
7535 }
7536 }
7512 7537
7513 /* Define callbacks. */ 7538 /* Define callbacks. */
7514 XtAddCallback (widget, XtNjumpProc, xaw3d_jump_callback, (XtPointer) bar); 7539 XtAddCallback (widget, XtNjumpProc, xaw_jump_callback, (XtPointer) bar);
7515 XtAddCallback (widget, XtNscrollProc, xaw3d_scroll_callback, 7540 XtAddCallback (widget, XtNscrollProc, xaw_scroll_callback,
7516 (XtPointer) bar); 7541 (XtPointer) bar);
7517 7542
7518 /* Realize the widget. Only after that is the X window created. */ 7543 /* Realize the widget. Only after that is the X window created. */
7519 XtRealizeWidget (widget); 7544 XtRealizeWidget (widget);
7520 7545
7521 #endif /* HAVE_XAW3D */ 7546 #endif /* !USE_MOTIF */
7522 7547
7523 /* Install an action hook that let's us detect when the user 7548 /* Install an action hook that let's us detect when the user
7524 finishes interacting with a scroll bar. */ 7549 finishes interacting with a scroll bar. */
7525 if (action_hook_id == 0) 7550 if (action_hook_id == 0)
7526 action_hook_id = XtAppAddActionHook (Xt_app_con, xt_action_hook, 0); 7551 action_hook_id = XtAppAddActionHook (Xt_app_con, xt_action_hook, 0);
7560 int size, value; 7585 int size, value;
7561 Boolean arrow1_selected, arrow2_selected; 7586 Boolean arrow1_selected, arrow2_selected;
7562 unsigned char flags; 7587 unsigned char flags;
7563 XmScrollBarWidget sb; 7588 XmScrollBarWidget sb;
7564 7589
7565 /* Slider size. Must be in the range [1 .. MAX - MIN] where NAX 7590 /* Slider size. Must be in the range [1 .. MAX - MIN] where MAX
7566 is the scroll bar's maximum and MIN is the scroll bar's minimum 7591 is the scroll bar's maximum and MIN is the scroll bar's minimum
7567 value. */ 7592 value. */
7568 size = shown * XM_SB_RANGE; 7593 size = shown * XM_SB_RANGE;
7569 size = min (size, XM_SB_RANGE); 7594 size = min (size, XM_SB_RANGE);
7570 size = max (size, 1); 7595 size = max (size, 1);
7588 7613
7589 if (NILP (bar->dragging)) 7614 if (NILP (bar->dragging))
7590 XmScrollBarSetValues (widget, value, size, 0, 0, False); 7615 XmScrollBarSetValues (widget, value, size, 0, 0, False);
7591 else if (last_scroll_bar_part == scroll_bar_down_arrow) 7616 else if (last_scroll_bar_part == scroll_bar_down_arrow)
7592 /* This has the negative side effect that the slider value is 7617 /* This has the negative side effect that the slider value is
7593 not would it would be if we scrolled here using line-wise or 7618 not what it would be if we scrolled here using line-wise or
7594 page-wise movement. */ 7619 page-wise movement. */
7595 XmScrollBarSetValues (widget, value, XM_SB_RANGE - value, 0, 0, False); 7620 XmScrollBarSetValues (widget, value, XM_SB_RANGE - value, 0, 0, False);
7596 else 7621 else
7597 { 7622 {
7598 /* If currently dragging, only update the slider size. 7623 /* If currently dragging, only update the slider size.
7608 7633
7609 sb->scrollBar.arrow1_selected = arrow1_selected; 7634 sb->scrollBar.arrow1_selected = arrow1_selected;
7610 sb->scrollBar.arrow2_selected = arrow2_selected; 7635 sb->scrollBar.arrow2_selected = arrow2_selected;
7611 sb->scrollBar.flags = flags; 7636 sb->scrollBar.flags = flags;
7612 } 7637 }
7613 #elif defined HAVE_XAW3D 7638 #else /* !USE_MOTIF i.e. use Xaw */
7614 { 7639 {
7615 /* Restrict to [0 1]. */ 7640 float old_top, old_shown;
7616 top = max (0, min (1, top)); 7641 Dimension height;
7617 shown = max (0, min (1, shown)); 7642 XtVaGetValues (widget,
7643 XtNtopOfThumb, &old_top,
7644 XtNshown, &old_shown,
7645 XtNheight, &height,
7646 NULL);
7647
7648 /* Massage the top+shown values. */
7649 if (NILP (bar->dragging) || last_scroll_bar_part == scroll_bar_down_arrow)
7650 top = max (0, min (1, top));
7651 else
7652 top = old_top;
7653 /* Keep two pixels available for moving the thumb down. */
7654 shown = max (0, min (1 - top - (2.0 / height), shown));
7618 7655
7619 /* If the call to XawScrollbarSetThumb below doesn't seem to work, 7656 /* If the call to XawScrollbarSetThumb below doesn't seem to work,
7620 check that your system's configuration file contains a define 7657 check that your system's configuration file contains a define
7621 for `NARROWPROTO'. See s/freebsd.h for an example. */ 7658 for `NARROWPROTO'. See s/freebsd.h for an example. */
7622 if (NILP (bar->dragging)) 7659 if (top != old_top || shown != old_shown)
7623 { 7660 {
7624 float old_top, old_shown; 7661 if (NILP (bar->dragging))
7625 XtVaGetValues (widget, XtNtopOfThumb, &old_top, XtNshown, &old_shown,
7626 NULL);
7627 if (top != old_top || shown != old_shown)
7628 XawScrollbarSetThumb (widget, top, shown); 7662 XawScrollbarSetThumb (widget, top, shown);
7629 }
7630 else
7631 {
7632 ScrollbarWidget sb = (ScrollbarWidget) widget;
7633 int scroll_mode = sb->scrollbar.scroll_mode;
7634
7635 sb->scrollbar.scroll_mode = 0;
7636
7637 if (last_scroll_bar_part == scroll_bar_down_arrow)
7638 XawScrollbarSetThumb (widget, top, 1 - top);
7639 else 7663 else
7640 { 7664 {
7641 float old_top; 7665 #ifdef HAVE_XAW3D
7642 XtVaGetValues (widget, XtNtopOfThumb, &old_top, NULL); 7666 ScrollbarWidget sb = (ScrollbarWidget) widget;
7643 XawScrollbarSetThumb (widget, old_top, min (shown, 1 - old_top)); 7667 int scroll_mode;
7668
7669 /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR. */
7670 if (xaw3d_arrow_scroll)
7671 {
7672 /* Xaw3d stupidly ignores resize requests while dragging
7673 so we have to make it believe it's not in dragging mode. */
7674 scroll_mode = sb->scrollbar.scroll_mode;
7675 if (scroll_mode == 2)
7676 sb->scrollbar.scroll_mode = 0;
7677 }
7678 #endif
7679 /* Try to make the scrolling a tad smoother. */
7680 if (!xaw3d_pick_top)
7681 shown = min (shown, old_shown);
7682
7683 XawScrollbarSetThumb (widget, top, shown);
7684
7685 #ifdef HAVE_XAW3D
7686 if (xaw3d_arrow_scroll && scroll_mode == 2)
7687 sb->scrollbar.scroll_mode = scroll_mode;
7688 #endif
7644 } 7689 }
7645
7646 sb->scrollbar.scroll_mode = scroll_mode;
7647 } 7690 }
7648 } 7691 }
7649 #endif /* HAVE_XAW3D */ 7692 #endif /* !USE_MOTIF */
7650 7693
7651 UNBLOCK_INPUT; 7694 UNBLOCK_INPUT;
7652 } 7695 }
7653 7696
7654 #endif /* USE_TOOLKIT_SCROLL_BARS */ 7697 #endif /* USE_TOOLKIT_SCROLL_BARS */
12822 12865
12823 #ifdef USE_X_TOOLKIT 12866 #ifdef USE_X_TOOLKIT
12824 XtToolkitInitialize (); 12867 XtToolkitInitialize ();
12825 Xt_app_con = XtCreateApplicationContext (); 12868 Xt_app_con = XtCreateApplicationContext ();
12826 XtAppSetFallbackResources (Xt_app_con, Xt_default_resources); 12869 XtAppSetFallbackResources (Xt_app_con, Xt_default_resources);
12870 xaw3d_arrow_scroll = False;
12871 xaw3d_pick_top = True;
12827 #endif 12872 #endif
12828 12873
12829 /* Note that there is no real way portable across R3/R4 to get the 12874 /* Note that there is no real way portable across R3/R4 to get the
12830 original error handler. */ 12875 original error handler. */
12831 XSetErrorHandler (x_error_handler); 12876 XSetErrorHandler (x_error_handler);