~ubuntu-branches/ubuntu/trusty/unity-control-center/trusty

« back to all changes in this revision

Viewing changes to panels/region/gtkentryaccel.c

  • Committer: Package Import Robot
  • Author(s): Robert Ancell
  • Date: 2014-01-08 16:29:18 UTC
  • Revision ID: package-import@ubuntu.com-20140108162918-g29dd08tr913y2qh
Tags: upstream-14.04.0
ImportĀ upstreamĀ versionĀ 14.04.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "gtkentryaccel.h"
 
2
#include <glib/gi18n.h>
 
3
 
 
4
#define GTK_ENTRY_ACCEL_MODIFIER_MASK (GDK_MODIFIER_MASK & \
 
5
                                       ~GDK_LOCK_MASK & \
 
6
                                       ~GDK_MOD2_MASK & \
 
7
                                       ~GDK_MOD3_MASK & \
 
8
                                       ~GDK_MOD4_MASK & \
 
9
                                       ~GDK_MOD5_MASK & \
 
10
                                       ~GDK_HYPER_MASK)
 
11
 
 
12
#define GTK_TYPE_ENTRY_ACCEL_POST_ACTION (gtk_entry_accel_post_action_get_type ())
 
13
#define GTK_ENTRY_ACCEL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ENTRY_ACCEL, GtkEntryAccelPrivate))
 
14
 
 
15
struct _GtkEntryAccelPrivate
 
16
{
 
17
  gchar *accel;
 
18
 
 
19
  guint key;
 
20
  guint code;
 
21
  GdkModifierType mask;
 
22
 
 
23
  GdkDevice *keyboard;
 
24
  GdkDevice *pointer;
 
25
 
 
26
  gboolean left_shift : 1;
 
27
  gboolean right_shift : 1;
 
28
  gboolean left_control : 1;
 
29
  gboolean right_control : 1;
 
30
  gboolean left_alt : 1;
 
31
  gboolean right_alt : 1;
 
32
  gboolean left_super : 1;
 
33
  gboolean right_super : 1;
 
34
};
 
35
 
 
36
G_DEFINE_TYPE (GtkEntryAccel, gtk_entry_accel, GTK_TYPE_ENTRY);
 
37
 
 
38
enum
 
39
{
 
40
  PROP_0,
 
41
  PROP_ACCEL,
 
42
  N_PROPERTIES
 
43
};
 
44
 
 
45
static GParamSpec *properties[N_PROPERTIES] = { NULL };
 
46
 
 
47
enum
 
48
{
 
49
  SIGNAL_KEY_PRESSED,
 
50
  N_SIGNALS
 
51
};
 
52
 
 
53
static guint signals[N_SIGNALS] = { 0 };
 
54
 
 
55
static GType
 
56
gtk_entry_accel_post_action_get_type (void)
 
57
{
 
58
  static GType type = 0;
 
59
 
 
60
  if (G_UNLIKELY (type == 0))
 
61
    {
 
62
      static const GEnumValue values[] = {
 
63
        { GTK_ENTRY_ACCEL_UPDATE, "GTK_ENTRY_ACCEL_UPDATE", "update" },
 
64
        { GTK_ENTRY_ACCEL_CANCEL, "GTK_ENTRY_ACCEL_CANCEL", "cancel" },
 
65
        { GTK_ENTRY_ACCEL_IGNORE, "GTK_ENTRY_ACCEL_IGNORE", "ignore" },
 
66
        { GTK_ENTRY_ACCEL_PASS_THROUGH, "GTK_ENTRY_ACCEL_PASS_THROUGH", "pass-through" },
 
67
        { 0, NULL, NULL }
 
68
      };
 
69
 
 
70
      type = g_enum_register_static (g_intern_static_string ("GtkEntryAccelPostAction"), values);
 
71
    }
 
72
 
 
73
  return type;
 
74
}
 
75
 
 
76
static void
 
77
gtk_entry_accel_reset_modifier_states (GtkEntryAccel *entry)
 
