[Aptitude-svn-commit] r3476 - in branches/aptitude-0.3/aptitude: . src/vscreen/config

Daniel Burrows dburrows@costa.debian.org
Mon, 27 Jun 2005 15:46:48 +0000


Author: dburrows
Date: Mon Jun 27 15:46:45 2005
New Revision: 3476

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/vscreen/config/keybindings.cc
   branches/aptitude-0.3/aptitude/src/vscreen/config/keybindings.h
Log:
Break more stuff by making more allowances for Unicode input.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Mon Jun 27 15:46:45 2005
@@ -1,3 +1,17 @@
+2005-06-27  Daniel Burrows  <dburrows@debian.org>
+
+	* src/vscreen/config/keybindings.cc, src/vscreen/config/keybindings.h:
+
+	  First crack at revising the keybinding routines to handle
+	  Unicode input.  In particular, the "key" type now includes a
+	  flag to indicate function-key-ness (this is useful since we need
+	  to distinguish function keys (KEY_*) from other keys now --
+	  curses uses a special return value from get_wch to indicate
+	  them, and I think it's because they might overlap real
+	  codepoints).
+
+	  This probably breaks everything again.
+
 2005-06-26  Daniel Burrows  <dburrows@debian.org>
 
 	* src/strhash.h:

Modified: branches/aptitude-0.3/aptitude/src/vscreen/config/keybindings.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/config/keybindings.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/config/keybindings.cc	Mon Jun 27 15:46:45 2005
@@ -25,24 +25,29 @@
 #include "../../../config.h"
 #endif
 
+// For _()
+#include "../../aptitude.h"
+
 #ifdef HAVE_LIBAPT_PKG
 #include <apt-pkg/error.h>
 #endif
 
 #include <ctype.h>
 
+#include <map>
+
 using namespace std;
 using namespace __gnu_cxx;
 
 keybindings global_bindings;
 
-hash_map<string, wint_t> keynames;
-hash_map<string, wint_t> s_keynames;
+map<wstring, key> keynames;
+map<wstring, key> s_keynames;
 // For simplicity, we use the convention that the names are stored in
 // lowercase; however, the routines to parse keys take this into account and
 // convert the input to lowercase before checking it.
 // FIXME: Function keys (F0-Fx) really ought to be handled specially
-hash_map<wint_t, string> rev_keynames;
+map<key, wstring> rev_keynames;
 
 bool key_tables_initialized=false;
 
@@ -53,202 +58,202 @@
 
   key_tables_initialized=true;
 
