Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 903702 | Differences between
and this patch

Collapse All | Expand All

(-)a/client/x11/main.c (-77 / +83 lines)
Lines 2-8 Link Here
2
/* vim:set et sts=4: */
2
/* vim:set et sts=4: */
3
/* ibus
3
/* ibus
4
 * Copyright (C) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
4
 * Copyright (C) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
5
 * Copyright (C) 2015-2022 Takao Fujiwara <takao.fujiwara1@gmail.com>
5
 * Copyright (C) 2015-2023 Takao Fujiwara <takao.fujiwara1@gmail.com>
6
 * Copyright (C) 2007-2015 Red Hat, Inc.
6
 * Copyright (C) 2007-2015 Red Hat, Inc.
7
 *
7
 *
8
 * main.c:
8
 * main.c:
Lines 49-54 Link Here
49
#include <getopt.h>
49
#include <getopt.h>
50
50
51
#define ESC_SEQUENCE_ISO10646_1 "\033%G"
51
#define ESC_SEQUENCE_ISO10646_1 "\033%G"
52
/* Wait for about 120 secs to return a key from async process-key-event. */
53
#define MAX_WAIT_KEY_TIME       120000
52
54
53
#define LOG(level, fmt_args...) \
55
#define LOG(level, fmt_args...) \
54
    if (g_debug_level >= (level)) { \
56
    if (g_debug_level >= (level)) { \
Lines 461-471 xim_unset_ic_focus (XIMS xims, IMChangeFocusStruct *call_data) Link Here
461
463
462
}
464
}
463
465
466
static void
467
_xim_forward_key_event_done (X11IC   *x11ic,
468
                             XEvent  *event,
469
                             gboolean processed)
470
{
471
    IMForwardEventStruct fe;
472
    if (processed) {
473
        if (!x11ic->has_preedit_area) {
474
            _xim_set_cursor_location (x11ic);
475
        }
476
        return;
477
    }
478
    g_assert (x11ic);
479
    g_assert (event);
480
481
    memset (&fe, 0, sizeof (fe));
482
    fe.major_code = XIM_FORWARD_EVENT;
483
    fe.icid = x11ic->icid;
484
    fe.connect_id = x11ic->connect_id;
485
    fe.sync_bit = 0;
486
    fe.serial_number = 0L;
487
    fe.event = *event;
488
    IMForwardEvent (_xims, (XPointer) &fe);
489
}
490
491
464
typedef struct {
492
typedef struct {
465
    IMForwardEventStruct *pfe;
466
    int                   count;
493
    int                   count;
467
    guint                 count_cb_id;
494
    guint                 count_cb_id;
468
    gboolean              retval;
495
    gboolean              retval;
496
    X11IC                *x11ic;
497
    CARD16                connect_id;
498
    XEvent                event;
469
} ProcessKeyEventReplyData;
499
} ProcessKeyEventReplyData;
470
500
471
static void
501
static void
Lines 474-480 _process_key_event_done (GObject *object, Link Here
474
                         gpointer      user_data)
504
                         gpointer      user_data)
475
{
505
{
476
    IBusInputContext *context = (IBusInputContext *)object;
506
    IBusInputContext *context = (IBusInputContext *)object;
477
    IMForwardEventStruct *pfe = (IMForwardEventStruct*) user_data;
507
    ProcessKeyEventReplyData *data = (ProcessKeyEventReplyData *)user_data;
478
508
479
    GError *error = NULL;
509
    GError *error = NULL;
480
    gboolean retval = ibus_input_context_process_key_event_async_finish (
510
    gboolean retval = ibus_input_context_process_key_event_async_finish (
Lines 488-503 _process_key_event_done (GObject *object, Link Here
488
    }
518
    }
489
519
490
    if (g_hash_table_lookup (_connections,
520
    if (g_hash_table_lookup (_connections,
491
                             GINT_TO_POINTER ((gint) pfe->connect_id))
521
                             GINT_TO_POINTER ((gint)data->connect_id))
492
        == NULL) {
522
        == NULL) {
493
        g_slice_free (IMForwardEventStruct, pfe);
523
        g_slice_free (ProcessKeyEventReplyData, data);
494
        return;
524
        return;
495
    }
525
    }
496
526
497
    if (retval == FALSE) {
527
    if (retval == FALSE)
498
        IMForwardEvent (_xims, (XPointer) pfe);
528
        _xim_forward_key_event_done (data->x11ic, &data->event, retval);
499
    }
529
    g_slice_free (ProcessKeyEventReplyData, data);
500
    g_slice_free (IMForwardEventStruct, pfe);
501
}
530
}
502
531
503
static void
532
static void
Lines 518-523 _process_key_event_reply_done (GObject *object, Link Here
518
    }
547
    }
519
    g_return_if_fail (data);
548
    g_return_if_fail (data);
520
    data->retval = retval;
549
    data->retval = retval;
550
    if (g_hash_table_lookup (_connections,
551
                             GINT_TO_POINTER ((gint)data->connect_id))
552
        == NULL) {
553
        return;
554
    }
