Пример #1
0
static void
ghack_main_window_key_press(GtkWidget *widget, GdkEventKey *event, 
	gpointer data)
{
    /* First, turn off the key press propogation.  We've got the
     * key, but we don't wan't the underlying Gtk widgets to get it,
     * since they do the wrong thing with the arrow keys (shift focus)... */
    gtk_signal_emit_stop_by_name( GTK_OBJECT(mainWindow), "key_press_event");
    
    /* stuff the key event into the keybuffer */
    ghack_handle_key_press(widget, event, data);
}
Пример #2
0
static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget),
                                              GtkNotebookPage *WXUNUSED(page),
                                              gint page,
                                              wxNotebook *notebook )
{
    // are you trying to call SetSelection() from a notebook event handler?
    // you shouldn't!
    wxCHECK_RET( !notebook->m_inSwitchPage,
                 wxT("gtk_notebook_page_change_callback reentered") );

    notebook->m_inSwitchPage = true;
    if (g_isIdle)
        wxapp_install_idle_handler();

    int old = notebook->GetSelection();

    if (notebook->m_skipNextPageChangeEvent)
    {
        // this event was programmatically generated by ChangeSelection() and thus must
        // be skipped
        notebook->m_skipNextPageChangeEvent = false;

        // make wxNotebook::GetSelection() return the correct (i.e. consistent
        // with wxBookCtrlEvent::GetSelection()) value even though the page is
        // not really changed in GTK+
        notebook->SetSelection(page);
    }
    else
    {
        if ( !notebook->SendPageChangingEvent(page) )
        {
            // program doesn't allow the page change
            gtk_signal_emit_stop_by_name(GTK_OBJECT(notebook->m_widget), "switch_page");
        }
        else // change allowed
        {
            // make wxNotebook::GetSelection() return the correct (i.e. consistent
            // with wxBookCtrlEvent::GetSelection()) value even though the page is
            // not really changed in GTK+
            notebook->SetSelection(page);

            notebook->SendPageChangedEvent(old);
        }
    }

    notebook->m_inSwitchPage = FALSE;
}
Пример #3
0
static gint gtk_radiobox_keypress_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxRadioBox *rb )
{
    if (g_isIdle)
        wxapp_install_idle_handler();

    if (!rb->m_hasVMT) return FALSE;
    if (g_blockEventsOnDrag) return FALSE;

    if ((gdk_event->keyval != GDK_Up) &&
        (gdk_event->keyval != GDK_Down) &&
        (gdk_event->keyval != GDK_Left) &&
        (gdk_event->keyval != GDK_Right))
    {
        return FALSE;
    }

    wxList::compatibility_iterator node = rb->m_boxes.Find( (wxObject*) widget );
    if (!node)
    {
        return FALSE;
    }

    gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" );

    if ((gdk_event->keyval == GDK_Up) ||
        (gdk_event->keyval == GDK_Left))
    {
        if (node == rb->m_boxes.GetFirst())
            node = rb->m_boxes.GetLast();
        else
            node = node->GetPrevious();
    }
    else
    {
        if (node == rb->m_boxes.GetLast())
            node = rb->m_boxes.GetFirst();
        else
            node = node->GetNext();
    }

    GtkWidget *button = (GtkWidget*) node->GetData();

    gtk_widget_grab_focus( button );

    return TRUE;
}
Пример #4
0
static gboolean list_motion_notify(GtkWidget *widget, GdkEventMotion *event,
				   gpointer user_data)
{
     gint mx,my;
     gint wx,wy,ww,wh;
     
     gdk_window_get_root_origin(widget->window,&wx,&wy);
     gdk_window_get_size(widget->window,&ww,&wh);
     mx = (gint) (event->x_root);
     my = (gint) (event->y_root);

     /*printf("mouse: <%d,%d>, window: <%d,%d>+<%d,%d>\n",mx,my,wx,wy,ww,wh);*/
     if (mx < wx || mx > wx+ww || my < wy || my > wy+wh)
	  gtk_signal_emit_stop_by_name(GTK_OBJECT(widget),
				       "motion-notify-event");
     return FALSE;
}
Пример #5
0
/*
 * FILEVIEW CALLBACKS
 */
