static void
xkb_layout_chooser_row_activated (GtkTreeView * tree_view,
				  GtkTreePath * path,
				  GtkTreeViewColumn * column,
				  GtkBuilder * chooser_dialog)
{
	GtkWidget *add_button = CWID ("btnOk");
	GtkWidget *dialog = CWID ("xkb_layout_chooser");

	if (gtk_widget_is_sensitive (add_button))
		gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
}
static void
xkb_layout_chooser_available_layouts_fill (GtkBuilder *
					   chooser_dialog,
					   const gchar cblid[],
					   const gchar cbvid[],
					   LayoutIterFunc layout_iterator,
					   ConfigItemProcessFunc
					   layout_handler,
					   GCallback combo_changed_notify)
{
	GtkWidget *cbl = CWID (cblid);
	GtkWidget *cbev = CWID (cbvid);
	GtkCellRenderer *renderer;
	GtkListStore *list_store;

	list_store = gtk_list_store_new
	    (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
	     G_TYPE_STRING);

	gtk_combo_box_set_model (GTK_COMBO_BOX (cbl),
				 GTK_TREE_MODEL (list_store));

	renderer = gtk_cell_renderer_text_new ();
	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cbl), renderer, TRUE);
	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (cbl),
					renderer, "markup",
					COMBO_BOX_MODEL_COL_VISIBLE, NULL);

	layout_iterator (config_registry, layout_handler, list_store);

	/* Turn on sorting after filling the model since that's faster */
	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE
					      (list_store),
					      COMBO_BOX_MODEL_COL_SORT,
					      GTK_SORT_ASCENDING);

	g_signal_connect_swapped (G_OBJECT (cbl), "changed",
				  combo_changed_notify, chooser_dialog);

	/* Setup the variants combo */
	renderer = gtk_cell_renderer_text_new ();
	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cbev),
				    renderer, TRUE);
	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (cbev),
					renderer, "markup",
					COMBO_BOX_MODEL_COL_VISIBLE, NULL);

	g_signal_connect_swapped (G_OBJECT (cbev), "changed",
				  G_CALLBACK
				  (xkb_layout_chooser_available_variant_changed),
				  chooser_dialog);
}
static void
xkb_layout_filter_changed (GtkBuilder * chooser_dialog)
{
	GtkTreeModelFilter *filtered_model =
	    GTK_TREE_MODEL_FILTER (gtk_builder_get_object (chooser_dialog,
							   "filtered_layout_list_model"));
	GtkWidget *xkb_layout_filter = CWID ("xkb_layout_filter");
	const gchar *pattern =
	    gtk_entry_get_text (GTK_ENTRY (xkb_layout_filter));
	gchar *upattern = g_utf8_strup (pattern, -1);

	if (!g_strcmp0 (pattern, "")) {
		g_object_set (G_OBJECT (xkb_layout_filter),
			      "secondary-icon-name", "edit-find-symbolic",
			      "secondary-icon-activatable", FALSE,
			      "secondary-icon-sensitive", FALSE, NULL);
	} else {
		g_object_set (G_OBJECT (xkb_layout_filter),
			      "secondary-icon-name", "edit-clear-symbolic",
			      "secondary-icon-activatable", TRUE,
			      "secondary-icon-sensitive", TRUE, NULL);
	}

	if (search_pattern_list != NULL)
		g_strfreev (search_pattern_list);

	search_pattern_list = g_strsplit (upattern, " ", -1);
	g_free (upattern);

	gtk_tree_model_filter_refilter (filtered_model);
}
static void
xkb_layout_chooser_print (GtkBuilder * chooser_dialog)
{
	GtkWidget *chooser = CWID ("xkb_layout_chooser");
	GtkWidget *kbdraw =
	    GTK_WIDGET (g_object_get_data (G_OBJECT (chooser), "kbdraw"));
	const char *id =
	    xkb_layout_chooser_get_selected_id (chooser_dialog);
	char *descr = xkb_layout_description_utf8 (id);
	matekbd_keyboard_drawing_print (MATEKBD_KEYBOARD_DRAWING
				     (kbdraw),
				     GTK_WINDOW (CWID
						 ("xkb_layout_chooser")),
				     descr);
	g_free (descr);
}
static void
xkb_layout_chooser_selection_changed (GtkTreeSelection * selection,
				      GtkBuilder * chooser_dialog)
{
	GList *selected_layouts =
	    gtk_tree_selection_get_selected_rows (selection, NULL);
	GtkWidget *add_button = CWID ("btnOk");
	GtkWidget *preview_button = CWID ("btnPreview");
	gboolean anything_selected = g_list_length (selected_layouts) == 1;
	gboolean dupe =
	    xkb_layout_chooser_selection_dupe (GTK_DIALOG
					       (CWID
						("xkb_layout_chooser")));

	gtk_widget_set_sensitive (add_button, anything_selected && !dupe);
	gtk_widget_set_sensitive (preview_button, anything_selected);
}
static void
remove_display_link (CcWacomPagePrivate *priv)
{
	gtk_widget_destroy (WID ("display-link"));

        gtk_container_child_set (CWID ("main-grid"),
                                 WID ("tablet-buttons-box"),
                                 "top_attach", 2, NULL);
}
static void
update_tablet_ui (CcWacomPage *page,
		  int          layout)
{
	CcWacomPagePrivate *priv;
	gboolean has_monitor = FALSE;

	priv = page->priv;

	/* Hide the pad buttons if no pad is present */
	gtk_widget_set_visible (WID ("map-buttons-button"), priv->pad != NULL);

	switch (layout) {
	case LAYOUT_NORMAL:
		remove_left_handed (priv);
		remove_display_link (priv);
		break;
	case LAYOUT_REVERSIBLE:
		remove_display_link (priv);
		break;
	case LAYOUT_SCREEN:
		remove_left_handed (priv);

		gtk_widget_destroy (WID ("combo-tabletmode"));
		gtk_widget_destroy (WID ("label-trackingmode"));
		gtk_widget_destroy (WID ("display-mapping-button"));

		gtk_widget_show (WID ("button-calibrate"));
		if (csd_wacom_device_get_display_monitor (priv->stylus) >= 0)
			has_monitor = TRUE;
		gtk_widget_set_sensitive (WID ("button-calibrate"), has_monitor);
		gtk_widget_show (WID ("display-link"));

		gtk_container_child_set (CWID ("main-grid"),
					 WID ("tablet-buttons-box"),
					 "top_attach", 1, NULL);
		gtk_container_child_set (CWID ("main-grid"),
					 WID ("display-link"),
					 "top_attach", 2, NULL);
		break;
	default:
		g_assert_not_reached ();
	}
}
static void
xkb_layout_chooser_enable_disable_buttons (GtkBuilder * chooser_dialog)
{
	GtkWidget *cbv =
	    CWID (gtk_notebook_get_current_page
		  (GTK_NOTEBOOK (CWID ("choosers_nb"))) ?
		  "xkb_language_variants_available" :
		  "xkb_country_variants_available");
	GtkTreeIter viter;
	gboolean enable_ok =
	    gtk_combo_box_get_active_iter (GTK_COMBO_BOX (cbv),
					   &viter);

	gtk_dialog_set_response_sensitive (GTK_DIALOG
					   (CWID
					    ("xkb_layout_chooser")),
					   GTK_RESPONSE_OK, enable_ok);
	gtk_widget_set_sensitive (CWID ("btnPrint"), enable_ok);
}
static void
xkb_layout_chooser_available_language_variants_fill (GtkBuilder *
						     chooser_dialog)
{
	GtkWidget *cbl = CWID ("xkb_languages_available");
	GtkWidget *cbv = CWID ("xkb_language_variants_available");
	GtkListStore *list_store;
	GtkTreeIter liter;

	list_store = gtk_list_store_new
	    (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
	     G_TYPE_STRING);

	if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (cbl), &liter)) {
		GtkTreeModel *lm =
		    gtk_combo_box_get_model (GTK_COMBO_BOX (cbl));
		gchar *lang_id;
		AddVariantData data = { list_store, 0 };

		/* Now the variants of the selected layout */
		gtk_tree_model_get (lm, &liter,
				    COMBO_BOX_MODEL_COL_REAL_ID,
				    &lang_id, -1);
		data.lang_id = lang_id;

		xkl_config_registry_foreach_language_variant
		    (config_registry, lang_id, (TwoConfigItemsProcessFunc)
		     xkb_layout_chooser_add_variant_to_available_language_variants,
		     &data);
		g_free (lang_id);
	}

	/* Turn on sorting after filling the store, since that's faster */
	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE
					      (list_store),
					      COMBO_BOX_MODEL_COL_SORT,
					      GTK_SORT_ASCENDING);

	gtk_combo_box_set_model (GTK_COMBO_BOX (cbv),
				 GTK_TREE_MODEL (list_store));
	gtk_combo_box_set_active (GTK_COMBO_BOX (cbv), 0);
}
gchar *
xkb_layout_chooser_get_selected_id (GtkBuilder * chooser_dialog)
{
	GtkWidget *cbv =
	    CWID (gtk_notebook_get_current_page
		  (GTK_NOTEBOOK (CWID ("choosers_nb"))) ?
		  "xkb_language_variants_available" :
		  "xkb_country_variants_available");
	GtkTreeModel *vm = gtk_combo_box_get_model (GTK_COMBO_BOX (cbv));
	GtkTreeIter viter;
	gchar *v_id;

	if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (cbv), &viter))
		return NULL;

	gtk_tree_model_get (vm, &viter,
			    COMBO_BOX_MODEL_COL_XKB_ID, &v_id, -1);

	return v_id;
}
void
xkb_layout_preview_update (GladeXML * chooser_dialog)
{
#ifdef HAVE_X11_EXTENSIONS_XKB_H
	GtkWidget *chooser = CWID ("xkb_layout_chooser");
	GtkWidget *kbdraw =
	    GTK_WIDGET (g_object_get_data (G_OBJECT (chooser), "kbdraw"));
	gchar *id = xkb_layout_chooser_get_selected_id (chooser_dialog);
	xkb_layout_preview_set_drawing_layout (kbdraw, id);
	g_free (id);
#endif
}
/* Create popup dialog */
void
xkb_options_popup_dialog (GtkBuilder * dialog)
{
	GtkWidget *chooser;

	chooser_dialog = gtk_builder_new ();
	gtk_builder_add_from_file (chooser_dialog, CINNAMONCC_UI_DIR
				   "/cinnamon-region-panel-options-dialog.ui",
				   NULL);

	chooser = CWID ("xkb_options_dialog");
	gtk_window_set_transient_for (GTK_WINDOW (chooser),
				      GTK_WINDOW (gtk_widget_get_toplevel (WID ("region_notebook"))));
	gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
	xkb_options_load_options (chooser_dialog);

	g_signal_connect (chooser, "response",
			  G_CALLBACK (chooser_response_cb), dialog);
	gtk_widget_show (chooser);
}
/* Create popup dialog */
void
xkb_options_popup_dialog (GtkBuilder * dialog)
{
	GtkWidget *chooser;

	chooser_dialog = gtk_builder_new ();
    gtk_builder_add_from_file (chooser_dialog, MATECC_UI_DIR
                               "/mate-keyboard-properties-options-dialog.ui",
                               NULL);

	chooser = CWID ("xkb_options_dialog");
	gtk_window_set_transient_for (GTK_WINDOW (chooser),
				      GTK_WINDOW (WID
						  ("keyboard_dialog")));
	xkb_options_load_options (chooser_dialog);

	g_signal_connect (chooser, "response",
			  G_CALLBACK (chooser_response_cb), dialog);

	gtk_dialog_run (GTK_DIALOG (chooser));
}
static void
xkb_layout_chooser_response (GtkDialog * dialog,
			     gint response, GtkBuilder * chooser_dialog)
{
	GdkRectangle rect;

	if (response == GTK_RESPONSE_OK) {
		gchar *selected_id = (gchar *)
		    xkb_layout_chooser_get_selected_id (chooser_dialog);

		if (selected_id != NULL) {
			GSList *layouts_list =
			    xkb_layouts_get_selected_list ();

			selected_id = g_strdup (selected_id);

			layouts_list =
			    g_slist_append (layouts_list, selected_id);
			xkb_layouts_set_selected_list (layouts_list);

			xkl_layout_chooser_add_default_switcher_if_necessary
			    (layouts_list);

			clear_xkb_elements_list (layouts_list);
		}
	} else if (response == gtk_dialog_get_response_for_widget
		   (dialog, CWID ("btnPrint"))) {
		xkb_layout_chooser_print (chooser_dialog);
		g_signal_stop_emission_by_name (dialog, "response");
		return;
	}

	gtk_window_get_position (GTK_WINDOW (dialog), &rect.x, &rect.y);
	gtk_window_get_size (GTK_WINDOW (dialog), &rect.width,
			     &rect.height);
	matekbd_preview_save_position (&rect);
}
GtkWidget *
xkb_layout_choose (GtkBuilder * dialog)
{
	GtkBuilder *chooser_dialog = gtk_builder_new ();
	GtkWidget *chooser, *xkb_filtered_layouts_list, *xkb_layout_filter;
	GtkTreeViewColumn *visible_column;
	GtkTreeSelection *selection;
	GtkListStore *model;
	GtkTreeModelFilter *filtered_model;

	gtk_builder_add_from_file (chooser_dialog, GNOMECC_UI_DIR
				   "/gnome-region-panel-layout-chooser.ui",
				   NULL);
	chooser = CWID ("xkb_layout_chooser");
	xkb_filtered_layouts_list = CWID ("xkb_filtered_layouts_list");
	xkb_layout_filter = CWID ("xkb_layout_filter");

	g_object_set_data (G_OBJECT (chooser), "xkb_filtered_layouts_list",
			   xkb_filtered_layouts_list);
	visible_column =
	    gtk_tree_view_column_new_with_attributes ("Layout",
						      gtk_cell_renderer_text_new
						      (), "markup",
						      COMBO_BOX_MODEL_COL_VISIBLE,
						      NULL);

	gtk_window_set_transient_for (GTK_WINDOW (chooser),
				      GTK_WINDOW
				      (gtk_widget_get_toplevel
				       (WID ("region_notebook"))));

	gtk_tree_view_append_column (GTK_TREE_VIEW
				     (xkb_filtered_layouts_list),
				     visible_column);
	g_signal_connect_swapped (G_OBJECT (xkb_layout_filter),
				  "notify::text",
				  G_CALLBACK
				  (xkb_layout_filter_changed),
				  chooser_dialog);

	g_signal_connect (G_OBJECT (xkb_layout_filter), "icon-release",
			  G_CALLBACK (xkb_layout_filter_clear), NULL);

	selection =
	    gtk_tree_view_get_selection (GTK_TREE_VIEW
					 (xkb_filtered_layouts_list));

	g_signal_connect (G_OBJECT (selection),
			  "changed",
			  G_CALLBACK
			  (xkb_layout_chooser_selection_changed),
			  chooser_dialog);

	xkb_layout_chooser_selection_changed (selection, chooser_dialog);

	g_signal_connect (G_OBJECT (xkb_filtered_layouts_list),
			  "row-activated",
			  G_CALLBACK (xkb_layout_chooser_row_activated),
			  chooser_dialog);

	filtered_model =
	    GTK_TREE_MODEL_FILTER (gtk_builder_get_object
				   (chooser_dialog,
				    "filtered_layout_list_model"));
	model =
	    GTK_LIST_STORE (gtk_builder_get_object
			    (chooser_dialog, "layout_list_model"));

	left_bracket_regex = g_regex_new ("<", 0, 0, NULL);

	xkl_config_registry_search_by_pattern (config_registry,
					       NULL,
					       (TwoConfigItemsProcessFunc)
					       (xkl_layout_add_to_list),
					       chooser_dialog);

	g_regex_unref (left_bracket_regex);

	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
					      COMBO_BOX_MODEL_COL_SORT,
					      GTK_SORT_ASCENDING);

	gtk_tree_model_filter_set_visible_func (filtered_model,
						xkb_filter_layouts,
						NULL, NULL);

	gtk_widget_grab_focus (xkb_layout_filter);

	gtk_widget_show (chooser);

	return chooser;
}
void
xkb_layout_choose (GtkBuilder * dialog)
{
	GtkBuilder *chooser_dialog;

	chooser_dialog = gtk_builder_new ();
	gtk_builder_add_from_file (chooser_dialog, MATECC_UI_DIR
				   "/mate-keyboard-properties-layout-chooser.ui",
				   NULL);
	GtkWidget *chooser = CWID ("xkb_layout_chooser");
	GtkWidget *lang_chooser = CWID ("xkb_languages_available");
	GtkWidget *notebook = CWID ("choosers_nb");
	GtkWidget *kbdraw = NULL;
	GtkWidget *toplevel = NULL;

	gtk_window_set_transient_for (GTK_WINDOW (chooser),
				      GTK_WINDOW (WID
						  ("keyboard_dialog")));

	xkb_layout_chooser_available_layouts_fill (chooser_dialog,
						   "xkb_countries_available",
						   "xkb_country_variants_available",
						   xkl_config_registry_foreach_country,
						   (ConfigItemProcessFunc)
						   xkb_layout_chooser_add_country_to_available_countries,
						   G_CALLBACK
						   (xkb_layout_chooser_available_country_changed));
	xkb_layout_chooser_available_layouts_fill (chooser_dialog,
						   "xkb_languages_available",
						   "xkb_language_variants_available",
						   xkl_config_registry_foreach_language,
						   (ConfigItemProcessFunc)
						   xkb_layout_chooser_add_language_to_available_languages,
						   G_CALLBACK
						   (xkb_layout_chooser_available_language_changed));

	g_signal_connect_after (G_OBJECT (notebook), "switch_page",
				G_CALLBACK
				(xkb_layout_chooser_page_changed),
				chooser_dialog);

	gtk_combo_box_set_active (GTK_COMBO_BOX
				  (CWID ("xkb_countries_available")),
				  FALSE);

	if (gtk_tree_model_iter_n_children
	    (gtk_combo_box_get_model (GTK_COMBO_BOX (lang_chooser)),
	     NULL)) {
		gtk_combo_box_set_active (GTK_COMBO_BOX
					  (CWID
					   ("xkb_languages_available")),
					  FALSE);
	} else {
		/* If language info is not available - remove the corresponding tab,
		   pretend there is no notebook at all */
		gtk_notebook_remove_page (GTK_NOTEBOOK (notebook), 1);
		gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook),
					    FALSE);
		gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook),
					      FALSE);
	}

