// Copyright status: this file is in the public domain. #include #include #include "lx.h" #include "proto.h" #include "internal.h" LX_XID lx_SGC_GC(LX_CONN *xc, LX_SGC sgcid) { SGC *sgc; union { unsigned char cre[108]; unsigned char chg[104]; } req; unsigned int protomask; int o; unsigned char *rqp; unsigned char *maskp; unsigned char opc; int need_set_dashes; int ndash; unsigned char *dashv; unsigned int offset; if (xc->flags & XCF_FAIL) { lx__bad_call(xc,"lx_SGC_GC"); return(LX_GC_None); } sgc = lx__lookup_sgc(xc,sgcid); if (! sgc) { lx__bad_call(xc,"lx_SGC_GC"); return(LX_GC_None); } if (sgc->gcid == LX_GC_None) { opc = XP_REQ_CreateGC; o = 16; rqp = &req.cre[0]; } else { opc = XP_REQ_ChangeGC; o = 12; rqp = &req.chg[0]; } maskp = &rqp[o-4]; protomask = 0; need_set_dashes = 0; if (sgc->setv.nrect >= 0) { // If setv.nrect>=0, we know clip_[xy]_origin are also set if (! (sgc->set & LX_GCM_ClipMask)) { lx_SetClipRectangles(xc, sgc->gcid, sgc->setv.core.clip_x_origin, sgc->setv.core.clip_y_origin, sgc->setv.nrect, sgc->setv.rectv, sgc->setv.rectord); sgc->pushv.core.clip_x_origin = sgc->setv.core.clip_x_origin; sgc->pushv.core.clip_y_origin = sgc->setv.core.clip_y_origin; sgc->set &= ~(LX_GCM_ClipXOrigin | LX_GCM_ClipYOrigin); } free(sgc->setv.rectv); sgc->setv.rectv = 0; sgc->setv.nrect = -1; } #define SIMPLE(name,type,suf,bit,field)\ if (sgc->set & LX_GCM_##name) \ { sgc->set &= ~LX_GCM_##name; \ if (sgc->setv.core.field != sgc->pushv.core.field) \ { sgc->pushv.core.field = sgc->setv.core.field; \ protomask |= bit; \ w_card32(&rqp[o],sgc->pushv.core.field); \ o += 4; \ } \ } #define MAPPED(name,converter,bit,field)\ if (sgc->set & LX_GCM_##name) \ { int v; \ sgc->set &= ~LX_GCM_##name; \ if (sgc->setv.core.field != sgc->pushv.core.field) \ { v = converter(sgc->setv.core.field); \ if (v < 0) \ { lx_abort(); \ return(LX_GC_None); \ } \ sgc->pushv.core.field = sgc->setv.core.field; \ protomask |= bit; \ w_card32(&rqp[o],v); \ o += 4; \ } \ } #define GRAPHICSEXPOSURES(name,type,suf,bit,field) SIMPLE(name,type,suf,bit,field); #define CLIPMASK(name,type,suf,bit,field)\ if (sgc->set & LX_GCM_##name) \ { sgc->set &= ~LX_GCM_##name; \ if (sgc->setv.core.field != sgc->pushv.core.field) \ { sgc->pushv.core.field = sgc->setv.core.field; \ protomask |= bit; \ w_card32(&rqp[o],(sgc->setv.core.field==LX_GCCLIPMASK_None)?0:sgc->setv.core.field);\ o += 4; \ } \ } // This code works only if Dashes is right after DashOffset, so... #if LX_GCM_Dashes != (LX_GCM_DashOffset << 1) #error "Dash code here needs fixing" #endif #define DASHES(name,type,suf,bit,field)\ if (sgc->set & LX_GCM_Dashes) \ { sgc->set &= ~LX_GCM_Dashes; \ if ( (sgc->setv.ndash != sgc->pushv.ndash) || \ bcmp(sgc->setv.dashv,sgc->pushv.dashv,sgc->pushv.ndash) )\ { if (lx__set_sgc_dash_list_len(&sgc->pushv,sgc->setv.ndash))\ { lx__nomem_fail(xc); \ return(LX_GC_None); \ } \ bcopy(sgc->setv.dashv,sgc->pushv.dashv,sgc->setv.ndash);\ if (sgc->pushv.ndash != 1) \ { need_set_dashes = 1; \ if (protomask & LX_GCM_DashOffset) \ { o -= 4; \ protomask &= ~LX_GCM_DashOffset; \ } \ offset = sgc->pushv.core.dash_offset; \ ndash = sgc->pushv.ndash; \ dashv = sgc->pushv.dashv; \ } \ else \ { protomask |= LX_GCM_Dashes; \ w_card32(&rqp[o],sgc->pushv.dashv[0]); \ } \ } \ } GCFIELDS #undef SIMPLE #undef MAPPED #undef GRAPHICSEXPOSURES #undef CLIPMASK #undef DASHES if (protomask || (opc == XP_REQ_CreateGC)) { lx__nochain(xc); switch (opc) { case XP_REQ_CreateGC: sgc->gcid = lx__new_resource_id(xc); w_card32(&rqp[8],sgc->drawable); break; case XP_REQ_ChangeGC: break; default: lx_abort(); return(LX_XID_Error); break; } rqp[0] = opc; rqp[1] = 0; w_card16(&rqp[2],o>>2); w_card32(&rqp[4],sgc->gcid); w_card32(maskp,protomask); lx__send_req(xc,rqp,o); } if (need_set_dashes) { lx_SetDashes(xc,sgc->gcid,offset,ndash,dashv); } return(sgc->gcid); }