[Aptitude-svn-commit] r3516 - in branches/aptitude-0.3/aptitude: . src/mine

Daniel Burrows dburrows@costa.debian.org
Thu, 30 Jun 2005 19:29:22 +0000


Author: dburrows
Date: Thu Jun 30 19:29:19 2005
New Revision: 3516

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/mine/cmine.cc
   branches/aptitude-0.3/aptitude/src/mine/cmine.h
Log:
Update the mine code for wide chracters.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Thu Jun 30 19:29:19 2005
@@ -1,3 +1,10 @@
+2005-06-30  Daniel Burrows  <dburrows@debian.org>
+
+	* src/mine/cmine.cc, src/mine/cmine.h:
+
+	  Update the mine code for wide characters.  Sort of, anyway.
+	  At least, it should work.
+
 2005-06-31 Tim Dijkstra <tim@famdijkstra.org>
 
 	* Updated minor corrections to nl.po

Modified: branches/aptitude-0.3/aptitude/src/mine/cmine.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/mine/cmine.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/mine/cmine.cc	Thu Jun 30 19:29:19 2005
@@ -16,6 +16,7 @@
 #include <vscreen/vscreen_widget.h>
 #include <vscreen/vscreen.h>
 
+#include <vscreen/transcode.h>
 #include <vscreen/vs_button.h>
 #include <vscreen/vs_center.h>
 #include <vscreen/vs_editline.h>
@@ -32,19 +33,19 @@
 #ifndef DONT_USE_FANCYBOXES
 // Some systems (*cough* Solaris xterms *cough*) don't like the fancy ASCII
 // graphics provided by libcurses
-#define MINE_ULCORNER ACS_ULCORNER
-#define MINE_URCORNER ACS_URCORNER
-#define MINE_HLINE ACS_HLINE
-#define MINE_VLINE ACS_VLINE
-#define MINE_LLCORNER ACS_LLCORNER
-#define MINE_LRCORNER ACS_LRCORNER
+#define MINE_ULCORNER WACS_ULCORNER
+#define MINE_URCORNER WACS_URCORNER
+#define MINE_HLINE WACS_HLINE
+#define MINE_VLINE WACS_VLINE
+#define MINE_LLCORNER WACS_LLCORNER
+#define MINE_LRCORNER WACS_LRCORNER
 #else
-#define MINE_ULCORNER '+'
-#define MINE_URCORNER '+'
-#define MINE_HLINE '-'
-#define MINE_VLINE '|'
-#define MINE_LLCORNER '+'
-#define MINE_LRCORNER '+'
+#define MINE_ULCORNER L'+'
+#define MINE_URCORNER L'+'
+#define MINE_HLINE L'-'
+#define MINE_VLINE L'|'
+#define MINE_LLCORNER L'+'
+#define MINE_LRCORNER L'+'
 #endif
 
 using namespace std;
@@ -84,39 +85,50 @@
       int width,height;
       getmaxyx(height,width);
 
-      string header="Minesweeper";
-      char buf[200];
+      wstring header=transcode(_("Minesweeper"));
+      wchar_t buf[200];
 
       if(board->get_state()==mine_board::playing)
-	snprintf(buf,
+	swprintf(buf,
 		 sizeof(buf),
-		 _("%i/%i mines  %d %s"),
+		 transcode(_("%i/%i mines  %d %s")).c_str(),
 		 board->get_nummines()-board->get_numflags(),
 		 board->get_nummines(),
 		 (int) board->get_duration(),
 		 board->get_duration()==1?_("second"):_("seconds"));
       else
-	snprintf(buf,
+	swprintf(buf,
 		 sizeof(buf),
-		 _("Minesweeper    %s in %d %s"),
+		 transcode(_("    %s in %d %s")).c_str(),
 		 board->get_state()==mine_board::won?_("Won"):_("Lost"),
 		 (int) board->get_duration(),
 		 board->get_duration()==1?_("second"):_("seconds"));
 
-      while(header.size()+strlen(buf)<(unsigned) width)
-	header+=' ';
+      int headerw=wcswidth(header.c_str(), header.size());
+      int bufw=wcswidth(buf, wcslen(buf));
+
+      while(headerw+bufw < width)
+	{
+	  header+=L' ';
+	  headerw+=wcwidth(L' ');
+	}
 
       unsigned int loc=0;
-      while(header.size()<(unsigned) width)
+      while(headerw < width)
 	{
-	  assert(loc<strlen(buf));
-	  header+=buf[loc++];
+	  assert(buf[loc]!=0);
+
+	  wchar_t wch=buf[loc];
+	  header+=buf;
+	  headerw+=wcwidth(wch);
+	  ++loc;
 	}
 
-      display_header(header.c_str(), (st+get_style("Header")).get_attrs());
+      display_header(header, st+get_style("Header"));
     }
   else
-    display_header(_("Minesweeper"), (st+get_style("Header")).get_attrs());
+    display_header(transcode(_("Minesweeper")),
+		   st+get_style("Header"));
 }
 
 void cmine::do_load_game(string s)
