gtkinputdialog.c 21.2 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1 2 3 4
/* GTK - The GIMP Toolkit
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
Elliot Lee's avatar
Elliot Lee committed
6 7 8 9 10 11
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
Elliot Lee's avatar
Elliot Lee committed
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15 16 17
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
Elliot Lee's avatar
Elliot Lee committed
18 19 20 21 22 23 24 25 26
 */

/*
 * gtkinputdialog.c
 *
 * Copyright 1997 Owen Taylor <owt1@cornell.edu>
 *
 */

27
/*
28
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
29 30 31 32 33 34
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 */


35
#include <glib/gprintf.h>
Elliot Lee's avatar
Elliot Lee committed
36 37 38
#include <stdlib.h>
#include "gdk/gdkkeysyms.h"
#include "gtkbutton.h"
39
#include "gtkentry.h"
Elliot Lee's avatar
Elliot Lee committed
40 41 42 43 44 45
#include "gtkhbox.h"
#include "gtkhseparator.h"
#include "gtkinputdialog.h"
#include "gtklabel.h"
#include "gtklistitem.h"
#include "gtkmain.h"
46
#include "gtkmarshalers.h"
Elliot Lee's avatar
Elliot Lee committed
47 48
#include "gtkmenu.h"
#include "gtkmenuitem.h"
49
#include "gtknotebook.h"
Elliot Lee's avatar
Elliot Lee committed
50
#include "gtkscrolledwindow.h"
51
#include "gtkstock.h"
52
#include "gtktable.h"
Elliot Lee's avatar
Elliot Lee committed
53 54
#include "gtkvbox.h"

Kristian Rietveld's avatar
Kristian Rietveld committed
55 56 57 58
#undef GTK_DISABLE_DEPRECATED
#include "gtkoptionmenu.h"
#define GTK_DISABLE_DEPRECATED

Owen Taylor's avatar
Owen Taylor committed
59 60
#include "gtkintl.h"

61 62 63 64 65 66 67 68 69 70 71 72 73
typedef struct _GtkInputDialogPrivate GtkInputDialogPrivate;
typedef struct _GtkInputKeyInfo       GtkInputKeyInfo;

struct _GtkInputDialogPrivate
{
  GtkWidget *device_menu;
  GtkWidget *device_optionmenu;
  GtkWidget *no_devices_label;
  GtkWidget *main_vbox;
};

struct _GtkInputKeyInfo
{
74 75 76
  gint       index;
  GtkWidget *entry;
  GtkInputDialog *inputd;
77
};
78

Elliot Lee's avatar
Elliot Lee committed
79 80 81 82 83 84 85 86 87 88 89
enum
{
  ENABLE_DEVICE,
  DISABLE_DEVICE,
  LAST_SIGNAL
};


#define AXIS_LIST_WIDTH 160
#define AXIS_LIST_HEIGHT 175

90 91 92
#define KEYS_LIST_WIDTH 200
#define KEYS_LIST_HEIGHT 175

Elliot Lee's avatar
Elliot Lee committed
93 94
/* Forward declarations */

95 96
static void gtk_input_dialog_class_init       (GtkInputDialogClass *klass);
static void gtk_input_dialog_init             (GtkInputDialog      *inputd);
97 98
static void gtk_input_dialog_screen_changed   (GtkWidget           *widget,
					       GdkScreen           *previous_screen);
99 100 101 102 103 104 105 106 107 108 109
static void gtk_input_dialog_set_device       (GtkWidget           *widget,
					       gpointer             data);
static void gtk_input_dialog_set_mapping_mode (GtkWidget           *w,
					       gpointer             data);
static void gtk_input_dialog_set_axis         (GtkWidget           *widget,
					       gpointer             data);
static void gtk_input_dialog_fill_axes        (GtkInputDialog      *inputd,
					       GdkDevice           *info);
static void gtk_input_dialog_set_key          (GtkInputKeyInfo     *key,
					       guint                keyval,
					       GdkModifierType      modifiers);
110
static gboolean gtk_input_dialog_key_press    (GtkWidget           *widget,
111 112 113 114 115 116 117 118
					       GdkEventKey         *event,
					       GtkInputKeyInfo     *key);
static void gtk_input_dialog_clear_key        (GtkWidget           *widget,
					       GtkInputKeyInfo     *key);
static void gtk_input_dialog_destroy_key      (GtkWidget           *widget,
					       GtkInputKeyInfo     *key);
