#include #include #include "lx.h" #include "proto.h" #include "internal.h" typedef struct priv_ListFontsWithInfo PRIV_ListFontsWithInfo; struct priv_ListFontsWithInfo { void (*eachcb)(char *, LX_FONTINFO *); } ; static void done_ListFontsWithInfo(LX_OP *op, const unsigned char *rep, void *pv) { PRIV_ListFontsWithInfo *p; int i; int nfp; int replen; LX_FONTINFO *fi; LX_TEXTDIRECTION td; int allexist; int o; int namelen; char *name; p = pv; do <"done"> { replen = r_card32(rep+4); namelen = rep[1]; if (namelen == 0) { if (replen != 7) { lx__protoerr(op->conn,"ListFontsWithInfo final response length wrong (%u, expected 7)",r_card32(rep+4)); } break <"done">; } if (replen < 7) { lx__protoerr(op->conn,"ListFontsWithInfo response too small (%u, min 7)",r_card32(rep+4)); break <"done">; } nfp = r_card16(rep+46); if (replen != 7+(2*nfp)+((namelen+3)>>2)) { lx__protoerr(op->conn,"ListFontsWithInfo response length wrong (%u, expected %d)",r_card32(rep+4),7+(2*nfp)+((namelen+3)>>2)); break <"done">; } do <"mem"> { name = malloc(namelen+1); if (! name) { lx__nomem_fail(op->conn); break <"done">; } td = lx__proto_to_textdirection(rep[48]); if (td == LX__map_error) { lx__protoerr(op->conn,"ListFontsWithInfo response has bad direction value %d",rep[48]); break <"done">; } switch (rep[51]) { case 0: case 1: allexist = rep[51]; break; default: lx__protoerr(op->conn,"ListFontsWithInfo response has bad all-chars-exist value %d",rep[51]); break <"done">; } 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->ncharinfo = 0; fi->charinfos = 0; 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->lx__priv = 0; (*p->eachcb)(name,fi); op->flags |= LXOF_MORE; return; } while (0); if (fi) { free(fi->propnames); free(fi->propvalues); } lx__nomem_fail(op->conn); break <"done">; } while (0); free(p); } LX_OP *lx_ListFontsWithInfo(LX_CONN *xc, const char *pattern, int max, void (*eachcb)(char *, LX_FONTINFO *)) { unsigned char reqhdr[8]; int patlen; PRIV_ListFontsWithInfo *p; patlen = strlen(pattern); if ((xc->flags & XCF_FAIL) || (max < 0) || (max > 65535) || (patlen > 65535) || !eachcb) { lx__bad_call(xc,"lx_ListFontsWithInfo"); return(0); } lx__nochain(xc); p = malloc(sizeof(PRIV_ListFontsWithInfo)); if (! p) { lx__nomem_fail(xc); return(0); } p->eachcb = eachcb; reqhdr[0] = XP_REQ_ListFontsWithInfo; reqhdr[1] = 0; w_card16(&reqhdr[2],2+((patlen+3)>>2)); w_card16(&reqhdr[4],max); w_card16(&reqhdr[6],patlen); lx__just_send(xc,&reqhdr[0],8); lx__just_send(xc,pattern,patlen); lx__send_padding(xc,patlen); return(lx__expect_reply(xc,0,0,&done_ListFontsWithInfo,p)); }