diff --git a/sflphone-gtk/src/actions.c b/sflphone-gtk/src/actions.c
index 204fbbf2524ce0cfba9d003a3135a3bd87df462f..4589bb5556970d50c8ac226d811f01a1f9028ac0 100644
--- a/sflphone-gtk/src/actions.c
+++ b/sflphone-gtk/src/actions.c
@@ -162,110 +162,150 @@ sflphone_hung_up (call_t * c )
   screen_clear();
 }
 
-void 
-sflphone_keypad( guint keyval, gchar * key)
+void process_dialing(call_t * c, guint keyval, gchar * key)
 {
-  call_t * c = (call_t*) call_list_get_by_state (CALL_STATE_DIALING);
-  if(c) // Currently dialing => edit number
+  switch (keyval)
   {
-    switch (keyval)
-    {
-    case 65293: /* ENTER */
-    case 65421: /* ENTER numpad */
-      sflphone_place_call(c);
-      break;
-    case 65307: /* ESCAPE */
-      dbus_hang_up(c);
-      break;
-    case 65288: /* BACKSPACE */
-      {  /* Brackets mandatory because of local vars */
-        gchar * before = c->to;
-        if(strlen(c->to) > 1){
-          c->to = g_strndup(c->to, strlen(c->to) -1);
-          g_free(before);
-          g_print("TO: %s\n", c->to);
-        
-          g_free(c->from);
-          c->from = g_strconcat("\"\" <", c->to, ">", NULL);
-          screen_set_call(c);
-          update_call_tree(c);
-        } 
-        else if(strlen(c->to) == 1)
-        {
-          dbus_hang_up(c);
-        }
-        
-      }
-      break;
-    case 65289: /* TAB */
-    case 65513: /* ALT */
-    case 65507: /* CTRL */
-    case 65515: /* SUPER */
-    case 65509: /* CAPS */
-    case 65505: /* SHIFT */
-      break;
-    default:
-      if (keyval < 255 || (keyval >65453 && keyval < 65466))
-      {  /* Brackets mandatory because of local vars */
-        gchar * before = c->to;
-        c->to = g_strconcat(c->to, key, NULL);
+  case 65293: /* ENTER */
+  case 65421: /* ENTER numpad */
+    sflphone_place_call(c);
+    break;
+  case 65307: /* ESCAPE */
+    dbus_hang_up(c);
+    break;
+  case 65288: /* BACKSPACE */
+    {  /* Brackets mandatory because of local vars */
+      gchar * before = c->to;
+      if(strlen(c->to) > 1){
+        c->to = g_strndup(c->to, strlen(c->to) -1);
         g_free(before);
         g_print("TO: %s\n", c->to);
-        
+      
         g_free(c->from);
         c->from = g_strconcat("\"\" <", c->to, ">", NULL);
         screen_set_call(c);
         update_call_tree(c);
+      } 
+      else if(strlen(c->to) == 1)
+      {
+        dbus_hang_up(c);
       }
-      break;
     }
+    break;
+  case 65289: /* TAB */
+  case 65513: /* ALT */
+  case 65507: /* CTRL */
+  case 65515: /* SUPER */
+  case 65509: /* CAPS */
+    break;
+  default:
+    if (keyval < 255 || (keyval >65453 && keyval < 65466))
+    { 
+      gchar * before = c->to;
+      c->to = g_strconcat(c->to, key, NULL);
+      g_free(before);
+      g_print("TO: %s\n", c->to);
+      
+      g_free(c->from);
+      c->from = g_strconcat("\"\" <", c->to, ">", NULL);
+      screen_set_call(c);
+      update_call_tree(c);
+    }
+    break;
   }
-  else 
+  
+}
+
+void process_new_call(guint keyval, gchar * key){
+  if (keyval < 255 || (keyval >65453 && keyval < 65466))
+    { 
+      /* Brackets mandatory because of local vars */
+      call_t * c = g_new0 (call_t, 1);
+      c->state = CALL_STATE_DIALING;
+      c->from = g_strconcat("\"\" <", key, ">", NULL);
+      
+      c->callID = g_new0(gchar, 100);
+      g_sprintf(c->callID, "%d", rand()); 
+      
+      c->to = g_strdup(key);
+      call_list_add(c);
+      screen_set_call(c);
+      update_call_tree_add(c);
+    }
+}
+
+void 
+sflphone_keypad( guint keyval, gchar * key)
+{
+  call_t * c = call_get_selected();
+  if(c)
   {
-    call_t * c = (call_t*) call_list_get_by_state (CALL_STATE_CURRENT);
-    if(c) // Currently in a call => send number to server
+  
+    switch(c->state) // Currently dialing => edit number
     {
-      switch (keyval)
-      {
-      case 65307: /* ESCAPE */
-        dbus_hang_up(c);
+      case CALL_STATE_DIALING:
+        process_dialing(c, keyval, key);
         break;
-      }
-    } 
-    else 
-    {
-      call_t * c = (call_t*) call_list_get_by_state (CALL_STATE_RINGING);
-      if(c) // Currently ring => edit number
-      {
+      case CALL_STATE_CURRENT:
+      case CALL_STATE_RINGING:
         switch (keyval)
         {
         case 65307: /* ESCAPE */
           dbus_hang_up(c);
           break;
+        default:
+          //TODO send DTMF, 
+          if (keyval < 255 || (keyval >65453 && keyval < 65466))
+          { 
+            gchar * temp = g_strconcat(call_get_number(c), key, NULL);
+            gchar * before = c->from;
+            c->from = g_strconcat("\"",call_get_name(c) ,"\" <", temp, ">", NULL);
+            g_free(before);
+            g_free(temp);
+            screen_set_call(c);
+            update_call_tree(c);
+          }
+          break;
         }
-      }
-      else
-      { // Not in a call, not dialing, create a new call 
-        if (keyval < 255 || (keyval >65453 && keyval < 65466))
-        { 
-          /* Brackets mandatory because of local vars */
-          call_t * c = g_new0 (call_t, 1);
-          c->state = CALL_STATE_DIALING;
-          c->from = g_strconcat("\"\" <", key, ">", NULL);
-          
-          c->callID = g_new0(gchar, 100);
-          g_sprintf(c->callID, "%d", rand()); 
-          
-          c->to = g_strdup(key);
-          call_list_add(c);
-          screen_set_call(c);
-          update_call_tree_add(c);
+        break;
+      case CALL_STATE_INCOMING:
+        switch (keyval)
+        {
+        case 65293: /* ENTER */
+        case 65421: /* ENTER numpad */
+          dbus_accept(c);
+          break;
+        case 65307: /* ESCAPE */
+          dbus_refuse(c);
+          break;
         }
-      }
-    }
+        break;
+      case CALL_STATE_HOLD:
+        switch (keyval)
+        {
+        case 65293: /* ENTER */
+        case 65421: /* ENTER numpad */
+          dbus_unhold(c);
+          break;
+        case 65307: /* ESCAPE */
+          dbus_hang_up(c);
+          break;
+        default: // When a call is on hold, typing new numbers will create a new call
+          process_new_call(keyval, key);
+          break;
+        }
+        break;
+      default:
+        break;
+     } 
+  }
+  else 
+  { // Not in a call, not dialing, create a new call 
+    process_new_call(keyval, key);
   }
 } 
 
+
 void 
 sflphone_place_call ( call_t * c )
 {
diff --git a/sflphone-gtk/src/calllist.c b/sflphone-gtk/src/calllist.c
index 1291f9c5f1dfc129da7cf26cb3deb7ceef043635..6203e2060b0a3248df6d65d99569a6c8c3b364b8 100644
--- a/sflphone-gtk/src/calllist.c
+++ b/sflphone-gtk/src/calllist.c
@@ -21,7 +21,8 @@
 
 #include <string.h>
 
-GQueue * callQueue;
+GQueue * callQueue = NULL;
+call_t * selectedCall = NULL;
 
 /* GCompareFunc to compare a callID (gchar* and a call_t) */
 gint 
@@ -142,3 +143,16 @@ call_list_get ( const gchar * callID )
     return NULL;
   }
 }
+
+void
+call_select ( call_t * c )
+{
+  selectedCall = c;
+}
+
+
+call_t *
+call_get_selected ()
+{
+  return selectedCall;
+}
diff --git a/sflphone-gtk/src/calllist.h b/sflphone-gtk/src/calllist.h
index 4de7286d3438f9d538e82ebbb71c00d847ad036b..9b0accb65755da8112fcfec7cd43b74bd69a367a 100644
--- a/sflphone-gtk/src/calllist.h
+++ b/sflphone-gtk/src/calllist.h
@@ -107,4 +107,12 @@ gchar * call_get_name (const call_t * c);
   * @return The number of the caller */
 gchar * call_get_number (const call_t * c);
 
+/** Mark a call as selected.  There can be only one selected call.  This call
+  * is the currently highlighted one in the list.
+  * @param c The call */
+void call_select ( call_t * c );
+
+/** Return the selected call.
+  * @return The number of the caller */
+call_t * call_get_selected ();
 #endif 
diff --git a/sflphone-gtk/src/calltree.c b/sflphone-gtk/src/calltree.c
index 1e2cd7c128dbe6bf2413113d7e122e96195c306b..590104b0cb574becfd976aebae578f00368decf9 100644
--- a/sflphone-gtk/src/calltree.c
+++ b/sflphone-gtk/src/calltree.c
@@ -18,6 +18,7 @@
  */
 
 #include <gtk/gtk.h>
+#include <actions.h>
 #include <calltree.h>
 #include <calllist.h>
 #include <dbus.h>
@@ -31,20 +32,19 @@ GtkWidget * holdButton;
 GtkWidget * transfertButton;
 GtkWidget * unholdButton;
 
-call_t * selectedCall;
-
 /**
  * Make a call
  */
 static void 
 call_button( GtkWidget *widget, gpointer   data )
 {
+  call_t * selectedCall = call_get_selected();
   if(selectedCall)
   {
     switch(selectedCall->state)
     {
       case CALL_STATE_DIALING:
-        dbus_place_call (selectedCall);
+        sflphone_place_call (selectedCall);
         break;
       case CALL_STATE_INCOMING:
         dbus_accept (selectedCall);
@@ -62,6 +62,7 @@ call_button( GtkWidget *widget, gpointer   data )
 static void 
 hang_up( GtkWidget *widget, gpointer   data )
 {
+  call_t * selectedCall = call_get_selected();
   if(selectedCall)
   {
     switch(selectedCall->state)
@@ -88,6 +89,7 @@ hang_up( GtkWidget *widget, gpointer   data )
 static void 
 hold( GtkWidget *widget, gpointer   data )
 {
+  call_t * selectedCall = call_get_selected();
   if(selectedCall)
   {
     switch(selectedCall->state)
@@ -121,6 +123,7 @@ transfert( GtkWidget *widget, gpointer   data )
 static void 
 unhold( GtkWidget *widget, gpointer   data )
 {
+  call_t * selectedCall = call_get_selected();
   if(selectedCall)
   {
     switch(selectedCall->state)
@@ -143,7 +146,8 @@ update_buttons ()
   gtk_widget_set_sensitive( GTK_WIDGET(transfertButton),  FALSE);
   gtk_widget_set_sensitive( GTK_WIDGET(unholdButton),     FALSE);
 	
-	if(selectedCall)  // TODO Make this a switch
+	call_t * selectedCall = call_get_selected();
+  if(selectedCall)  // TODO Make this a switch
 	{
 	  if( selectedCall->state == CALL_STATE_INCOMING)
 	  {
@@ -192,7 +196,7 @@ selected(GtkTreeSelection *sel, GtkTreeModel *model)
 	val.g_type = 0;
 	gtk_tree_model_get_value (model, &iter, 2, &val);
 	
-	selectedCall = (call_t*) g_value_get_pointer(&val);
+	call_select((call_t*) g_value_get_pointer(&val));
   g_value_unset(&val);
   
   update_buttons();
@@ -326,8 +330,9 @@ update_call_tree_remove (call_t * c)
       }
 	  }
 	}
+	call_t * selectedCall = call_get_selected();
 	if(selectedCall == c)
-	  selectedCall = NULL;
+	  call_select(NULL);
 	update_buttons();
 }
 
diff --git a/sflphone-gtk/src/mainwindow.c b/sflphone-gtk/src/mainwindow.c
index 4246fea08bb8c7408d1b9004d02bcb52e9555b6a..36a696637cc646db2dce62c6732d68380f526b51 100644
--- a/sflphone-gtk/src/mainwindow.c
+++ b/sflphone-gtk/src/mainwindow.c
@@ -93,8 +93,10 @@ on_key_released (GtkWidget   *widget,
 #endif 
   // If a modifier key is pressed, it's a shortcut, pass along
   if(event->state & GDK_CONTROL_MASK || 
-     event->state & GDK_SHIFT_MASK   || 
      event->state & GDK_MOD1_MASK    ||
+     event->keyval == 60             || // <
+     event->keyval == 62             || // >
+     event->keyval == 34             || // "
      event->keyval == 65361          || // left arrow
      event->keyval == 65363          || // right arrow
      event->keyval == 32                // space