static void gtk_input_dialog_fill_keys        (GtkInputDialog      *inputd,
					       GdkDevice           *info);
Elliot Lee's avatar
Elliot Lee committed
119 120

static GtkObjectClass *parent_class = NULL;
121
static guint input_dialog_signals[LAST_SIGNAL] = { 0 };
Elliot Lee's avatar
Elliot Lee committed
122

Manish Singh's avatar
Manish Singh committed
123
GType
124
gtk_input_dialog_get_type (void)
Elliot Lee's avatar
Elliot Lee committed
125
{
Manish Singh's avatar
Manish Singh committed
126
  static GType input_dialog_type = 0;
Elliot Lee's avatar
Elliot Lee committed
127 128 129

  if (!input_dialog_type)
    {
Manish Singh's avatar
Manish Singh committed
130
      static const GTypeInfo input_dialog_info =
Elliot Lee's avatar
Elliot Lee committed
131 132
      {
	sizeof (GtkInputDialogClass),
Manish Singh's avatar
Manish Singh committed
133 134 135 136 137 138 139 140
	NULL,		/* base_init */
	NULL,		/* base_finalize */
	(GClassInitFunc) gtk_input_dialog_class_init,
	NULL,		/* class_finalize */
	NULL,		/* class_data */
	sizeof (GtkInputDialog),
	0,		/* n_preallocs */
	(GInstanceInitFunc) gtk_input_dialog_init,
Elliot Lee's avatar
Elliot Lee committed
141 142
      };

Manish Singh's avatar
Manish Singh committed
143 144 145
      input_dialog_type =
	g_type_register_static (GTK_TYPE_DIALOG, "GtkInputDialog",
				&input_dialog_info, 0);
Elliot Lee's avatar
Elliot Lee committed
146 147 148 149 150
    }

  return input_dialog_type;
}

151
GtkInputDialogPrivate *
152
gtk_input_dialog_get_private (GtkInputDialog *input_dialog)
153 154 155 156 157 158 159
{
  GtkInputDialogPrivate *private;
  static GQuark private_quark = 0;

  if (!private_quark)
    private_quark = g_quark_from_static_string ("gtk-input-dialog-private");

160
  private = g_object_get_qdata (G_OBJECT (input_dialog), private_quark);
161 162 163 164

  if (!private)
    {
      private = g_new0 (GtkInputDialogPrivate, 1);
165
      g_object_set_qdata_full (G_OBJECT (input_dialog), private_quark,
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
			       private, g_free);
    }

  return private;
}

static GtkInputDialog *
input_dialog_from_widget (GtkWidget *widget)
{
  GtkWidget *toplevel;
  
  if (GTK_IS_MENU_ITEM (widget))
    {
      GtkMenu *menu = GTK_MENU (widget->parent);
      widget = gtk_menu_get_attach_widget (menu);
    }

  toplevel = gtk_widget_get_toplevel (widget);
  return GTK_INPUT_DIALOG (toplevel);
}

Elliot Lee's avatar
Elliot Lee committed
187 188 189
static void
gtk_input_dialog_class_init (GtkInputDialogClass *klass)
{
190 191
  GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
  
Manish Singh's avatar
Manish Singh committed
192
  parent_class = g_type_class_peek_parent (klass);
Elliot Lee's avatar
Elliot Lee committed
193

194 195
  widget_class->screen_changed = gtk_input_dialog_screen_changed;
  
196 197 198
  klass->enable_device = NULL;
  klass->disable_device = NULL;

Elliot Lee's avatar
Elliot Lee committed
199
  input_dialog_signals[ENABLE_DEVICE] =
Manish Singh's avatar
Manish Singh committed
200 201 202 203 204 205 206 207
    g_signal_new ("enable_device",
		  G_OBJECT_CLASS_TYPE (klass),
		  G_SIGNAL_RUN_LAST,
		  G_STRUCT_OFFSET (GtkInputDialogClass, enable_device),
		  NULL, NULL,
		  _gtk_marshal_VOID__OBJECT,
		  G_TYPE_NONE, 1,
		  GDK_TYPE_DEVICE);
Elliot Lee's avatar
Elliot Lee committed
208 209

  input_dialog_signals[DISABLE_DEVICE] =
Manish Singh's avatar
Manish Singh committed
210 211 212 213 214 215 216 217
    g_signal_new ("disable_device",
		  G_OBJECT_CLASS_TYPE (klass),
		  G_SIGNAL_RUN_LAST,
		  G_STRUCT_OFFSET (GtkInputDialogClass, disable_device),
		  NULL, NULL,
		  _gtk_marshal_VOID__OBJECT,
		  G_TYPE_NONE, 1,
		  GDK_TYPE_DEVICE);
Elliot Lee's avatar
Elliot Lee committed
218 219 220 221 222
}