555
    /* _xim_forward_key_event_done() should be called in
556
     * _process_key_event_reply_done() because g_main_context_iteration()
557
     * can call another xim_forward_event() and xim_forward_event() can be
558
     * nested and the first _process_key_event_reply_done() is returned
559
     * at last with g_main_context_iteration() so
560
     * if _xim_forward_key_event_done() is called out of
561
     * _process_key_event_reply_done(), the key events order
562
     * can be swapped.
563
     */
564
    _xim_forward_key_event_done (data->x11ic, &data->event, retval);
521
    data->count = 0;
565
    data->count = 0;
522
    g_source_remove (data->count_cb_id);
566
    g_source_remove (data->count_cb_id);
523
}
567
}
Lines 529-537 _process_key_event_count_cb (gpointer user_data) Link Here
529
    g_return_val_if_fail (data, G_SOURCE_REMOVE);
573
    g_return_val_if_fail (data, G_SOURCE_REMOVE);
530
    if (!data->count)
574
    if (!data->count)
531
        return G_SOURCE_REMOVE;
575
        return G_SOURCE_REMOVE;
532
    /* Wait for about 10 secs. */
576
    if (data->count++ == MAX_WAIT_KEY_TIME) {
533
    if (data->count++ == 10000) {
577
        g_warning ("Key event is not returned for %usecs.", MAX_WAIT_KEY_TIME);
534
        data->count = 0;
535
        return G_SOURCE_REMOVE;
578
        return G_SOURCE_REMOVE;
536
    }
579
    }
537
    return G_SOURCE_CONTINUE;
580
    return G_SOURCE_CONTINUE;
Lines 571-602 xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) Link Here
571
                                      event.keyval,
614
                                      event.keyval,
572
                                      event.hardware_keycode - 8,
615
                                      event.hardware_keycode - 8,
573
                                      event.state);
616
                                      event.state);
574
        if (retval) {
617
        _xim_forward_key_event_done (x11ic, &call_data->event, retval);
575
            if (!x11ic->has_preedit_area) {
576
                _xim_set_cursor_location (x11ic);
577
            }
578
            return 1;
579
        }
580
581
        IMForwardEventStruct fe;
582
        memset (&fe, 0, sizeof (fe));
583
584
        fe.major_code = XIM_FORWARD_EVENT;
585
        fe.icid = x11ic->icid;
586
        fe.connect_id = x11ic->connect_id;
587
        fe.sync_bit = 0;
588
        fe.serial_number = 0L;
589
        fe.event = call_data->event;
590
591
        IMForwardEvent (_xims, (XPointer) &fe);
592
593
        retval = 1;
618
        retval = 1;
594
        break;
619
        break;
595
    }
620
    }
596
    case 2: {
621
    case 2: {
597
        GSource *source = g_timeout_source_new (1);
622
        GSource *source = g_timeout_source_new (1);
598
        ProcessKeyEventReplyData *data = NULL;
623
        ProcessKeyEventReplyData *data = NULL;
599
        IMForwardEventStruct fe;
600
624
601
        if (source)
625
        if (source)
602
            data = g_slice_new0 (ProcessKeyEventReplyData);
626
            data = g_slice_new0 (ProcessKeyEventReplyData);
Lines 610-620 xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) Link Here
610
            if (source)
634
            if (source)
611
                g_source_destroy (source);
635
                g_source_destroy (source);
612
        } else {
636
        } else {
613
            CARD16 connect_id = x11ic->connect_id;
614
            data->count = 1;
637
            data->count = 1;
615
            g_source_attach (source, NULL);
638
            g_source_attach (source, NULL);
616
            g_source_unref (source);
639
            g_source_unref (source);
617
            data->count_cb_id = g_source_get_id (source);
640
            data->count_cb_id = g_source_get_id (source);
641
            data->connect_id = call_data->connect_id;
642
            data->x11ic = x11ic;
643
            data->event = *((XEvent*)xevent);
618
            ibus_input_context_process_key_event_async (
644
            ibus_input_context_process_key_event_async (
619
                    x11ic->context,
645
                    x11ic->context,
620
                    event.keyval,
646
                    event.keyval,
Lines 626-632 xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) Link Here
626
                    data);
652
                    data);
627
            g_source_set_callback (source, _process_key_event_count_cb,
653
            g_source_set_callback (source, _process_key_event_count_cb,
628
                                   data, NULL);
654
                                   data, NULL);
629
            while (data->count)
655
            while (data->count > 0 && data->count < MAX_WAIT_KEY_TIME)
630
                g_main_context_iteration (NULL, TRUE);
656
                g_main_context_iteration (NULL, TRUE);
631
            if (source->ref_count > 0) {
657
            if (source->ref_count > 0) {
632
                /* g_source_get_id() could causes a SEGV */
658
                /* g_source_get_id() could causes a SEGV */
Lines 634-679 xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) Link Here
634
                        "issue in %p.", source);
660
                        "issue in %p.", source);
635
            }
661
            }
636
            retval = data->retval;
662
            retval = data->retval;
637
            g_slice_free (ProcessKeyEventReplyData, data);