@@ -130,7 +142,8 @@
 
 	  snprintf(buf, 512, _("Could not open file \"%s\""), s.c_str());
 
-	  popup_widget(vs_dialog_ok(buf, NULL, get_style("Error")));
+	  popup_widget(vs_dialog_ok(transcode(buf), NULL,
+				    get_style("Error")));
 	}
       else
 	{
@@ -142,9 +155,11 @@
 	    {
 	      char buf[512];
 
-	      snprintf(buf, 512, _("Could not load game from %s"), s.c_str());
+	      snprintf(buf, 512, _("Could not load game from %s"),
+		       s.c_str());
 
-	      popup_widget(vs_dialog_ok(buf, NULL, get_style("Error")));
+	      popup_widget(vs_dialog_ok(transcode(buf), NULL,
+					get_style("Error")));
 	      delete brd;
 	    }
 	  else
@@ -167,7 +182,8 @@
 
 	  snprintf(buf, 512, _("Could not open file \"%s\""), s.c_str());
 
-	  popup_widget(vs_dialog_ok(buf, NULL, get_style("Error")));
+	  popup_widget(vs_dialog_ok(transcode(buf), NULL,
+				    get_style("Error")));
 	}
       else
 	{
@@ -182,42 +198,44 @@
 				 vs_editline *widthedit,
 				 vs_editline *minesedit)
 {
-  string s=heightedit->get_text();
+  wstring s=heightedit->get_text();
 
-  char *end=const_cast<char *>(s.c_str());
+  wchar_t *end=const_cast<wchar_t *>(s.c_str());
 
-  long height=strtol(s.c_str(), &end, 0);
+  long height=wcstol(s.c_str(), &end, 0);
 
   if(s.c_str()[0]=='\0' || *end!='\0' || height<1)
     {
       // FIXME: should say "positive integer" but the translators will
       // lynch me ;-)
-      popup_widget(vs_dialog_ok(_("The board height must be a number"),
+      //
+      //
+      // That's ok, they'll do that anyway in a couple releases ;-)
+      popup_widget(vs_dialog_ok(transcode(_("The board height must be a positive integer")),
 				NULL,
 				get_style("Error")));
       return;
     }
 
   s=widthedit->get_text();
-  end=const_cast<char *>(s.c_str());
-  long width=strtol(s.c_str(), &end, 0);
+  end=const_cast<wchar_t *>(s.c_str());
+  long width=wcstol(s.c_str(), &end, 0);
 
   if(s.c_str()[0]=='\0' || *end!='\0' || width<1)
     {
-      popup_widget(vs_dialog_ok(_("The board width must be a number"),
+      popup_widget(vs_dialog_ok(transcode(_("The board width must be a positive integer")),
 				NULL,
 				get_style("Error")));
       return;
     }
 
   s=minesedit->get_text();
-  end=const_cast<char *>(s.c_str());
-  long mines=strtol(s.c_str(), &end, 0);
+  end=const_cast<wchar_t *>(s.c_str());
+  long mines=wcstol(s.c_str(), &end, 0);
 
   if(s.c_str()[0]=='\0' || *end!='\0' || mines<1)
     {
-      // awkward wording
-      popup_widget(vs_dialog_ok(_("The number of mines must be a number"),
+      popup_widget(vs_dialog_ok(transcode(_("Invalid mine count; please enter a positive integer")),
 				NULL,
 				get_style("Error")));
       return;
@@ -238,13 +256,13 @@
   vs_label *overalllabel=new vs_label(_("Setup custom game"));
 
   vs_label *heightlabel=new vs_label(_("Height of board: "));
-  vs_editline *heightedit=new vs_editline("");
+  vs_editline *heightedit=new vs_editline(L"");
 
   vs_label *widthlabel=new vs_label(_("Width of board: "));
-  vs_editline *widthedit=new vs_editline("");
+  vs_editline *widthedit=new vs_editline(L"");
 
   vs_label *mineslabel=new vs_label(_("Number of mines: "));
-  vs_editline *minesedit=new vs_editline("");
+  vs_editline *minesedit=new vs_editline(L"");
 
   vs_button *okbutton=new vs_button(_("Ok"));
   vs_button *cancelbutton=new vs_button(_("Cancel"));
@@ -366,7 +384,7 @@
 	do_custom_game();
 	break;
       default:
-	popup_widget(vs_dialog_ok("Internal error: execution reached an impossible point",
+	popup_widget(vs_dialog_ok(transcode("Internal error: execution reached an impossible point"),
 				  NULL,
 				  get_style("Error")));
 	break;
@@ -387,12 +405,11 @@
   // Prints out silly messages when the player wins or loses
 {
   if(board->get_state()==mine_board::won)
-    // I should continue the Nethack theme, but I've never won so I don't
-    // know what the message should be :)
-    popup_widget(vs_dialog_ok(_("You have won.")));
+    // "You hold up the Amulet of Yendor.  An invisible choir sings..."
+    popup_widget(vs_dialog_ok(transcode(_("You have won."))));
   else if(board->get_state()==mine_board::lost)
     {
-      popup_widget(vs_dialog_ok(_("You lose!")));
+      popup_widget(vs_dialog_ok(transcode(_("You lose!"))));
 #if 0
       // (messages in reverse order because the minibuf is a stack by default..
       // I could use the special feature of sticking them at the end, but I
@@ -506,14 +523,12 @@
   vscreen_update();
 }
 
-bool cmine::handle_char(chtype ch)
-  // Input-handling routine.
+bool cmine::handle_key(const key &k)
 {
   int width,height;
-  getmaxyx(height,width);
-  // Not all branches need it but it's cheap..
+  getmaxyx(height, width);
 
-  if(bindings->key_matches(ch, "MineUncoverSweepSquare"))
+  if(bindings->key_matches(k, "MineUncoverSweepSquare"))
     {
       if(board->get_state()==mine_board::playing)
 	{
@@ -526,23 +541,23 @@
 	}
       vscreen_update();
     }
-  else if(bindings->key_matches(ch, "MineUncoverSquare"))
+  else if(bindings->key_matches(k, "MineUncoverSquare"))
     {
       board->uncover(curx, cury);
       vscreen_update();
     }
-  else if(bindings->key_matches(ch, "MineSweepSquare"))
+  else if(bindings->key_matches(k, "MineSweepSquare"))
     {
       board->sweep(curx, cury);
       vscreen_update();
     }
-  else if(bindings->key_matches(ch, "MineFlagSquare"))
+  else if(bindings->key_matches(k, "MineFlagSquare"))
     {
       board->toggle_flag(curx, cury);
       // FIXME: handle errors?
       vscreen_update();
     }
-  else if(bindings->key_matches(ch, "Up"))
+  else if(bindings->key_matches(k, "Up"))
     {
       if(cury>0)
 	{
@@ -552,7 +567,7 @@
 	  vscreen_update();
 	}
     }
-  else if(bindings->key_matches(ch, "Down"))
+  else if(bindings->key_matches(k, "Down"))
     {
       if(cury<board->get_height()-1)
 	{
@@ -562,7 +577,7 @@
 	  vscreen_update();
 	}
     }
-  else if(bindings->key_matches(ch, "Left"))
+  else if(bindings->key_matches(k, "Left"))
     {
       if(curx>0)
 	{
@@ -572,7 +587,7 @@
 	  vscreen_update();
 	}
     }
-  else if(bindings->key_matches(ch, "Right"))
+  else if(bindings->key_matches(k, "Right"))
     {
       if(curx<board->get_width()-1)
 	{
@@ -582,23 +597,23 @@
 	  vscreen_update();
 	}
     }
-  else if(bindings->key_matches(ch, "MineNewGame"))
+  else if(bindings->key_matches(k, "MineNewGame"))
     do_new_game();
-  else if(bindings->key_matches(ch, "MineLoadGame"))
+  else if(bindings->key_matches(k, "MineLoadGame"))
     prompt_string(_("Enter the filename to load: "),
 		  "",
 		  arg(sigc::mem_fun(*this, &cmine::do_load_game)),
 		  NULL,
 		  NULL,
 		  &load_history);
-  else if(bindings->key_matches(ch, "MineSaveGame"))
+  else if(bindings->key_matches(k, "MineSaveGame"))
     prompt_string(_("Enter the filename to save: "),
 		  "",
 		  arg(sigc::mem_fun(*this, &cmine::do_save_game)),
 		  NULL,
 		  NULL,
 		  &save_history);
-  else if(bindings->key_matches(ch, "Help"))
+  else if(bindings->key_matches(k, "Help"))
     {
       char buf[512];
 
@@ -628,7 +643,7 @@
 
   if(screenx>=0 && screenx<width && screeny>=0 && screeny<height-1)
     {
-      chtype ch;
+      wchar_t ch;
       style cur_st;
       const mine_board::board_entry &entry=board->get_square(x, y);
       // We want to handle the case of 'game-over' differently from
@@ -640,24 +655,24 @@
 	    {
 	      if(entry.flagged)
 		{
-		  ch='F';
+		  ch=L'F';
 		  cur_st=get_style("MineFlag");
 		}
 	      else
 		{
-		  ch=' ';
+		  ch=L' ';
 		  cur_st=get_style("DefaultWidgetBackground");
 		}
 	    }
 	  else if(entry.contains_mine)
 	    {
-	      ch='^';
+	      ch=L'^';
 	      cur_st=get_style("MineBombColor");
 	    }
 	  else if(entry.adjacent_mines==0)
-	    ch='.';
+	    ch=L'.';
 	  else
-	    ch=('0'+entry.adjacent_mines);
+	    ch=(L'0'+entry.adjacent_mines);
 	}
       else
 	{
@@ -666,28 +681,30 @@
 	      if(board->get_state()==mine_board::lost &&
 		 x==board->get_minex() && y==board->get_miney())
 		{
-		  ch='*';
+		  ch=L'*';
 		  cur_st=get_style("MineDetonated");
 		}
 	      else
 		{
-		  ch='^';
+		  ch=L'^';
 		  cur_st=get_style("MineBomb");
 		}
 	    }
 	  else if(entry.uncovered)
 	    {
 	      if(entry.adjacent_mines==0)
-		ch='.';
+		ch=L'.';
 	      else
-		ch=('0'+entry.adjacent_mines);
+		ch=(L'0'+entry.adjacent_mines);
 	    }
 	  else
-	    ch=' ';
+	    ch=L' ';
 	}
       if(board->get_state()==mine_board::playing && x==curx && y==cury)
 	cur_st+=style_attrs_flip(A_REVERSE);
-      mvaddch(screeny, screenx, ch);
+
+      apply_style(cur_st);
+      mvadd_wch(screeny, screenx, ch);
     }
 }
 
@@ -699,11 +716,14 @@
       getmaxyx(height, width);
 
       if(height!=prevheight || width!=prevwidth)
-	// If the window size has changed (or we just got a window for the
-	// first time) we need to reset the boundaries.  Really, this ought to
-	// be done by a callback (aka virtual function) that gets called for
-	// the first assignment of a cwindow to the vscreen or when the
-	// screen resizes.
+	// If the window size has changed (or we just got a window for
+	// the first time) we need to reset the boundaries.  Really,
+	// this ought to be done by a callback (aka virtual function)
+	// that gets called for the first assignment of a cwindow to
+	// the vscreen or when the screen resizes.
+	//
+	// Probably should be connected to layout_me() if anyone
+	// cares.
 	{
 	  prevwidth=width;
 	  prevheight=height;
@@ -720,11 +740,11 @@
       if(board)
 	{
 	  int right=basex+board->get_width()+1, down=basey+1+board->get_height()+1;
-	  // x and y coordinates, respectively, of the right and lower board
-	  // edges.
+	  // x and y coordinates, respectively, of the right and lower
+	  // board edges.
 	  int line_start_x=basex>0?basex+1:1, line_start_y=basey>=0?basey+2:1;
-	  // The starting coordinates of the horizontal and vertical lines,
-	  // respectively.
+	  // The starting coordinates of the horizontal and vertical
+	  // lines, respectively.
 
 	  int horiz_line_width, vert_line_height;
 	  if(basex+board->get_width()>=width)
@@ -736,22 +756,21 @@
 	    vert_line_height=height-1-line_start_y;
 	  else
 	    vert_line_height=basey+2+board->get_height()-line_start_y;
-	  // Calculate the widths of the sides of the board.  This might look
-	  // a little like black voodoo magic.  It is.  You wouldn't believe
-	  // how many chickens I had to..er, nevermind :)
-	  // Probably this could be cleaned up; there seems to be a lot of
-	  // confusion resulting from the value of basey.  I think now that
-	  // basey+y should go from 1 to height instead of 0 to height-1 -- it
-	  // might make things more confusing elsewhere but would simplify
-	  // the drawing routines tremendously.
-
-	  // The reason that we only use 'basey+1' below is that we have to
-	  // draw the board inside the 'main' window provided by the
-	  // minibuf_win.
+	  // Calculate the widths of the sides of the board.  This
+	  // might look a little like black voodoo magic.  It is.  You
+	  // wouldn't believe how many chickens I had to..er,
+	  // nevermind :)
 	  //
-	  //  A better long-term solution is to have the minibuf_win divide
-	  // itself into three subwindows and hand us one.  This may happen
-	  // eventually, but maybe after I hand the assignment in :)
+	  // Probably this could be cleaned up; there seems to be a
+	  // lot of confusion resulting from the value of basey.  I
+	  // think now that basey+y should go from 1 to height instead
+	  // of 0 to height-1 -- it might make things more confusing
+	  // elsewhere but would simplify the drawing routines
+	  // tremendously.
+
+	  // The reason that we only use 'basey+1' below is that we
+	  // have to draw the board inside the 'main' window provided
+	  // by the minibuf_win.
 
 	  int minx=(basex<-1?-basex:0),miny=(basey<-1?-1-basey:0);
 	  // The /board coordinates/ of the minimal x and y values visible
@@ -774,28 +793,42 @@
 	  if(basey>=0)
 	    {
 	      if(basex>=0)
-		mvaddch(basey+1, basex, MINE_ULCORNER);
+		mvadd_wch(basey+1, basex, MINE_ULCORNER);
 
-	      mvhline(basey+1, line_start_x, MINE_HLINE, horiz_line_width);
+	      // NB: Assumes MINE_HLINE has a width of 1
+	      for(int x=line_start_x;
+		  x-line_start_x < horiz_line_width; ++x)
+		mvadd_wch(basey+1, x, MINE_HLINE);
 	    }
 
 	  if(basex>=0)
-	    mvvline(line_start_y, basex, MINE_VLINE, vert_line_height);
+	    {
+	      for(int y=line_start_y;
+		  y-line_start_y < vert_line_height; ++y)
+		mvadd_wch(y, basex, MINE_VLINE);
+	    }
 
 	  if(right<width)
 	    {
 	      if(basey>=0)
-		mvaddch(basey+1, right, MINE_URCORNER);
-	      mvvline(line_start_y, right, MINE_VLINE, vert_line_height);
+		mvadd_wch(basey+1, right, MINE_URCORNER);
+
+	      for(int y=line_start_y;
+		  y-line_start_y < vert_line_height; ++y)
+		mvadd_wch(y, 0, MINE_VLINE);
+
 	      if(down<height-1)
-		mvaddch(down, right, MINE_LRCORNER);
+		mvadd_wch(down, right, MINE_LRCORNER);
 	    }
 
 	  if(down<height-1)
 	    {
 	      if(basex>=0)
-		mvaddch(down, basex, MINE_LLCORNER);
-	      mvhline(down, line_start_x, MINE_HLINE, horiz_line_width);
+		mvadd_wch(down, basex, MINE_LLCORNER);
+
+	      for(int x=line_start_x;
+		  x-line_start_x < horiz_line_width; ++x)
+		mvadd_wch(down, x, MINE_HLINE);
 	    }
 
 	  // Now the squares:
@@ -814,11 +847,11 @@
   set_style("MineBomb", style_fg(COLOR_RED)+style_attrs_on(A_BOLD));
   set_style("MineDetonated", style_fg(COLOR_CYAN));
 
-  global_bindings.set("MineUncoverSweepSquare", KEY_ENTER);
-  global_bindings.set("MineFlagSquare", 'f');
-  global_bindings.set("MineNewGame", 'n');
-  global_bindings.set("MineSaveGame", 'S');
-  global_bindings.set("MineLoadGame", 'L');
+  global_bindings.set("MineUncoverSweepSquare", key(KEY_ENTER, true));
+  global_bindings.set("MineFlagSquare", key(L'f', false));
+  global_bindings.set("MineNewGame", key(L'n', false));
+  global_bindings.set("MineSaveGame", key(L'S', false));
+  global_bindings.set("MineLoadGame", key(L'L', false));
 
   bindings=new keybindings(&global_bindings);
 }

Modified: branches/aptitude-0.3/aptitude/src/mine/cmine.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/mine/cmine.h	(original)
+++ branches/aptitude-0.3/aptitude/src/mine/cmine.h	Thu Jun 30 19:29:19 2005
@@ -70,7 +70,7 @@
   void paint_header(const style &st);
 public:
   cmine();
-  bool handle_char(chtype ch);
+  bool handle_key(const key &k);
   void paint(const style &st);
   ~cmine()
   {