static void
gtk_input_dialog_init (GtkInputDialog *inputd)
{
223
  GtkInputDialogPrivate *private = gtk_input_dialog_get_private (inputd);
Elliot Lee's avatar
Elliot Lee committed
224 225 226 227 228
  GtkWidget *util_box;
  GtkWidget *label;
  GtkWidget *mapping_menu;
  GtkWidget *menuitem;
  GtkWidget *separator;
229
  GtkWidget *notebook;
Elliot Lee's avatar
Elliot Lee committed
230

231 232
  gtk_widget_push_composite_child ();

Owen Taylor's avatar
Owen Taylor committed
233
  gtk_window_set_title (GTK_WINDOW (inputd), _("Input"));
Elliot Lee's avatar
Elliot Lee committed
234

235
  /* main vbox */
Elliot Lee's avatar
Elliot Lee committed
236

237 238 239 240
  private->main_vbox = gtk_vbox_new (FALSE, 4);
  gtk_container_set_border_width (GTK_CONTAINER (private->main_vbox), 5);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (inputd)->vbox), private->main_vbox,
		      TRUE, TRUE, 0);
Elliot Lee's avatar
Elliot Lee committed
241

242
  private->no_devices_label = gtk_label_new (_("No extended input devices"));
243 244 245
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (inputd)->vbox),
		      private->no_devices_label,
		      TRUE, TRUE, 0);
Elliot Lee's avatar
Elliot Lee committed
246

247
  /* menu for selecting device */
Elliot Lee's avatar
Elliot Lee committed
248

249
  private->device_menu = gtk_menu_new ();
Elliot Lee's avatar
Elliot Lee committed
250

251 252
  util_box = gtk_hbox_new (FALSE, 2);
  gtk_box_pack_start (GTK_BOX (private->main_vbox), util_box, FALSE, FALSE, 0);
Elliot Lee's avatar
Elliot Lee committed
253

254 255
  label = gtk_label_new_with_mnemonic (_("_Device:"));
  gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2);
Elliot Lee's avatar
Elliot Lee committed
256

257 258 259 260 261
  private->device_optionmenu = gtk_option_menu_new ();
  gtk_label_set_mnemonic_widget (GTK_LABEL (label), private->device_optionmenu);
  gtk_box_pack_start (GTK_BOX (util_box), private->device_optionmenu, TRUE, TRUE, 2);
  gtk_widget_show (private->device_optionmenu);
  gtk_option_menu_set_menu (GTK_OPTION_MENU (private->device_optionmenu), private->device_menu);
Elliot Lee's avatar
Elliot Lee committed
262

263
  gtk_widget_show (label);
Elliot Lee's avatar
Elliot Lee committed
264

265
  /* Device options */
Elliot Lee's avatar
Elliot Lee committed
266

267
  /* mapping mode option menu */
Elliot Lee's avatar
Elliot Lee committed
268

269
  mapping_menu = gtk_menu_new ();
Elliot Lee's avatar
Elliot Lee committed
270

271 272 273 274 275 276
  menuitem = gtk_menu_item_new_with_label(_("Disabled"));
  gtk_menu_shell_append (GTK_MENU_SHELL (mapping_menu), menuitem);
  gtk_widget_show (menuitem);
  g_signal_connect (menuitem, "activate",
		    G_CALLBACK (gtk_input_dialog_set_mapping_mode),
		    GINT_TO_POINTER (GDK_MODE_DISABLED));
Elliot Lee's avatar
Elliot Lee committed
277

278 279 280 281 282 283
  menuitem = gtk_menu_item_new_with_label(_("Screen"));
  gtk_menu_shell_append (GTK_MENU_SHELL (mapping_menu), menuitem);
  gtk_widget_show (menuitem);
  g_signal_connect (menuitem, "activate",
		    G_CALLBACK (gtk_input_dialog_set_mapping_mode),
		    GINT_TO_POINTER (GDK_MODE_SCREEN));
Elliot Lee's avatar
Elliot Lee committed
284