663
            if (data->count == 0) {
638
664
                g_slice_free (ProcessKeyEventReplyData, data);
639
            if (g_hash_table_lookup (_connections,
640
                                     GINT_TO_POINTER ((gint)connect_id))
641
                == NULL) {
642
                return 1;
665
                return 1;
643
            }
666
            }
644
        }
667
        }
645
668
646
        if (retval) {
669
        g_slice_free (ProcessKeyEventReplyData, data);
647
            if (! x11ic->has_preedit_area) {
670
        if (g_hash_table_lookup (_connections,
648
                _xim_set_cursor_location (x11ic);
671
                                 GINT_TO_POINTER ((gint)call_data->connect_id))
649
            }
672
                == NULL) {
650
            return 1;
673
                return 1;
651
        }
674
        }
652
675
        _xim_forward_key_event_done (x11ic, &call_data->event, retval);
653
        memset (&fe, 0, sizeof (fe));
654
655
        fe.major_code = XIM_FORWARD_EVENT;
656
        fe.icid = x11ic->icid;
657
        fe.connect_id = x11ic->connect_id;
658
        fe.sync_bit = 0;
659
        fe.serial_number = 0L;
660
        fe.event = call_data->event;
661
662
        IMForwardEvent (_xims, (XPointer) &fe);
663
664
        retval = 1;
676
        retval = 1;
665
        break;
677
        break;
666
    }
678
    }
667
    default: {
679
    default: {
668
        IMForwardEventStruct *pfe;
680
        ProcessKeyEventReplyData *data;
669
681
670
        pfe = g_slice_new0 (IMForwardEventStruct);
682
        if (!(data = g_slice_new0 (ProcessKeyEventReplyData))) {
671
        pfe->major_code = XIM_FORWARD_EVENT;
683
            g_warning ("Cannot allocate async data");
672
        pfe->icid = x11ic->icid;
684
            _xim_forward_key_event_done (x11ic, &call_data->event, 0);
673
        pfe->connect_id = x11ic->connect_id;
685
            return 1;
674
        pfe->sync_bit = 0;
686
        }
675
        pfe->serial_number = 0L;
687
        data->connect_id = call_data->connect_id;
676
        pfe->event = call_data->event;
688
        data->x11ic = x11ic;
689
        data->event = call_data->event;
677
690
678
        ibus_input_context_process_key_event_async (
691
        ibus_input_context_process_key_event_async (
679
                                      x11ic->context,
692
                                      x11ic->context,
Lines 683-689 xim_forward_event (XIMS xims, IMForwardEventStruct *call_data) Link Here
683
                                      -1,
696
                                      -1,
684
                                      NULL,
697
                                      NULL,
685
                                      _process_key_event_done,
698
                                      _process_key_event_done,
686
                                      pfe);
699
                                      data);
687
        retval = 1;
700
        retval = 1;
688
    }
701
    }
689
    }
702
    }
Lines 962-972 _xim_forward_key_event (X11IC *x11ic, Link Here
962
                        guint    keycode,
975
                        guint    keycode,
963
                        guint    state)
976
                        guint    state)
964
{
977
{
965
    g_return_if_fail (x11ic != NULL);
966
967
    IMForwardEventStruct fe = {0};
968
    XEvent xkp = {0};
978
    XEvent xkp = {0};
969
979
980
    g_return_if_fail (x11ic != NULL);
981
970
    xkp.xkey.type = (state & IBUS_RELEASE_MASK) ? KeyRelease : KeyPress;
982
    xkp.xkey.type = (state & IBUS_RELEASE_MASK) ? KeyRelease : KeyPress;
971
    xkp.xkey.serial = 0L;
983
    xkp.xkey.serial = 0L;
972
    xkp.xkey.send_event = False;
984
    xkp.xkey.send_event = False;
Lines 975-994 _xim_forward_key_event (X11IC *x11ic, Link Here
975
    xkp.xkey.window =
987
    xkp.xkey.window =
976
        x11ic->focus_window ? x11ic->focus_window : x11ic->client_window;
988
        x11ic->focus_window ? x11ic->focus_window : x11ic->client_window;
977
    xkp.xkey.subwindow = None;
989
    xkp.xkey.subwindow = None;
978
    xkp.xkey.root = DefaultRootWindow (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
990
    xkp.xkey.root = DefaultRootWindow (
991
            GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
979
992
980
    xkp.xkey.time = 0;
993
    xkp.xkey.time = 0;
981
    xkp.xkey.state = state;
994
    xkp.xkey.state = state;
982
    xkp.xkey.keycode = (keycode == 0) ? 0 : keycode + 8;
995
    xkp.xkey.keycode = (keycode == 0) ? 0 : keycode + 8;
983
996
984
    fe.major_code = XIM_FORWARD_EVENT;
997
    _xim_forward_key_event_done (x11ic, &xkp, FALSE);
985
    fe.icid = x11ic->icid;
986
    fe.connect_id = x11ic->connect_id;
987
    fe.sync_bit = 0;
988
    fe.serial_number = 0L;
989
    fe.event = xkp;
990
991
    IMForwardEvent (_xims, (XPointer) & fe);
992
}
998
}
993
999
994
static void
1000
static void

Return to bug 903702