static void
updir_click_cb(GtkWidget *widget, GdkEventButton *event, FileView *view)
{
  if (event->button == 1)
  {
    gchar path[PATH_MAX];
    g_snprintf(path, sizeof(path), "%s/..", view->dir);
    change_dir(view, path);
  }
  else if (event->button == 3)
  {
    gchar *home;
    if ((home = getenv("HOME")) != NULL)
      change_dir(view, home);
    else
      status_message(_("Environment variable 'HOME' not set."));
  }
  gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "button_press_event");
  focus_row(view, view->row, TRUE, TRUE, TRUE);
}
Пример #6
0
static void entry_insert_cb(GtkText *gtktext, gchar *newtext, guint len, guint *ppos, gpointer d)
{
  gint origpos;

  gtk_signal_handler_block_by_func(GTK_OBJECT(gtktext),
				   GTK_SIGNAL_FUNC(entry_insert_cb), 
				   NULL );
  
  gtk_text_insert(GTK_TEXT(gtktext), NULL,
		  &(GTK_WIDGET(gtktext)->style->fg[0]), NULL, newtext, len);

  gtk_signal_handler_unblock_by_func(GTK_OBJECT(gtktext),
				     GTK_SIGNAL_FUNC(entry_insert_cb),
				     NULL);
  
  gtk_signal_emit_stop_by_name(GTK_OBJECT(gtktext), "insert-text");
  *ppos += len;

  origpos = gtk_editable_get_position(GTK_EDITABLE(gtktext));

  if (iswordsep(newtext[0])) 
    {
      /* did we just end a word? */
      if (*ppos >= 2) check_at(gtktext, *ppos-2);
      
      /* did we just split a word? */
      if (*ppos < gtk_text_get_length(gtktext))
	check_at(gtktext, *ppos+1);
    } 
  else 
    {
      /* check as they type, *except* if they're typing at the end (the most
       * common case.
       */
      if (*ppos < gtk_text_get_length(gtktext) && !iswordsep(GTK_TEXT_INDEX(gtktext, *ppos)))
	check_at(gtktext, *ppos-1);
    }

  gtk_editable_set_position(GTK_EDITABLE(gtktext), origpos);
  gtk_editable_select_region(GTK_EDITABLE(gtktext), origpos, origpos);
}
Пример #7
0
gint key_release_event(GtkWidget *widget, GdkEventKey *event)
{
  switch (event->keyval) {
  case GDK_Left:
    if (control_spin == 1) control_spin = 0;
    break;
  case GDK_Right:
    if (control_spin == -1) control_spin = 0;
    break;
  case GDK_Up:
  case GDK_space:
    control_fire = 0;
    break;
  case GDK_Down:
    control_speed = 0;
    break;
  }
  /* prevent the default handler from being run */
  gtk_signal_emit_stop_by_name(GTK_OBJECT(widget),"key_release_event");
  return TRUE;
}
Пример #8
0
gint key_press_event(GtkWidget *widget, GdkEventKey *event)
{
  switch (event->keyval) {
  case GDK_Left:
    control_spin = 1;
    break;
  case GDK_Right:
    control_spin = -1;
    break;
  case GDK_Up:
  case GDK_space:
    control_fire = 1;
    break;
  case GDK_Down:
    control_speed = 1;
    break;
  case GDK_r:
    game_init();
    break;
  case GDK_q:
    gtk_main_quit();
    break;

#ifdef FULLSCREEN_MESA_3DFX
  case GDK_f:
    switch_fullscreen(widget);
    break;
#endif

  case GDK_d:
    draw_fast = (!draw_fast);
    break;
  }
  /* prevent the default handler from being run */
  gtk_signal_emit_stop_by_name(GTK_OBJECT(widget),"key_press_event");
  return TRUE;
}
Пример #9
0
static gboolean
file_list_key_press_cb(GtkWidget *widget, GdkEventKey *event, FileView *view)
{
  GList *tmp;

  /* get rid of all the modifiers that we don't care about */
  event->state &= ~(GDK_LOCK_MASK | GDK_MOD2_MASK | GDK_MOD3_MASK |
                    GDK_MOD4_MASK | GDK_MOD5_MASK);
  for (tmp = cfg.key_bindings; tmp != NULL; tmp = tmp->next)
  {
    KeyBinding *kb = tmp->data;

    if ((event->state == kb->state) &&
        (gdk_keyval_to_lower(event->keyval) == kb->keyval))
    { /* key bindings are case insensitive */
      do_command(kb->action);
      gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "key_press_event");
      return TRUE;
    }
  }

  /* Alt+<letter> Shortcuts to activate the menus */
  if (event->state & GDK_MOD1_MASK)
  {
    switch (event->keyval)
    {
    case 'B': case 'b':
      gtk_signal_emit_by_name(GTK_OBJECT(view->bookmark_menu_item),
                              "activate-item");
      break;
    case 'F': case 'f':
      gtk_signal_emit_by_name(GTK_OBJECT(view->filter_menu_item),
                              "activate-item");
      break;
    default:
      break;
    }
    return TRUE;
  }

  if ((event->keyval < 0x100) && (event->state <= 1))
  { /* The key is a letter and the only possible modifier is Shift */
    if (cfg.use_vi_keys)
    {
      switch (event->keyval)
      {
      case 'j':
        event->keyval = GDK_Down;
        return TRUE;
      case 'k':
        event->keyval = GDK_Up;
        return TRUE;
      case 'l':
        open_cb(NULL);
        gtk_widget_grab_focus(curr_view->clist);
        return TRUE;
      case 'h':
        change_dir(view, "..");
        return TRUE;
      case 'g':
        focus_row(view, 0, TRUE, TRUE, TRUE);
        return TRUE;
      case 'G':
        focus_row(view, (GTK_CLIST(view->clist)->rows - 1), TRUE, TRUE, TRUE);
        return TRUE;
      case 't':
        toggle_tag_cb();
        return TRUE;
      case '/':
        find_cb(NULL);
        return TRUE;
      default:
        break;
      }
    }
    else
    {
      /* Select row beggining with letter entered */
      gint row = find_filename_begining_with(event->keyval);
      if (row > 0)
        focus_row(view, row, TRUE, TRUE, TRUE);
      return TRUE;
    }
  }
  return FALSE;
}
Пример #10
0
static gint
gtk_listbox_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxListBox *listbox )
{
    if (g_isIdle)
        wxapp_install_idle_handler();

    if (g_blockEventsOnDrag)
        return FALSE;

    bool ret = false;

    if ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab))
    {
        wxNavigationKeyEvent new_event;
        /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
        new_event.SetDirection( (gdk_event->keyval == GDK_Tab) );
        /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
        new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) );
        new_event.SetCurrentFocus( listbox );
        ret = listbox->GetEventHandler()->ProcessEvent( new_event );
    }

    if ((gdk_event->keyval == GDK_Return) && (!ret))
    {
        // eat return in all modes
        ret = true;
    }

