void _xcb_im_handle_destroy_ic(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_destroy_ic_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); do { if (frame.input_method_ID != client->connect_id) { break; } xcb_im_input_context_t* ic = NULL; HASH_FIND(hh, client->input_contexts, &frame.input_context_ID, sizeof(uint16_t), ic); if (!ic) { break; } xcb_im_destroy_ic_reply_fr_t reply_frame; reply_frame.input_method_ID = client->connect_id; reply_frame.input_context_ID = frame.input_context_ID; xcb_im_destroy_ic_fr_free(&frame); _xcb_im_destroy_ic(im, ic); _xcb_im_send_frame(im, client, reply_frame, true); return; } while(0); // error xcb_im_destroy_ic_fr_free(&frame); _xcb_im_send_error_message(im, client); return; }
void _xcb_im_handle_close(xcb_im_t* im, xcb_im_client_table_t* client, const xcb_im_proto_header_t* hdr, uint8_t* data, bool *del) { size_t len = XIM_MESSAGE_BYTES(hdr); close_fr frame; close_fr_read(&frame, &data, &len, client->c.byte_order != im->byte_order); if (!data) { close_fr_free(&frame); return; } if (im->callback) { im->callback(im, &client->c, hdr, &frame, im->user_data); } close_fr_free(&frame); close_reply_fr reply_frame; reply_frame.input_method_ID = frame.input_method_ID; bool fail = true; size_t length = close_reply_fr_size(&reply_frame); uint8_t* reply = _xcb_im_new_message(im, client, XIM_CLOSE_REPLY, 0, length); do { if (!reply) { break; } close_reply_fr_write(&reply_frame, reply + XCB_IM_HEADER_SIZE, client->c.byte_order != im->byte_order); if (!_xcb_im_send_message(im, client, reply, length)) { break; } fail = false; } while(0); free(reply); if (fail) { _xcb_im_send_error_message(im, client); } return; }
void _xcb_im_handle_create_ic(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_create_ic_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); do { if (frame.input_method_ID != client->connect_id) { break; } xcb_im_input_context_t* ic = _xcb_im_new_input_context(im, client); if (!ic) { break; } _xcb_im_parse_ic_values(im, ic, frame.ic_attributes.size, frame.ic_attributes.items); xcb_im_create_ic_reply_fr_t reply_frame; reply_frame.input_method_ID = client->connect_id; reply_frame.input_context_ID = ic->id; if (im->callback) { im->callback(im, client, ic, hdr, &frame, &reply_frame, im->user_data); } _xcb_im_send_frame(im, client, reply_frame, true); if (im->onKeys.nKeys == 0 && im->offKeys.nKeys == 0) { _xcb_im_set_event_mask(im, client, reply_frame.input_context_ID, im->event_mask, ~im->event_mask); } xcb_im_create_ic_fr_free(&frame); return; } while(0); // error xcb_im_create_ic_fr_free(&frame); _xcb_im_send_error_message(im, client); return; }
void _xcb_im_handle_set_ic_values(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_set_ic_values_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); do { if (frame.input_method_ID != client->connect_id) { break; } xcb_im_input_context_t* ic = NULL; HASH_FIND(hh, client->input_contexts, &frame.input_context_ID, sizeof(uint16_t), ic); if (!ic) { break; } _xcb_im_parse_ic_values(im, ic, frame.ic_attribute.size, frame.ic_attribute.items); if (im->callback) { im->callback(im, client, ic, hdr, &frame, NULL, im->user_data); } xcb_im_set_ic_values_fr_free(&frame); xcb_im_set_ic_values_reply_fr_t reply_frame; reply_frame.input_method_ID = client->connect_id; reply_frame.input_context_ID = frame.input_context_ID; _xcb_im_send_frame(im, client, reply_frame, true); return; } while(0); // error xcb_im_set_ic_values_fr_free(&frame); _xcb_im_send_error_message(im, client); return; }
void _xcb_im_handle_get_ic_values(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_get_ic_values_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); do { if (frame.input_method_ID != client->connect_id) { break; } xcb_im_input_context_t* ic = NULL; HASH_FIND(hh, client->input_contexts, &frame.input_context_ID, sizeof(uint16_t), ic); if (!ic) { break; } if (im->callback) { im->callback(im, client, ic, hdr, &frame, NULL, im->user_data); } xcb_im_get_ic_values_reply_fr_t reply_frame; reply_frame.input_method_ID = client->connect_id; reply_frame.input_context_ID = frame.input_context_ID; reply_frame.ic_attribute.size = 0; uint32_t nBuffers = 0; xcb_im_xicattribute_fr_t buffers[ARRAY_SIZE(Default_ICattr)]; memset(buffers, 0, sizeof(buffers)); uint32_t i = 0; while(i < frame.ic_attribute.size) { buffers[nBuffers].attribute_ID = frame.ic_attribute.items[i]; if (frame.ic_attribute.items[i] == im->statusAttr_id) { i = _xcb_im_get_nested_ic_values(im, ic, &ic->status, im->id2statusoffset, frame.ic_attribute.items, i + 1, frame.ic_attribute.size, &buffers[nBuffers]); } else if (frame.ic_attribute.items[i] == im->preeditAttr_id) { i = _xcb_im_get_nested_ic_values(im, ic, &ic->preedit, im->id2preeditoffset, frame.ic_attribute.items, i + 1, frame.ic_attribute.size, &buffers[nBuffers]); } else { const xcb_im_default_ic_attr_t* entry = _xcb_im_default_ic_attr_entry(im, frame.ic_attribute.items[i]); i++; if (!entry) { continue; } if (strcmp(entry->name, XCB_XIM_XNFilterEvents) == 0) { uint32_t result = XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE; buffers[nBuffers].value = malloc(sizeof(uint32_t)); buffers[nBuffers].value_length = sizeof(uint32_t); if (data) { uint32_t_write(&result, buffers[nBuffers].value, im->byte_order != ic->client->byte_order); } } } if (buffers[nBuffers].value) { nBuffers ++; } } reply_frame.ic_attribute.size = nBuffers; reply_frame.ic_attribute.items = buffers; xcb_im_get_ic_values_fr_free(&frame); _xcb_im_send_frame(im, client, reply_frame, true); for (uint32_t i = 0; i < nBuffers; i++) { free(buffers[i].value); } return; } while(0); // error xcb_im_get_ic_values_fr_free(&frame); _xcb_im_send_error_message(im, client); return; }