285 286 287 288 289 290
  menuitem = gtk_menu_item_new_with_label(_("Window"));
  gtk_menu_shell_append (GTK_MENU_SHELL (mapping_menu), menuitem);
  gtk_widget_show (menuitem);
  g_signal_connect (menuitem, "activate",
		    G_CALLBACK (gtk_input_dialog_set_mapping_mode),
		    GINT_TO_POINTER (GDK_MODE_WINDOW));
Elliot Lee's avatar
Elliot Lee committed
291

292 293 294 295 296 297 298 299
  label = gtk_label_new_with_mnemonic (_("_Mode: "));
  gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2);
  
  inputd->mode_optionmenu = gtk_option_menu_new ();
  gtk_label_set_mnemonic_widget (GTK_LABEL (label), inputd->mode_optionmenu);
  gtk_box_pack_start (GTK_BOX (util_box), inputd->mode_optionmenu, FALSE, FALSE, 2);
  gtk_widget_show (inputd->mode_optionmenu);
  gtk_option_menu_set_menu (GTK_OPTION_MENU (inputd->mode_optionmenu), mapping_menu);
Elliot Lee's avatar
Elliot Lee committed
300

301
  gtk_widget_show(label);
Elliot Lee's avatar
Elliot Lee committed
302

303
  gtk_widget_show (util_box);
Elliot Lee's avatar
Elliot Lee committed
304

305 306
  util_box = gtk_hbox_new (FALSE, 2);
  gtk_box_pack_start (GTK_BOX(private->main_vbox), util_box, FALSE, FALSE, 0);
Elliot Lee's avatar
Elliot Lee committed
307

308 309
  gtk_widget_show (label);
  gtk_widget_show (util_box);
Elliot Lee's avatar
Elliot Lee committed
310

311 312 313
  separator = gtk_hseparator_new();
  gtk_box_pack_start (GTK_BOX (private->main_vbox), separator, FALSE, TRUE, 0);
  gtk_widget_show (separator);
314

315
  /* Notebook */
316

317 318 319
  notebook = gtk_notebook_new ();
  gtk_box_pack_start (GTK_BOX (private->main_vbox), notebook, TRUE, TRUE, 0);
  gtk_widget_show (notebook);
320
      
321
  /*  The axis listbox  */
Elliot Lee's avatar
Elliot Lee committed
322

323
  label = gtk_label_new_with_mnemonic (_("_Axes"));
Elliot Lee's avatar
Elliot Lee committed
324

325 326 327
  inputd->axis_listbox = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(inputd->axis_listbox),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
328
      
329 330 331 332
  gtk_widget_set_size_request (inputd->axis_listbox,
			       AXIS_LIST_WIDTH, AXIS_LIST_HEIGHT);
  gtk_notebook_append_page (GTK_NOTEBOOK(notebook), 
			    inputd->axis_listbox, label);
Elliot Lee's avatar
Elliot Lee committed
333

334
  gtk_widget_show (inputd->axis_listbox);
335

336
  inputd->axis_list = 0;
337

338
  /* Keys listbox */
339

340
  label = gtk_label_new_with_mnemonic (_("_Keys"));
341

342 343 344 345 346 347 348
  inputd->keys_listbox = gtk_scrolled_window_new (NULL, NULL);
  gtk_widget_set_size_request (inputd->keys_listbox,
			       KEYS_LIST_WIDTH, KEYS_LIST_HEIGHT);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (inputd->keys_listbox),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), 
			    inputd->keys_listbox, label);
Elliot Lee's avatar
Elliot Lee committed
349

350
  gtk_widget_show (inputd->keys_listbox);
Elliot Lee's avatar
Elliot Lee committed
351

352
  inputd->keys_list = 0;
Elliot Lee's avatar
Elliot Lee committed
353

354
  inputd->save_button = gtk_button_new_from_stock (GTK_STOCK_SAVE);
Elliot Lee's avatar
Elliot Lee committed
355 356 357 358 359
  GTK_WIDGET_SET_FLAGS (inputd->save_button, GTK_CAN_DEFAULT);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG(inputd)->action_area),
		      inputd->save_button, TRUE, TRUE, 0);
  gtk_widget_show (inputd->save_button);

360
  inputd->close_button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
Elliot Lee's avatar
Elliot Lee committed
361 362 363 364 365 366 367
  GTK_WIDGET_SET_FLAGS (inputd->close_button, GTK_CAN_DEFAULT);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG(inputd)->action_area),
		      inputd->close_button, TRUE, TRUE, 0);

  gtk_widget_show (inputd->close_button);
  gtk_widget_grab_default (inputd->close_button);

