void _xcb_im_handle_forward_event(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_forward_event_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); do { if (client->connect_id != frame.input_method_ID) { break; } if (XIM_MESSAGE_BYTES(hdr) < xcb_im_forward_event_fr_size(&frame) + sizeof(xcb_key_press_event_t)) { 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 (client->sync) { _xcb_im_add_queue(im, client, ic->id, hdr, &frame, data); } else { xcb_key_press_event_t key_event; memcpy(&key_event, data, sizeof(xcb_key_press_event_t)); if (im->callback) { im->callback(im, client, ic, hdr, &frame, &key_event, im->user_data); } } } while(0); xcb_im_forward_event_fr_free(&frame); }
void _xcb_im_handle_sync_reply(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_sync_reply_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); do { if (client->connect_id != frame.input_method_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; } client->sync = false; if (im->sync) { im->sync = false; if (im->callback) { im->callback(im, client, ic, hdr, &frame, NULL, im->user_data); } } _xcb_im_process_queue(im, client); } while(0); xcb_im_sync_reply_fr_free(&frame); }
void _xcb_im_handle_ext_forward_keyevent(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_ext_forward_keyevent_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); do { if (client->connect_id != frame.input_method_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_key_press_event_t key_event; memset(&key_event, 0, sizeof(key_event)); key_event.response_type = frame.xEvent_u_u_type; key_event.sequence = frame.sequence_number; key_event.root = im->default_screen->root; key_event.time = frame.time; key_event.detail = frame.keycode; key_event.state = frame.state; key_event.event = frame.window; if (im->callback) { im->callback(im, client, ic, hdr, &frame, &key_event, im->user_data); } } while(0); xcb_im_ext_forward_keyevent_fr_free(&frame); }
void _xcb_im_handle_query_extension(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_query_extension_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); int nExts = 0; xcb_im_ext_fr_t ext_list[ARRAY_SIZE(Default_Extension)]; for (size_t i = 0; i < frame.extensions_supported_by_the_IM_library.size; i++) { for (size_t j = 0; j < ARRAY_SIZE(Default_Extension); j ++) { if (frame.extensions_supported_by_the_IM_library.items[i].length_of_string == im->extension[j].length_of_extension_name && strncmp((char*) frame.extensions_supported_by_the_IM_library.items[i].string, (char*) im->extension[j].extension_name, frame.extensions_supported_by_the_IM_library.items[i].length_of_string) == 0) { ext_list[nExts] = im->extension[j]; nExts ++; break; } } } xcb_im_query_extension_fr_free(&frame); xcb_im_query_extension_reply_fr_t reply_frame; reply_frame.input_method_ID = client->connect_id; reply_frame.list_of_extensions_supported_by_th.items = ext_list; reply_frame.list_of_extensions_supported_by_th.size = nExts; _xcb_im_send_frame(im, client, reply_frame, true); }
void _xcb_im_handle_open(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_open_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); if (im->callback) { im->callback(im, client, NULL, hdr, &frame, NULL, im->user_data); } xcb_im_open_fr_free(&frame); /*endif*/ if (im->onKeys.nKeys || im->offKeys.nKeys) { _xcb_im_send_trigger_key(im, client); } xcb_im_open_reply_fr_t reply_frame; reply_frame.input_method_ID = client->connect_id; reply_frame.IM_attribute_supported.size = ARRAY_SIZE(im->imattr); reply_frame.IC_attribute_supported.size = ARRAY_SIZE(im->icattr); reply_frame.IM_attribute_supported.items = im->imattr; reply_frame.IC_attribute_supported.items = im->icattr; _xcb_im_send_frame(im, client, reply_frame, true); }
void _xcb_im_handle_open(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); open_fr frame; open_fr_read(&frame, &data, &len, client->c.byte_order != im->byte_order); if (!data) { open_fr_free(&frame); return; } if (im->callback) { im->callback(im, &client->c, hdr, &frame, im->user_data); } open_fr_free(&frame); /*endif*/ if (im->onKeys.nKeys || im->offKeys.nKeys) { _xcb_im_send_trigger_key(im, client); } open_reply_fr reply_frame; reply_frame.input_method_ID = client->c.connect_id; reply_frame.IM_attribute_supported.size = ARRAY_SIZE(im->imattr); reply_frame.IC_attribute_supported.size = ARRAY_SIZE(im->icattr); reply_frame.IM_attribute_supported.items = im->imattr; reply_frame.IC_attribute_supported.items = im->icattr; xim_send_frame(reply_frame, open_reply_fr, XIM_OPEN_REPLY); }
void _xcb_im_handle_connect(xcb_im_t* im, xcb_im_client_table_t* client, const xcb_im_proto_header_t* hdr, uint8_t* data) { size_t len = XIM_MESSAGE_BYTES(hdr); connect_fr frame; connect_fr_read(&frame, &data, &len, client->c.byte_order != im->byte_order); if (!data) { connect_fr_free(&frame); return; } if (im->callback) { im->callback(im, &client->c, hdr, &frame, im->user_data); } connect_fr_free(&frame); connect_reply_fr reply_frame; reply_frame.server_major_protocol_version = frame.client_major_protocol_version; reply_frame.server_minor_protocol_version = frame.client_minor_protocol_version; xim_send_frame(reply_frame, connect_reply_fr, XIM_CONNECT_REPLY); return; }
void _xcb_im_handle_create_ic(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); create_ic_fr frame; create_ic_fr_read(&frame, &data, &len, client->c.byte_order != im->byte_order); if (!data) { create_ic_fr_free(&frame); return; } // TODO create_ic_fr_free(&frame); /* create_ic_reply_fr reply_frame; reply_frame.input_method_ID = client->c.connect_id; xim_send_frame(reply_frame, create_ic_reply_fr, XIM_CREATE_IC_REPLY); if (im->onKeys.nKeys == 0 && im->offKeys.nKeys == 0) { _xcb_im_set_event_mask(im, client, icid, im->event_mask, ~im->event_mask); }*/ }
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_reset_ic(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_reset_ic_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); do { if (client->connect_id != frame.input_method_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_reset_ic_reply_fr_t reply_frame; reply_frame.input_method_ID = frame.input_method_ID; reply_frame.input_context_ID = frame.input_context_ID; reply_frame.committed_string = NULL; reply_frame.byte_length_of_committed_string = 0; if (im->callback) { im->callback(im, client, ic, hdr, &frame, &reply_frame, im->user_data); } _xcb_im_send_frame(im, client, reply_frame, true); free(reply_frame.committed_string); } while(0); xcb_im_reset_ic_fr_free(&frame); }
void _xcb_im_handle_get_im_values(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); get_im_values_fr frame; get_im_values_fr_read(&frame, &data, &len, client->c.byte_order != im->byte_order); if (!data) { get_im_values_fr_free(&frame); return; } get_im_values_reply_fr reply_frame; size_t nBuffers = 0; ximattribute_fr buffers[ARRAY_SIZE(Default_IMattr)]; for (size_t i = 0; i < frame.im_attribute_id.size; i++) { if (frame.im_attribute_id.items[i] >= ARRAY_SIZE(im->id2attr)) { continue; } ximattr_fr* attr = im->id2attr[frame.im_attribute_id.items[i]]; if ((attr < im->imattr) || (attr >= im->imattr + ARRAY_SIZE(Default_IMattr))) { continue; } // TODO, now we only have one attribute, so no check is needed here // in the future this can be a function pointer input_styles_fr fr; fr.XIMStyle_list.size = im->inputStyles.nStyles; fr.XIMStyle_list.items = calloc(im->inputStyles.nStyles, sizeof(inputstyle_fr)); for (size_t j = 0; j < im->inputStyles.nStyles; j ++) { fr.XIMStyle_list.items[j].inputstyle = im->inputStyles.styles[j]; } buffers[nBuffers].attribute_ID = frame.im_attribute_id.items[i]; buffers[nBuffers].value = malloc(input_styles_fr_size(&fr)); buffers[nBuffers].value_length = input_styles_fr_size(&fr); input_styles_fr_write(&fr, buffers[nBuffers].value, client->c.byte_order != im->byte_order); input_styles_fr_free(&fr); nBuffers++; } reply_frame.input_method_ID = client->c.connect_id; reply_frame.im_attribute_returned.items = buffers; reply_frame.im_attribute_returned.size = nBuffers; get_im_values_fr_free(&frame); xim_send_frame(reply_frame, get_im_values_reply_fr, XIM_GET_IM_VALUES_REPLY); for (size_t i = 0; i < nBuffers; i++) { free(buffers[i].value); } }
void _xcb_im_handle_get_im_values(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_get_im_values_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); xcb_im_get_im_values_reply_fr_t reply_frame; size_t nBuffers = 0; xcb_im_ximattribute_fr_t buffers[ARRAY_SIZE(Default_IMattr)]; bool met[ARRAY_SIZE(Default_IMattr)]; memset(met, 0, sizeof(met)); for (size_t i = 0; i < frame.im_attribute_id.size; i++) { if (frame.im_attribute_id.items[i] >= ARRAY_SIZE(im->id2attr)) { continue; } xcb_im_ximattr_fr_t* attr = im->id2attr[frame.im_attribute_id.items[i]]; if ((attr < im->imattr) || (attr >= im->imattr + ARRAY_SIZE(Default_IMattr))) { continue; } if (met[attr - im->imattr]) { continue; } if (!Default_IMattr[attr - im->imattr].get_value) { continue; } if (!Default_IMattr[attr - im->imattr].get_value(im, client, &buffers[nBuffers])) { continue; } buffers[nBuffers].attribute_ID = frame.im_attribute_id.items[i]; met[attr - im->imattr] = true; nBuffers++; } reply_frame.input_method_ID = client->connect_id; reply_frame.im_attribute_returned.items = buffers; reply_frame.im_attribute_returned.size = nBuffers; xcb_im_get_im_values_fr_free(&frame); _xcb_im_send_frame(im, client, reply_frame, true); for (size_t i = 0; i < nBuffers; i++) { free(buffers[i].value); } }
void _xcb_im_handle_trigger_notify(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_trigger_notify_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); do { if (client->connect_id != frame.input_method_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_trigger_notify_reply_fr_t reply_frame; reply_frame.input_method_ID = frame.input_method_ID; reply_frame.input_context_ID = frame.input_context_ID; /* NOTE: * XIM_TRIGGER_NOTIFY_REPLY should be sent before XIM_SET_EVENT_MASK * in case of XIM_TRIGGER_NOTIFY(flag == ON), while it should be * sent after XIM_SET_EVENT_MASK in case of * XIM_TRIGGER_NOTIFY(flag == OFF). */ if (frame.flag == 0) { _xcb_im_send_frame(im, client, reply_frame, false); xcb_im_preedit_start(im, ic); } if (im->callback) { im->callback(im, client, ic, hdr, &frame, NULL, im->user_data); } if (frame.flag == 1) { xcb_im_preedit_end(im, ic); _xcb_im_send_frame(im, client, reply_frame, false); } } while(0); xcb_im_trigger_notify_fr_free(&frame); }
void _xcb_im_handle_close(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_close_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); if (im->callback) { im->callback(im, client, NULL, hdr, &frame, NULL, im->user_data); } xcb_im_close_fr_free(&frame); xcb_im_close_reply_fr_t reply_frame; reply_frame.input_method_ID = frame.input_method_ID; _xcb_im_send_frame(im, client, reply_frame, true); return; }
void _xcb_im_handle_preedit_caret_reply(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); preedit_caret_reply_fr frame; preedit_caret_reply_fr_read(&frame, &data, &len, client->c.byte_order != im->byte_order); if (!data) { preedit_caret_reply_fr_free(&frame); return; } if (im->callback) { im->callback(im, &client->c, hdr, &frame, im->user_data); } preedit_caret_reply_fr_free(&frame); }
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_connect(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_connect_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); if (im->callback) { im->callback(im, client, NULL, hdr, &frame, NULL, im->user_data); } xcb_im_connect_fr_free(&frame); xcb_im_connect_reply_fr_t reply_frame; reply_frame.server_major_protocol_version = frame.client_major_protocol_version; reply_frame.server_minor_protocol_version = frame.client_minor_protocol_version; _xcb_im_send_frame(im, client, reply_frame, true); return; }
void _xcb_im_handle_encoding_negotiation(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); encoding_negotiation_fr frame; encoding_negotiation_fr_read(&frame, &data, &len, client->c.byte_order != im->byte_order); if (!data) { encoding_negotiation_fr_free(&frame); return; } size_t i, j; for (i = 0; i < frame.supported_list_of_encoding_in_IM_library.size; i++) { for (j = 0; j < im->encodings.nEncodings; j ++) { if (strcmp((char*) frame.supported_list_of_encoding_in_IM_library.items[i].string, im->encodings.encodings[j]) == 0) { break; } } if (j != im->encodings.nEncodings) { break; } } // no match then we use 0. if (i == frame.supported_list_of_encoding_in_IM_library.size) { i = 0; } encoding_negotiation_fr_free(&frame); encoding_negotiation_reply_fr reply_frame; reply_frame.input_method_ID = client->c.connect_id; reply_frame.index_of_the_encoding_dterminated = i; reply_frame.category_of_the_encoding_determined = 0; xim_send_frame(reply_frame, encoding_negotiation_reply_fr, XIM_ENCODING_NEGOTIATION_REPLY); }
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_ext_move(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_ext_move_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); do { if (client->connect_id != frame.input_method_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; } ic->preedit.spot_location.x = frame.X; ic->preedit.spot_location.y = frame.Y; } while(0); xcb_im_ext_move_fr_free(&frame); }
void _xcb_im_handle_query_extension(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); query_extension_fr frame; query_extension_fr_read(&frame, &data, &len, client->c.byte_order != im->byte_order); if (!data) { query_extension_fr_free(&frame); return; } int nExts = 0; ext_fr ext_list[ARRAY_SIZE(Default_Extension)]; for (size_t i = 0; i < frame.extensions_supported_by_the_IM_library.size; i++) { for (size_t j = 0; j < ARRAY_SIZE(Default_Extension); j ++) { if (frame.extensions_supported_by_the_IM_library.items[i].length_of_string == im->extension[j].length_of_extension_name && strcmp((char*) frame.extensions_supported_by_the_IM_library.items[i].string, (char*) im->extension[j].extension_name) == 0) { ext_list[nExts] = im->extension[j]; nExts ++; break; } } } query_extension_fr_free(&frame); query_extension_reply_fr reply_frame; reply_frame.input_method_ID = client->c.connect_id; reply_frame.list_of_extensions_supported_by_th.items = ext_list; reply_frame.list_of_extensions_supported_by_th.size = nExts; xim_send_frame(reply_frame, query_extension_reply_fr, XIM_QUERY_EXTENSION_REPLY); }
void _xcb_im_handle_encoding_negotiation(xcb_im_t* im, xcb_im_client_t* client, const xcb_im_packet_header_fr_t* hdr, uint8_t* data) { xcb_im_encoding_negotiation_fr_t frame; _xcb_im_read_frame_with_error(im, client, frame, data, XIM_MESSAGE_BYTES(hdr)); size_t i, j; for (i = 0; i < frame.supported_list_of_encoding_in_IM_library.size; i++) { for (j = 0; j < im->encodings.nEncodings; j ++) { if (frame.supported_list_of_encoding_in_IM_library.items[i].length_of_string == strlen(im->encodings.encodings[j]) && strncmp((char*) frame.supported_list_of_encoding_in_IM_library.items[i].string, im->encodings.encodings[j], frame.supported_list_of_encoding_in_IM_library.items[i].length_of_string) == 0) { break; } } if (j != im->encodings.nEncodings) { break; } } // no match then we use 0. if (i == frame.supported_list_of_encoding_in_IM_library.size) { i = 0; } xcb_im_encoding_negotiation_fr_free(&frame); xcb_im_encoding_negotiation_reply_fr_t reply_frame; reply_frame.input_method_ID = client->connect_id; reply_frame.index_of_the_encoding_determined = i; reply_frame.category_of_the_encoding_determined = 0; _xcb_im_send_frame(im, client, reply_frame, true); }
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; }