Exemplo n.º 1
0
static gboolean
do_ungrab_key (Binding *binding)
{
	GdkWindow *rootwin = gdk_get_default_root_window ();

	TRACE (g_print ("Removing grab for '%s'\n", binding->keystring));

	grab_ungrab_with_ignorable_modifiers (rootwin,
					      binding,
					      FALSE /* ungrab */);

	return TRUE;
}
Exemplo n.º 2
0
/* Grab or ungrab the keycode+modifiers combination, first plainly, and then
 * including each ignorable modifier in turn.
 */
static gboolean
grab_ungrab_with_ignorable_modifiers (GdkWindow *rootwin,
                                      uint       keycode,
                                      uint       modifiers,
                                      gboolean   grab)
{
	guint i;
	gboolean success = FALSE;

	/* Ignorable modifiers */
	guint mod_masks [] = {
		0, /* modifier only */
		GDK_MOD2_MASK,
		GDK_LOCK_MASK,
		GDK_MOD2_MASK | GDK_LOCK_MASK,
	};

	gdk_error_trap_push ();

	for (i = 0; i < G_N_ELEMENTS (mod_masks); i++) {
		if (grab) {
			XGrabKey (GDK_WINDOW_XDISPLAY (rootwin),
			          keycode,
			          modifiers | mod_masks [i],
			          GDK_WINDOW_XID (rootwin),
			          False,
			          GrabModeAsync,
			          GrabModeAsync);
		} else {
			XUngrabKey (GDK_WINDOW_XDISPLAY (rootwin),
			            keycode,
			            modifiers | mod_masks [i],
			            GDK_WINDOW_XID (rootwin));
		}
	}
	gdk_flush();
	if (gdk_error_trap_pop()) {
		TRACE (g_warning ("Failed grab/ungrab"));
		if (grab) {
			/* On error, immediately release keys again */
			grab_ungrab_with_ignorable_modifiers(rootwin,
			                                     keycode,
			                                     modifiers,
			                                     FALSE);
		}
	} else {
		success = TRUE;
	}
	return success;
}
Exemplo n.º 3
0
static gboolean
do_grab_key (Binding *binding)
{
	GdkKeymap *keymap = gdk_keymap_get_default ();
	GdkWindow *rootwin = gdk_get_default_root_window ();

	EggVirtualModifierType virtual_mods = 0;
	guint keysym = 0;

	if (keymap == NULL || rootwin == NULL)
		return FALSE;

	if (!egg_accelerator_parse_virtual (binding->keystring,
					    &keysym,
					    &virtual_mods))
		return FALSE;

	TRACE (g_print ("Got accel %d, %d\n", keysym, virtual_mods));

	binding->keycode = XKeysymToKeycode (GDK_WINDOW_XDISPLAY (rootwin),
					     keysym);
	if (binding->keycode == 0)
		return FALSE;

	TRACE (g_print ("Got keycode %d\n", binding->keycode));

	egg_keymap_resolve_virtual_modifiers (keymap,
					      virtual_mods,
					      &binding->modifiers);
	if (binding->modifiers == 0)
		return FALSE;

	TRACE (g_print ("Got modmask %d\n", binding->modifiers));

	gdk_error_trap_push ();

	grab_ungrab_with_ignorable_modifiers (rootwin,
					      binding,
					      TRUE /* grab */);

	gdk_flush ();

	if (gdk_error_trap_pop ()) {
	   g_warning ("Binding '%s' failed!\n", binding->keystring);
	   return FALSE;
	}

	return TRUE;
}
Exemplo n.º 4
0
static void accel_cleared_callback (GtkCellRendererText *cell, const char *path_string, gpointer data)
{
	GtkTreeView *view = (GtkTreeView *) data;
	GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
	GtkAccelKey *key_entry = NULL;
	GtkTreeIter iter = {0};
	GtkTreeModel *model = NULL;

	model = gtk_tree_view_get_model (view);
	gtk_tree_model_get_iter (model, &iter, path);
	gtk_tree_path_free (path);
	gtk_tree_model_get (model, &iter, HOTKEY_COLUMN, &key_entry, -1);

	g_assert(key_entry);

	/* unregister what's previously registered */
	grab_ungrab_with_ignorable_modifiers(key_entry, FALSE);

	key_entry->accel_key = key_entry->accel_mods = key_entry->accel_flags = 0;
}
Exemplo n.º 5
0
static void accel_edited_callback(GtkCellRendererText *cell, const char *path_string, guint accel_key, 
				  GdkModifierType accel_mods, guint hardware_keycode, gpointer data)
{
	GtkTreeView *view = (GtkTreeView *)data;
	GtkTreeModel *model = NULL;
	GtkTreeIter iter = {0};
	GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
	GtkAccelKey *key_entry = NULL, temp_key = {0};
	GtkWidget *msg_dialog = NULL;
	gchar *temp_str = NULL;

	model = gtk_tree_view_get_model (view);
	gtk_tree_model_get_iter (model, &iter, path);
	gtk_tree_path_free (path);
	gtk_tree_model_get (model, &iter, HOTKEY_COLUMN, &key_entry, -1);

	/* sanity check and check to see if the same key combo was pressed again */
	if (key_entry == NULL || 
	(key_entry->accel_key == accel_key && 
	key_entry->accel_mods == accel_mods && 
	key_entry->accel_flags == hardware_keycode))
		return;

	/* CapsLock isn't supported as a keybinding modifier, so keep it from confusing us */
	accel_mods &= ~GDK_LOCK_MASK;

	temp_key.accel_key = accel_key;
	temp_key.accel_flags = hardware_keycode;
	temp_key.accel_mods   = accel_mods;


	/* Check for unmodified keys */
	if (temp_key.accel_mods == 0 && temp_key.accel_key != 0)
	{
		if ((temp_key.accel_key >= GDK_a && temp_key.accel_key <= GDK_z)
		   || (temp_key.accel_key >= GDK_A && temp_key.accel_key <= GDK_Z)
		   || (temp_key.accel_key >= GDK_0 && temp_key.accel_key <= GDK_9)
		   || (temp_key.accel_key >= GDK_kana_fullstop && temp_key.accel_key <= GDK_semivoicedsound)
		   || (temp_key.accel_key >= GDK_Arabic_comma && temp_key.accel_key <= GDK_Arabic_sukun)
		   || (temp_key.accel_key >= GDK_Serbian_dje && temp_key.accel_key <= GDK_Cyrillic_HARDSIGN)
		   || (temp_key.accel_key >= GDK_Greek_ALPHAaccent && temp_key.accel_key <= GDK_Greek_omega)
		   || (temp_key.accel_key >= GDK_hebrew_doublelowline && temp_key.accel_key <= GDK_hebrew_taf)
		   || (temp_key.accel_key >= GDK_Thai_kokai && temp_key.accel_key <= GDK_Thai_lekkao)
		   || (temp_key.accel_key >= GDK_Hangul && temp_key.accel_key <= GDK_Hangul_Special)
		   || (temp_key.accel_key >= GDK_Hangul_Kiyeog && temp_key.accel_key <= GDK_Hangul_J_YeorinHieuh)
		   || keyval_is_forbidden (temp_key.accel_key))
		{
			temp_str = gtk_accelerator_get_label (accel_key, accel_mods);

			msg_dialog = gtk_message_dialog_new (
						GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view))),
						GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
						GTK_MESSAGE_WARNING,
						GTK_BUTTONS_OK, 
						STR_INVALID_HOTKEY, 
						temp_str);
			g_object_set(msg_dialog, "title", STR_INVALID_HOTKEY_TITLE, NULL);

			g_free (temp_str); temp_str = NULL;
			gtk_dialog_run (GTK_DIALOG (msg_dialog));
			gtk_widget_destroy (msg_dialog);
			msg_dialog = NULL;

			return;
		}
	}

	/* try registering the new key combo */
	if(grab_ungrab_with_ignorable_modifiers(&temp_key, TRUE))
	{
		/* unregistering previous hotkey is not necessary on Win32
		   since the same prev. hotkey is modified to the new one */
#ifndef G_OS_WIN32
		/* unregister the previous hotkey */
		grab_ungrab_with_ignorable_modifiers(key_entry, FALSE);
#endif

		/* set the value in the list store to the newly set key combo
		   so that it gets reflected in the Accel Cell Renderer */
		key_entry->accel_key = accel_key;
		key_entry->accel_flags = hardware_keycode;
		key_entry->accel_mods = accel_mods;
	}
	else
	{
		temp_str = gtk_accelerator_get_label (accel_key, accel_mods);

		msg_dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view))),
							GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
							GTK_MESSAGE_WARNING,
							GTK_BUTTONS_OK, 
							STR_DUPLICATE_HOTKEY, 
							temp_str);
		g_object_set(msg_dialog, "title", STR_INVALID_HOTKEY_TITLE, NULL);

		g_free (temp_str); temp_str = NULL;
		gtk_dialog_run (GTK_DIALOG (msg_dialog));
		gtk_widget_destroy (msg_dialog);

		return;
	}
}
Exemplo n.º 6
0
/* Grab or ungrab then keyval and modifiers combination, grabbing all key
 * combinations yielding the same key values.
 * Includes ignorable modifiers using grab_ungrab_with_ignorable_modifiers.
 */