368
  gtk_widget_pop_composite_child ();
369 370

  gtk_input_dialog_screen_changed (GTK_WIDGET (inputd), NULL);
Elliot Lee's avatar
Elliot Lee committed
371 372
}

373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
static void
gtk_input_dialog_screen_changed (GtkWidget *widget,
				 GdkScreen *previous_screen)
{
  GtkInputDialog *inputd = GTK_INPUT_DIALOG (widget);
  GtkInputDialogPrivate *private = gtk_input_dialog_get_private (inputd);
  
  GList *device_info = NULL;
  GdkDevice *core_pointer = NULL;
  GList *tmp_list;

  if (gtk_widget_has_screen (widget))
    {
      GdkDisplay *display;
      
      display = gtk_widget_get_display (widget);
      device_info = gdk_display_list_devices (display);
      core_pointer = gdk_display_get_core_pointer (display);
    }
Elliot Lee's avatar
Elliot Lee committed
392

393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
  inputd->current_device = NULL;
  gtk_container_foreach (GTK_CONTAINER (private->device_menu),
			 (GtkCallback)gtk_widget_destroy, NULL);
  
  if (g_list_length(device_info) <= 1) /* only core device */
    {
      gtk_widget_hide (private->main_vbox);
      gtk_widget_show (private->no_devices_label);
      gtk_widget_set_sensitive(inputd->save_button, FALSE);
    }
  else
    {
      gtk_widget_show (private->main_vbox);
      gtk_widget_hide (private->no_devices_label);
      gtk_widget_set_sensitive(inputd->save_button, TRUE);

      for (tmp_list = device_info; tmp_list; tmp_list = tmp_list->next)
	{
	  GdkDevice *info = tmp_list->data;
	  if (info != core_pointer)
	    {
	      GtkWidget *menuitem;
	      
	      menuitem = gtk_menu_item_new_with_label (info->name);
	      
	      gtk_menu_shell_append (GTK_MENU_SHELL (private->device_menu),
				     menuitem);
	      gtk_widget_show (menuitem);
	      g_signal_connect (menuitem, "activate",
				G_CALLBACK (gtk_input_dialog_set_device),
				info);
	    }
	}
      
      gtk_input_dialog_set_device (widget, device_info->data);
      gtk_option_menu_set_history (GTK_OPTION_MENU (private->device_optionmenu), 0);
    }
}
     
Elliot Lee's avatar
Elliot Lee committed
432 433 434 435 436
GtkWidget*
gtk_input_dialog_new (void)
{
  GtkInputDialog *inputd;

Manish Singh's avatar
Manish Singh committed
437
  inputd = g_object_new (GTK_TYPE_INPUT_DIALOG, NULL);
Elliot Lee's avatar
Elliot Lee committed
438 439 440 441 442

  return GTK_WIDGET (inputd);
}

static void
Manish Singh's avatar
Manish Singh committed
443 444
gtk_input_dialog_set_device (GtkWidget *w,
			     gpointer   data)
Elliot Lee's avatar
Elliot Lee committed
445
{
446
  GdkDevice *device = data;
447
  GtkInputDialog *inputd = input_dialog_from_widget (w);
Elliot Lee's avatar
Elliot Lee committed
448

449
  inputd->current_device = device;
Elliot Lee's avatar
Elliot Lee committed
450

Manish Singh's avatar
Manish Singh committed
451 452
  gtk_input_dialog_fill_axes (inputd, device);
  gtk_input_dialog_fill_keys (inputd, device);
Elliot Lee's avatar
Elliot Lee committed
453

Manish Singh's avatar
Manish Singh committed
454 455
  gtk_option_menu_set_history (GTK_OPTION_MENU (inputd->mode_optionmenu),
			       device->mode);
Elliot Lee's avatar
Elliot Lee committed
456 457 458
}

static void
459 460
gtk_input_dialog_set_mapping_mode (GtkWidget *w,
				   gpointer   data)