-  keynames["tab"]='\t';
-  rev_keynames['\t']="tab";
-  keynames["space"]=' ';
-  rev_keynames[' ']="space";
-
-  keynames["comma"]=',';
-  rev_keynames[',']="comma";
-
-  keynames["break"]=KEY_BREAK;
-  rev_keynames[KEY_BREAK]="break";
-  keynames["down"]=KEY_DOWN;
-  rev_keynames[KEY_DOWN]="down";
-  keynames["up"]=KEY_UP;
-  rev_keynames[KEY_UP]="up";
-  keynames["left"]=KEY_LEFT;
-  rev_keynames[KEY_LEFT]="left";
-  keynames["right"]=KEY_RIGHT;
-  rev_keynames[KEY_RIGHT]="right";
-  keynames["home"]=KEY_HOME;
-  rev_keynames[KEY_HOME]="home";
-  keynames["backspace"]=KEY_BACKSPACE;
-  rev_keynames[KEY_BACKSPACE]="backspace";
-  keynames["f0"]=KEY_F(0);
-  rev_keynames[KEY_F(0)]="f0";
-  keynames["f1"]=KEY_F(1);
-  rev_keynames[KEY_F(1)]="f1";
-  keynames["f2"]=KEY_F(2);
-  rev_keynames[KEY_F(2)]="f2";
-  keynames["f3"]=KEY_F(3);
-  rev_keynames[KEY_F(3)]="f3";
-  keynames["f4"]=KEY_F(4);
-  rev_keynames[KEY_F(4)]="f4";
-  keynames["f5"]=KEY_F(5);
-  rev_keynames[KEY_F(5)]="f5";
-  keynames["f6"]=KEY_F(6);
-  rev_keynames[KEY_F(6)]="f6";
-  keynames["f7"]=KEY_F(7);
-  rev_keynames[KEY_F(7)]="f7";
-  keynames["f8"]=KEY_F(8);
-  rev_keynames[KEY_F(8)]="f8";
-  keynames["f9"]=KEY_F(9);
-  rev_keynames[KEY_F(9)]="f9";
-  keynames["f10"]=KEY_F(10);
-  rev_keynames[KEY_F(10)]="f10";
-  keynames["delete_line"]=KEY_DL;
-  rev_keynames[KEY_DL]="delete_line";
-  keynames["insert_line"]=KEY_IL;
-  rev_keynames[KEY_IL]="insert_line";
-  keynames["delete"]=KEY_DC;
-  rev_keynames[KEY_DC]="delete";
-  keynames["insert"]=KEY_IC;
-  rev_keynames[KEY_IC]="insert";
-  keynames["insert_exit"]=KEY_EIC;
-  rev_keynames[KEY_EIC]="insert_exit";
-  keynames["clear"]=KEY_CLEAR;
-  rev_keynames[KEY_CLEAR]="clear";
-  keynames["clear_eos"]=KEY_EOS;
-  rev_keynames[KEY_EOS]="clear_eos";
-  keynames["clear_eol"]=KEY_EOL;
-  rev_keynames[KEY_EOL]="clear_eol";
-  keynames["scrollf"]=KEY_SF;
-  rev_keynames[KEY_SF]="scrollf";
-  keynames["scrollr"]=KEY_SR;
-  rev_keynames[KEY_SR]="scrollr";
-  keynames["pagedown"]=KEY_NPAGE;
-  rev_keynames[KEY_NPAGE]="pagedown";
-  keynames["pageup"]=KEY_PPAGE;
-  rev_keynames[KEY_PPAGE]="pageup";
-  keynames["enter"]=KEY_ENTER;
-  rev_keynames[KEY_ENTER]="enter";
-  keynames["return"]=KEY_ENTER;
-  keynames["print"]=KEY_PRINT;
-  rev_keynames[KEY_PRINT]="print";
-  keynames["a1"]=KEY_A1;
-  rev_keynames[KEY_A1]="a1";
-  keynames["a3"]=KEY_A3;
-  rev_keynames[KEY_A3]="a3";
-  keynames["b2"]=KEY_B2;
-  rev_keynames[KEY_B2]="b2";
-  keynames["c1"]=KEY_C1;
-  rev_keynames[KEY_C1]="c1";
-  keynames["c3"]=KEY_C3;
-  rev_keynames[KEY_C3]="c3";
-  keynames["backtab"]=KEY_BTAB;
-  rev_keynames[KEY_BTAB]="backtab";
-  keynames["begin"]=KEY_BEG;
-  rev_keynames[KEY_BEG]="begin";
-  keynames["cancel"]=KEY_CANCEL;
-  rev_keynames[KEY_CANCEL]="cancel";
-  keynames["close"]=KEY_CLOSE;
-  rev_keynames[KEY_CLOSE]="close";
-  keynames["command"]=KEY_COMMAND;
-  rev_keynames[KEY_COMMAND]="command";
-  keynames["copy"]=KEY_COPY;
-  rev_keynames[KEY_COPY]="copy";
-  keynames["create"]=KEY_CREATE;
-  rev_keynames[KEY_CREATE]="create";
-  keynames["end"]=KEY_END;
-  rev_keynames[KEY_END]="end";
-  keynames["exit"]=KEY_EXIT;
-  rev_keynames[KEY_EXIT]="exit";
-  keynames["find"]=KEY_FIND;
-  rev_keynames[KEY_FIND]="find";
-  keynames["help"]=KEY_HELP;
-  rev_keynames[KEY_HELP]="help";
-  keynames["mark"]=KEY_MARK;
-  rev_keynames[KEY_MARK]="mark";
-  keynames["message"]=KEY_MESSAGE;
-  rev_keynames[KEY_MESSAGE]="message";
-  keynames["move"]=KEY_MOVE;
-  rev_keynames[KEY_MOVE]="move";
-  keynames["next"]=KEY_NEXT;
-  rev_keynames[KEY_NEXT]="next";
-  keynames["open"]=KEY_OPEN;
-  rev_keynames[KEY_OPEN]="open";
-  keynames["options"]=KEY_OPTIONS;
-  rev_keynames[KEY_OPTIONS]="options";
-  keynames["previous"]=KEY_PREVIOUS;
-  rev_keynames[KEY_PREVIOUS]="previous";
-  keynames["redo"]=KEY_REDO;
-  rev_keynames[KEY_REDO]="redo";
-  keynames["reference"]=KEY_REFERENCE;
-  rev_keynames[KEY_REFERENCE]="reference";
-  keynames["refresh"]=KEY_REFRESH;
-  rev_keynames[KEY_REFRESH]="refresh";
-  keynames["replace"]=KEY_REPLACE;
-  rev_keynames[KEY_REPLACE]="replace";
-  keynames["restart"]=KEY_RESTART;
-  rev_keynames[KEY_RESTART]="restart";
-  keynames["resume"]=KEY_RESUME;
-  rev_keynames[KEY_RESUME]="resume";
-  keynames["save"]=KEY_SAVE;
-  rev_keynames[KEY_SAVE]="save";
-  keynames["select"]=KEY_SELECT;
-  rev_keynames[KEY_SELECT]="select";
-  keynames["suspend"]=KEY_SUSPEND;
-  rev_keynames[KEY_SUSPEND]="suspend";
-  keynames["undo"]=KEY_UNDO;
-  rev_keynames[KEY_UNDO]="undo";
-
-  s_keynames["begin"]=KEY_SBEG;
-  rev_keynames[KEY_SBEG]="begin";
-  s_keynames["cancel"]=KEY_SCANCEL;
-  rev_keynames[KEY_SCANCEL]="cancel";
-  s_keynames["command"]=KEY_SCOMMAND;
-  rev_keynames[KEY_SCOMMAND]="command";
-  s_keynames["copy"]=KEY_SCOPY;
-  rev_keynames[KEY_SCOPY]="copy";
-  s_keynames["create"]=KEY_SCREATE;
-  rev_keynames[KEY_SCREATE]="create";
-  s_keynames["delete"]=KEY_SDC;
-  rev_keynames[KEY_SDC]="delete";
-  s_keynames["delete_line"]=KEY_SDL;
-  rev_keynames[KEY_SDL]="delete_line";
-  s_keynames["end"]=KEY_SEND;
-  rev_keynames[KEY_SEND]="end";
-  s_keynames["clear_eol"]=KEY_SEOL;
-  rev_keynames[KEY_SEOL]="clear_eol";
-  s_keynames["exit"]=KEY_SEXIT;
-  rev_keynames[KEY_SEXIT]="exit";
-  s_keynames["find"]=KEY_SFIND;
-  rev_keynames[KEY_SFIND]="find";
-  s_keynames["help"]=KEY_SHELP;
-  rev_keynames[KEY_SHELP]="help";
-  s_keynames["home"]=KEY_SHOME;
-  rev_keynames[KEY_SHOME]="home";
-  s_keynames["insert"]=KEY_SIC;
-  rev_keynames[KEY_SIC]="insert";
-  s_keynames["left"]=KEY_SLEFT;
-  rev_keynames[KEY_SLEFT]="left";
-  s_keynames["message"]=KEY_SMESSAGE;
-  rev_keynames[KEY_SMESSAGE]="message";
-  s_keynames["move"]=KEY_SMOVE;
-  rev_keynames[KEY_SMOVE]="move";
-  s_keynames["next"]=KEY_SNEXT;
-  rev_keynames[KEY_SNEXT]="next";
-  s_keynames["options"]=KEY_SOPTIONS;
-  rev_keynames[KEY_SOPTIONS]="options";
-  s_keynames["previous"]=KEY_SPREVIOUS;
-  rev_keynames[KEY_SPREVIOUS]="previous";
-  s_keynames["print"]=KEY_SPRINT;
-  rev_keynames[KEY_SPRINT]="print";
-  s_keynames["redo"]=KEY_SREDO;
-  rev_keynames[KEY_SREDO]="redo";
-  s_keynames["replace"]=KEY_SREPLACE;
-  rev_keynames[KEY_SREPLACE]="replace";
-  s_keynames["right"]=KEY_SRIGHT;
-  rev_keynames[KEY_SRIGHT]="right";
-  s_keynames["resume"]=KEY_SRSUME;
-  rev_keynames[KEY_SRSUME]="resume";
-  s_keynames["save"]=KEY_SSAVE;
-  rev_keynames[KEY_SSAVE]="save";
-  s_keynames["suspend"]=KEY_SSUSPEND;
-  rev_keynames[KEY_SSUSPEND]="suspend";
-  s_keynames["undo"]=KEY_SUNDO;
-  rev_keynames[KEY_SUNDO]="undo";
+  keynames[L"tab"]=key(L'\t', false);
+  rev_keynames[key(L'\t', false)]=L"tab";
+  keynames[L"space"]=key(L' ', false);
+  rev_keynames[key(L' ', false)]=L"space";
+
+  keynames[L"comma"]=key(L',', false);
+  rev_keynames[key(L',', false)]=L"comma";
+
+  keynames[L"break"]=key(KEY_BREAK, true);
+  rev_keynames[key(KEY_BREAK, true)]=L"break";
+  keynames[L"down"]=key(KEY_DOWN, true);
+  rev_keynames[key(KEY_DOWN, true)]=L"down";
+  keynames[L"up"]=key(KEY_UP, true);
+  rev_keynames[key(KEY_UP, true)]=L"up";
+  keynames[L"left"]=key(KEY_LEFT, true);
+  rev_keynames[key(KEY_LEFT, true)]=L"left";
+  keynames[L"right"]=key(KEY_RIGHT, true);
+  rev_keynames[key(KEY_RIGHT, true)]=L"right";
+  keynames[L"home"]=key(KEY_HOME, true);
+  rev_keynames[key(KEY_HOME, true)]=L"home";
+  keynames[L"backspace"]=key(KEY_BACKSPACE, true);
+  rev_keynames[key(KEY_BACKSPACE, true)]=L"backspace";
+  keynames[L"f0"]=key(KEY_F(0), true);
+  rev_keynames[key(KEY_F(0), true)]=L"f0";
+  keynames[L"f1"]=key(KEY_F(1), true);
+  rev_keynames[key(KEY_F(1), true)]=L"f1";
+  keynames[L"f2"]=key(KEY_F(2), true);
+  rev_keynames[key(KEY_F(2), true)]=L"f2";
+  keynames[L"f3"]=key(KEY_F(3), true);
+  rev_keynames[key(KEY_F(3), true)]=L"f3";
+  keynames[L"f4"]=key(KEY_F(4), true);
+  rev_keynames[key(KEY_F(4), true)]=L"f4";
+  keynames[L"f5"]=key(KEY_F(5), true);
+  rev_keynames[key(KEY_F(5), true)]=L"f5";
+  keynames[L"f6"]=key(KEY_F(6), true);
+  rev_keynames[key(KEY_F(6), true)]=L"f6";
+  keynames[L"f7"]=key(KEY_F(7), true);
+  rev_keynames[key(KEY_F(7), true)]=L"f7";
+  keynames[L"f8"]=key(KEY_F(8), true);
+  rev_keynames[key(KEY_F(8), true)]=L"f8";
+  keynames[L"f9"]=key(KEY_F(9), true);
+  rev_keynames[key(KEY_F(9), true)]=L"f9";
+  keynames[L"f10"]=key(KEY_F(10), true);
+  rev_keynames[key(KEY_F(10), true)]=L"f10";
+  keynames[L"delete_line"]=key(KEY_DL, true);
+  rev_keynames[key(KEY_DL, true)]=L"delete_line";
+  keynames[L"insert_line"]=key(KEY_IL, true);
+  rev_keynames[key(KEY_IL, true)]=L"insert_line";
+  keynames[L"delete"]=key(KEY_DC, true);
+  rev_keynames[key(KEY_DC, true)]=L"delete";
+  keynames[L"insert"]=key(KEY_IC, true);
+  rev_keynames[key(KEY_IC, true)]=L"insert";
+  keynames[L"insert_exit"]=key(KEY_EIC, true);
+  rev_keynames[key(KEY_EIC, true)]=L"insert_exit";
+  keynames[L"clear"]=key(KEY_CLEAR, true);
+  rev_keynames[key(KEY_CLEAR, true)]=L"clear";
+  keynames[L"clear_eos"]=key(KEY_EOS, true);
+  rev_keynames[key(KEY_EOS, true)]=L"clear_eos";
+  keynames[L"clear_eol"]=key(KEY_EOL, true);
+  rev_keynames[key(KEY_EOL, true)]=L"clear_eol";
+  keynames[L"scrollf"]=key(KEY_SF, true);
+  rev_keynames[key(KEY_SF, true)]=L"scrollf";
+  keynames[L"scrollr"]=key(KEY_SR, true);
+  rev_keynames[key(KEY_SR, true)]=L"scrollr";
+  keynames[L"pagedown"]=key(KEY_NPAGE, true);
+  rev_keynames[key(KEY_NPAGE, true)]=L"pagedown";
+  keynames[L"pageup"]=key(KEY_PPAGE, true);
+  rev_keynames[key(KEY_PPAGE, true)]=L"pageup";
+  keynames[L"enter"]=key(KEY_ENTER, true);
+  rev_keynames[key(KEY_ENTER, true)]=L"enter";
+  keynames[L"return"]=key(KEY_ENTER, true);
+  keynames[L"print"]=key(KEY_PRINT, true);
+  rev_keynames[key(KEY_PRINT, true)]=L"print";
+  keynames[L"a1"]=key(KEY_A1, true);
+  rev_keynames[key(KEY_A1, true)]=L"a1";
+  keynames[L"a3"]=key(KEY_A3, true);
+  rev_keynames[key(KEY_A3, true)]=L"a3";
+  keynames[L"b2"]=key(KEY_B2, true);
+  rev_keynames[key(KEY_B2, true)]=L"b2";
+  keynames[L"c1"]=key(KEY_C1, true);
+  rev_keynames[key(KEY_C1, true)]=L"c1";
+  keynames[L"c3"]=key(KEY_C3, true);
+  rev_keynames[key(KEY_C3, true)]=L"c3";
+  keynames[L"backtab"]=key(KEY_BTAB, true);
+  rev_keynames[key(KEY_BTAB, true)]=L"backtab";
+  keynames[L"begin"]=key(KEY_BEG, true);
+  rev_keynames[key(KEY_BEG, true)]=L"begin";
+  keynames[L"cancel"]=key(KEY_CANCEL, true);
+  rev_keynames[key(KEY_CANCEL, true)]=L"cancel";
+  keynames[L"close"]=key(KEY_CLOSE, true);
+  rev_keynames[key(KEY_CLOSE, true)]=L"close";
+  keynames[L"command"]=key(KEY_COMMAND, true);
+  rev_keynames[key(KEY_COMMAND, true)]=L"command";
+  keynames[L"copy"]=key(KEY_COPY, true);
+  rev_keynames[key(KEY_COPY, true)]=L"copy";
+  keynames[L"create"]=key(KEY_CREATE, true);
+  rev_keynames[key(KEY_CREATE, true)]=L"create";
+  keynames[L"end"]=key(KEY_END, true);
+  rev_keynames[key(KEY_END, true)]=L"end";
+  keynames[L"exit"]=key(KEY_EXIT, true);
+  rev_keynames[key(KEY_EXIT, true)]=L"exit";
+  keynames[L"find"]=key(KEY_FIND, true);
+  rev_keynames[key(KEY_FIND, true)]=L"find";
+  keynames[L"help"]=key(KEY_HELP, true);
+  rev_keynames[key(KEY_HELP, true)]=L"help";
+  keynames[L"mark"]=key(KEY_MARK, true);
+  rev_keynames[key(KEY_MARK, true)]=L"mark";
+  keynames[L"message"]=key(KEY_MESSAGE, true);
+  rev_keynames[key(KEY_MESSAGE, true)]=L"message";
+  keynames[L"move"]=key(KEY_MOVE, true);
+  rev_keynames[key(KEY_MOVE, true)]=L"move";
+  keynames[L"next"]=key(KEY_NEXT, true);
+  rev_keynames[key(KEY_NEXT, true)]=L"next";
+  keynames[L"open"]=key(KEY_OPEN, true);
+  rev_keynames[key(KEY_OPEN, true)]=L"open";
+  keynames[L"options"]=key(KEY_OPTIONS, true);
+  rev_keynames[key(KEY_OPTIONS, true)]=L"options";
+  keynames[L"previous"]=key(KEY_PREVIOUS, true);
+  rev_keynames[key(KEY_PREVIOUS, true)]=L"previous";
+  keynames[L"redo"]=key(KEY_REDO, true);
+  rev_keynames[key(KEY_REDO, true)]=L"redo";
+  keynames[L"reference"]=key(KEY_REFERENCE, true);
+  rev_keynames[key(KEY_REFERENCE, true)]=L"reference";
+  keynames[L"refresh"]=key(KEY_REFRESH, true);
+  rev_keynames[key(KEY_REFRESH, true)]=L"refresh";
+  keynames[L"replace"]=key(KEY_REPLACE, true);
+  rev_keynames[key(KEY_REPLACE, true)]=L"replace";
+  keynames[L"restart"]=key(KEY_RESTART, true);
+  rev_keynames[key(KEY_RESTART, true)]=L"restart";
+  keynames[L"resume"]=key(KEY_RESUME, true);
+  rev_keynames[key(KEY_RESUME, true)]=L"resume";
+  keynames[L"save"]=key(KEY_SAVE, true);
+  rev_keynames[key(KEY_SAVE, true)]=L"save";
+  keynames[L"select"]=key(KEY_SELECT, true);
+  rev_keynames[key(KEY_SELECT, true)]=L"select";
+  keynames[L"suspend"]=key(KEY_SUSPEND, true);
+  rev_keynames[key(KEY_SUSPEND, true)]=L"suspend";
+  keynames[L"undo"]=key(KEY_UNDO, true);
+  rev_keynames[key(KEY_UNDO, true)]=L"undo";
+
+  s_keynames[L"begin"]=key(KEY_SBEG, true);
+  rev_keynames[key(KEY_SBEG, true)]=L"begin";
+  s_keynames[L"cancel"]=key(KEY_SCANCEL, true);
+  rev_keynames[key(KEY_SCANCEL, true)]=L"cancel";
+  s_keynames[L"command"]=key(KEY_SCOMMAND, true);
+  rev_keynames[key(KEY_SCOMMAND, true)]=L"command";
+  s_keynames[L"copy"]=key(KEY_SCOPY, true);
+  rev_keynames[key(KEY_SCOPY, true)]=L"copy";
+  s_keynames[L"create"]=key(KEY_SCREATE, true);
+  rev_keynames[key(KEY_SCREATE, true)]=L"create";
+  s_keynames[L"delete"]=key(KEY_SDC, true);
+  rev_keynames[key(KEY_SDC, true)]=L"delete";
+  s_keynames[L"delete_line"]=key(KEY_SDL, true);
+  rev_keynames[key(KEY_SDL, true)]=L"delete_line";
+  s_keynames[L"end"]=key(KEY_SEND, true);
+  rev_keynames[key(KEY_SEND, true)]=L"end";
+  s_keynames[L"clear_eol"]=key(KEY_SEOL, true);
+  rev_keynames[key(KEY_SEOL, true)]=L"clear_eol";
+  s_keynames[L"exit"]=key(KEY_SEXIT, true);
+  rev_keynames[key(KEY_SEXIT, true)]=L"exit";
+  s_keynames[L"find"]=key(KEY_SFIND, true);
+  rev_keynames[key(KEY_SFIND, true)]=L"find";
+  s_keynames[L"help"]=key(KEY_SHELP, true);
+  rev_keynames[key(KEY_SHELP, true)]=L"help";
+  s_keynames[L"home"]=key(KEY_SHOME, true);
+  rev_keynames[key(KEY_SHOME, true)]=L"home";
+  s_keynames[L"insert"]=key(KEY_SIC, true);
+  rev_keynames[key(KEY_SIC, true)]=L"insert";
+  s_keynames[L"left"]=key(KEY_SLEFT, true);
+  rev_keynames[key(KEY_SLEFT, true)]=L"left";
+  s_keynames[L"message"]=key(KEY_SMESSAGE, true);
+  rev_keynames[key(KEY_SMESSAGE, true)]=L"message";
+  s_keynames[L"move"]=key(KEY_SMOVE, true);
+  rev_keynames[key(KEY_SMOVE, true)]=L"move";
+  s_keynames[L"next"]=key(KEY_SNEXT, true);
+  rev_keynames[key(KEY_SNEXT, true)]=L"next";
+  s_keynames[L"options"]=key(KEY_SOPTIONS, true);
+  rev_keynames[key(KEY_SOPTIONS, true)]=L"options";
+  s_keynames[L"previous"]=key(KEY_SPREVIOUS, true);
+  rev_keynames[key(KEY_SPREVIOUS, true)]=L"previous";
+  s_keynames[L"print"]=key(KEY_SPRINT, true);
+  rev_keynames[key(KEY_SPRINT, true)]=L"print";
+  s_keynames[L"redo"]=key(KEY_SREDO, true);
+  rev_keynames[key(KEY_SREDO, true)]=L"redo";
+  s_keynames[L"replace"]=key(KEY_SREPLACE, true);
+  rev_keynames[key(KEY_SREPLACE, true)]=L"replace";
+  s_keynames[L"right"]=key(KEY_SRIGHT, true);
+  rev_keynames[key(KEY_SRIGHT, true)]=L"right";
+  s_keynames[L"resume"]=key(KEY_SRSUME, true);
+  rev_keynames[key(KEY_SRSUME, true)]=L"resume";
+  s_keynames[L"save"]=key(KEY_SSAVE, true);
+  rev_keynames[key(KEY_SSAVE, true)]=L"save";
+  s_keynames[L"suspend"]=key(KEY_SSUSPEND, true);
+  rev_keynames[key(KEY_SSUSPEND, true)]=L"suspend";
+  s_keynames[L"undo"]=key(KEY_SUNDO, true);
+  rev_keynames[key(KEY_SUNDO, true)]=L"undo";
 }
 
 void keybindings::set(string tag, keybinding strokes)
