strans/xim/xcb-imdkit/src/imdkit_p.h
2025-12-23 20:21:56 +09:00

293 lines
11 KiB
C

/*
* SPDX-FileCopyrightText: 2014 Weng Xuetian <wengxt@gmail.com>
*
* SPDX-License-Identifier: LGPL-2.1-only
*
*/
#ifndef _XCB_IMDKIT_IMDKIT_P_H_
#define _XCB_IMDKIT_IMDKIT_P_H_
#include "common.h"
#include "imdkit.h"
#include "list.h"
#include "message.h"
#include "uthash.h"
#include "ximproto_p.h"
#define LOCALES_BUFSIZE (sizeof(XCB_IM_ALL_LOCALES) + 32)
/*
* values for the flag of XIM_ERROR
*/
#define XIM_IMID_VALID 0x0001
#define XIM_ICID_VALID 0x0002
/*
* XIM Error Code
*/
#define XIM_BadAlloc 1
#define XIM_BadStyle 2
#define XIM_BadClientWindow 3
#define XIM_BadFocusWindow 4
#define XIM_BadArea 5
#define XIM_BadSpotLocation 6
#define XIM_BadColormap 7
#define XIM_BadAtom 8
#define XIM_BadPixel 9
#define XIM_BadPixmap 10
#define XIM_BadName 11
#define XIM_BadCursor 12
#define XIM_BadProtocol 13
#define XIM_BadForeground 14
#define XIM_BadBackground 15
#define XIM_LocaleNotSupported 16
#define XIM_BadSomething 999
/*
* byte order
*/
#define BIGENDIAN (CARD8)0x42 /* MSB first */
#define LITTLEENDIAN (CARD8)0x6c /* LSB first */
/*
* values for the category of XIM_ENCODING_NEGOTIATON_REPLY
*/
#define XIM_Encoding_NameCategory 0
#define XIM_Encoding_DetailCategory 1
/*
* value for the index of XIM_ENCODING_NEGOTIATON_REPLY
*/
#define XIM_Default_Encoding_IDX -1
#define _xcb_im_read_frame_with_error(IM, CLIENT, FRAME, DATA, LEN) \
do { \
size_t len = (LEN); \
frame_read_func(FRAME)(&FRAME, &DATA, &len, \
(CLIENT)->byte_order != (IM)->byte_order); \
if (!DATA) { \
frame_free_func(FRAME)(&FRAME); \
_xcb_im_send_error_message((IM), (CLIENT)); \
return; \
} \
} while (0)
#define _xcb_im_read_frame(IM, CLIENT, FRAME, DATA, LEN) \
do { \
size_t len = (LEN); \
frame_read_func(FRAME)(&FRAME, &DATA, &len, \
(CLIENT)->byte_order != (IM)->byte_order); \
if (!DATA) { \
frame_free_func(FRAME)(&FRAME); \
return; \
} \
} while (0)
#define _xcb_im_send_frame(IM, CLIENT, FRAME, SEND_ERROR) \
do { \
bool fail = true; \
bool swap = (CLIENT)->byte_order != (IM)->byte_order; \
size_t length = frame_size_func(FRAME); \
uint8_t *reply; \
uint8_t *alloc_reply = NULL; \
uint8_t \
static_reply[XCB_IM_HEADER_SIZE + (frame_has_static_size(FRAME) \
? frame_size_func(FRAME) \
: 1)]; \
if (frame_has_static_size(FRAME)) { \
reply = static_reply; \
_xcb_write_xim_message_header( \
reply, XIM_PROTO_FRAME_OPCODE(FRAME), 0, length, swap); \
} else { \
reply = _xcb_new_xim_message(XIM_PROTO_FRAME_OPCODE(FRAME), 0, \
length, swap); \
alloc_reply = reply; \
} \
do { \
if (!reply) { \
break; \
} \
frame_write_func(FRAME)(&(FRAME), reply + XCB_IM_HEADER_SIZE, \
swap); \
if (!_xcb_im_send_message((IM), (CLIENT), reply, length)) { \
break; \
} \
fail = false; \
} while (0); \
free(alloc_reply); \
if ((SEND_ERROR) && fail) { \
_xcb_im_send_error_message((IM), (CLIENT)); \
} \
} while (0)
struct _xcb_im_input_context_t {
uint16_t id;
xcb_im_client_t *client;
uint32_t input_style;
xcb_window_t client_win;
xcb_window_t focus_win;
xcb_im_preedit_attr_t preedit;
uint32_t preedit_mask;
xcb_im_status_attr_t status;
uint32_t status_mask;
UT_hash_handle hh;
void *data;
xcb_im_free_function free_data_function;
uint16_t forward_event_sequence;
};
struct _xcb_im_client_t {
xcb_window_t accept_win;
int connect_id;
xcb_window_t client_win;
uint8_t byte_order;
bool sync;
uint16_t icid;
xcb_im_input_context_t *ic_free_list;
xcb_im_input_context_t *input_contexts;
list_head queue;
xcb_im_property_offset_t *offsets;
UT_hash_handle hh1;
UT_hash_handle hh2;
};
typedef struct _xcb_im_default_im_attr_t {
char *name;
uint16_t type;
bool (*get_value)(xcb_im_t *im, xcb_im_client_t *client,
xcb_im_ximattribute_fr_t *attr);
} xcb_im_default_im_attr_t;
bool _xcb_im_get_input_styles_attr(xcb_im_t *im, xcb_im_client_t *client,
xcb_im_ximattribute_fr_t *attr);
static const xcb_im_default_im_attr_t Default_IMattr[] = {
{XCB_XIM_XNQueryInputStyle, XimType_XIMStyles,
_xcb_im_get_input_styles_attr},
/* {XCB_XIM_XNQueryIMValuesList, XimType_XIMValuesList}, */
};
typedef struct _xcb_im_default_ic_attr_t {
char *name;
uint16_t type;
bool read;
} xcb_im_default_ic_attr_t;
static const xcb_im_default_ic_attr_t Default_ICattr[] = {
{XCB_XIM_XNInputStyle, XimType_CARD32, false},
{XCB_XIM_XNClientWindow, XimType_Window, false},
{XCB_XIM_XNFocusWindow, XimType_Window, false},
{XCB_XIM_XNFilterEvents, XimType_CARD32, false},
{XCB_XIM_XNPreeditAttributes, XimType_NEST, false},
{XCB_XIM_XNStatusAttributes, XimType_NEST, false},
{XCB_XIM_XNFontSet, XimType_XFontSet, false},
{XCB_XIM_XNArea, XimType_XRectangle, true},
{XCB_XIM_XNAreaNeeded, XimType_XRectangle, true},
{XCB_XIM_XNColormap, XimType_CARD32, false},
{XCB_XIM_XNStdColormap, XimType_CARD32, false},
{XCB_XIM_XNForeground, XimType_CARD32, true},
{XCB_XIM_XNBackground, XimType_CARD32, true},
{XCB_XIM_XNBackgroundPixmap, XimType_CARD32, false},
{XCB_XIM_XNSpotLocation, XimType_XPoint, true},
{XCB_XIM_XNLineSpace, XimType_CARD32, true},
{XCB_XIM_XNSeparatorofNestedList, XimType_SeparatorOfNestedList, false},
};
struct _xcb_im_t {
xcb_connection_t *conn;
xcb_im_ximattr_fr_t imattr[ARRAY_SIZE(Default_IMattr)];
xcb_im_xicattr_fr_t icattr[ARRAY_SIZE(Default_ICattr)];
xcb_im_ext_fr_t extension[ARRAY_SIZE(Default_Extension)];
uint16_t preeditAttr_id;
uint16_t statusAttr_id;
uint16_t separatorAttr_id;
xcb_im_ximattr_fr_t
*id2attr[ARRAY_SIZE(Default_IMattr) + ARRAY_SIZE(Default_ICattr)];
ssize_t id2preeditoffset[ARRAY_SIZE(Default_IMattr) +
ARRAY_SIZE(Default_ICattr)];
uint32_t
id2preeditmask[ARRAY_SIZE(Default_IMattr) + ARRAY_SIZE(Default_ICattr)];
ssize_t id2statusoffset[ARRAY_SIZE(Default_IMattr) +
ARRAY_SIZE(Default_ICattr)];
uint32_t
id2statusmask[ARRAY_SIZE(Default_IMattr) + ARRAY_SIZE(Default_ICattr)];
ssize_t
id2icoffset[ARRAY_SIZE(Default_IMattr) + ARRAY_SIZE(Default_ICattr)];
uint32_t event_mask;
xcb_im_trigger_keys_t onKeys;
xcb_im_trigger_keys_t offKeys;
xcb_im_styles_t inputStyles;
xcb_im_encodings_t encodings;
char *locale;
char *serverName;
xcb_window_t serverWindow;
int screen_id;
xcb_atom_t atoms[XIM_ATOM_LAST];
xcb_im_client_t *free_list;
xcb_im_client_t *clients_by_id;
xcb_im_client_t *clients_by_win;
uint16_t connect_id;
xcb_screen_t *screen;
xcb_screen_t *default_screen;
uint32_t sequence;
xcb_im_callback callback;
void *user_data;
void (*logger)(const char *, ...);
uint8_t byte_order;
bool init;
bool sync;
bool use_sync_mode;
bool use_sync_event;
};
typedef union _xcb_im_ic_attr_value_t {
xcb_rectangle_t rect;
xcb_point_t point;
uint32_t byte4;
struct {
uint8_t *data;
uint8_t len;
} raw;
} xcb_im_ic_attr_value_t;
typedef struct _xcb_im_queue_t {
uint16_t icid;
xcb_im_packet_header_fr_t hdr;
xcb_im_forward_event_fr_t frame;
xcb_key_press_event_t event;
list_head list;
} xcb_im_queue_t;
xcb_im_input_context_t *_xcb_im_new_input_context(xcb_im_t *im,
xcb_im_client_t *client);
const xcb_im_default_ic_attr_t *_xcb_im_default_ic_attr_entry(xcb_im_t *im,
uint32_t id);
bool _xcb_im_send_message(xcb_im_t *im, xcb_im_client_t *client, uint8_t *data,
size_t length);
void _xcb_im_send_error_message(xcb_im_t *im, xcb_im_client_t *client);
void _xcb_im_destroy_client(xcb_im_t *im, xcb_im_client_t *client);
void _xcb_im_destroy_ic(xcb_im_t *im, xcb_im_input_context_t *ic);
void _xcb_im_send_set_event_mask(xcb_im_t *im, xcb_im_client_t *client,
uint32_t icid, uint32_t forward_event_mask,
uint32_t sync_mask);
void _xcb_im_set_ic_event_mask(xcb_im_t *im, xcb_im_input_context_t *client);
void _xcb_im_set_im_event_mask(xcb_im_t *im, xcb_im_client_t *ic);
void _xcb_im_add_queue(xcb_im_t *im, xcb_im_client_t *client, uint16_t icid,
const xcb_im_packet_header_fr_t *hdr,
xcb_im_forward_event_fr_t *frame, uint8_t *data);
void _xcb_im_process_queue(xcb_im_t *im, xcb_im_client_t *client);
static inline bool _xcb_im_has_trigger_key(xcb_im_t *im) {
return im->onKeys.nKeys || im->offKeys.nKeys;
}
#endif // _XCB_IMDKIT_IMDKIT_P_H_