<commit_before>namespace Caribou {
    /**
     * Singleton object providing access to the X Window facility.
     */
    public class XAdapter : Object {

        /* Signals */
        public signal void modifiers_changed (uint modifiers);
        public signal void group_changed (uint gid, string group, string variant);

        /* Private properties */
        static XAdapter instance;
        unowned X.Display xdisplay;
        X.ID xid;
        Xkb.Desc xkbdesc;
        Xkl.Engine xkl_engine;
        uint reserved_keysym;
        uchar reserved_keycode;
        uchar modifiers;
        uchar group;
        uint[] level_switch_modifiers;

        public delegate void KeyButtonCallback (uint keybuttoncode, bool pressed);

        private class KeyButtonHandler {
            public unowned KeyButtonCallback cb { get; private set; }
            public KeyButtonHandler (KeyButtonCallback cb) {
                this.cb = cb;
            }
        }

        Gee.HashMap<uint, KeyButtonHandler> button_funcs;
        Gee.HashMap<uint, KeyButtonHandler> key_funcs;

        construct {
            Xkb.State xkb_state;
            unowned Xkl.State xkl_state;

            Gdk.Window rootwin = Gdk.get_default_root_window();
            this.xdisplay = Gdk.X11Display.get_xdisplay (rootwin.get_display ());
            xid = Gdk.X11Window.get_xid (rootwin);
            this.xkbdesc = Xkb.get_keyboard (this.xdisplay,
                                             Xkb.GBN_AllComponentsMask,
                                             Xkb.UseCoreKbd);
            this.xkl_engine = Xkl.Engine.get_instance (this.xdisplay);
            xkl_engine.start_listen (Xkl.EngineListenModes.TRACK_KEYBOARD_STATE);
            xkl_state = this.xkl_engine.get_current_state ();
            this.group = (uchar) xkl_state.group;
            xkl_engine.X_state_changed.connect_after (xkl_state_changed);

            Xkb.get_state (this.xdisplay, Xkb.UseCoreKbd, out xkb_state);
            this.modifiers = xkb_state.mods;

            this.reserved_keycode = 0;

            this.level_switch_modifiers = {
                0,
                Gdk.ModifierType.SHIFT_MASK
            };
            var lv3_mod = keysym_to_modifier (Gdk.Key.ISO_Level3_Shift);
            if (lv3_mod != 0) {
                level_switch_modifiers += lv3_mod;
                level_switch_modifiers += Gdk.ModifierType.SHIFT_MASK | lv3_mod;
            }

            button_funcs = new Gee.HashMap<uint, KeyButtonHandler> ();

            key_funcs = new Gee.HashMap<uint, KeyButtonHandler> ();

            Xkb.select_events (
                this.xdisplay, Xkb.UseCoreKbd,
                Xkb.StateNotifyMask | Xkb.AccessXNotifyMask,
                Xkb.StateNotifyMask | Xkb.AccessXNotifyMask);

            ((Gdk.Window) null).add_filter (x_event_filter); // Did I blow your mind?
        }

        ~XAdapter () {
            Xkb.free_keyboard(this.xkbdesc, Xkb.GBN_AllComponentsMask, true);
        }

        public static XAdapter get_default() {
            if (instance == null)
                instance = new XAdapter ();
            return instance;
        }

        private Gdk.FilterReturn x_event_filter (Gdk.XEvent xevent, Gdk.Event event) {
            void* pointer = &xevent;
            Xkb.Event* xkbev = (Xkb.Event *) pointer;
            X.Event* xev = (X.Event *) pointer;

			this.xkl_engine.filter_events(xev);

            if (xev.type == X.EventType.ButtonPress ||
                xev.type == X.EventType.ButtonRelease) {
                KeyButtonHandler handler =
                    (KeyButtonHandler) button_funcs.get (xev.xbutton.button);
                if (handler != null)
                    handler.cb (xev.xbutton.button,
                                xev.type == X.EventType.ButtonPress);
            } else if (xev.type == X.EventType.KeyPress ||
                       xev.type == X.EventType.KeyRelease) {<commit_msg>libcaribou: fix dereferencing Gdk.XEvent pointer with Vala 0.16<commit_after>namespace Caribou {
    /**
     * Singleton object providing access to the X Window facility.
     */
    public class XAdapter : Object {

        /* Signals */
        public signal void modifiers_changed (uint modifiers);
        public signal void group_changed (uint gid, string group, string variant);

        /* Private properties */
        static XAdapter instance;
        unowned X.Display xdisplay;
        X.ID xid;
        Xkb.Desc xkbdesc;
        Xkl.Engine xkl_engine;
        uint reserved_keysym;
        uchar reserved_keycode;
        uchar modifiers;
        uchar group;
        uint[] level_switch_modifiers;

        public delegate void KeyButtonCallback (uint keybuttoncode, bool pressed);

        private class KeyButtonHandler {
            public unowned KeyButtonCallback cb { get; private set; }
            public KeyButtonHandler (KeyButtonCallback cb) {
                this.cb = cb;
            }
        }

        Gee.HashMap<uint, KeyButtonHandler> button_funcs;
        Gee.HashMap<uint, KeyButtonHandler> key_funcs;

        construct {
            Xkb.State xkb_state;
            unowned Xkl.State xkl_state;

            Gdk.Window rootwin = Gdk.get_default_root_window();
            this.xdisplay = Gdk.X11Display.get_xdisplay (rootwin.get_display ());
            xid = Gdk.X11Window.get_xid (rootwin);
            this.xkbdesc = Xkb.get_keyboard (this.xdisplay,
                                             Xkb.GBN_AllComponentsMask,
                                             Xkb.UseCoreKbd);
            this.xkl_engine = Xkl.Engine.get_instance (this.xdisplay);
            xkl_engine.start_listen (Xkl.EngineListenModes.TRACK_KEYBOARD_STATE);
            xkl_state = this.xkl_engine.get_current_state ();
            this.group = (uchar) xkl_state.group;
            xkl_engine.X_state_changed.connect_after (xkl_state_changed);

            Xkb.get_state (this.xdisplay, Xkb.UseCoreKbd, out xkb_state);
            this.modifiers = xkb_state.mods;

            this.reserved_keycode = 0;

            this.level_switch_modifiers = {
                0,
                Gdk.ModifierType.SHIFT_MASK
            };
            var lv3_mod = keysym_to_modifier (Gdk.Key.ISO_Level3_Shift);
            if (lv3_mod != 0) {
                level_switch_modifiers += lv3_mod;
                level_switch_modifiers += Gdk.ModifierType.SHIFT_MASK | lv3_mod;
            }

            button_funcs = new Gee.HashMap<uint, KeyButtonHandler> ();

            key_funcs = new Gee.HashMap<uint, KeyButtonHandler> ();

            Xkb.select_events (
                this.xdisplay, Xkb.UseCoreKbd,
                Xkb.StateNotifyMask | Xkb.AccessXNotifyMask,
                Xkb.StateNotifyMask | Xkb.AccessXNotifyMask);

            ((Gdk.Window) null).add_filter (x_event_filter); // Did I blow your mind?
        }

        ~XAdapter () {
            Xkb.free_keyboard(this.xkbdesc, Xkb.GBN_AllComponentsMask, true);
        }

        public static XAdapter get_default() {
            if (instance == null)
                instance = new XAdapter ();
            return instance;
        }

        private Gdk.FilterReturn x_event_filter (Gdk.XEvent xevent, Gdk.Event event) {
            // After the following commit, Vala changed the definition
            // of Gdk.XEvent from struct to class:
            // http://git.gnome.org/browse/vala/commit/?id=9c52e7b7
            //
            // This affects the meaning of address-of (&) operator:
            // '&xevent' now refers to the address of XEvent*, not
            // XEvent.
#if VALA_0_16
            void* pointer = xevent;
#else
            void* pointer = &xevent;
#endif
            Xkb.Event* xkbev = (Xkb.Event *) pointer;
            X.Event* xev = (X.Event *) pointer;

			this.xkl_engine.filter_events(xev);

            if (xev.type == X.EventType.ButtonPress ||
                xev.type == X.EventType.ButtonRelease) {
                KeyButtonHandler handler =
                    (KeyButtonHandler) button_funcs.get (xev.xbutton.button);
                if (handler != null)
                    handler.cb (xev.xbutton.button,
                                xev.type == X.EventType.ButtonPress);
            } else if (xev.type == X.EventType.KeyPress ||
                       xev.type == X.EventType.KeyRelease) {
{'fraction_non_alphanumeric': 0.08775705404112864, 'fraction_numerical': 0.004184600669536107, 'mean_word_length': 1.7525501809805857, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7286225', 'n_tokens_mistral': 2467, 'n_tokens_neox': 2382, 'n_words': 492}