Elliot Lee's avatar
Elliot Lee committed
461
{
462
  GtkInputDialog *inputd = input_dialog_from_widget (w);
463
  GdkDevice *info = inputd->current_device;
Elliot Lee's avatar
Elliot Lee committed
464
  GdkInputMode old_mode = info->mode;
465
  GdkInputMode mode = GPOINTER_TO_INT (data);
Elliot Lee's avatar
Elliot Lee committed
466

467 468 469
  if (!info)
    return;

Elliot Lee's avatar
Elliot Lee committed
470 471
  if (mode != old_mode)
    {
472
      if (gdk_device_set_mode (info, mode))
Elliot Lee's avatar
Elliot Lee committed
473 474
	{
	  if (mode == GDK_MODE_DISABLED)
Manish Singh's avatar
Manish Singh committed
475 476 477 478
	    g_signal_emit (inputd,
			   input_dialog_signals[DISABLE_DEVICE],
			   0,
			   info);
Elliot Lee's avatar
Elliot Lee committed
479
	  else
Manish Singh's avatar
Manish Singh committed
480 481 482 483
	    g_signal_emit (inputd,
			   input_dialog_signals[ENABLE_DEVICE],
			   0,
			   info);
Elliot Lee's avatar
Elliot Lee committed
484 485 486 487 488 489 490 491 492 493
	}
      else
	gtk_option_menu_set_history (GTK_OPTION_MENU (inputd->mode_optionmenu),
				     old_mode);

      /* FIXME: error dialog ? */
    }
}

static void
Manish Singh's avatar
Manish Singh committed
494 495
gtk_input_dialog_set_axis (GtkWidget *w,
			   gpointer   data)
Elliot Lee's avatar
Elliot Lee committed
496
{
497
  GdkAxisUse use = GPOINTER_TO_INT(data) & 0xFFFF;
Elliot Lee's avatar
Elliot Lee committed
498 499
  GdkAxisUse old_use;
  GdkAxisUse *new_axes;
500
  GtkInputDialog *inputd = input_dialog_from_widget (w);
501
  GdkDevice *info = inputd->current_device;
Elliot Lee's avatar
Elliot Lee committed
502

503
  gint axis = (GPOINTER_TO_INT(data) >> 16) - 1;
Elliot Lee's avatar
Elliot Lee committed
504 505 506
  gint old_axis;
  int i;

507 508 509
  if (!info)
    return;

Elliot Lee's avatar
Elliot Lee committed
510 511 512 513
  new_axes = g_new (GdkAxisUse, info->num_axes);
  old_axis = -1;
  for (i=0;i<info->num_axes;i++)
    {
514 515
      new_axes[i] = info->axes[i].use;
      if (info->axes[i].use == use)
Elliot Lee's avatar
Elliot Lee committed
516 517 518 519
	old_axis = i;
    }

  if (axis != -1)
520
    old_use = info->axes[axis].use;
Elliot Lee's avatar
Elliot Lee committed
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
  else
    old_use = GDK_AXIS_IGNORE;

  if (axis == old_axis)
    return;

  /* we must always have an x and a y axis */
  if ((axis == -1 && (use == GDK_AXIS_X || use == GDK_AXIS_Y)) ||
      (old_axis == -1 && (old_use == GDK_AXIS_X || old_use == GDK_AXIS_Y)))
    {
      gtk_option_menu_set_history (
	        GTK_OPTION_MENU (inputd->axis_items[use]),
		old_axis + 1);
    }
  else
    {
      if (axis != -1)
538
	gdk_device_set_axis_use (info, axis, use);
Elliot Lee's avatar
Elliot Lee committed
539 540

      if (old_axis != -1)
541
	gdk_device_set_axis_use (info, old_axis, old_use);
Elliot Lee's avatar
Elliot Lee committed
542 543 544 545 546 547 548 549 550 551 552 553 554

      if (old_use != GDK_AXIS_IGNORE)
	{
	  gtk_option_menu_set_history (
		GTK_OPTION_MENU (inputd->axis_items[old_use]),
		old_axis + 1);
	}
    }

  g_free (new_axes);
}

static void
555
gtk_input_dialog_fill_axes(GtkInputDialog *inputd, GdkDevice *info)
Elliot Lee's avatar
Elliot Lee committed
556
{
557
  static const char *axis_use_strings[GDK_AXIS_LAST] =
Elliot Lee's avatar
Elliot Lee committed
558 559
  {
    "",
Owen Taylor's avatar
Owen Taylor committed
560 561 562 563
    N_("X"),
    N_("Y"),
    N_("Pressure"),
    N_("X Tilt"),
564 565
    N_("Y Tilt"),
    N_("Wheel")
Elliot Lee's avatar
Elliot Lee committed
566 567 568 569 570 571 572 573 574 575 576 577 578
  };

  int i,j;
  GtkWidget *menu;
  GtkWidget *option_menu;
  GtkWidget *label;

  /* remove all the old items */
  if (inputd->axis_list)
    {
      gtk_widget_hide (inputd->axis_list);	/* suppress resizes (or get warnings) */
      gtk_widget_destroy (inputd->axis_list);
    }
579
  inputd->axis_list = gtk_table_new (GDK_AXIS_LAST, 2, 0);
580 581
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (inputd->axis_listbox), 
					 inputd->axis_list);