78
{
 
79
  g_return_if_fail (GTK_IS_ENTRY_ACCEL (entry));
 
80
 
 
81
  entry->priv->left_shift = FALSE;
 
82
  entry->priv->right_shift = FALSE;
 
83
  entry->priv->left_control = FALSE;
 
84
  entry->priv->right_control = FALSE;
 
85
  entry->priv->left_alt = FALSE;
 
86
  entry->priv->right_alt = FALSE;
 
87
  entry->priv->left_super = FALSE;
 
88
  entry->priv->right_super = FALSE;
 
89
}
 
90
 
 
91
static gboolean
 
92
gtk_entry_accel_get_modifier_state (GtkEntryAccel *entry,
 
93
                                    guint          key)
 
94
{
 
95
  g_return_val_if_fail (GTK_IS_ENTRY_ACCEL (entry), FALSE);
 
96
 
 
97
  switch (key)
 
98
    {
 
99
    case GDK_KEY_Shift_L:
 
100
      return entry->priv->left_shift;
 
101
    case GDK_KEY_Shift_R:
 
102
      return entry->priv->right_shift;
 
103
    case GDK_KEY_Control_L:
 
104
      return entry->priv->left_control;
 
105
    case GDK_KEY_Control_R:
 
106
      return entry->priv->right_control;
 
107
    case GDK_KEY_Meta_L:
 
108
    case GDK_KEY_Alt_L:
 
109
      return entry->priv->left_alt;
 
110
    case GDK_KEY_Meta_R:
 
111
    case GDK_KEY_Alt_R:
 
112
      return entry->priv->right_alt;
 
113
    case GDK_KEY_Super_L:
 
114
      return entry->priv->left_super;
 
115
    case GDK_KEY_Super_R:
 
116
      return entry->priv->right_super;
 
117
    }
 
118
 
 
119
  return FALSE;
 
120
}
 
121
 
 
122
static void
 
123
gtk_entry_accel_set_modifier_state (GtkEntryAccel *entry,
 
124
                                    guint          key,
 
125
                                    gboolean       state)
 
126
{
 
127
  g_return_if_fail (GTK_IS_ENTRY_ACCEL (entry));
 
128
 
 
129
  switch (key)
 
130
    {
 
131
    case GDK_KEY_Shift_L:
 
132
      entry->priv->left_shift = state;
 
133
      break;
 
134
    case GDK_KEY_Shift_R:
 
135
      entry->priv->right_shift = state;
 
136
      break;
 
137
    case GDK_KEY_Control_L:
 
138
      entry->priv->left_control = state;
 
139
      break;
 
140
    case GDK_KEY_Control_R:
 
141
      entry->priv->right_control = state;
 
142
      break;
 
143
    case GDK_KEY_Meta_L:
 
144
    case GDK_KEY_Alt_L:
 
145
      entry->priv->left_alt = state;
 
146
      break;
 
147
    case GDK_KEY_Meta_R:
 
148
    case GDK_KEY_Alt_R:
 
149
      entry->priv->right_alt = state;
 
150
      break;
 
151
    case GDK_KEY_Super_L:
 
152
      entry->priv->left_super = state;
 
153
      break;
 
154
    case GDK_KEY_Super_R:
 
155
      entry->priv->right_super = state;
 
156
      break;
 
157
    }
 
158
}
 
159
 
 
160
static void
 
161
gtk_entry_accel_update_text (GtkEntryAccel *entry)
 
162
{
 
163
  if (entry->priv->keyboard == NULL || entry->priv->pointer == NULL)
 
164
    {
 
165
      if (entry->priv->key != 0 || entry->priv->code != 0 || entry->priv->mask != 0)
 
166
        {
 
167
          gchar *label = gtk_accelerator_get_label_with_keycode (NULL,
 
168
                                                                 entry->priv->key,
 
169
                                                                 entry->priv->code,
 
170
                                                                 entry->priv->mask);
 
171
 
 
172
          gtk_entry_set_text (GTK_ENTRY (entry), label);
 
173
 
 
174
          g_free (label);
 
175
        }
 
176
      else
 
177
        gtk_entry_set_text (GTK_ENTRY (entry), "");
 
178
    }
 
179
  else
 
180
    gtk_entry_set_text (GTK_ENTRY (entry), _("New acceleratorā€¦"));
 
181
}
 
