/* send an attention. this may get called at any time, so we can't use * DSI buffers to send one. return 0 on error */ int dsi_attention(DSI *dsi, AFPUserBytes flags) { /* header + AFPUserBytes */ char block[DSI_BLOCKSIZ + sizeof(AFPUserBytes)]; u_int32_t len, nlen; u_int16_t id; if (dsi->flags & DSI_SLEEPING) return 1; if (dsi->in_write) { return -1; } id = htons(dsi_serverID(dsi)); flags = htons(flags); len = MIN(sizeof(flags), dsi->attn_quantum); nlen = htonl(len); memset(block, 0, sizeof(block)); block[0] = DSIFL_REQUEST; /* sending a request */ block[1] = DSIFUNC_ATTN; /* it's an attention */ memcpy(block + 2, &id, sizeof(id)); /* code = 0 */ memcpy(block + 8, &nlen, sizeof(nlen)); memcpy(block + 16, &flags, sizeof(flags)); /* reserved = 0 */ /* send an attention */ return dsi_stream_write(dsi, block, DSI_BLOCKSIZ + len, DSI_NOWAIT); }
void dsi_close(DSI *dsi) { /* server generated. need to set all the fields. */ if (!(dsi->flags & DSI_SLEEPING) && !(dsi->flags & DSI_DISCONNECTED)) { dsi->header.dsi_flags = DSIFL_REQUEST; dsi->header.dsi_command = DSIFUNC_CLOSE; dsi->header.dsi_requestID = htons(dsi_serverID(dsi)); dsi->header.dsi_code = dsi->header.dsi_reserved = htonl(0); dsi->cmdlen = 0; dsi_send(dsi); dsi->proto_close(dsi); } free(dsi); }
/* server generated tickles. as this is only called by the tickle handler, * we don't need to block signals. */ int dsi_tickle(DSI *dsi) { char block[DSI_BLOCKSIZ]; uint16_t id; if ((dsi->flags & DSI_SLEEPING) || dsi->in_write) return 1; id = htons(dsi_serverID(dsi)); memset(block, 0, sizeof(block)); block[0] = DSIFL_REQUEST; block[1] = DSIFUNC_TICKLE; memcpy(block + 2, &id, sizeof(id)); /* code = len = reserved = 0 */ return dsi_stream_write(dsi, block, DSI_BLOCKSIZ, DSI_NOWAIT); }