1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif /* ifdef HAVE_CONFIG_H */
4 
5 #include <stdlib.h>
6 
7 #include "Ecore.h"
8 #include "ecore_private.h"
9 #include "ecore_x_private.h"
10 #include "Ecore_X.h"
11 
12 static int _ecore_x_error_handle(Display *d,
13                                  XErrorEvent *ev);
14 static int _ecore_x_io_error_handle(Display *d);
15 
16 static void (*_error_func)(void *data) = NULL;
17 static void *_error_data = NULL;
18 static void (*_io_error_func)(void *data) = NULL;
19 static void *_io_error_data = NULL;
20 static int _error_request_code = 0;
21 static int _error_code = 0;
22 static Ecore_X_ID _error_resource_id = 0;
23 
24 /**
25  * Set the error handler.
26  * @param func The error handler function
27  * @param data The data to be passed to the handler function
28  *
29  * Set the X error handler function
30  */
31 EAPI void
ecore_x_error_handler_set(void (* func)(void * data),const void * data)32 ecore_x_error_handler_set(void (*func)(void *data),
33                           const void *data)
34 {
35    _error_func = func;
36    _error_data = (void *)data;
37 }
38 
39 /**
40  * Set the I/O error handler.
41  * @param func The I/O error handler function
42  * @param data The data to be passed to the handler function
43  *
44  * Set the X I/O error handler function
45  */
46 EAPI void
ecore_x_io_error_handler_set(void (* func)(void * data),const void * data)47 ecore_x_io_error_handler_set(void (*func)(void *data),
48                              const void *data)
49 {
50    _io_error_func = func;
51    _io_error_data = (void *)data;
52 }
53 
54 /**
55  * Get the request code that caused the error.
56  * @return The request code causing the X error
57  *
58  * Return the X request code that caused the last X error
59  */
60 EAPI int
ecore_x_error_request_get(void)61 ecore_x_error_request_get(void)
62 {
63    return _error_request_code;
64 }
65 
66 /**
67  * Get the error code from the error.
68  * @return The error code from the X error
69  *
70  * Return the error code from the last X error
71  */
72 //FIXME: Use Ecore_X_Error_Code type when 2.0 is released
73 EAPI int
ecore_x_error_code_get(void)74 ecore_x_error_code_get(void)
75 {
76    return _error_code;
77 }
78 
79 /**
80  * Get the resource id that caused the error.
81  * @return The resource id causing the X error
82  *
83  * Return the X resource id that caused the last X error
84  */
85 EAPI Ecore_X_ID
ecore_x_error_resource_id_get(void)86 ecore_x_error_resource_id_get(void)
87 {
88    return _error_resource_id;
89 }
90 
91 void
_ecore_x_error_handler_init(void)92 _ecore_x_error_handler_init(void)
93 {
94    XSetErrorHandler((XErrorHandler)_ecore_x_error_handle);
95    XSetIOErrorHandler((XIOErrorHandler)_ecore_x_io_error_handle);
96 }
97 
98 static int
_ecore_x_error_handle(Display * d,XErrorEvent * ev)99 _ecore_x_error_handle(Display *d,
100                       XErrorEvent *ev)
101 {
102    if (!_ecore_xlib_sync) goto skip;
103    switch (ev->error_code)
104      {
105       case BadRequest:	/* bad request code */
106         ERR("BadRequest");
107         break;
108       case BadValue:	/* int parameter out of range */
109         ERR("BadValue");
110         break;
111       case BadWindow:	/* parameter not a Window */
112         ERR("BadWindow");
113         break;
114       case BadPixmap:	/* parameter not a Pixmap */
115         ERR("BadPixmap");
116         break;
117       case BadAtom:	/* parameter not an Atom */
118         ERR("BadAtom");
119         break;
120       case BadCursor:	/* parameter not a Cursor */
121         ERR("BadCursor");
122         break;
123       case BadFont:	/* parameter not a Font */
124         ERR("BadFont");
125         break;
126       case BadMatch:	/* parameter mismatch */
127         ERR("BadMatch");
128         break;
129       case BadDrawable:	/* parameter not a Pixmap or Window */
130         ERR("BadDrawable");
131         break;
132       case BadAccess:	/* depending on context */
133         ERR("BadAccess");
134         break;
135       case BadAlloc:	/* insufficient resources */
136         ERR("BadAlloc");
137         break;
138       case BadColor:	/* no such colormap */
139         ERR("BadColor");
140         break;
141       case BadGC:	/* parameter not a GC */
142         ERR("BadGC");
143         break;
144       case BadIDChoice:	/* choice not in range or already used */
145         ERR("BadIDChoice");
146         break;
147       case BadName:	/* font or color name doesn't exist */
148         ERR("BadName");
149         break;
150       case BadLength:	/* Request length incorrect */
151         ERR("BadLength");
152         break;
153       case BadImplementation:	/* server is defective */
154         ERR("BadImplementation");
155         break;
156      }
157 skip:
158    if (d == _ecore_x_disp)
159      {
160         _error_request_code = ev->request_code;
161         _error_code = ev->error_code;
162         _error_resource_id = ev->resourceid;
163         if (_error_func)
164           _error_func(_error_data);
165      }
166    return 0;
167 }
168 
169 static int
_ecore_x_io_error_handle(Display * d)170 _ecore_x_io_error_handle(Display *d)
171 {
172    if (d == _ecore_x_disp)
173      {
174         if (_io_error_func)
175           {
176              _ecore_x_disp = NULL;
177              _ecore_x_shutdown();
178              _io_error_func(_io_error_data);
179           }
180         else
181           exit(-1);
182      }
183 
184    return 0;
185 }
186 
187