// Copyright status: this file is in the public domain. #include #include #include #include "lx.h" #include "internal.h" void lx_default_err(void) { } LX_X_ERR_ACTION lx_default_X_err(LX_CONN *xc, const LX_X_ERR *err) { (void)xc; (void)err; lx_default_err(); return(LX_X_ERR_CRASH); } void lx_default_lib_err(LX_CONN *xc, const LX_LIB_ERR *err) { lx_default_err(); lx_lib_err_print(stderr,xc,err); exit(1); } void lx_X_err_print(FILE *to, LX_CONN *xc, const LX_X_ERR *e) { fprintf(to,"X error%s%s%s: ",xc->text?" [":"", xc->text, xc->text?"]":""); #define NOVAL(name,field) \ case LX_XE_##name: \ fprintf(to,"Bad%s, sequence %04x opcode %u.%u\n", \ #name, \ (unsigned int)e->u.field.seq, \ (unsigned int)e->u.field.opc_major, \ (unsigned int)e->u.field.opc_minor); \ break; #define VAL(name,field,valfield,label) \ case LX_XE_##name: \ fprintf(to,"Bad%s, sequence %04x opcode %u.%u: bad %s %08lx\n", \ #name, \ (unsigned int)e->u.field.seq, \ (unsigned int)e->u.field.opc_major, \ (unsigned int)e->u.field.opc_minor, \ label, (unsigned long int)e->u.field.valfield); \ break; switch (e->type) { NOVAL(Request,request) VAL(Value,value,value,"value") VAL(Window,window,id,"window id") VAL(Pixmap,pixmap,id,"pixmap id") VAL(Atom,atom,id,"atom id") VAL(Cursor,cursor,id,"cursor id") VAL(Font,font,id,"font id") NOVAL(Match,match) VAL(Drawable,drawable,id,"drawable id") NOVAL(Access,access) NOVAL(Alloc,alloc) VAL(Colormap,colormap,id,"colormap id") VAL(GContext,gcontext,id,"GC id") VAL(IDChoice,idchoice,id,"id") NOVAL(Name,name) NOVAL(Length,length) NOVAL(Implementation,implementation) case LX_XE_Other: fprintf(to,"type %u, sequence %04x, opcode %u.%u\n", e->u.other.type,e->u.other.seq,e->u.other.opc_major,e->u.other.opc_minor); break; } #undef NOVAL #undef VAL } void lx_lib_err_print(FILE *to, LX_CONN *xc, const LX_LIB_ERR *err) { fprintf(to,"X library error%s%s%s: ",xc->text?" [":"", xc->text, xc->text?"]":""); switch (err->type) { case LX_LE_NOMEM: fprintf(to,"out of memory\n"); break; case LX_LE_SYSERR: fprintf(to,"%s: %s\n",err->u.syserr.call,strerror(err->u.syserr.err)); break; case LX_LE_OSLIBERR: if (err->u.osliberr.msg) { fprintf(to,"%s: %s\n",err->u.osliberr.call,err->u.osliberr.msg); } else { fprintf(to,"%s failed\n",err->u.osliberr.call); } break; case LX_LE_BAD_CALL: fprintf(to,"invalid call to %s\n",err->u.bad_call.fn); break; case LX_LE_NO_DISPLAY: fprintf(to,"no display specified\n"); break; case LX_LE_BAD_DISPLAY: fprintf(to,"invalid display string specified\n"); break; case LX_LE_UNX_EOF: fprintf(to,"unexpected EOF on server connection\n"); break; case LX_LE_ALL_FAIL: fprintf(to,"can't connect: %s\n",err->u.all_fail.msg); break; case LX_LE_PROTO_ERR: fprintf(to,"protocol error: %s\n",err->u.proto_err.msg); break; case LX_LE_REJECTED: fprintf(to,"server rejected connection: %s\n",err->u.rejected.msg); break; default: fprintf(to,"impossible error type %d\n",(int)err->type); break; } } // lx_open depends on this working on an only-partially-set-up LX_CONN. LX_X_ERR_ACTION (*lx_err_set_X(LX_CONN *c, LX_X_ERR_ACTION (*h)(LX_CONN *, const LX_X_ERR *)))(LX_CONN *, const LX_X_ERR *) { LX_X_ERR_ACTION (*prev)(LX_CONN *, const LX_X_ERR *); prev = c->x_err; c->x_err = h ? h : &lx_default_X_err; return(prev); } // lx_open depends on this working on an only-partially-set-up LX_CONN. void (*lx_err_set_lib(LX_CONN *c, void (*h)(LX_CONN *, const LX_LIB_ERR *)))(LX_CONN *, const LX_LIB_ERR *) { void (*prev)(LX_CONN *, const LX_LIB_ERR *); prev = c->lib_err; c->lib_err = h ? h : &lx_default_lib_err; return(prev); }