@@ -256,161 +261,163 @@
   keymap[tag]=strokes;
 }
 
-bool keybindings::key_matches(wint_t ch, string tag)
+bool keybindings::key_matches(const key &k, string tag)
 {
   hash_map<string, keybinding>::iterator found=keymap.find(tag);
   if(found==keymap.end())
-    return parent?parent->key_matches(ch, tag):false;
+    return parent?parent->key_matches(k, tag):false;
   else
     {
       for(keybinding::iterator i=found->second.begin(); i!=found->second.end(); i++)
 	{
-	  if(*i==KEY_ENTER)
+	  if(*i==key(KEY_ENTER, true))
 	    {
-	      if(ch==KEY_ENTER || ch=='\r' || ch=='\n')
+	      if(k==key(KEY_ENTER, true) ||
+		 k==key(L'\r', false) || k==key(L'\n', false))
 		return true;
 	    }
-	  else if(ch==*i)
+	  else if(k==*i)
 	    return true;
 	}
       return false;
     }
 }
 
-wint_t parse_key(string keystr)
+key parse_key(wstring keystr)
 {
   bool sfound=false,cfound=false,afound=false;
-  string tmpstr=keystr;
-  wint_t rval=(wint_t) ERR;
+  wstring tmpstr=keystr;
+  key rval((wint_t) ERR, true);
 
   init_key_tables();
 
-  while(tmpstr.size()>2 && tmpstr[1]=='-')
+  while(tmpstr.size()>2 && tmpstr[1]==L'-')
     {
       switch(tmpstr[0])
 	{
-	case 's':
-	case 'S':
+	case L's':
+	case L'S':
 	  sfound=true;
 	  break;
-	case 'a':
-	case 'A':
-	case 'm':
-	case 'M':
+	case L'a':
+	case L'A':
+	case L'm':
+	case L'M':
 	  afound=true;
 	  break;
-	case 'c':
-	case 'C':
+	case L'c':
+	case L'C':
 	  cfound=true;
 	  break;
 	default:
 #ifdef HAVE_LIBAPT_PKG
-	  _error->Error("Cannot parse key description: %s", keystr.c_str());
+	  _error->Error(_("Cannot parse key description: %ls"), keystr.c_str());
 #endif
-	  return (wint_t) ERR;
+	  return key((wint_t) ERR, true);
 	}
-      tmpstr=string(tmpstr,2);
+      tmpstr=wstring(tmpstr,2);
     }
 
   if(tmpstr.size()==0)
     {
 #ifdef HAVE_LIBAPT_PKG
-      _error->Error("Invalid null keybinding");
+      _error->Error(_("Invalid null keybinding"));
 #endif
-      return (wint_t) ERR;
+      return key((wint_t) ERR, true);
     }
 
   if(cfound && tmpstr.size()>1)
     {
 #ifdef HAVE_LIBAPT_PKG
-      _error->Error("Sorry, control modifiers may not be used with unprintable characters");
+      _error->Error(_("Sorry, control modifiers may not be used with unprintable characters"));
 #endif
-      return (wint_t) ERR;
+      return key((wint_t) ERR, true);
     }
 
   if(tmpstr.size()==1)
     {
-      rval=sfound?toupper(tmpstr[0]):tmpstr[0];
+      wint_t ch=sfound?towupper(tmpstr[0]):tmpstr[0];
+      // How do control-keys interact with wide characters?
       if(cfound)
-	rval=KEY_CTRL(rval);
+	return KEY_CTRL(ch);
       if(afound)
-	rval=KEY_ALT(rval);
+	return KEY_ALT(ch);
       return rval;
     }
   else
     {
       for(unsigned int i=0; i<tmpstr.size(); i++)
-	tmpstr[i]=tolower(tmpstr[i]);
-      hash_map<string, wint_t>::iterator found=(sfound?s_keynames:keynames).find(tmpstr);
+	tmpstr[i]=towlower(tmpstr[i]);
+      map<wstring, key>::iterator found=(sfound?s_keynames:keynames).find(tmpstr);
       if(found==(sfound?s_keynames:keynames).end())
-	return (wint_t) ERR;
+	return key((wint_t) ERR, true);
       else
 	{
 	  rval=found->second;
 	  if(afound)
-	    rval=KEY_ALT(rval);
+	    rval=KEY_ALT(rval.ch);
 
 	  return rval;
 	}
     }
 }
 