Elliot Lee's avatar
Elliot Lee committed
582 583 584 585
  gtk_widget_show (inputd->axis_list);

  gtk_widget_realize (inputd->axis_list);
  gdk_window_set_background (inputd->axis_list->window,
586
			     &inputd->axis_list->style->base[GTK_STATE_NORMAL]);
Elliot Lee's avatar
Elliot Lee committed
587 588 589 590 591

  for (i=GDK_AXIS_X;i<GDK_AXIS_LAST;i++)
    {
      /* create the label */

Owen Taylor's avatar
Owen Taylor committed
592
      label = gtk_label_new (_(axis_use_strings[i]));
593 594
      gtk_table_attach (GTK_TABLE (inputd->axis_list), label, 0, 1, i, i+1, 
			0, 0, 2, 2);
Elliot Lee's avatar
Elliot Lee committed
595 596 597 598 599 600 601 602 603 604

      /* and the use option menu */
      menu = gtk_menu_new();

      for (j = -1; j < info->num_axes; j++)
	{
	  char buffer[16];
	  GtkWidget *menu_item;

	  if (j == -1)
Owen Taylor's avatar
Owen Taylor committed
605
	    menu_item = gtk_menu_item_new_with_label (_("none"));
Elliot Lee's avatar
Elliot Lee committed
606 607
	  else
	    {
608
	      g_snprintf (buffer, sizeof (buffer), "%d", j+1);
Elliot Lee's avatar
Elliot Lee committed
609 610
	      menu_item = gtk_menu_item_new_with_label (buffer);
	    }
Manish Singh's avatar
Manish Singh committed
611 612 613
	  g_signal_connect (menu_item, "activate",
			    G_CALLBACK (gtk_input_dialog_set_axis),
			    GINT_TO_POINTER (0x10000 * (j + 1) + i));
Elliot Lee's avatar
Elliot Lee committed
614
	  gtk_widget_show (menu_item);
615
	  gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
Elliot Lee's avatar
Elliot Lee committed
616 617 618
	}

      inputd->axis_items[i] = option_menu = gtk_option_menu_new ();
619 620
      gtk_table_attach (GTK_TABLE (inputd->axis_list), option_menu, 
			1, 2, i, i+1, 0, 0, 2, 2);
Elliot Lee's avatar
Elliot Lee committed
621 622 623 624

      gtk_widget_show (option_menu);
      gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
      for (j = 0; j < info->num_axes; j++)
625
	if (info->axes[j].use == (GdkAxisUse) i)
Elliot Lee's avatar
Elliot Lee committed
626 627 628 629 630 631
	  {
	    gtk_option_menu_set_history (GTK_OPTION_MENU (option_menu), j+1);
	    break;
	  }

      gtk_widget_show (label);
632 633 634 635 636 637
    }
}

static void 
gtk_input_dialog_clear_key (GtkWidget *widget, GtkInputKeyInfo *key)
{
638 639 640
  if (!key->inputd->current_device)
    return;
  
Owen Taylor's avatar
Owen Taylor committed
641
  gtk_entry_set_text (GTK_ENTRY(key->entry), _("(disabled)"));
642
  gdk_device_set_key (key->inputd->current_device, key->index, 0, 0);
643 644 645 646 647 648 649 650 651 652 653
}

static void 
gtk_input_dialog_set_key (GtkInputKeyInfo *key,
			  guint keyval, GdkModifierType modifiers)
{
  GString *str;
  gchar chars[2];

  if (keyval)
    {
654
      str = g_string_new (NULL);
655 656
      
      if (modifiers & GDK_SHIFT_MASK)
657
	g_string_append (str, "Shift+");
658
      if (modifiers & GDK_CONTROL_MASK)
659
	g_string_append (str, "Ctrl+");
660 661 662 663 664 665 666 667 668 669
      if (modifiers & GDK_MOD1_MASK)
	g_string_append (str, "Alt+");
      
      if ((keyval >= 0x20) && (keyval <= 0xFF))
	{
	  chars[0] = keyval;
	  chars[1] = 0;
	  g_string_append (str, chars);
	}
      else
Owen Taylor's avatar
Owen Taylor committed
670
	g_string_append (str, _("(unknown)"));
671 672 673 674 675 676
      gtk_entry_set_text (GTK_ENTRY(key->entry), str->str);

      g_string_free (str, TRUE);
    }
  else
    {
Owen Taylor's avatar
Owen Taylor committed
677
      gtk_entry_set_text (GTK_ENTRY(key->entry), _("(disabled)"));
678 679 680
    }
}