static gboolean
grab_ungrab (GdkWindow *rootwin,
             uint       keyval,
             uint       modifiers,
             gboolean   grab)
{
	int k;
	GdkKeymap *map;
	GdkKeymapKey *keys;
	gint n_keys;
	GdkModifierType add_modifiers;
	XkbDescPtr xmap;
	gboolean success = FALSE;

	xmap = XkbGetMap(GDK_WINDOW_XDISPLAY(rootwin),
	                 XkbAllClientInfoMask,
	                 XkbUseCoreKbd);

	map = gdk_keymap_get_default();
	gdk_keymap_get_entries_for_keyval(map, keyval, &keys, &n_keys);

	if (n_keys == 0)
		return FALSE;

	for (k = 0; k < n_keys; k++) {
		/* NOTE: We only bind for the first group,
		 * so regardless of current keyboard layout, it will
		 * grab the key from the default Layout.
		 */
		if (keys[k].group != WE_ONLY_USE_ONE_GROUP) {
			continue;
		}

		add_modifiers = FinallyGetModifiersForKeycode(xmap,
		                                              keys[k].keycode,
		                                              keys[k].group,
		                                              keys[k].level);

		if (add_modifiers == MODIFIERS_ERROR) {
			continue;
		}
		TRACE (g_print("grab/ungrab keycode: %d, lev: %d, grp: %d, ",
			keys[k].keycode, keys[k].level, keys[k].group));
		TRACE (g_print("modifiers: 0x%x (consumed: 0x%x)\n",
		               add_modifiers | modifiers, add_modifiers));
		if (grab_ungrab_with_ignorable_modifiers(rootwin,
		                                         keys[k].keycode,
		                                         add_modifiers | modifiers,
		                                         grab)) {

			success = TRUE;
		} else {
			/* When grabbing, break on error */
			if (grab && !success) {
				break;
			}
		}

	}
	g_free(keys);
	XkbFreeClientMap(xmap, 0, TRUE);

	return success;
}