-string keyname(wint_t ch)
+wstring keyname(const key &k)
 {
   init_key_tables();
 
   // This is a nasty special-case..all of this stuff is nasty special-cases..
   // someday I need to learn the underlying logic, if there is any..
-  if(ch==31)
-    return "C-_";
+  if(k.ch==31 && k.function_key)
+    return L"C-_";
   // <31 seem to be control-characters?  doh...is 32 the amount to add?
   // Daniel is confused..
-  if((ch&(~31))==0)
-    return "C-"+keyname(ch|64|32);
+  if((k.ch&(~31))==0 && !k.function_key)
+    return L"C-"+keyname(key(k.ch|64|32, false));
   // and 200 seems to be the ALT-character?
-  else if(ch&0x200)
-    return "A-"+keyname(ch&~0x200);
+  else if(k.ch&0x200)
+    return L"A-"+keyname(key(k.ch&~0x200, false));
   else
     {
-      hash_map<wint_t, string>::iterator found=rev_keynames.find(ch);
+      map<key, wstring>::iterator found=rev_keynames.find(k);
 
       if(found!=rev_keynames.end())
 	return found->second;
       else
 	{
-	  char tmp[2];
-	  tmp[0]=ch;
+	  wchar_t tmp[2];
+	  tmp[0]=k.ch;
 	  tmp[1]=0;
-	  return string(tmp);
+	  return wstring(tmp);
 	}
     }
 }
 