182
 
 
183
static void
 
184
gtk_entry_accel_set_key (GtkEntryAccel   *entry,
 
185
                         guint            key,
 
186
                         guint            code,
 
187
                         GdkModifierType  mask)
 
188
{
 
189
  if (key != entry->priv->key || code != entry->priv->code || mask != entry->priv->mask)
 
190
    {
 
191
      entry->priv->key = key;
 
192
      entry->priv->code = code;
 
193
      entry->priv->mask = mask;
 
194
 
 
195
      g_free (entry->priv->accel);
 
196
 
 
197
      if (key != 0 || code != 0 || mask != 0)
 
198
        entry->priv->accel = gtk_accelerator_name_with_keycode (NULL, key, code, mask);
 
199
      else
 
200
        entry->priv->accel = NULL;
 
201
 
 
202
      g_object_notify_by_pspec (G_OBJECT (entry), properties[PROP_ACCEL]);
 
203
    }
 
204
 
 
205
  gtk_entry_accel_update_text (entry);
 
206
}
 
207
 
 
208
static void
 
209
gtk_entry_accel_ungrab_input (GtkEntryAccel *entry,
 
210
                              GdkEvent      *event)
 
211
{
 
212
  guint32 time = gdk_event_get_time (event);
 
213
 
 
214
  if (entry->priv->keyboard != NULL && entry->priv->pointer != NULL)
 
215
    gtk_grab_remove (GTK_WIDGET (entry));
 
216
 
 
217
  if (entry->priv->keyboard != NULL)
 
218
    {
 
219
      gdk_device_ungrab (entry->priv->keyboard, time);
 
220
      g_clear_object (&entry->priv->keyboard);
 
221
    }
 
222
 
 
223
  if (entry->priv->pointer != NULL)
 
224
    {
 
225
      gdk_device_ungrab (entry->priv->pointer, time);
 
226
      g_clear_object (&entry->priv->pointer);
 
227
    }
 
228
 
 
229
  gtk_entry_accel_reset_modifier_states (entry);
 
230
  gtk_entry_accel_update_text (entry);
 
231
}
 
232
 
 
233
static void
 
234
gtk_entry_accel_grab_input (GtkEntryAccel *entry,
 
235
                            GdkEvent      *event)
 
236
{
 
237
  GdkWindow *window = NULL;
 
238
  GdkDevice *device = NULL;
 
239
  GdkDevice *keyboard = NULL;
 
240
  GdkDevice *pointer = NULL;
 
241
  guint32 time;
 
242
 
 
243
  if (entry->priv->keyboard != NULL && entry->priv->pointer != NULL)
 
244
    return;
 
245
 
 
246
  gtk_entry_accel_ungrab_input (entry, event);
 
247
 
 
248
  if (event != NULL)
 
249
    device = gdk_event_get_device (event);
 
250
 
 
251
  if (device == NULL)
 
252
    device = gtk_get_current_event_device ();
 
253
 
 
254
  if (device == NULL)
 
255
    return;
 
256
 
 
257
  if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
 
258
    {
 
259
      keyboard = device;
 
260
      pointer = gdk_device_get_associated_device (device);
 
261
    }
 
262
  else
 
263
    {
 
264
      pointer = device;
 
265
      keyboard = gdk_device_get_associated_device (device);
 
266
    }
 
267
 
 
268
  if (gdk_device_get_source (keyboard) != GDK_SOURCE_KEYBOARD)
 
269
    return;
 
270
 
 
271
  window = gtk_widget_get_window (GTK_WIDGET (entry));
 
272
  time = gdk_event_get_time (event);
 
273
 
 
274
  if (gdk_device_grab (keyboard,
 
275
                       window,
 
276
                       GDK_OWNERSHIP_WINDOW,
 
277
                       FALSE,
 
278
                       GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
 
279
                       NULL,
 
280
                       time) != GDK_GRAB_SUCCESS)
 
281
    return;
 
282
 
 
283
  if (gdk_device_grab (pointer,
 
284
                       window,
 
285
                       GDK_OWNERSHIP_WINDOW,
 
286
                       FALSE,
 
287
                       GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK,
 
288
                       NULL,
 
289
                       time) != GDK_GRAB_SUCCESS)
 
290
    {
 
291
      gdk_device_ungrab (keyboard, time);
 
292
 
 
293
      return;
 
294
    }
 
295
 
 
296
  gtk_grab_add (GTK_WIDGET (entry));
 
297
 
 
298
  entry->priv->keyboard = g_object_ref (keyboard);
 
299
  entry->priv->pointer = g_object_ref (pointer);
 
300
}
 