#if wxUSE_CHECKLISTBOX
    if ((gdk_event->keyval == ' ') && (listbox->m_hasCheckBoxes) && (!ret))
    {
        int sel = listbox->GtkGetIndex( widget );

        wxCheckListBox *clb = (wxCheckListBox *)listbox;

        clb->Check( sel, !clb->IsChecked(sel) );

        wxCommandEvent new_event( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, listbox->GetId() );
        new_event.SetEventObject( listbox );
        new_event.SetInt( sel );
        ret = listbox->GetEventHandler()->ProcessEvent( new_event );
    }
#endif // wxUSE_CHECKLISTBOX

    // Check or uncheck item with SPACE
    if ((gdk_event->keyval == ' ') && (!ret) &&
         (((listbox->GetWindowStyleFlag() & wxLB_MULTIPLE) != 0) ||
          ((listbox->GetWindowStyleFlag() & wxLB_EXTENDED) != 0)) )
    {
        int sel = listbox->GtkGetIndex( widget );

        if (sel != -1)
        {
            ret = true;

            if (listbox->IsSelected( sel ))
                gtk_list_unselect_item( listbox->m_list, sel );
            else
                gtk_list_select_item( listbox->m_list, sel );

            wxCommandEvent new_event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() );
            new_event.SetEventObject( listbox );
            wxArrayInt aSelections;
            int n, count = listbox->GetSelections(aSelections);
            if ( count > 0 )
            {
                n = aSelections[0];
                if ( listbox->HasClientObjectData() )
                    new_event.SetClientObject( listbox->GetClientObject(n) );
                else if ( listbox->HasClientUntypedData() )
                    new_event.SetClientData( listbox->GetClientData(n) );
                new_event.SetString( listbox->GetString(n) );
            }
            else
            {
                n = -1;
            }
            new_event.SetInt(n);
            listbox->GetEventHandler()->ProcessEvent( new_event );
        }
    }

    if (ret)
    {
        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" );
        return TRUE;
    }

    return FALSE;
}
Пример #11
0
static gint gtk_notebook_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxNotebook *notebook )
{
    if (g_isIdle)
        wxapp_install_idle_handler();

    if (!notebook->m_hasVMT) return FALSE;
    if (g_blockEventsOnDrag) return FALSE;

    /* win is a control: tab can be propagated up */
    if ((gdk_event->keyval == GDK_Left) || (gdk_event->keyval == GDK_Right))
    {
        int page;
        int nMax = notebook->GetPageCount();
        if ( nMax-- ) // decrement it to get the last valid index
        {
            int nSel = notebook->GetSelection();

            // change selection wrapping if it becomes invalid
            page = (gdk_event->keyval != GDK_Left) ? nSel == nMax ? 0
                                       : nSel + 1
                        : nSel == 0 ? nMax
                                    : nSel - 1;
        }
        else // notebook is empty, no next page
        {
            return FALSE;
        }

        // m_selection = page;
        gtk_notebook_set_page( GTK_NOTEBOOK(widget), page );

        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" );
        return TRUE;
    }

    /* win is a control: tab can be propagated up */
    if ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab))
    {
        int sel = notebook->GetSelection();
        if (sel == wxNOT_FOUND)
            return TRUE;
        wxGtkNotebookPage *nb_page = notebook->GetNotebookPage(sel);
        wxCHECK_MSG( nb_page, FALSE, wxT("invalid selection in wxNotebook") );

        wxNavigationKeyEvent event;
        event.SetEventObject( notebook );
        /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
        event.SetDirection( (gdk_event->keyval == GDK_Tab) );
        /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
        event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) ||
                               (gdk_event->keyval == GDK_Left) || (gdk_event->keyval == GDK_Right) );
        event.SetCurrentFocus( notebook );

        wxNotebookPage *client = notebook->GetPage(sel);
        if ( !client->HandleWindowEvent( event ) )
        {
             client->SetFocus();
        }

        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" );
        return TRUE;
    }

    return FALSE;
}
Пример #12
0
static void
cb_comment_editlist_confirm (EditableList * editlist,
			     EditableListActionType type,
			     gint selected_row,
			     EditableListConfirmFlags * flags, gpointer data)
{
    GtkWidget *t_auto = prefs_win.comment_auto_toggle;
    GtkWidget *key_entry = prefs_win.comment_key_entry;
    GtkWidget *name_entry = prefs_win.comment_name_entry;
    CommentDataEntry *entry = NULL;
    const gchar *key, *name;
    gchar   message[BUF_SIZE];
    gboolean duplicate = FALSE;

    key = gtk_entry_get_text (GTK_ENTRY (key_entry));
    name = gtk_entry_get_text (GTK_ENTRY (name_entry));

    gtk_widget_set_sensitive (key_entry, TRUE);
    gtk_widget_set_sensitive (name_entry, TRUE);
    gtk_widget_set_sensitive (t_auto, TRUE);

    if (selected_row < 0)
    {
	gtk_widget_set_sensitive (t_auto, FALSE);
    }
    else
    {
	entry = editable_list_get_row_data (editlist, selected_row);
	if (entry)
	{
	    gtk_widget_set_sensitive (key_entry, entry->userdef);
	    gtk_widget_set_sensitive (name_entry, entry->userdef);

	    if (!entry->def_val_fn)
		gtk_widget_set_sensitive (t_auto, FALSE);

	    if (!entry->userdef)
	    {
		*flags |= EDITABLE_LIST_CONFIRM_CANNOT_ADD;
		*flags |= EDITABLE_LIST_CONFIRM_CANNOT_DELETE;
	    }
	}
    }

    if (!key || !*key || !name || !*name)
    {
	*flags |= EDITABLE_LIST_CONFIRM_CANNOT_ADD;
	*flags |= EDITABLE_LIST_CONFIRM_CANNOT_CHANGE;
    }

    if ((!key || !*key) && (!name || !*name) && selected_row < 0)
	*flags |= EDITABLE_LIST_CONFIRM_CANNOT_NEW;


    if (type != EDITABLE_LIST_ACTION_ADD
	&& type != EDITABLE_LIST_ACTION_CHANGE)
	return;

    if (!check_value (key, name))
    {
	*flags |= EDITABLE_LIST_CONFIRM_CANNOT_ADD;
	*flags |= EDITABLE_LIST_CONFIRM_CANNOT_CHANGE;
	gtk_signal_emit_stop_by_name (GTK_OBJECT (editlist),
				      "action_confirm");
	return;
    }


#if 0
    if ((type == EDITABLE_LIST_ACTION_CHANGE) && entry && !entry->userdef)
    {
	if (strcmp (entry->key, key))
	{
	    /*
	     * FIXME!! add error handling 
	     */
	    *flags |= EDITABLE_LIST_CONFIRM_CANNOT_CHANGE;
	    return;
	}
	if (strcmp (_(entry->display_name), name))
	{
	    /*
	     * FIXME!! add error handling 
	     */
	    *flags |= EDITABLE_LIST_CONFIRM_CANNOT_CHANGE;
	    return;
	}
    }
#endif


    if (type == EDITABLE_LIST_ACTION_ADD)
	duplicate = check_duplicate_comment_key (key, -1);
    else if ((type == EDITABLE_LIST_ACTION_CHANGE) && entry && entry->userdef)
	duplicate = check_duplicate_comment_key (key, selected_row);

    if (duplicate)
    {
	g_snprintf (message, BUF_SIZE, _("\"%s\" is already defined."), key);
	dialog_message (_("Error!!"), message, NULL);
	*flags |= EDITABLE_LIST_CONFIRM_CANNOT_ADD;
	*flags |= EDITABLE_LIST_CONFIRM_CANNOT_CHANGE;
	gtk_signal_emit_stop_by_name (GTK_OBJECT (editlist),
				      "action_confirm");
    }
}
Пример #13
0
static int
gtk_combo_entry_key_press (GtkEntry * entry, GdkEventKey * event, GtkCombo * combo)
{
  GList *li;

  /* completion */
  if ((event->keyval == GDK_Tab) && (event->state & GDK_MOD1_MASK)) 
    {
    GCompletion * cmpl;
    gchar* prefix;
    gchar* nprefix = NULL;
    gint pos;

    if ( !GTK_LIST (combo->list)->children )
      return FALSE;
    
    gtk_signal_emit_stop_by_name (GTK_OBJECT (entry), "key_press_event");

    cmpl = g_completion_new ((GCompletionFunc)gtk_combo_func);
    g_completion_add_items (cmpl, GTK_LIST (combo->list)->children);

    pos = GTK_EDITABLE (entry)->current_pos;
    prefix = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, pos);

    g_completion_complete(cmpl, prefix, &nprefix);

    if (nprefix && strlen (nprefix) > strlen (prefix)) 
      {
    	gtk_editable_insert_text (GTK_EDITABLE (entry), nprefix + pos, 
				 strlen (nprefix) - strlen (prefix), &pos);
    	GTK_EDITABLE (entry)->current_pos = pos;
    }

    if (nprefix)
      g_free (nprefix);
    g_free (prefix);
    g_completion_free (cmpl);

    return TRUE;
  }

  if (!combo->use_arrows || !GTK_LIST (combo->list)->children)
    return FALSE;

  li = g_list_find (GTK_LIST (combo->list)->children, gtk_combo_find (combo));

  if ((event->keyval == GDK_Up)
      || (event->keyval == GDK_KP_Up)
      || ((event->state & GDK_MOD1_MASK) && ((event->keyval == 'p') || (event->keyval == 'P'))))
    {
      if (li)
	li = li->prev;
      if (!li && combo->use_arrows_always)
	{
	  li = g_list_last (GTK_LIST (combo->list)->children);
	}
      if (li)
	{
	  gtk_list_select_child (GTK_LIST (combo->list), GTK_WIDGET (li->data));
	  gtk_signal_emit_stop_by_name (GTK_OBJECT (entry), "key_press_event");
	  return TRUE;
	}
    }
  else if ((event->keyval == GDK_Down)
	   || (event->keyval == GDK_KP_Down)
	   || ((event->state & GDK_MOD1_MASK) && ((event->keyval == 'n') || (event->keyval == 'N'))))
    {
      if (li)
	li = li->next;
      if (!li && combo->use_arrows_always)
	{
	  li = GTK_LIST (combo->list)->children;
	}
      if (li)
	{
	  gtk_list_select_child (GTK_LIST (combo->list), GTK_WIDGET (li->data));
	  gtk_signal_emit_stop_by_name (GTK_OBJECT (entry), "key_press_event");
	  return TRUE;
	}
    }
  return FALSE;
}
Пример #14
0
gboolean
on_mailbox_key_press_event (GtkWidget * widget,
    GdkEventKey * event, gpointer UNUSED(user_data))
{
    switch (event->keyval)
    {
    case GDK_Return:
    case GDK_space:
	putmail (widget);
	break;
    case GDK_N:
    case GDK_n:
    case GDK_Right:
	on_toolbar_next_clicked (NULL, NULL);
	break;
    case GDK_P:
    case GDK_p:
    case GDK_Left:
	on_toolbar_prev_clicked (NULL, NULL);
	break;
    case GDK_Down:
	{
	    GtkWidget *text;
	    GtkAdjustment *adj;

	    text = lookup_widget (gems, "text1");
	    adj = GTK_TEXT (text)->vadj;
	    gtk_adjustment_set_value (adj, adj->value + adj->step_increment);
	}
	break;
    case GDK_Page_Down:
	{
	    GtkWidget *text;
	    GtkAdjustment *adj;

	    text = lookup_widget (gems, "text1");
	    adj = GTK_TEXT (text)->vadj;
	    gtk_adjustment_set_value (adj, adj->value + adj->page_increment);
	}
	break;
    case GDK_Up:
	{
	    GtkWidget *text;
	    GtkAdjustment *adj;

	    text = lookup_widget (gems, "text1");
	    adj = GTK_TEXT (text)->vadj;
	    gtk_adjustment_set_value (adj, adj->value - adj->step_increment);
	}
	break;
    case GDK_Page_Up:
	{
	    GtkWidget *text;
	    GtkAdjustment *adj;

	    text = lookup_widget (gems, "text1");
	    adj = GTK_TEXT (text)->vadj;
	    gtk_adjustment_set_value (adj, adj->value - adj->page_increment);
	}
	break;
    default:
	return FALSE;
    }

    /*
     * the return TRUE; should stop the event, but it doesn't :/ 
     */
    gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event");
    return TRUE;
}
Пример #15
0
static gint
script_fu_cc_key_function (GtkWidget   *widget,
			   GdkEventKey *event,
			   gpointer     data)
{
  GList *list;
  int direction = 0;

  switch (event->keyval)
    {
    case GDK_Return:
      gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event");

      if (script_fu_cc_is_empty ())
	return TRUE;

      list = g_list_nth (history, (g_list_length (history) - 1));
      if (list->data)
	g_free (list->data);
      list->data = g_strdup (gtk_entry_get_text (GTK_ENTRY (cint.cc)));

      gtk_text_freeze (GTK_TEXT (cint.console));
      gtk_text_insert (GTK_TEXT (cint.console), cint.font_strong, NULL, NULL, "=> ", -1);
      gtk_text_insert (GTK_TEXT (cint.console), cint.font, NULL, NULL,
		       gtk_entry_get_text (GTK_ENTRY (cint.cc)), -1);
      gtk_text_insert (GTK_TEXT (cint.console), cint.font, NULL, NULL, "\n\n", -1);
      gtk_text_thaw (GTK_TEXT (cint.console));

      cint.vadj->value = cint.vadj->upper - cint.vadj->page_size;
      gtk_signal_emit_by_name (GTK_OBJECT (cint.vadj), "changed");

      gtk_entry_set_text (GTK_ENTRY (cint.cc), "");
      gdk_flush ();

      repl_c_string ((char *) list->data, 0, 0, 1);
      gimp_displays_flush ();

      history = g_list_append (history, NULL);
      if (history_len == history_max)
	{
	  history = g_list_remove (history, history->data);
	  if (history->data)
	    g_free (history->data);
	}
      else
	history_len++;
      history_cur = g_list_length (history) - 1;

      return TRUE;
      break;

    case GDK_KP_Up:
    case GDK_Up:
      gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event");
      direction = -1;
      break;

    case GDK_KP_Down:
    case GDK_Down:
      gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event");
      direction = 1;
      break;

    case GDK_P:
    case GDK_p:
      if (event->state & GDK_CONTROL_MASK)
	{
	  gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event");
	  direction = -1;
	}
      break;

    case GDK_N:
    case GDK_n:
      if (event->state & GDK_CONTROL_MASK)
	{
	  gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event");
	  direction = 1;
	}
      break;

    default:
      break;
    }

  if (direction)
    {
      /*  Make sure we keep track of the current one  */
      if (history_cur == g_list_length (history) - 1)
	{
	  list = g_list_nth (history, history_cur);
	  if (list->data)
	    g_free (list->data);
	  list->data = g_strdup (gtk_entry_get_text (GTK_ENTRY (cint.cc)));
	}

      history_cur += direction;
      if (history_cur < 0)
	history_cur = 0;
      if (history_cur >= history_len)
	history_cur = history_len - 1;

      gtk_entry_set_text (GTK_ENTRY (cint.cc), (char *) (g_list_nth (history, history_cur))->data);

      return TRUE;
    }

  return FALSE;
}