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 (&current_sys_kbd_config,
				   conf_client, xkl_engine);

	gkbd_keyboard_config_load_from_gconf (&current_kbd_config,
					      &initial_sys_kbd_config);

	gkbd_keyboard_config_load_from_x_current (&current_sys_kbd_config,
						  NULL);

	if (!try_activating_xkb_config_if_new (&current_sys_kbd_config)) {
		if (filter_xkb_config ()) {
			if (!try_activating_xkb_config_if_new
			    (&current_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 (&current_sys_kbd_config);
}
Esempio n. 6
0
/*
 * "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");
}