301
 
 
302
static void
 
303
gtk_entry_accel_dispose (GObject *object)
 
304
{
 
305
  GtkEntryAccel *entry = GTK_ENTRY_ACCEL (object);
 
306
 
 
307
  gtk_entry_accel_ungrab_input (entry, NULL);
 
308
 
 
309
  G_OBJECT_CLASS (gtk_entry_accel_parent_class)->dispose (object);
 
310
}
 
311
 
 
312
static void
 
313
gtk_entry_accel_finalize (GObject *object)
 
314
{
 
315
  GtkEntryAccel *entry = GTK_ENTRY_ACCEL (object);
 
316
 
 
317
  g_free (entry->priv->accel);
 
318
 
 
319
  G_OBJECT_CLASS (gtk_entry_accel_parent_class)->finalize (object);
 
320
}
 
321
 
 
322
static void
 
323
gtk_entry_accel_get_property (GObject    *object,
 
324
                              guint       property_id,
 
325
                              GValue     *value,
 
326
                              GParamSpec *pspec)
 
327
{
 
328
  GtkEntryAccel *entry = GTK_ENTRY_ACCEL (object);
 
329
  const gchar *accel;
 
330
 
 
331
  switch (property_id)
 
332
    {
 
333
    case PROP_ACCEL:
 
334
      accel = gtk_entry_accel_get_accel (entry);
 
335
      g_value_set_string (value, accel != NULL ? accel : "");
 
336
      break;
 
337
 
 
338
    default:
 
339
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 
340
      break;
 
341
    }
 
342
}
 
343
 
 
344
static void
 
345
gtk_entry_accel_set_property (GObject      *object,
 
346
                              guint         property_id,
 
347
                              const GValue *value,
 
348
                              GParamSpec   *pspec)
 
349
{
 
350
  GtkEntryAccel *entry = GTK_ENTRY_ACCEL (object);
 
351
 
 
352
  switch (property_id)
 
353
    {
 
354
    case PROP_ACCEL:
 
355
      gtk_entry_accel_set_accel (entry, g_value_get_string (value));
 
356
      break;
 
357
 
 
358
    default:
 
359
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 
360
      break;
 
361
    }
 
362
}
 
363
 
 
364
static gboolean
 
365
gtk_entry_accel_button_press_event (GtkWidget      *widget,
 
366
                                    GdkEventButton *event)
 
367
{
 
368
  if (event->button == 1)
 
369
    {
 
370
      GtkEntryAccel *entry = GTK_ENTRY_ACCEL (widget);
 
371
 
 
372
      if (entry->priv->keyboard != NULL && entry->priv->pointer != NULL)
 
373
        gtk_entry_accel_ungrab_input (entry, (GdkEvent *) event);
 
374
      else
 
375
        gtk_entry_accel_grab_input (entry, (GdkEvent *) event);
 
376
 
 
377
      gtk_entry_accel_update_text (entry);
 
378
    }
 
379
 
 
380
  return TRUE;
 
381
}
 
382
 
 
383
static gboolean
 
384
gtk_entry_accel_post_action_accumulator (GSignalInvocationHint *ihint,
 
385
                                         GValue                *return_accu,
 
386
                                         const GValue          *handler_return,
 
387
                                         gpointer               data)
 