681
static gboolean
682 683 684 685
gtk_input_dialog_key_press (GtkWidget *widget, 
			    GdkEventKey *event,
			    GtkInputKeyInfo *key)
{
686 687 688
  if (!key->inputd->current_device)
    return FALSE;
  
689
  gtk_input_dialog_set_key (key, event->keyval, event->state & 0xFF);
690 691
  gdk_device_set_key (key->inputd->current_device, key->index, 
		      event->keyval, event->state & 0xFF);
692

Manish Singh's avatar
Manish Singh committed
693
  g_signal_stop_emission_by_name (widget, "key_press_event");
694 695 696 697 698 699 700 701 702 703 704
  
  return TRUE;
}

static void 
gtk_input_dialog_destroy_key (GtkWidget *widget, GtkInputKeyInfo *key)
{
  g_free (key);
}

static void
705
gtk_input_dialog_fill_keys(GtkInputDialog *inputd, GdkDevice *info)
706 707 708 709 710
{
  int i;
  GtkWidget *label;
  GtkWidget *button;

711
  char buffer[32];
712 713 714 715 716 717 718 719 720
  
  /* remove all the old items */
  if (inputd->keys_list)
    {
      gtk_widget_hide (inputd->keys_list);	/* suppress resizes (or get warnings) */
      gtk_widget_destroy (inputd->keys_list);
    }

  inputd->keys_list = gtk_table_new (info->num_keys, 3, FALSE);
721 722
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (inputd->keys_listbox), 
					 inputd->keys_list);
723 724 725 726
  gtk_widget_show (inputd->keys_list);

  gtk_widget_realize (inputd->keys_list);
  gdk_window_set_background (inputd->keys_list->window,
727
			     &inputd->keys_list->style->base[GTK_STATE_NORMAL]);
728 729 730 731 732 733 734 735 736

  for (i=0;i<info->num_keys;i++)
    {
      GtkInputKeyInfo *key = g_new (GtkInputKeyInfo, 1);
      key->index = i;
      key->inputd = inputd;

      /* create the label */

737
      g_snprintf (buffer, sizeof (buffer), "%d", i+1);
738
      label = gtk_label_new (buffer);
739 740 741 742 743 744 745 746 747 748 749
      gtk_table_attach (GTK_TABLE (inputd->keys_list), label, 0, 1, i, i+1, 
			0, 0, 2, 2);
      gtk_widget_show (label);

      /* the entry */

      key->entry = gtk_entry_new ();
      gtk_table_attach (GTK_TABLE (inputd->keys_list), key->entry, 1, 2, i, i+1, 
			GTK_EXPAND | GTK_FILL , 0, 2, 2);
      gtk_widget_show (key->entry);

Manish Singh's avatar
Manish Singh committed
750 751 752 753
      g_signal_connect (key->entry, "key_press_event",
			G_CALLBACK (gtk_input_dialog_key_press), key);
      g_signal_connect (key->entry, "destroy",
			G_CALLBACK (gtk_input_dialog_destroy_key), key);
754 755 756
      
      /* and clear button */

Owen Taylor's avatar
Owen Taylor committed
757
      button = gtk_button_new_with_label (_("clear"));
758 759 760 761
      gtk_table_attach (GTK_TABLE (inputd->keys_list), button, 2, 3, i, i+1, 
			0, 0, 2, 2);
      gtk_widget_show (button);

Manish Singh's avatar
Manish Singh committed
762 763
      g_signal_connect (button, "clicked",
			G_CALLBACK (gtk_input_dialog_clear_key), key);
Elliot Lee's avatar
Elliot Lee committed
764

765 766
      gtk_input_dialog_set_key (key, info->keys[i].keyval,
				info->keys[i].modifiers);
Elliot Lee's avatar
Elliot Lee committed
767 768
    }
}