Files
strans/tests/ibus_client_smoke.c

170 lines
4.1 KiB
C

#define _POSIX_C_SOURCE 200809L
#include <ibus.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Log Log;
struct Log
{
GMainLoop *loop;
int legacy;
int modern;
int commit;
int invalid;
int sawpreedit;
int sawcommit;
};
static void
legacy(IBusInputContext *ctx, IBusText *text, guint cursor,
gboolean visible, void *arg)
{
IBusAttrList *attrs;
IBusAttribute *a;
Log *log;
const char *s;
(void)ctx;
log = arg;
log->legacy++;
s = ibus_text_get_text(text);
if(strcmp(s, "k") == 0){
attrs = ibus_text_get_attributes(text);
a = attrs == NULL ? NULL : ibus_attr_list_get(attrs, 0);
if(cursor != 1 || !visible || attrs == NULL || a == NULL ||
a->type != IBUS_ATTR_TYPE_UNDERLINE ||
a->value != IBUS_ATTR_UNDERLINE_SINGLE ||
a->start_index != 0 || a->end_index != 1 ||
ibus_attr_list_get(attrs, 1) != NULL)
log->invalid = 1;
else
log->sawpreedit = 1;
}
if(log->loop != NULL && log->sawpreedit && log->sawcommit)
g_main_loop_quit(log->loop);
}
static void
modern(IBusInputContext *ctx, IBusText *text, guint cursor,
gboolean visible, guint mode, void *arg)
{
Log *log;
(void)ctx;
(void)text;
(void)cursor;
(void)visible;
(void)mode;
log = arg;
log->modern++;
log->invalid = 1;
if(log->loop != NULL)
g_main_loop_quit(log->loop);
}
static void
commit(IBusInputContext *ctx, IBusText *text, void *arg)
{
IBusAttrList *attrs;
Log *log;
const char *s;
(void)ctx;
log = arg;
log->commit++;
s = ibus_text_get_text(text);
attrs = ibus_text_get_attributes(text);
if(strcmp(s, "") != 0 || attrs == NULL ||
ibus_attr_list_get(attrs, 0) != NULL)
log->invalid = 1;
else
log->sawcommit = 1;
if(log->loop != NULL && log->sawpreedit && log->sawcommit)
g_main_loop_quit(log->loop);
}
static gboolean
timeout(void *arg)
{
g_main_loop_quit(arg);
return G_SOURCE_REMOVE;
}
static int
waitdone(Log *log)
{
guint timer;
if(log->sawpreedit && log->sawcommit)
return 1;
log->loop = g_main_loop_new(NULL, FALSE);
timer = g_timeout_add_seconds(4, timeout, log->loop);
g_main_loop_run(log->loop);
if(g_main_context_find_source_by_id(NULL, timer) != NULL)
g_source_remove(timer);
g_main_loop_unref(log->loop);
log->loop = NULL;
return log->sawpreedit && log->sawcommit;
}
int
main(int argc, char **argv)
{
IBusBus *bus;
IBusInputContext *ctx;
Log log;
int ok;
if(argc != 2){
fprintf(stderr, "usage: ibus_client_smoke address\n");
return 2;
}
if(setenv("IBUS_ADDRESS", argv[1], 1) < 0 ||
unsetenv("IBUS_ADDRESS_FILE") < 0 ||
unsetenv("DBUS_SESSION_BUS_ADDRESS") < 0 || unsetenv("DISPLAY") < 0){
perror("ibus_client_smoke: environment");
return 1;
}
memset(&log, 0, sizeof log);
ibus_init();
bus = ibus_bus_new();
if(bus == NULL || !ibus_bus_is_connected(bus)){
fprintf(stderr, "ibus_client_smoke: cannot connect to private bus\n");
if(bus != NULL) g_object_unref(bus);
return 1;
}
ctx = ibus_bus_create_input_context(bus, "strans-libibus-smoke");
if(ctx == NULL){
fprintf(stderr, "ibus_client_smoke: cannot create input context\n");
g_object_unref(bus);
return 1;
}
g_signal_connect(ctx, "update-preedit-text", G_CALLBACK(legacy), &log);
g_signal_connect(ctx, "update-preedit-text-with-mode", G_CALLBACK(modern),
&log);
g_signal_connect(ctx, "commit-text", G_CALLBACK(commit), &log);
ibus_input_context_set_capabilities(ctx, IBUS_CAP_PREEDIT_TEXT);
ibus_input_context_focus_in(ctx);
ok = ibus_input_context_process_key_event(ctx, 'n', 0, IBUS_CONTROL_MASK) &&
ibus_input_context_process_key_event(ctx, 'k', 0, 0) &&
ibus_input_context_process_key_event(ctx, 'a', 0, 0) &&
ibus_input_context_process_key_event(ctx, '0', 0, 0) &&
waitdone(&log);
ibus_input_context_focus_out(ctx);
if(log.legacy == 0 || log.modern != 0 || log.commit != 1 ||
log.invalid || !log.sawpreedit || !log.sawcommit)
ok = 0;
g_object_unref(ctx);
g_object_unref(bus);
if(!ok){
fprintf(stderr,
"ibus_client_smoke: legacy=%d modern=%d commit=%d invalid=%d preedit=%d committed=%d\n",
log.legacy, log.modern, log.commit, log.invalid,
log.sawpreedit, log.sawcommit);
return 1;
}
printf("official libibus client preedit and commit: ok\n");
return 0;
}