388
{
 
389
  GtkEntryAccelPostAction action = g_value_get_enum (return_accu);
 
390
  GtkEntryAccelPostAction current_action = g_value_get_enum (handler_return);
 
391
 
 
392
  if (action == GTK_ENTRY_ACCEL_UPDATE)
 
393
    action = current_action;
 
394
 
 
395
  g_value_set_enum (return_accu, action);
 
396
 
 
397
  return action == GTK_ENTRY_ACCEL_UPDATE;
 
398
}
 
399
 
 
400
static GtkEntryAccelPostAction
 
401
gtk_entry_accel_real_key_pressed (GtkEntryAccel   *entry,
 
402
                                  guint           *key,
 
403
                                  guint           *code,
 
404
                                  GdkModifierType *mask)
 
405
{
 
406
  return GTK_ENTRY_ACCEL_UPDATE;
 
407
}
 
408
 
 
409
static GtkEntryAccelPostAction
 
410
gtk_entry_accel_key_pressed (GtkEntryAccel   *entry,
 
411
                             guint           *key,
 
412
                             guint           *code,
 
413
                             GdkModifierType *mask)
 
414
{
 
415
  GtkEntryAccelPostAction action;
 
416
 
 
417
  g_signal_emit (entry,
 
418
                 signals[SIGNAL_KEY_PRESSED],
 
419
                 0,
 
420
                 key,
 
421
                 code,
 
422
                 mask,
 
423
                 &action);
 
424
 
 
425
  return action;
 
426
}
 
427
 
 
428
static gboolean
 
429
gtk_entry_accel_key_press_event (GtkWidget   *widget,
 
430
                                 GdkEventKey *event)
 
431
{
 
432
  GtkEntryAccel *entry = GTK_ENTRY_ACCEL (widget);
 
433
  guint key = event->keyval;
 
434
  guint mask = event->state & GTK_ENTRY_ACCEL_MODIFIER_MASK;
 
435
  gboolean grabbed = entry->priv->keyboard != NULL && entry->priv->pointer != NULL;
 
436
 
 
437
  gtk_entry_accel_set_modifier_state (entry, key, TRUE);
 
438
 
 
439
  return ((grabbed ? mask : (mask & ~GDK_SHIFT_MASK)) != 0 ||
 
440
          (key != GDK_KEY_Tab &&
 
441
           key != GDK_KEY_KP_Tab &&
 
442
           key != GDK_KEY_ISO_Left_Tab &&
 
443
           key != GDK_KEY_3270_BackTab) ||
 
444
          GTK_WIDGET_CLASS (gtk_entry_accel_parent_class)->key_press_event (widget, event));
 
445
}
 
446
 
 
447
static guint
 
448
gtk_entry_accel_get_mask_for_key (guint key)
 
449
{
 
450
  switch (key)
 
451
    {
 
452
    case GDK_KEY_Shift_L:
 
453
    case GDK_KEY_Shift_R:
 
454
      return GDK_SHIFT_MASK;
 
455
    case GDK_KEY_Control_L:
 
456
    case GDK_KEY_Control_R:
 
457
      return GDK_CONTROL_MASK;
 
458
    case GDK_KEY_Caps_Lock:
 
459
    case GDK_KEY_Shift_Lock:
 
460
      return GDK_LOCK_MASK;
 
461
    case GDK_KEY_Meta_L:
 
462
    case GDK_KEY_Meta_R:
 
463
      return GDK_META_MASK;
 
464
    case GDK_KEY_Alt_L:
 
465
    case GDK_KEY_Alt_R:
 
466
      return GDK_MOD1_MASK;
 
467
    case GDK_KEY_Super_L:
 
468
    case GDK_KEY_Super_R:
 
469
      return GDK_SUPER_MASK;
 
470
    case GDK_KEY_Hyper_L:
 
471
    case GDK_KEY_Hyper_R:
 
472
      return GDK_HYPER_MASK;
 
473
    }
 
474
 
 
475
  return 0;
 
476
}
 
477
 
 
478
static guint
 
479
gtk_entry_accel_get_mirrored_key (guint key)
 
