#include #include "lx.h" #include "proto.h" #include "internal.h" typedef struct priv_QueryFont PRIV_QueryFont; struct priv_QueryFont { LX_FONTINFO **infop; } ; static void done_QueryFont(LX_OP *op, const unsigned char *rep) { PRIV_QueryFont *p; int i; int nfp; int nci; int replen; LX_FONTINFO *fi; LX_TEXTDIRECTION td; int allexist; int o; p = op->reqpriv; do <"ret"> { replen = r_card32(rep+4); if (replen < 7) { lx__protoerr(op->conn,"QueryFont response too small (%u, min 7)",r_card32(rep+4)); break <"ret">; } nfp = r_card16(rep+46); nci = r_card32(rep+56); if (replen != 7+(2*nfp)+(3*nci)) { lx__protoerr(op->conn,"QueryFont response length wrong (%u, expected %d)",r_card32(rep+4),7+(2*nfp)+(3*nci)); break <"ret">; } if (p->infop) { do <"good"> { td = lx__proto_to_textdirection(rep[48]); if (td == LX__TEXTDIRECTION_Error) { lx__protoerr(op->conn,"QueryFont response has bad direction value %d",rep[48]); break <"ret">; } switch (rep[51]) { case 0: case 1: allexist = rep[51]; break; default: lx__protoerr(op->conn,"QueryFont response has bad all-chars-exist value %d",rep[51]); break <"ret">; } do <"mem"> { fi = malloc(sizeof(LX_FONTINFO)); if (! fi) break <"mem">; fi->propnames = 0; fi->propvalues = 0; fi->charinfos = 0; fi->propnames = malloc(nfp*sizeof(LX_XID)); if (! fi->propnames) break <"mem">; fi->propvalues = malloc(nfp*sizeof(LX_XID)); if (! fi->propvalues) break <"mem">; fi->charinfos = malloc(nci*sizeof(LX_XID)); if (! fi->charinfos) break <"mem">; lx__grab_charinfo(&fi->minbounds,rep+8); lx__grab_charinfo(&fi->maxbounds,rep+24); fi->mincb2 = r_card16(rep+40); fi->maxcb2 = r_card16(rep+42); fi->defchar = r_card16(rep+44); fi->dir = td; fi->minb1 = rep[49]; fi->maxb1 = rep[50]; fi->all_chars_exist = allexist; fi->font_ascent = r_int16(rep+52); fi->font_descent = r_int16(rep+54); o = 60; fi->nprops = nfp; for (i=0;ipropnames[i] = r_card32(rep+o); fi->propvalues[i] = r_card32(rep+o+4); o += 8; } fi->ncharinfo = nci; for (i=0;icharinfos+i,rep+o); o += 12; } fi->lx__priv = 0; break <"good">; } while (0); if (fi) { free(fi->propnames); free(fi->propvalues); free(fi->charinfos); } lx__nomem_fail(op->conn); break <"ret">; } while (0); } } while (0); op->reqpriv = 0; free(p); } LX_OP *lx_QueryFont(LX_CONN *xc, LX_XID fontable, LX_FONTINFO **infop) { unsigned char req[8]; PRIV_QueryFont *p; if (xc->flags & XCF_FAIL) { lx__bad_call(xc,"lx_QueryFont"); return(0); } p = malloc(sizeof(PRIV_QueryFont)); if (! p) { lx__nomem_fail(xc); return(0); } p->infop = infop; req[0] = XP_REQ_QueryFont; req[1] = 0; w_card16(&req[2],2); w_card32(&req[4],fontable); return(lx__expect_reply(xc,&req[0],-1,&done_QueryFont,p,0)); }