Package: xdemineur
Version: 2.1.1-14
Severity: wishlist
Tags: patch

The xdemineur game ergonomy would be greatly improved if it could be
played only with the keyboard (preferably one-handed). The attached
patch implements this feature. Please consider including it (although
it may still be improved).

-- System Information:
Debian Release: 5.0.6
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.26-2-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages xdemineur depends on:
ii  libc6                       2.7-18lenny4 GNU C Library: Shared libraries
ii  libx11-6                    2:1.1.5-2    X11 client-side library
ii  libxext6                    2:1.0.4-2    X11 miscellaneous extension librar
ii  libxpm4                     1:3.5.7-1    X11 pixmap library

xdemineur recommends no packages.

xdemineur suggests no packages.

-- no debconf information
This is a patch for xdemineur 2.1.1-14 as shipped in Debian 5.0.6 (Lenny) to
allow playing only with the keyboard without a mouse.

TODO: make the active square transparent
TODO: document what key does what

diff --git a/Imakefile b/Imakefile
index 09dedcb..ba50744 100644
--- a/Imakefile
+++ b/Imakefile
@@ -10,6 +10,7 @@ XCOMM purpose.  It is provided "as is" without express or 
implied
 XCOMM warranty.
 
 XCOMM        DEFINES = -Wall
+        DEFINES = -DXK_TECHNICAL
 LOCAL_LIBRARIES = -lXpm $(XLIB)
         DEPLIBS = $(DEPXLIB)
            SRCS = demineur.c main.c util.c xdemineur.c
diff --git a/demineur.h b/demineur.h
index e8da620..255845d 100644
--- a/demineur.h
+++ b/demineur.h
@@ -38,6 +38,8 @@ typedef struct
    int        columns ;   /* number of columns */
    int        mines ;     /* number of mines   */
    square_t   **board ;   /* the game board    */
+   int        active_row ;     /* row of the currently selected square */
+   int        active_column ;  /* column of the currently selected square */
 }
 board_t ;
 
diff --git a/pixmaps/active.xpm b/pixmaps/active.xpm
new file mode 100644
index 0000000..64356e7
--- /dev/null
+++ b/pixmaps/active.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+
+static char *xpm_active[] =
+{
+   /* width height ncolors chars_per_pixel */
+   "20 20 2 1" ,
+   /* colors */
+   "  c none" ,
+   ". c red m white" ,
+   /* pixels */
+   "...................." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   ".                  ." ,
+   "...................." ,
+} ;
diff --git a/xdemineur.c b/xdemineur.c
index e673a65..3e668e3 100644
--- a/xdemineur.c
+++ b/xdemineur.c
@@ -68,6 +68,7 @@ static char *const cvsid = "$Id: xdemineur.c,v 1.3.2.2 
1999/07/29 21:25:33 babaf
 #include "pixmaps/mine.xpm"
 #include "pixmaps/mine_lost.xpm"
 #include "pixmaps/mine_false.xpm"
+#include "pixmaps/active.xpm"
 
 /* ------------------------------------------------------------------------- */
 
@@ -155,7 +156,8 @@ static unsigned long black , white , gray , light_gray ;
 
 static Pixmap face_normal , face_click , face_play , face_happy , face_sad ,
               digit[10] , square[9] ,
-              relief , flag , question , mine , mine_lost , mine_false ;
+              relief , flag , question , mine , mine_lost , mine_false ,
+              active ;
 
 /* ------------------------------------------------------------------------- */
 
@@ -183,6 +185,7 @@ void xdemineur_initialize ( int argc , char **argv ,
 
    board.columns = COLUMNS_MIN ;
    board.rows    = ROWS_MIN ;
+   board.active_column = board.active_row = 1 ;
 
    size_hints.flags = 0 ;
    if ( geometry != NULL )
@@ -374,6 +377,7 @@ void xdemineur_pixmaps ( )
    xdemineur_xpm ( xpm_mine       , &mine ) ;
    xdemineur_xpm ( xpm_mine_lost  , &mine_lost ) ;
    xdemineur_xpm ( xpm_mine_false , &mine_false ) ;
+   xdemineur_xpm ( xpm_active     , &active ) ;
 }
 
 /* ------------------------------------------------------------------------- */
@@ -395,6 +399,33 @@ void xdemineur_xpm ( char **data , Pixmap *pixmap_return )
 
 /* ------------------------------------------------------------------------- */
 
+static int change_active_square ( int deltarow, int deltacolumn )
+{
+  if (board.active_row + deltarow > board.rows
+   || board.active_row + deltarow < 1
+   || board.active_column + deltacolumn > board.columns
+   || board.active_column + deltacolumn < 1 )
+  {
+    return -1;
+  }
+
+  board.active_row += deltarow;
+  board.active_column += deltacolumn;
+  xdemineur_square ( board.active_row - deltarow ,
+                     board.active_column - deltacolumn ) ;
+  xdemineur_square ( board.active_row, board.active_column ) ;
+
+  return 0;
+}
+
+static void new_game ( )
+{
+  demineur_end ( ) ;
+  demineur_initialize ( 0 ) ;
+  xdemineur_display ( ) ;
+  demineur_start_timer ( ) ;
+}
+
 void xdemineur_event_loop ( )
 {
    fd_set       readfds ;
@@ -438,6 +469,31 @@ void xdemineur_event_loop ( )
             XDestroyRegion ( region ) ;
             xdemineur_end ( ) ;
             return ;
+         case XK_leftarrow :
+         case XK_h :
+            change_active_square (  0 , -1 ) ;
+            break ;
+         case XK_rightarrow :
+         case XK_l :
+           change_active_square (  0 ,  1 ) ;
+           break ;
+         case XK_uparrow :
+         case XK_k :
+           change_active_square ( -1 ,  0 ) ;
+           break ;
+         case XK_downarrow :
+         case XK_j :
+           change_active_square (  1 ,  0 ) ;
+           break ;
+         case XK_space :
+           demineur_play ( board.active_row , board.active_column );
+           break ;
+         case XK_n :
+           demineur_flag_question ( board.active_row , board.active_column );
+           break ;
+         case XK_p :
+           new_game ( ) ;
+           break ;
          }
          break ;
       case ButtonPress :
@@ -544,10 +600,7 @@ void xdemineur_event_loop ( )
          case STATE_FACE :
             if ( item == ITEM_FACE )   /* new game */
             {
-               demineur_end ( ) ;
-               demineur_initialize ( 0 ) ;
-               xdemineur_display ( ) ;
-               demineur_start_timer ( ) ;
+               new_game ( ) ;
             }
             else
             {
@@ -892,6 +945,13 @@ void xdemineur_square ( int row , int column )
          }
          break ;
    }
+
+   if ( row == board.active_row && column == board.active_column )
+   {
+     /* TODO: how the fsck do I print a 1px red border? */
+     XCopyArea  ( display , active , window , gc , 0 , 0 , SQUARE_WIDTH , 
SQUARE_HEIGHT , x , y ) ;
+   }
+
 }
 
 /* ------------------------------------------------------------------------- */
@@ -968,6 +1028,7 @@ void xdemineur_end ( )
    XFreePixmap ( display , mine       ) ;
    XFreePixmap ( display , mine_lost  ) ;
    XFreePixmap ( display , mine_false ) ;
+   XFreePixmap ( display , active     ) ;
 
    XFreeGC ( display , gc ) ;
    XFreePixmap ( display , icon_bitmap ) ;

Reply via email to