480
{
 
481
  switch (key)
 
482
    {
 
483
    case GDK_KEY_Shift_L:
 
484
      return GDK_KEY_Shift_R;
 
485
    case GDK_KEY_Shift_R:
 
486
      return GDK_KEY_Shift_L;
 
487
    case GDK_KEY_Control_L:
 
488
      return GDK_KEY_Control_R;
 
489
    case GDK_KEY_Control_R:
 
490
      return GDK_KEY_Control_L;
 
491
    case GDK_KEY_Meta_L:
 
492
      return GDK_KEY_Meta_R;
 
493
    case GDK_KEY_Meta_R:
 
494
      return GDK_KEY_Meta_L;
 
495
    case GDK_KEY_Alt_L:
 
496
      return GDK_KEY_Alt_R;
 
497
    case GDK_KEY_Alt_R:
 
498
      return GDK_KEY_Alt_L;
 
499
    case GDK_KEY_Super_L:
 
500
      return GDK_KEY_Super_R;
 
501
    case GDK_KEY_Super_R:
 
502
      return GDK_KEY_Super_L;
 
503
    case GDK_KEY_Hyper_L:
 
504
      return GDK_KEY_Hyper_R;
 
505
    }
 
506
 
 
507
  return 0;
 
508
}
 
509
 
 
510
static gboolean
 
511
gtk_entry_accel_key_release_event (GtkWidget   *widget,
 
512
                                   GdkEventKey *event)
 
513
{
 
514
  GtkEntryAccel *entry = GTK_ENTRY_ACCEL (widget);
 
515
  guint key = event->keyval;
 
516
  guint code = event->hardware_keycode;
 
517
  guint mask = event->state & GTK_ENTRY_ACCEL_MODIFIER_MASK;
 
518
 
 
519
  if (entry->priv->keyboard != NULL && entry->priv->pointer != NULL)
 
520
    {
 
521
      switch (key)
 
522
        {
 
523
        case GDK_KEY_Meta_L:
 
524
          key = GDK_KEY_Alt_L;
 
525
          break;
 
526
 
 
527
        case GDK_KEY_Meta_R:
 
528
          key = GDK_KEY_Alt_R;
 
529
          break;
 
530
        }
 
531
 
 
532
      if (event->is_modifier && !gtk_entry_accel_get_modifier_state (entry, gtk_entry_accel_get_mirrored_key (key)))
 
533
        mask &= ~gtk_entry_accel_get_mask_for_key (key);
 
534
 
 
535
      gtk_entry_accel_ungrab_input (entry, (GdkEvent *) event);
 
536
 
 
537
      switch (gtk_entry_accel_key_pressed (entry, &key, &code, &mask))
 
538
        {
 
539
        case GTK_ENTRY_ACCEL_UPDATE:
 
540
          gtk_entry_accel_set_key (entry, key, code, mask);
 
541
        case GTK_ENTRY_ACCEL_CANCEL:
 
542
          gtk_entry_accel_ungrab_input (entry, (GdkEvent *) event);
 
543
        case GTK_ENTRY_ACCEL_IGNORE:
 
544
          return TRUE;
 
545
        }
 
546
 
 
547
      event->keyval = key;
 
548
      event->hardware_keycode = code;
 
549
      event->state = mask;
 
550
 
 
551
      gtk_entry_accel_ungrab_input (entry, (GdkEvent *) event);
 
552
 
 
553
      return GTK_WIDGET_CLASS (gtk_entry_accel_parent_class)->key_release_event (widget, event);
 
554
    }
 
555
 
 
556
  if (mask == 0 &&
 
557
      (key == GDK_KEY_Return ||
 
558
       key == GDK_KEY_KP_Enter ||
 
559
       key == GDK_KEY_ISO_Enter ||
 
560
       key == GDK_KEY_3270_Enter))
 
561
    {
 
562
      gtk_entry_accel_grab_input (entry, (GdkEvent *) event);
 
563
      gtk_entry_accel_update_text (entry);
 
564
 
 
565
      return TRUE;
 
566
    }
 
567
 
 
568
  return ((mask & ~GDK_SHIFT_MASK) != 0 ||
 
569
          (key != GDK_KEY_Tab &&
 
570
           key != GDK_KEY_KP_Tab &&
 
571
           key != GDK_KEY_ISO_Left_Tab &&
 
572
           key != GDK_KEY_3270_BackTab) ||
 
573
          GTK_WIDGET_CLASS (gtk_entry_accel_parent_class)->key_release_event (widget, event));
 
574
}
 