-string readable_keyname(wint_t ch)
+wstring readable_keyname(const key &k)
 {
-  if(ch == ',')
-    return ",";
+  if(k == key(L',', false))
+    return L",";
   else
-    return keyname(ch);
+    return keyname(k);
 }
 
 // Doesn't return all available bindings as that gets way too long.
-string keybindings::keyname(const string &tag)
+wstring keybindings::keyname(const string &tag)
 {
   hash_map<string, keybinding>::iterator found=keymap.find(tag);
 
   if(found!=keymap.end())
     return ::keyname(found->second.front());
   else
-    return "";
+    return L"";
 }
 
-string keybindings::readable_keyname(const string &tag)
+wstring keybindings::readable_keyname(const string &tag)
 {
   hash_map<string, keybinding>::iterator found=keymap.find(tag);
 
   if(found != keymap.end())
     return ::readable_keyname(found->second.front());
   else
-    return "";
+    return L"";
 }

Modified: branches/aptitude-0.3/aptitude/src/vscreen/config/keybindings.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/config/keybindings.h	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/config/keybindings.h	Mon Jun 27 15:46:45 2005
@@ -42,7 +42,42 @@
 #include "../../generic/strhash.h"
 #include "../curses++.h"
 
-typedef std::vector<wint_t> keybinding;
+/** Represents a keystroke as seen by curses.  Since the function keys
+ *  can overlap Unicode codepoints, we need to include a value that
+ *  distinguishes them.
+ */
+struct key
+{
+  /** The key code. */
+  wint_t ch;
+
+  /** If \b true, this is a function key. */
+  bool function_key;
+
+  key()
+    :ch((wint_t) ERR), function_key(true)
+  {
+  }
+
+  key(wint_t _ch, bool _function_key)
+    :ch(_ch), function_key(_function_key)
+  {
+  }
+
+  /** Lexicographic ordering on keys. */
+  bool operator<(const key &other) const
+  {
+    return ch < other.ch || (ch == other.ch &&
+			     !function_key && other.function_key);
+  }
+
+  bool operator==(const key &other) const
+  {
+    return ch == other.ch && function_key == other.function_key;
+  }
+};
+
+typedef std::vector<key> keybinding;
 
 class keybindings
 {
@@ -59,13 +94,13 @@
   /** \return the first binding of the given key, in a form suitable
    *   for inclusion in a config file.
    */
-  std::string keyname(const std::string &tag);
+  std::wstring keyname(const std::string &tag);
 
 
   /** \return a human-readable string identifying the given keystroke
    *   (as opposed to 'keyname', which is a strict reverse mapping).
    */
-  std::string readable_keyname(const std::string &tag);
+  std::wstring readable_keyname(const std::string &tag);
 
   keybinding get(std::string tag)
     // Returns the keybinding for the given string.  Almost never needed.
@@ -82,28 +117,28 @@
   // Adds a setting for the given binding, clobbering whatever was there
   // previously.
 
-  void set(std::string tag, wint_t stroke)
+  void set(std::string tag, const key &stroke)
   {
     keybinding strokes;
     strokes.push_back(stroke);
     set(tag, strokes);
   }
 
-  bool key_matches(wint_t ch, std::string tag);
+  bool key_matches(const key &k, std::string tag);
   // Tests whether the given keystroke matches the keybinding with the given
   // name.  If no keybinding by that name exists, the match fails.
 };
 
-wint_t parse_key(std::string keystr);
+key parse_key(std::wstring keystr);
 // Parses a string to a keycode.  Returns ERR if the parse fails.
 
-std::string keyname(wint_t ch);
+std::wstring keyname(const key &k);
 // Returns a string identifying the given keystroke.
 
 /** \return a human-readable string identifying the given keystroke
  *   (as opposed to 'keyname', which is a strict reverse mapping).
  */
-std::string readable_keyname(wint_t ch);
+std::wstring readable_keyname(const key &k);
 
 extern keybindings global_bindings;
 // For now, this is where the global bindings are stored (I might want to move
@@ -112,8 +147,8 @@
 // Stolen from pinfo.  I don't like the looks of it, but presumably it works
 // (in some circumstances).  This is a FIXME, btw :)
 /* adapted from Midnight Commander */
-#define KEY_CTRL(x) ((x)&31)	/* macro to get CTRL+key sequence */
-#define KEY_ALT(x) (0x200 | (x))	/* macro to get ALT+key sequence */
+#define KEY_CTRL(x) key(((x)&31), true)
+#define KEY_ALT(x) key((0x200 | (x)), true)
 
 
 #endif