// Copyright status: this file is in the public domain. #include #include #include "lx.h" #include "proto.h" #include "internal.h" void lx_ChangeProperty(LX_CONN *xc, LX_XID window, LX_ATOM property, LX_ATOM type, int format, LX_PROPERTYMODE mode, const void *data, int len) { int reqlen; unsigned char *req; int ushift; int proto_mode; int i; lx__nochain(xc); do <"badcall"> { // 65535*4 is a conservative maximum which also ensures no arithmetic overflow below. if ((xc->flags & XCF_FAIL) || (len < 0) || (len > 65535*4)) break <"badcall">; proto_mode = lx__propertymode_to_proto(mode); if (proto_mode < 0) break <"badcall">; switch (format) { case 8: ushift = 0; break; case 16: ushift = 1; break; case 32: ushift = 2; break; default: break <"badcall">; } reqlen = 6 + (((len << ushift) + 3) >> 2); if (reqlen > 65535) break <"badcall">; req = malloc(reqlen<<2); if (! req) { lx__nomem_fail(xc); return; } req[0] = XP_REQ_ChangeProperty; req[1] = proto_mode; w_card16(&req[2],reqlen); w_card32(&req[4],window); w_card32(&req[8],property); w_card32(&req[12],type); req[16] = format; req[17] = 0; // unused req[18] = 0; // unused req[19] = 0; // unused w_card32(&req[20],len); switch (format) { case 8: bcopy(data,req+24,len); if (len & 3) bzero(req+24+len,4-(len&3)); // padding break; case 16: for (i=len-1;i>=0;i--) w_card16(req+24+(2*i),((const CARD16 *)data)[i]); if (len & 1) w_card16(req+24+(2*len),0); // padding break; case 32: for (i=len-1;i>=0;i--) w_card32(req+24+(4*i),((const CARD32 *)data)[i]); break; default: lx_abort(); break; } lx__send_req(xc,&req[0],reqlen<<2); return; } while (0); lx__bad_call(xc,"lx_ChangeProperty"); }