575
 
 
576
static void
 
577
gtk_entry_accel_class_init (GtkEntryAccelClass *klass)
 
578
{
 
579
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
580
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
581
 
 
582
  object_class->dispose = gtk_entry_accel_dispose;
 
583
  object_class->finalize = gtk_entry_accel_finalize;
 
584
  object_class->get_property = gtk_entry_accel_get_property;
 
585
  object_class->set_property = gtk_entry_accel_set_property;
 
586
  widget_class->button_press_event = gtk_entry_accel_button_press_event;
 
587
  widget_class->key_press_event = gtk_entry_accel_key_press_event;
 
588
  widget_class->key_release_event = gtk_entry_accel_key_release_event;
 
589
  klass->key_pressed = gtk_entry_accel_real_key_pressed;
 
590
 
 
591
  properties[PROP_ACCEL] = g_param_spec_string ("accel",
 
592
                                                "Accelerator",
 
593
                                                "Current accelerator",
 
594
                                                NULL,
 
595
                                                G_PARAM_READWRITE);
 
596
 
 
597
  g_object_class_install_property (object_class,
 
598
                                   PROP_ACCEL,
 
599
                                   properties[PROP_ACCEL]);
 
600
 
 
601
  signals[SIGNAL_KEY_PRESSED] = g_signal_new ("key-pressed",
 
602
                                              G_OBJECT_CLASS_TYPE (klass),
 
603
                                              G_SIGNAL_RUN_LAST,
 
604
                                              G_STRUCT_OFFSET (GtkEntryAccelClass, key_pressed),
 
605
                                              gtk_entry_accel_post_action_accumulator,
 
606
                                              NULL,
 
607
                                              NULL,
 
608
                                              GTK_TYPE_ENTRY_ACCEL_POST_ACTION,
 
609
                                              3,
 
610
                                              G_TYPE_POINTER,
 
611
                                              G_TYPE_POINTER,
 
612
                                              G_TYPE_POINTER);
 
613
 
 
614
  g_type_class_add_private (klass, sizeof (GtkEntryAccelPrivate));
 
615
}
 
616
 
 
617
static void
 
618
gtk_entry_accel_init (GtkEntryAccel *self)
 
619
{
 
620
  self->priv = GTK_ENTRY_ACCEL_GET_PRIVATE (self);
 
621
}
 
622
 
 
623
GtkWidget *
 
624
gtk_entry_accel_new (void)
 
625
{
 
626
  return g_object_new (GTK_TYPE_ENTRY_ACCEL, NULL);
 
627
}
 
628
 
 
629
const gchar *
 
630
gtk_entry_accel_get_accel (GtkEntryAccel *entry)
 
631
{
 
632
  g_return_val_if_fail (GTK_IS_ENTRY_ACCEL (entry), NULL);
 
633
 
 
634
  return entry->priv->accel;
 
635
}
 
636
 
 
637
void
 
638
gtk_entry_accel_set_accel (GtkEntryAccel *entry,
 
639
                           const gchar   *accel)
 
640
{
 
641
  guint key = 0;
 
642
  guint *codes = NULL;
 
643
  GdkModifierType mask = 0;
 
644
 
 
645
  g_return_if_fail (GTK_IS_ENTRY_ACCEL (entry));
 
646
 
 
647
  if (accel != NULL)
 
648
    gtk_accelerator_parse_with_keycode (accel, &key, &codes, &mask);
 
649
 
 
650
  gtk_entry_accel_set_key (entry, key, codes != NULL ? codes[0] : 0, mask);
 
651
 
 
652
  g_free (codes);
 
653
}