Esempio n. 1
0
static void
xfce_keyboard_layout_helper_set (XfceKeyboardLayoutHelper *helper,
                                 const gchar *xfconf_option_name,
                                 gchar ***xkl_config_option,
                                 const gchar *debug_name)
{
    gchar *xfconf_values, *xkl_values;
    gchar **values;

    if (!helper->xkb_disable_settings)
    {
        xfconf_values  = g_strjoinv (",", *xkl_config_option);
        xkl_values  = xfconf_channel_get_string (helper->channel,
                      xfconf_option_name, xfconf_values);

        if (g_strcmp0 (xfconf_values, xkl_values) != 0)
        {
            values = g_strsplit_set (xkl_values, ",", 0);
            g_strfreev (*xkl_config_option);
            *xkl_config_option = values;
            xkl_config_rec_activate (helper->config, helper->engine);

            xfsettings_dbg (XFSD_DEBUG_KEYBOARD_LAYOUT, "set %s to \"%s\"", debug_name, xkl_values);
        }

        g_free (xfconf_values);
        g_free (xkl_values);
    }
}
Esempio n. 2
0
static void
xfce_keyboard_layout_helper_set_model (XfceKeyboardLayoutHelper *helper)
{
    gchar *xkbmodel;

    if (!helper->xkb_disable_settings)
    {
        xkbmodel = xfconf_channel_get_string (helper->channel, "/Default/XkbModel", NULL);
        if (!xkbmodel || !*xkbmodel)
        {
            /* If xkb model is not set by user, we want to try to use the system default */
            g_free (xkbmodel);
            xkbmodel = g_strdup (helper->system_keyboard_model);
        }

        if (g_strcmp0 (helper->config->model, xkbmodel) != 0)
        {
            g_free (helper->config->model);
            helper->config->model = xkbmodel;
            xkl_config_rec_activate (helper->config, helper->engine);

            xfsettings_dbg (XFSD_DEBUG_KEYBOARD_LAYOUT, "set model to \"%s\"", xkbmodel);
        }
        else
        {
            g_free (xkbmodel);
        }
    }
}
Esempio n. 3
0
static void
xfce_keyboard_layout_helper_process_xmodmap (void)
{
    const gchar *xmodmap_path;

    xmodmap_path = g_build_filename (xfce_get_homedir (), ".Xmodmap", NULL);

    if (g_file_test (xmodmap_path, G_FILE_TEST_EXISTS))
    {
        /* There is a .Xmodmap file, try to use it */
        const gchar *xmodmap_command;
        GError      *error = NULL;

        xmodmap_command = g_strconcat ("xmodmap ", xmodmap_path, NULL);

        xfsettings_dbg (XFSD_DEBUG_KEYBOARD_LAYOUT, "spawning \"%s\"", xmodmap_command);

        /* Launch the xmodmap command and only print errors when in debugging mode */
        if (!g_spawn_command_line_async (xmodmap_command, &error))
        {
            DBG ("Xmodmap call failed: %s", error->message);
            g_error_free (error);
        }
    }

    g_free ((gchar*) xmodmap_path);
}
Esempio n. 4
0
static void
xfce_keyboard_layout_reset_xkl_config (XklEngine *xklengine,
                                       XfceKeyboardLayoutHelper *helper)
{
    if (!helper->xkb_disable_settings)
    {
        gchar *xfconf_model;

        xfsettings_dbg (XFSD_DEBUG_KEYBOARD_LAYOUT,
                        "New keyboard detected; restoring XKB settings.");

        xkl_config_rec_reset (helper->config);
        xkl_config_rec_get_from_server (helper->config, helper->engine);

        xfconf_model = xfconf_channel_get_string (helper->channel, "/Default/XkbModel", NULL);
        if (xfconf_model && *xfconf_model &&
                g_strcmp0 (xfconf_model, helper->config->model) != 0 &&
                g_strcmp0 (helper->system_keyboard_model, helper->config->model) != 0)
        {
            /* We get X-new-device notifications multiple times for a single keyboard device (why?);
               if keyboard model is set in user preferences,
               we'll reset the default to the user preference when first notified
               and we don't want to use that as a system default the next time
               the user tries to reset keyboard model to the default in xfce4-keyboard-settings.

               The above conditional says: if user set the keyboard model and that's the one
               we see here, don't assume it's the system default since it was us who set it
               on the previous notification.
             */
            g_free (helper->system_keyboard_model);
            helper->system_keyboard_model = g_strdup (helper->config->model);
            xfsettings_dbg (XFSD_DEBUG_KEYBOARD_LAYOUT,
                            "system default keyboard model reset: %s",
                            helper->system_keyboard_model);
        }
        g_free (xfconf_model);

        xfce_keyboard_layout_helper_set_model (helper);
        xfce_keyboard_layout_helper_set_layout (helper);
        xfce_keyboard_layout_helper_set_variant (helper);
        xfce_keyboard_layout_helper_set_grpkey (helper);
        xfce_keyboard_layout_helper_set_composekey (helper);

        xfce_keyboard_layout_helper_process_xmodmap ();
    }
}
Esempio n. 5
0
static void
xfce_keyboard_layout_helper_set_option (XfceKeyboardLayoutHelper *helper,
                                        const gchar *xkb_option_name,
                                        const gchar *xfconf_option_name)
{
    if (!helper->xkb_disable_settings)
    {
        gchar *option_value;
        gchar *xkl_option_value;
        gchar *other_options;

        xkl_option_value = xfce_keyboard_layout_get_option (helper->config->options,
                           xkb_option_name, &other_options);

        option_value = xfconf_channel_get_string (helper->channel, xfconf_option_name,
                       xkl_option_value);
        if (g_strcmp0 (option_value, xkl_option_value) != 0)
        {
            gchar *options_string;
            if (other_options == NULL)
            {
                options_string = g_strdup (option_value);
            }
            else
            {
                if (strlen (option_value) != 0)
                {
                    options_string = g_strconcat (option_value, ",", other_options, NULL);
                }
                else
                {
                    options_string = strdup (other_options);
                }
            }

            g_strfreev (helper->config->options);
            helper->config->options = g_strsplit (options_string, ",", 0);
            xkl_config_rec_activate (helper->config, helper->engine);

            xfsettings_dbg (XFSD_DEBUG_KEYBOARD_LAYOUT, "set %s to \"%s\"",
                            xkb_option_name, option_value);
            g_free (options_string);
        }

        g_free (other_options);
        g_free (option_value);
    }
}
Esempio n. 6
0
static gboolean
xfce_xsettings_helper_fc_notify (gpointer data)
{
    XfceXSettingsHelper *helper = XFCE_XSETTINGS_HELPER (data);
    XfceXSetting        *setting;

    helper->fc_notify_timeout_id = 0;

    /* check if the font config setup changed */
    if (!FcConfigUptoDate (NULL) && FcInitReinitialize ())
    {
        /* stop the monitors */
        xfce_xsettings_helper_fc_free (helper);

        setting = g_hash_table_lookup (helper->settings, FC_PROPERTY);
        if (setting == NULL)
        {
            /* create new setting */
            setting = g_slice_new0 (XfceXSetting);
            setting->value = g_new0 (GValue, 1);
            g_value_init (setting->value, G_TYPE_INT);
            g_hash_table_insert (helper->settings, g_strdup (FC_PROPERTY), setting);
        }

        /* update setting */
        setting->last_change_serial = helper->serial;
        g_value_set_int (setting->value, time (NULL));

        xfsettings_dbg (XFSD_DEBUG_FONTCONFIG, "timestamp updated (time=%d)",
                        g_value_get_int (setting->value));

        /* schedule xsettings update */
        if (helper->notify_idle_id == 0)
            helper->notify_idle_id = g_idle_add (xfce_xsettings_helper_notify_idle, helper);

        /* restart monitoring */
        helper->fc_init_id = g_idle_add (xfce_xsettings_helper_fc_init, helper);
    }

    return FALSE;
}
Esempio n. 7
0
static GdkFilterReturn
xfce_xsettings_helper_event_filter (GdkXEvent *gdkxevent,
                                    GdkEvent  *gdkevent,
                                    gpointer   data)
{
    XfceXSettingsHelper *helper = XFCE_XSETTINGS_HELPER (data);
    GSList              *li;
    XfceXSettingsScreen *screen;
    XEvent              *xevent = gdkxevent;

    /* check if another settings manager took over the selection
     * of one of the windows */
    if (xevent->xany.type == SelectionClear)
    {
        for (li = helper->screens; li != NULL; li = li->next)
        {
            screen = li->data;

            if (xevent->xany.window == screen->window
                && xevent->xselectionclear.selection == screen->selection_atom)
            {
                /* remove the screen */
                helper->screens = g_slist_delete_link (helper->screens, li);
                xfce_xsettings_helper_screen_free (screen);

                xfsettings_dbg (XFSD_DEBUG_XSETTINGS, "lost selection, %d screens left",
                                g_slist_length (helper->screens));

                /* remove this filter if there are no screens */
                if (helper->screens == NULL)
                    gdk_window_remove_filter (NULL, xfce_xsettings_helper_event_filter, data);

                return GDK_FILTER_REMOVE;
            }
        }
    }

    return GDK_FILTER_CONTINUE;
}
Esempio n. 8
0
static gboolean
xfce_xsettings_helper_fc_init (gpointer data)
{
    XfceXSettingsHelper *helper = XFCE_XSETTINGS_HELPER (data);

    g_return_val_if_fail (helper->fc_monitors == NULL, FALSE);

    helper->fc_init_id = 0;

    if (FcInit ())
    {
        helper->fc_monitors = g_ptr_array_new ();

        /* start monitoring config files and font directories */
        xfce_xsettings_helper_fc_monitor (helper, FcConfigGetConfigFiles (NULL));
        xfce_xsettings_helper_fc_monitor (helper, FcConfigGetFontDirs (NULL));

        xfsettings_dbg (XFSD_DEBUG_FONTCONFIG, "monitoring %d paths",
                        helper->fc_monitors->len);
    }

    return FALSE;
}
Esempio n. 9
0
static void
xfce_xsettings_helper_notify (XfceXSettingsHelper *helper)
{
    XfceXSettingsNotify *notify;
    CARD32               orderint = 0x01020304;
    guchar              *needle;
    XfceXSettingsScreen *screen;
    GSList              *li;
    gint                 dpi;

    g_return_if_fail (XFCE_IS_XSETTINGS_HELPER (helper));

    notify = g_slice_new0 (XfceXSettingsNotify);
    notify->buf = g_new0 (guchar, 12);
    if (G_UNLIKELY (notify->buf == NULL))
      goto errnomem;
    notify->buf_len = 12;
    needle = notify->buf;

    /* general notification form:
     *
     * 1  CARD8   byte-order
     * 3          unused
     * 4  CARD32  SERIAL
     * 4  CARD32  N_SETTINGS
     */

    /* byte-order */
    *(CARD8 *)needle = (*(char *)&orderint == 1) ? MSBFirst : LSBFirst;
    needle += 4;

    /* serial for this notification */
    *(CARD32 *)needle = helper->serial++;

    /* add all the settings */
    g_hash_table_foreach (helper->settings,
        (GHFunc) xfce_xsettings_helper_setting_append, notify);

    if (G_UNLIKELY (notify->buf == NULL))
      goto errnomem;

    /* number of settings */
    needle = notify->buf + 8;
    *(CARD32 *)needle = notify->n_settings;

    gdk_error_trap_push ();

    /* set new xsettings buffer to the screens */
    for (li = helper->screens; li != NULL; li = li->next)
    {
        screen = li->data;

        /* set the accurate dpi for this screen */
        if (notify->dpi_offset > 0)
        {
            dpi = xfce_xsettings_helper_screen_dpi (screen);
            needle = notify->buf + notify->dpi_offset;
            *(INT32 *)needle = dpi * 1024;
        }

        XChangeProperty (screen->xdisplay, screen->window,
                         helper->xsettings_atom, helper->xsettings_atom,
                         8, PropModeReplace, notify->buf, notify->buf_len);
    }

    if (gdk_error_trap_pop () != 0)
    {
        g_critical ("Failed to set properties");
    }

    xfsettings_dbg (XFSD_DEBUG_XSETTINGS,
                    "%d settings changed (serial=%lu, len=%"G_GSIZE_FORMAT")",
                    notify->n_settings, helper->serial - 1, notify->buf_len);

    g_free (notify->buf);
  errnomem:
    g_slice_free (XfceXSettingsNotify, notify);
}
Esempio n. 10
0
static void
xfce_xsettings_helper_notify_xft (XfceXSettingsHelper *helper)
{
    Display      *xdisplay;
    gchar        *str;
    GString      *resource;
    XfceXSetting *setting;
    guint         i;
    GValue        bool_val = { 0, };
    const gchar  *props[][2] =
    {
        /* { xfconf name}, { xft name } */
        { "/Xft/Antialias", "Xft.antialias:" },
        { "/Xft/Hinting", "Xft.hinting:" },
        { "/Xft/HintStyle", "Xft.hintstyle:" },
        { "/Xft/RGBA", "Xft.rgba:" },
        { "/Xft/Lcdfilter", "Xft.lcdfilter:" },
        { "/Xft/DPI", "Xft.dpi:" },
        { "/Gtk/CursorThemeName", "Xcursor.theme:" },
        { "/Gtk/CursorThemeSize", "Xcursor.size:" }
    };

    g_return_if_fail (XFCE_IS_XSETTINGS_HELPER (helper));

    if (G_LIKELY (helper->screens == NULL))
        return;

    xdisplay = XOpenDisplay (NULL);
    g_return_if_fail (xdisplay != NULL);

    /* get the resource string from this display from screen zero */
    str = XResourceManagerString (xdisplay);
    resource = g_string_new (str);

    /* update/insert the properties */
    for (i = 0; i < G_N_ELEMENTS (props); i++)
    {
        setting = g_hash_table_lookup (helper->settings, props[i][0]);
        if (G_LIKELY (setting != NULL))
        {
            xfce_xsettings_helper_notify_xft_update (resource, props[i][1],
                                                     setting->value);
        }
    }

    /* set for Xcursor.theme */
    g_value_init (&bool_val, G_TYPE_BOOLEAN);
    g_value_set_boolean (&bool_val, TRUE);
    xfce_xsettings_helper_notify_xft_update (resource, "Xcursor.theme_core:", &bool_val);
    g_value_unset (&bool_val);

    gdk_error_trap_push ();

    /* set the new resource manager string */
    XChangeProperty (xdisplay,
                     RootWindow (xdisplay, 0),
                     XA_RESOURCE_MANAGER, XA_STRING, 8,
                     PropModeReplace,
                     (guchar *) resource->str,
                     resource->len);

    XCloseDisplay (xdisplay);

    if (gdk_error_trap_pop () != 0)
        g_critical ("Failed to update the resource manager string");

    xfsettings_dbg (XFSD_DEBUG_XSETTINGS,
                    "resource manager (xft) changed (len=%"G_GSIZE_FORMAT")",
                    resource->len);

    g_string_free (resource, TRUE);
}
Esempio n. 11
0
gboolean
xfce_xsettings_helper_register (XfceXSettingsHelper *helper,
                                GdkDisplay          *gdkdisplay,
                                gboolean             force_replace)
{
    Display             *xdisplay;
    Window               root_window;
    Window               window;
    gchar                atom_name[64];
    Atom                 selection_atom;
    gint                 n_screens, n;

    XfceXSettingsScreen *screen;
    Time                 timestamp;
    XClientMessageEvent  xev;
    gboolean             succeed;

    g_return_val_if_fail (GDK_IS_DISPLAY (gdkdisplay), FALSE);
    g_return_val_if_fail (XFCE_IS_XSETTINGS_HELPER (helper), FALSE);
    g_return_val_if_fail (helper->screens == NULL, FALSE);

    xdisplay = GDK_DISPLAY_XDISPLAY (gdkdisplay);
    helper->xsettings_atom = XInternAtom (xdisplay, "_XSETTINGS_SETTINGS", False);

    gdk_error_trap_push ();

    n_screens = gdk_display_get_n_screens (gdkdisplay);
    for (n = 0; n < n_screens; n++)
    {
        g_snprintf (atom_name, sizeof (atom_name), "_XSETTINGS_S%d", n);
        selection_atom = XInternAtom (xdisplay, atom_name, False);

        if (!force_replace
            && XGetSelectionOwner (xdisplay, selection_atom) != None)
        {
            g_message ("Skipping screen %d, it already has an xsettings manager...", n);
            continue;
        }

        succeed = FALSE;

        /* create new window */
        root_window = RootWindow (xdisplay, n);
        window = XCreateSimpleWindow (xdisplay, root_window, -1, -1, 1, 1, 0, 0, 0);
        g_assert (window != 0);
        XSelectInput (xdisplay, window, PropertyChangeMask);

        /* get the current xserver timestamp */
        timestamp = xfce_xsettings_get_server_time (xdisplay, window);

        /* request ownership of the xsettings selection on this screen */
        XSetSelectionOwner (xdisplay, selection_atom, window, timestamp);

        /* check if the have the selection */
        if (G_LIKELY (XGetSelectionOwner (xdisplay, selection_atom) == window))
        {
            /* register this xsettings window for this screen */
            xev.type = ClientMessage;
            xev.window = root_window;
            xev.message_type = XInternAtom (xdisplay, "MANAGER", True);
            xev.format = 32;
            xev.data.l[0] = timestamp;
            xev.data.l[1] = selection_atom;
            xev.data.l[2] = window;
            xev.data.l[3] = 0;  /* manager specific data */
            xev.data.l[4] = 0;  /* manager specific data */

            if (XSendEvent (xdisplay, root_window, False,
                            StructureNotifyMask, (XEvent *)&xev) != 0)
            {
                /* the window was successfully registered as the new
                 * xsettings window for this screen */
                succeed = TRUE;
            }
            else
            {
                g_warning ("Failed to register the xsettings window for screen %d", n);
            }
        }
        else
        {
            g_warning ("Unable to get the xsettings selection for screen %d", n);
        }

        if (G_LIKELY (succeed))
        {
            /* add the window to the internal list */
            screen = g_slice_new0 (XfceXSettingsScreen);
            screen->window = window;
            screen->selection_atom = selection_atom;
            screen->xdisplay = xdisplay;
            screen->screen_num = n;

            xfsettings_dbg (XFSD_DEBUG_XSETTINGS, "%s registered on screen %d", atom_name, n);

            helper->screens = g_slist_prepend (helper->screens, screen);
        }
        else
        {
            XDestroyWindow (xdisplay, window);
        }
    }

    if (gdk_error_trap_pop () != 0)
        g_critical ("Failed to initialize screens");

    if (helper->screens != NULL)
    {
        /* watch for selection changes */
        gdk_window_add_filter (NULL, xfce_xsettings_helper_event_filter, helper);

        /* send notifications */
        xfce_xsettings_helper_notify (helper);
        xfce_xsettings_helper_notify_xft (helper);

        /* startup fontconfig monitoring */
        helper->fc_init_id = g_idle_add (xfce_xsettings_helper_fc_init, helper);

        return TRUE;
    }

    return FALSE;
}
static void
xfce_accessibility_helper_set_xkb (XfceAccessibilityHelper *helper,
                                   gulong                   mask)
{

    XkbDescPtr xkb;
    gint       delay, interval, time_to_max;
    gint       max_speed, curve;

    gdk_error_trap_push ();

    /* allocate */
    xkb = XkbAllocKeyboard ();
    if (G_LIKELY (xkb))
    {
        /* we always change this, so add it to the mask */
        SET_FLAG (mask, XkbControlsEnabledMask);

        /* if setting sticky keys, we set expiration too */
        if (HAS_FLAG (mask, XkbStickyKeysMask) ||
                HAS_FLAG (mask, XkbSlowKeysMask) ||
                HAS_FLAG (mask, XkbBounceKeysMask) ||
                HAS_FLAG (mask, XkbMouseKeysMask) ||
                HAS_FLAG (mask, XkbAccessXKeysMask))
          SET_FLAG (mask, XkbAccessXTimeoutMask);

        /* add the mouse keys values mask if needed */
        if (HAS_FLAG (mask, XkbMouseKeysMask))
            SET_FLAG (mask, XkbMouseKeysAccelMask);

        /* load the xkb controls into the structure */
        XkbGetControls (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), mask, xkb);

        /* AccessXKeys */
        if (HAS_FLAG (mask, XkbAccessXKeysMask))
        {
            if (xfconf_channel_get_bool (helper->channel, "/AccessXKeys", FALSE))
            {
                SET_FLAG (xkb->ctrls->enabled_ctrls, XkbAccessXKeysMask);
                UNSET_FLAG (xkb->ctrls->axt_ctrls_mask, XkbAccessXKeysMask);
                UNSET_FLAG (xkb->ctrls->axt_ctrls_values, XkbAccessXKeysMask);

                xfsettings_dbg (XFSD_DEBUG_ACCESSIBILITY, "AccessXKeys enabled");
            }
            else
            {
                UNSET_FLAG (xkb->ctrls->enabled_ctrls, XkbAccessXKeysMask);
                SET_FLAG (xkb->ctrls->axt_ctrls_mask, XkbAccessXKeysMask);
                UNSET_FLAG (xkb->ctrls->axt_ctrls_values, XkbAccessXKeysMask);

                xfsettings_dbg (XFSD_DEBUG_ACCESSIBILITY, "AccessXKeys disabled");
            }
        }

        /* Sticky keys */
        if (HAS_FLAG (mask, XkbStickyKeysMask))
        {
            if (xfconf_channel_get_bool (helper->channel, "/StickyKeys", FALSE))
            {
                SET_FLAG (xkb->ctrls->enabled_ctrls, XkbStickyKeysMask);
                UNSET_FLAG (xkb->ctrls->axt_ctrls_mask, XkbStickyKeysMask);
                UNSET_FLAG (xkb->ctrls->axt_ctrls_values, XkbStickyKeysMask);

                if (xfconf_channel_get_bool (helper->channel, "/StickyKeys/LatchToLock", FALSE))
                    SET_FLAG (xkb->ctrls->ax_options, XkbAX_LatchToLockMask);
                else
                    UNSET_FLAG (xkb->ctrls->ax_options, XkbAX_LatchToLockMask);

                if (xfconf_channel_get_bool (helper->channel, "/StickyKeys/TwoKeysDisable", FALSE))
                    SET_FLAG (xkb->ctrls->ax_options, XkbAX_TwoKeysMask);
                else
                    UNSET_FLAG (xkb->ctrls->ax_options, XkbAX_TwoKeysMask);

                xfsettings_dbg (XFSD_DEBUG_ACCESSIBILITY, "stickykeys enabled (ax_options=%d)",
                                xkb->ctrls->ax_options);
            }
            else
            {
                UNSET_FLAG (xkb->ctrls->enabled_ctrls, XkbStickyKeysMask);
                SET_FLAG (xkb->ctrls->axt_ctrls_mask, XkbStickyKeysMask);
                UNSET_FLAG (xkb->ctrls->axt_ctrls_values, XkbStickyKeysMask);

                xfsettings_dbg (XFSD_DEBUG_ACCESSIBILITY, "stickykeys disabled");
            }
        }

        /* Slow keys */
        if (HAS_FLAG (mask, XkbSlowKeysMask))
        {
            if (xfconf_channel_get_bool (helper->channel, "/SlowKeys", FALSE))
            {
                SET_FLAG (xkb->ctrls->enabled_ctrls, XkbSlowKeysMask);
                UNSET_FLAG (xkb->ctrls->axt_ctrls_mask, XkbSlowKeysMask);
                UNSET_FLAG (xkb->ctrls->axt_ctrls_values, XkbSlowKeysMask);

                delay = xfconf_channel_get_int (helper->channel, "/SlowKeys/Delay", 100);
                xkb->ctrls->slow_keys_delay = CLAMP (delay, 1, G_MAXUSHORT);

                xfsettings_dbg (XFSD_DEBUG_ACCESSIBILITY, "slowkeys enabled (delay=%d)",
                                xkb->ctrls->slow_keys_delay);
            }
            else
            {
                UNSET_FLAG (xkb->ctrls->enabled_ctrls, XkbSlowKeysMask);
                SET_FLAG (xkb->ctrls->axt_ctrls_mask, XkbSlowKeysMask);
                UNSET_FLAG (xkb->ctrls->axt_ctrls_values, XkbSlowKeysMask);

                xfsettings_dbg (XFSD_DEBUG_ACCESSIBILITY, "slowkeys disabled");
            }
        }

        /* Bounce keys */
        if (HAS_FLAG (mask, XkbBounceKeysMask))
        {
            if (xfconf_channel_get_bool (helper->channel, "/BounceKeys", FALSE))
            {
                SET_FLAG (xkb->ctrls->enabled_ctrls, XkbBounceKeysMask);
                UNSET_FLAG (xkb->ctrls->axt_ctrls_mask, XkbBounceKeysMask);
                UNSET_FLAG (xkb->ctrls->axt_ctrls_values, XkbBounceKeysMask);

                delay = xfconf_channel_get_int (helper->channel, "/BounceKeys/Delay", 100);
                xkb->ctrls->debounce_delay = CLAMP (delay, 1, G_MAXUSHORT);

                xfsettings_dbg (XFSD_DEBUG_ACCESSIBILITY, "bouncekeys enabled (delay=%d)",
                                xkb->ctrls->debounce_delay);
            }
            else
            {
                UNSET_FLAG (xkb->ctrls->enabled_ctrls, XkbBounceKeysMask);
                SET_FLAG (xkb->ctrls->axt_ctrls_mask, XkbBounceKeysMask);
                UNSET_FLAG (xkb->ctrls->axt_ctrls_values, XkbBounceKeysMask);

                xfsettings_dbg (XFSD_DEBUG_ACCESSIBILITY, "bouncekeys disabled");
            }
        }

        /* Mouse keys */
        if (HAS_FLAG (mask, XkbMouseKeysMask))
        {
            if (xfconf_channel_get_bool (helper->channel, "/MouseKeys", FALSE))
            {
                SET_FLAG (xkb->ctrls->enabled_ctrls, XkbMouseKeysMask);
                UNSET_FLAG (xkb->ctrls->axt_ctrls_mask, XkbMouseKeysMask);
                UNSET_FLAG (xkb->ctrls->axt_ctrls_values, XkbMouseKeysMask);

                /* get values */
                delay = xfconf_channel_get_int (helper->channel, "/MouseKeys/Delay", 160);
                interval = xfconf_channel_get_int (helper->channel, "/MouseKeys/Interval", 20);
                time_to_max = xfconf_channel_get_int (helper->channel, "/MouseKeys/TimeToMax", 3000);
                max_speed = xfconf_channel_get_int (helper->channel, "/MouseKeys/MaxSpeed", 1000);
                curve = xfconf_channel_get_int (helper->channel, "/MouseKeys/Curve", 0);

                /* calculate maximum speed and to to reach it */
                interval = CLAMP (interval, 1, G_MAXUSHORT);
                max_speed = (max_speed * interval) / 1000;
                time_to_max = (time_to_max + interval / 2) / interval;

                /* set new values, clamp to limits */
                xkb->ctrls->mk_delay = CLAMP (delay, 1, G_MAXUSHORT);
                xkb->ctrls->mk_interval = interval;
                xkb->ctrls->mk_time_to_max = CLAMP (time_to_max, 1, G_MAXUSHORT);
                xkb->ctrls->mk_max_speed = CLAMP (max_speed, 1, G_MAXUSHORT);
                xkb->ctrls->mk_curve = CLAMP (curve, -1000, 1000);

                xfsettings_dbg (XFSD_DEBUG_ACCESSIBILITY, "mousekeys enabled (delay=%d, interval=%d, "
                                "time_to_max=%d, max_speed=%d, curve=%d)",
                                xkb->ctrls->mk_delay, xkb->ctrls->mk_interval,
                                xkb->ctrls->mk_time_to_max, xkb->ctrls->mk_max_speed,
                                xkb->ctrls->mk_curve);
            }
            else
            {
                UNSET_FLAG (xkb->ctrls->enabled_ctrls, XkbMouseKeysMask);
                SET_FLAG (xkb->ctrls->axt_ctrls_mask, XkbMouseKeysMask);
                UNSET_FLAG (xkb->ctrls->axt_ctrls_values, XkbMouseKeysMask);
                UNSET_FLAG (mask, XkbMouseKeysAccelMask);

                xfsettings_dbg (XFSD_DEBUG_ACCESSIBILITY, "mousekeys disabled");
            }
        }

        /* set the modified controls */
        if (!XkbSetControls (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), mask, xkb))
            g_message ("Setting the xkb controls failed");

        /* free the structure */
        XkbFreeControls (xkb, mask, True);
        XFree (xkb);
    }
    else
    {
        /* warning */
        g_critical ("XkbAllocKeyboard() returned a null pointer");
    }

    if (gdk_error_trap_pop () != 0)
       g_critical ("Failed to set keyboard controls");
}