// 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 ?? }
/* * Gets the state from the window property */ gboolean xkl_engine_get_toplevel_window_state(XklEngine * engine, Window toplevel_win, XklState * state_out) { Atom type_ret; int format_ret; unsigned long nitems, rest; CARD32 *prop = NULL; gboolean ret = FALSE; gint grp = -1; guint inds = 0; if ((XGetWindowProperty (xkl_engine_get_display(engine), toplevel_win, xkl_engine_priv(engine, atoms)[XKLAVIER_STATE], 0L, XKLAVIER_STATE_PROP_LENGTH, False, XA_INTEGER, &type_ret, &format_ret, &nitems, &rest, (unsigned char **) (void *) &prop) == Success) && (type_ret == XA_INTEGER) && (format_ret == 32)) { grp = prop[0]; if (grp >= xkl_engine_get_num_groups(engine) || grp < 0) grp = 0; inds = prop[1]; if (state_out != NULL) { state_out->group = grp; state_out->indicators = inds; } if (prop != NULL) XFree(prop); ret = TRUE; } if (ret) xkl_debug(150, "Appwin " WINID_FORMAT ", '%s' has the group %d, indicators %X\n", toplevel_win, xkl_get_debug_window_title(engine, toplevel_win), grp, inds); else xkl_debug(150, "Appwin " WINID_FORMAT ", '%s' does not have state\n", toplevel_win, xkl_get_debug_window_title(engine, toplevel_win)); return ret; }
// If the group changes static void _state_changed (XklEngine *pEngine, XklEngineStateChange type, gint iGroup, gboolean bRestore) { XklState *state = xkl_engine_get_current_state (myData.pEngine); cd_debug ("State Changed: %d -> %d (%d) ; %d", myData.iCurrentGroup, state->group, iGroup, state->indicators); if (type == GROUP_CHANGED && myData.iCurrentGroup != state->group) // new keyboard layout { gchar *cShortGroupName = NULL; const gchar *cCurrentGroup = NULL; // Get the current num group guint n = xkl_engine_get_num_groups (myData.pEngine); g_return_if_fail (n > 0); int iNewGroup = MAX (0, MIN (n-1, state->group)); // workaround for 64bits to avoid strange numbers in 'state' const gchar **pGroupNames = xkl_engine_get_groups_names (myData.pEngine); g_return_if_fail (pGroupNames != NULL); cCurrentGroup = pGroupNames[iNewGroup]; g_return_if_fail (cCurrentGroup != NULL); cd_debug (" group name : %s (%d groups)", cCurrentGroup, n); // build the displayed group name cShortGroupName = g_strndup (cCurrentGroup, myConfig.iNLetters); int index = 0; int i; for (i = 0; i < state->group; i ++) // look for groups before us having the same name. { if (strncmp (cCurrentGroup, pGroupNames[i], myConfig.iNLetters) == 0) index ++; } if (index != 0) // add a number if several groups have the same name. { gchar *tmp = cShortGroupName; cShortGroupName = g_strdup_printf ("%s%d", cShortGroupName, index+1); g_free (tmp); } myData.iCurrentGroup = state->group; cd_xkbd_update_icon (cCurrentGroup, cShortGroupName, TRUE); g_free (cShortGroupName); } else if (type == INDICATORS_CHANGED) cd_debug ("Indicators changed"); // according to libxklavier/tests/test_monitor.c, it should work... but I have to miss something }