#ifdef HAVE_X11_EXTENSIONS_XKB_H
	if (!strcmp (xkl_engine_get_backend_name (engine), "XKB")) {
		kbdraw = xkb_layout_preview_create_widget (chooser_dialog);
		g_object_set_data (G_OBJECT (chooser), "kbdraw", kbdraw);
		gtk_container_add (GTK_CONTAINER
				   (CWID ("previewFrame")), kbdraw);
		gtk_widget_show_all (kbdraw);
		gtk_button_box_set_child_secondary (GTK_BUTTON_BOX
						    (CWID
						     ("hbtnBox")),
						    CWID
						    ("btnPrint"), TRUE);
	} else
#endif
	{
		gtk_widget_hide_all (CWID ("vboxPreview"));
		gtk_widget_hide (CWID ("btnPrint"));
	}

	g_signal_connect (G_OBJECT (chooser),
			  "response",
			  G_CALLBACK (xkb_layout_chooser_response),
			  chooser_dialog);

	toplevel = gtk_widget_get_toplevel (chooser);
	if (gtk_widget_is_toplevel (toplevel)) {
		GdkRectangle *rect = matekbd_preview_load_position ();
		if (rect != NULL) {
			gtk_window_move (GTK_WINDOW (toplevel),
					 rect->x, rect->y);
			gtk_window_resize (GTK_WINDOW (toplevel),
					   rect->width, rect->height);
			g_free (rect);
		}
	}

	xkb_layout_preview_update (chooser_dialog);
	gtk_dialog_run (GTK_DIALOG (chooser));
	gtk_widget_destroy (chooser);
}