Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}