static void popup_menu_set_group (GtkMenuItem * item, gpointer param) { gint group_number = GPOINTER_TO_INT (param); XklEngine *engine = gkbd_status_get_xkl_engine (); XklState st; Window cur; st.group = group_number; xkl_engine_allow_one_switch_to_secondary_group (engine); cur = xkl_engine_get_current_window (engine); if (cur != (Window) NULL) { xkl_debug (150, "Enforcing the state %d for window %lx\n", st.group, cur); xkl_engine_save_state (engine, xkl_engine_get_current_window (engine), &st); /* XSetInputFocus( GDK_DISPLAY(), cur, RevertToNone, CurrentTime );*/ } else { xkl_debug (150, "??? Enforcing the state %d for unknown window\n", st.group); /* strange situation - bad things can happen */ } xkl_engine_lock_group (engine, st.group); }
// A scroll on the icon void cd_xkbd_set_prev_next_group (int iDelta) { XklState *state = xkl_engine_get_current_state (myData.pEngine); cd_debug ("keyboard current state : %d;%d +%d", state->group, state->indicators, iDelta); int i = 0, n = xkl_engine_get_num_groups (myData.pEngine); g_return_if_fail (n > 0); int iCurrentGroup = MAX (0, MIN (n-1, state->group)); // on blinde car libxklavier peut bugger en 64bits. const gchar **pGroupNames = xkl_engine_get_groups_names (myData.pEngine); do // on passe au groupe suivant/precedent en sautant les faux (-). { i ++; iCurrentGroup += iDelta; // xkl_engine_get_next_group ne marche pas. if (iCurrentGroup == n) iCurrentGroup = 0; else if (iCurrentGroup < 0) iCurrentGroup = n - 1; } while (i < n && (pGroupNames[iCurrentGroup] == NULL || *pGroupNames[iCurrentGroup] == '-')); state->group = iCurrentGroup; cd_debug ("keyboard new state : %d", state->group); xkl_engine_allow_one_switch_to_secondary_group (myData.pEngine); // sert a quoi ?? Window Xid = xkl_engine_get_current_window (myData.pEngine); xkl_engine_save_state (myData.pEngine, Xid, state); xkl_engine_lock_group (myData.pEngine, state->group); // sert a quoi ?? }
static void popup_menu_set_group (gint group_number, gboolean only_menu) { XklEngine *engine = gkbd_status_get_xkl_engine (); XklState *st = xkl_engine_get_current_state(engine); Window cur; st->group = group_number; xkl_engine_allow_one_switch_to_secondary_group (engine); cur = xkl_engine_get_current_window (engine); if (cur != (Window) NULL) { xkl_debug (150, "Enforcing the state %d for window %lx\n", st->group, cur); xkl_engine_save_state (engine, xkl_engine_get_current_window (engine), st); /* XSetInputFocus( GDK_DISPLAY(), cur, RevertToNone, CurrentTime );*/ } else { xkl_debug (150, "??? Enforcing the state %d for unknown window\n", st->group); /* strange situation - bad things can happen */ } if (!only_menu) xkl_engine_lock_group (engine, st->group); }
// Select the layout from the menu void cd_xkbd_set_group (int iNumGroup) { XklState *state = xkl_engine_get_current_state (myData.pEngine); cd_debug ("keyboard current state : %d;%d", state->group, state->indicators); state->group = iNumGroup; Window Xid = xkl_engine_get_current_window (myData.pEngine); xkl_engine_allow_one_switch_to_secondary_group (myData.pEngine); // sert a quoi ?? xkl_engine_save_state (myData.pEngine, Xid, state); xkl_engine_lock_group (myData.pEngine, state->group); // sert a quoi ?? }
static void apply_xkb_settings (void) { GConfClient *conf_client; GkbdKeyboardConfig current_sys_kbd_config; int group_to_activate = -1; char *gdm_layout; char *s; if (!inited_ok) return; conf_client = gconf_client_get_default (); /* With GDM the user can already set a layout from the login * screen. Try to keep that setting. * We clear gdm_keyboard_layout early, so we don't risk * recursion from gconf notification. */ gdm_layout = g_strdup (gdm_keyboard_layout); gdm_keyboard_layout = NULL; /* gdm's configuration and $GDM_KEYBOARD_LAYOUT separates layout and * variant with a space, but gconf uses tabs; so convert to be robust * with both */ for (s = gdm_layout; s && *s; ++s) { if (*s == ' ') { *s = '\t'; } } if (gdm_layout != NULL) { GSList *layouts; GSList *found_node; int max_groups; max_groups = xkl_engine_get_max_num_groups (xkl_engine); layouts = gconf_client_get_list (conf_client, GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, GCONF_VALUE_STRING, NULL); /* Add the layout if it doesn't already exist. XKB limits the * total number of layouts. If we already have the maximum * number of layouts configured, we replace the last one. This * prevents the list from becoming full if the user has a habit * of selecting many different keyboard layouts in GDM. */ found_node = g_slist_find_custom (layouts, gdm_layout, (GCompareFunc) g_strcmp0); if (!found_node) { /* Insert at the last valid place, or at the end of * list, whichever comes first */ layouts = g_slist_insert (layouts, g_strdup (gdm_layout), max_groups - 1); if (g_slist_length (layouts) > max_groups) { GSList *last; GSList *free_layouts; last = g_slist_nth (layouts, max_groups - 1); free_layouts = last->next; last->next = NULL; g_slist_foreach (free_layouts, (GFunc) g_free, NULL); g_slist_free (free_layouts); } gconf_client_set_list (conf_client, GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, GCONF_VALUE_STRING, layouts, NULL); } g_slist_foreach (layouts, (GFunc) g_free, NULL); g_slist_free (layouts); } gkbd_keyboard_config_init (¤t_sys_kbd_config, conf_client, xkl_engine); gkbd_keyboard_config_load_from_gconf (¤t_kbd_config, &initial_sys_kbd_config); gkbd_keyboard_config_load_from_x_current (¤t_sys_kbd_config, NULL); if (!try_activating_xkb_config_if_new (¤t_sys_kbd_config)) { if (filter_xkb_config ()) { if (!try_activating_xkb_config_if_new (¤t_sys_kbd_config)) { g_warning ("Could not activate the filtered XKB configuration"); activation_error (); } } else { g_warning ("Could not activate the XKB configuration"); activation_error (); } } else xkl_debug (100, "Actual KBD configuration was not changed: redundant notification\n"); if (gdm_layout != NULL) { /* If there are multiple layouts, * try to find the one closest to the gdm layout */ GSList *l; int i; size_t len = strlen (gdm_layout); for (i = 0, l = current_kbd_config.layouts_variants; l; i++, l = l->next) { char *lv = l->data; if (strncmp (lv, gdm_layout, len) == 0 && (lv[len] == '\0' || lv[len] == '\t')) { group_to_activate = i; break; } } } g_free (gdm_layout); if (group_to_activate != -1) xkl_engine_lock_group (current_config.engine, group_to_activate); gkbd_keyboard_config_term (¤t_sys_kbd_config); }
/* * "Adds" app window to the set of managed windows. * Actually, no data structures involved. The only thing we do is save app state * and register ourselves us listeners. * Note: User's callback is called */ void xkl_engine_add_toplevel_window(XklEngine * engine, Window toplevel_win, Window parent, gboolean ignore_existing_state, XklState * init_state) { XklState state = *init_state; gint default_group_to_use = -1; GValue params[3]; GValue rv; guint signal_id; if (toplevel_win == xkl_engine_priv(engine, root_window)) xkl_debug(150, "??? root app win ???\n"); xkl_debug(150, "Trying to add window " WINID_FORMAT "/%s with group %d\n", toplevel_win, xkl_get_debug_window_title(engine, toplevel_win), init_state->group); if (!ignore_existing_state) { gboolean have_state = xkl_engine_get_toplevel_window_state(engine, toplevel_win, &state); if (have_state) { xkl_debug(150, "The window " WINID_FORMAT " does not require to be added, it already has the xklavier state \n", toplevel_win); return; } } memset(params, 0, sizeof(params)); g_value_init(params, XKL_TYPE_ENGINE); g_value_set_object(params, engine); g_value_init(params + 1, G_TYPE_LONG); g_value_set_long(params + 1, toplevel_win); g_value_init(params + 2, G_TYPE_LONG); g_value_set_long(params + 2, parent); memset(&rv, 0, sizeof(rv)); g_value_init(&rv, G_TYPE_INT); g_value_set_int(&rv, default_group_to_use); signal_id = g_signal_lookup("new-toplevel-window", xkl_engine_get_type()); g_signal_emitv(params, signal_id, 0, &rv); default_group_to_use = g_value_get_int(&rv); if (default_group_to_use == -1) { Window transient_for = 0; if (XGetTransientForHint(xkl_engine_get_display(engine), toplevel_win, &transient_for)) { if (transient_for) { XklState trans_state; gboolean have_state = xkl_engine_get_toplevel_window_state(engine, transient_for, &trans_state); if (have_state) { default_group_to_use = trans_state.group; } } } } if (default_group_to_use == -1) default_group_to_use = xkl_engine_priv(engine, default_group); if (default_group_to_use != -1) state.group = default_group_to_use; xkl_engine_save_toplevel_window_state(engine, toplevel_win, &state); xkl_engine_select_input_merging(engine, toplevel_win, FocusChangeMask | PropertyChangeMask); if (default_group_to_use != -1) { if (xkl_engine_priv(engine, curr_toplvl_win) == toplevel_win) { if ((xkl_engine_priv(engine, secondary_groups_mask) & (1 << default_group_to_use)) != 0) xkl_engine_allow_one_switch_to_secondary_group (engine); xkl_engine_lock_group(engine, default_group_to_use); } } if (parent == (Window) NULL) parent = xkl_engine_get_registered_parent(engine, toplevel_win); xkl_debug(150, "done\n"); }