home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume13 / dominion / part22 / cur_stuff.c next >
C/C++ Source or Header  |  1992-02-11  |  19KB  |  825 lines

  1.   /* cur_stuff.c -- stuff that uses curses a lot */
  2.  
  3. /*
  4.  * Copyright (C) 1990 Free Software Foundation, Inc.
  5.  * Written by the dominion project.
  6.  *
  7.  * This file is part of dominion.
  8.  *
  9.  * dominion is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU General Public License as published
  11.  * by the Free Software Foundation; either version 1, or (at your option)
  12.  * any later version.
  13.  *
  14.  * This software is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this software; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24. /* pager(fname) - pages through a file                             */
  25. /* mygetch() - runs getch(), and gives help if user types '?'      */
  26. /* wget_name(w, name) - gets a name in a curses window             */
  27. /* wget_string(w, str, len) - gets a string in a curses window     */
  28. /* wget_number(w, p) - gets a number in a curses window            */
  29.  
  30. #include "dominion.h"
  31. #include "misc.h"
  32. #include "cur_stuff.h"
  33. #include <stdio.h>
  34.  
  35. extern Suser user;
  36. extern Sworld world;
  37. extern int (*keymap[128])(), (*wrapx)(), (*wrapy)();
  38. extern struct s_desig_map desig_map[];
  39. extern struct s_altitude_map altitude_map[];
  40. extern struct item_map terrains[];
  41.  
  42. WINDOW *sectw;
  43. /* WINDOW *sectw, *armyw; */
  44.  
  45. /* statline and statline2 moved to misc.c */
  46.  
  47.   /* simple standalone pager, used for news and other stuff */
  48. pager(fname)
  49.      char fname[];
  50. {
  51.   FILE *fp, *fopen();
  52.   WINDOW *pagew;
  53.   long page_lines = LINES-2, lines = 0;
  54.   char line[200];
  55.   char c;
  56.   int i;
  57.  
  58.   if ((fp = fopen(fname, "r")) == NULL) {
  59.     statline2_err("cannot open file", fname);
  60.     return '\0';
  61.   }
  62.   pagew = newwin(LINES-2, COLS, 0, 0);
  63.   touchwin(pagew);
  64.   lines = 0;
  65.   while (fgets(line, 180, fp) != NULL) {
  66.     line[COLS-2] = '\0';    /* make sure it fits on screen */
  67.     mvwaddstr(pagew, lines, 0, line);
  68.     wclrtoeol(pagew);
  69.     wrefresh(pagew);
  70.     ++lines;
  71.     if (lines % page_lines == 0) { /* next page? */
  72.       wclrtobot(pagew);
  73.       wrefresh(pagew);
  74.       lines = 0;
  75.       statline("SPACE to continue, [q] or [n] to leave this file", fname);
  76.       switch(c = getch()) {
  77.       case 'q':
  78.       case 'n':
  79.     fclose(fp);
  80.     return c;
  81.     break;
  82.       case 'f':            /* skip 23 lines */
  83.     for (i = 0; i < 23 && fgets(line, 180, fp); ++i) {
  84.     }
  85.     break;
  86.       case ' ':
  87.     break;
  88.       default:
  89.     break;
  90.       }
  91.       wmove(pagew, 0, 0);
  92.     }
  93.   }
  94.   fclose(fp);
  95.   wclrtobot(pagew);
  96.   wrefresh(pagew);
  97.   delwin(pagew);
  98.   return ' ';
  99. }
  100.  
  101.   /* draw the world map */
  102. draw_map()
  103. {
  104.   if (user.map_style == NORMAL_MAP) {
  105.     draw_map_regular();
  106.   } else {
  107.     draw_map_compact();
  108.   }
  109. }
  110.  
  111.   /* draw the map with a space between adjacent sectors */
  112. draw_map_regular()
  113. {
  114.   char s[80];
  115.   int x = user.cursor.x, y = user.cursor.y /*,
  116.          xoff = user.center.x-(COLS-2)/4, yoff = user.center.y - (LINES-2)/2*/;
  117.   int i, j, iw, jw, n;
  118.   int mark;    /* what to draw in that sector, negative if highlight */
  119.   Ssector *sp = &world.map[x][y];
  120.   int visibility;
  121.  
  122.     /* clean up the space from the previous armies */
  123.   for (i = 0; i <= 2*user.last_n_armies; ++i) {
  124.     move(i, ARMYW_X);
  125.     clrtoeol();
  126.   }
  127.   user.last_n_armies = sect_n_armies(sp);
  128.  
  129.   for (i = xoff(); (i < xoff()+(COLS-2)/2) && (i < xoff()+world.xmax); ++i) {
  130.     for (j = yoff(); (j < yoff()+LINES-2) && (j < yoff()+world.ymax); ++j) {
  131.       if (!is_under_sectw(2*(i-xoff()), j-yoff())) {
  132.           /* now wrap the coordinates, so we handle the topology */
  133.     move(j-yoff(), 2*(i-xoff()));    /* move does not want wrapping */
  134.     iw = (*wrapx)(i,j);
  135.     jw = (*wrapy)(i,j);
  136.     visibility = user.visible_sectors[iw][jw];
  137.     if (visibility > SEE_NOTHING && visibility != SEE_ARMIES) {
  138.       if ((mark = which_mark(iw, jw, &user)) < 0) {
  139.         standout();
  140.         addch(-mark);
  141.         standend();
  142.       } else {
  143.         addch(mark);
  144.       }
  145.     } else {        /* if not visible, put a space */
  146.       addch(' ');
  147.     }
  148.       }
  149.     }
  150.   }
  151.   show_armies(&world.map[x][y]);
  152.   sprintf(s, "Nation %s; money %d; Thon %d;   type %c for help",
  153.       user.np->name, user.np->money, world.turn, user.help_char);
  154.   statline(s, "draw_map_regular");
  155.   show_sector(x, y);
  156.   move((*wrapy)(x-xoff(),y-yoff()), 2*(*wrapx)(x-xoff(),y-yoff()));
  157.   refresh();
  158. }
  159.  
  160. draw_map_compact()        /* compact drawing of map */
  161. {
  162.   char s[80];
  163.   int x = user.cursor.x, y = user.cursor.y;
  164.   int i, j, n;
  165.   int mark;    /* what to draw in that sector, negative if highlight */
  166.   Ssector *sp = &world.map[x][y];
  167.   int visibility;
  168.  
  169.     /* clean up the space from the previous armie */
  170.   for (i = 0; i <= 2*user.last_n_armies; ++i) {
  171.     move(i, ARMYW_X);
  172.     clrtoeol();
  173.   }
  174.   user.last_n_armies = sect_n_armies(sp);
  175.  
  176.   for (i = xoff_compact();
  177.        (i < xoff_compact() + COLS-2) && (i < xoff_compact() + world.xmax); ++i) {
  178.     for (j = yoff(); (j < yoff() + LINES-2) && (j < yoff() + world.ymax); ++j) {
  179.       move(j-yoff(), i-xoff_compact());
  180.       visibility = user.visible_sectors[(*wrapx)(i,j)][(*wrapy)(i,j)];
  181.       if (visibility > SEE_NOTHING && visibility != SEE_ARMIES) {
  182.     if ((mark = which_mark((*wrapx)(i,j), (*wrapy)(i,j), &user)) < 0) {
  183.       standout();
  184.       addch(-mark);
  185.       standend();
  186.     } else {
  187.       addch(mark);
  188.     }
  189.       } else {            /* if not visible, put a space */
  190.     addch(' ');
  191.       }
  192.     }
  193.   }
  194.   show_armies(&world.map[x][y]);
  195.   sprintf(s, "Nation %s; money %d; Thon %d;   type %c for help",
  196.       user.np->name, user.np->money, world.turn, user.help_char);
  197.   statline(s, "draw_map_compact");
  198.   show_sector(user.cursor.x, user.cursor.y);
  199.   move((*wrapy)(x-xoff_compact(),y-yoff()), (*wrapx)(x-xoff_compact(),y-yoff()));
  200.   refresh();
  201. }
  202.  
  203. show_sector(x, y)        /* give info on the sector */
  204.      int x, y;
  205. {
  206.   Ssector *sp = &world.map[x][y];
  207.   char s[2*NAMELEN];
  208.   int visibility = user.visible_sectors[x][y];
  209.  
  210.   if (user.show_sect_win && user.just_moved) {
  211.     /* put the stuff in the special sector window */
  212.   mvwprintw(sectw, 1, 1, "(%d,%d)", xrel(x,y,user.np->capital),
  213.         yrel(x,y,user.np->capital));
  214.  
  215.   wclrtobot(sectw);
  216.  
  217.     /* Show sector name if they can see the population of the sector! */
  218.   if (visibility & SEE_POPULATION) {
  219.     wprintw(sectw," %s", sp->name);
  220.   }
  221.   
  222.     /* Shows owner if can see owner */
  223.   wmove(sectw, 2, 1);
  224.   if ((visibility & SEE_OWNER) && (sp->owner!=0)) {
  225.     wprintw(sectw,"%s-", world.nations[sp->owner].name);
  226.   }
  227.   
  228.     /* Shows designation if can see designation */
  229.   if (visibility & SEE_DESIG) {
  230.     if (sp->owner != 0 || sp->designation != D_NODESIG) {
  231.       wprintw(sectw, "%s", desig_map[sp->designation].name);
  232.       if (has_bubble(sp)) {
  233.     waddstr(sectw, "/B");
  234.       }
  235.       if (has_hidden(sp)) {
  236.     waddstr(sectw, "/H");
  237.       }
  238.       if (has_traded(sp)) {
  239.     waddstr(sectw, "/T");
  240.       }
  241.       if (has_impenetrable(sp)) {
  242.     waddstr(sectw, "/I");
  243.       }
  244.       if (has_hostile(sp)) {
  245.     waddstr(sectw, "/h");
  246.       }
  247.     }
  248.   }
  249.   
  250.   if (visibility & SEE_LAND_WATER) {
  251.     mvwprintw(sectw, 3, 1, "%s ", terrains[sp->terrain - MIN_TERRAIN].name);
  252.     wprintw(sectw, "%s", altitude_map[map_alt(sp->altitude)].name);
  253.   }
  254.  
  255.     wmove(sectw, 4, 1);    
  256.     if (visibility & SEE_POPULATION) {
  257.       wprintw(sectw, "%d people", sp->n_people);
  258.       if (sp->owner != 0) {    /* print race of owner, if owner is not 0 */
  259.     wprintw(sectw, " (%c)",    world.nations[sp->owner].race.mark);
  260.       }
  261.     }
  262.   
  263.   if (visibility & SEE_RESOURCES) {
  264.     mvwprintw(sectw, 5, 1, "metal %d", sp->metal);
  265.     mvwprintw(sectw, 5, 13, "jewels %d", sp->jewels);
  266.   }
  267.   
  268.   if (visibility & SEE_RESOURCES) {
  269.     mvwprintw(sectw, 6, 2, "soil %d", sp->soil);
  270.   }
  271.   if (visibility & SEE_LAND_WATER) {
  272.     mvwprintw(sectw, 6, 11, "movecost %d",
  273.           get_generic_move_cost(&world.nations[user.id],sp));
  274. /*          get_move_cost(&world.nations[user.id],sp)); */
  275.   }
  276.  
  277.   box(sectw, '|', '-');
  278.   } /* (for future optimization) */
  279.   wrefresh(sectw);
  280. }
  281.  
  282. bad_key()            /* user typed an undefined key */
  283. {
  284.   statline("type space to go on", "bad_key");
  285.   while (getch() != ' ') {
  286.   }
  287. }
  288.  
  289. redraw()
  290. {
  291. /*  user.center = user.cursor; */
  292.   clear();
  293.   refresh();
  294.   user.just_moved = 1;
  295. }
  296.  
  297. windows()            /* user gets to manage windows */
  298. {
  299.   WINDOW *winw;            /* for this screen only */
  300.   Pt new_loc;            /* new location of the window */
  301.  
  302.   statline("", "windows");
  303.   winw = newwin(6, 26, 2, 2);
  304.   wstandout(winw);
  305.   mvwprintw(winw, 1, 4, "you can choose: ");
  306.   wstandend(winw);
  307.   mvwprintw(winw, 2, 0, "m - [m]ove sector window");
  308.   mvwprintw(winw, 3, 0, "h - [h]ide sector window");
  309.   mvwprintw(winw, 4, 0, "s - [s]how sector window");
  310.   move(4,0);
  311.   box(winw, '|', '-');
  312.   wrefresh(winw);
  313.   move(4,0);
  314.   switch(getch()) {
  315.   case 'm':
  316.     new_loc.x = sectw->_begx;
  317.     new_loc.y = sectw->_begy;
  318.     mvprintw(LINES-2, 0, "starting at (%d,%d)", new_loc.x, new_loc.y);
  319.     refresh();
  320.       /* absolute dragging */
  321.     new_loc = drag_cursor(new_loc, DRAG_ABS, NULL, NULL);
  322.     mvwin(sectw, new_loc.y, new_loc.x);
  323.     break;
  324.   case 'h':
  325.     user.show_sect_win = 0;
  326.     werase(sectw);
  327.     wrefresh(sectw);
  328.     touchwin(stdscr);
  329.     break;
  330.   case 's':
  331.     if (!user.show_sect_win) {
  332.       show_sector(user.cursor.x, user.cursor.y);
  333.     }
  334.     user.show_sect_win = 1;
  335.     break;
  336.   default:
  337.     break;
  338.   }
  339.   delwin(winw);            /* done with it */
  340.   touch_all_wins();
  341. /*  fflush(stdin); */
  342. }
  343.  
  344. touch_all_wins()    /* make sure all permanent windows get touched */
  345. {
  346.   touchwin(stdscr);
  347. /*  if (user.show_sect_win) {
  348.     touchwin(sectw);
  349.   }
  350. */
  351.   user.just_moved = 1;
  352. }
  353.  
  354.   /* this is used in general to track the user's movements */
  355. Pt drag_cursor(pt, flags, comment, legal)
  356.      Pt pt;
  357.      int flags;
  358.      char (*comment)();
  359.      int (*legal)();
  360. {
  361.   char c;
  362.   char s[100], comment_str[100];
  363.   Pt old_pt;
  364.   int done = 0;
  365.  
  366.   old_pt = pt;
  367.  
  368.   statline("move the cursor; type space when done", "drag_cursor");
  369.  
  370.   if ((flags == DRAG_REL) && (user.map_style == NORMAL_MAP)) {
  371.     wrap(&pt);            /* regural map, relative drag */
  372.     move(pt.y-yoff(), 2*(pt.x-xoff()));
  373.   } else if (flags == DRAG_REL) { /* compact map, but still relative */
  374.     wrap(&pt);
  375.     move((*wrapy)(pt.x-xoff_compact(), pt.y-yoff()),
  376.      (*wrapx)(pt.x-xoff_compact(),pt.y-yoff()));
  377.   } else {            /* absolute positions */
  378.     move(pt.y, pt.x);
  379.   }
  380.   refresh();
  381.   while (((c = getch()) != ' ') && !done) {
  382.     old_pt = pt;
  383.     switch (c) {
  384.     case '?':
  385.       online_info();
  386.       break;
  387.     case 'h':
  388.     case '4':
  389.       --pt.x;
  390.       break;
  391.     case 'j':
  392.     case '2':
  393.       ++pt.y;
  394.       break;
  395.     case 'k':
  396.     case '8':  
  397.       --pt.y;
  398.       break;
  399.     case 'l':
  400.     case '6':  
  401.       ++pt.x;
  402.       break;
  403.     case 'y':
  404.     case '7':
  405.       --pt.x;
  406.       --pt.y;
  407.       break;
  408.     case 'u':
  409.     case '9':
  410.       ++pt.x;
  411.       --pt.y;
  412.       break;
  413.     case 'b':
  414.     case '1':
  415.       --pt.x;
  416.       ++pt.y;
  417.       break;
  418.     case 'n':
  419.     case '3':
  420.       ++pt.x;
  421.       ++pt.y;
  422.       break;
  423.     default:
  424.       continue;
  425.     }
  426.     if (legal != NULL) {    /* if there *is* a legal() func... */
  427.       wrap(&pt);
  428.       if (!((*legal)(pt, user.np, user.current_army))) {
  429.     beep();            /* illegal */
  430.     pt = old_pt;
  431.     statline2("hit space", "invalid point");
  432.     get_space();
  433.       }
  434.     }
  435.     if (flags == DRAG_REL) {    /* cludge, and ugly, since we wrap later */
  436.       wrap(&pt);
  437.       sprintf(s, "(%d,%d)", xrel(pt.x,pt.y,user.np->capital),
  438.           yrel(pt.x,pt.y,user.np->capital));
  439.     } else {
  440.       sprintf(s, "(%d,%d)", pt.x, pt.y);
  441.     }
  442.     if (comment != NULL) {
  443.       done = comment(comment_str);
  444.       statline2(comment_str, s);
  445.     } else {
  446.       statline2("", s);
  447.     }
  448.     switch (flags) {
  449.     case DRAG_REL:
  450.       wrap(&pt);
  451.       re_center(pt.x, pt.y);
  452.       user.just_moved = 1;
  453.       draw_map();
  454. /*      show_sector(pt.x, pt.y); */
  455.       if (user.map_style == NORMAL_MAP) {
  456.     move((*wrapy)(pt.x-xoff(),pt.y-yoff()), 2*(*wrapx)(pt.x-xoff(),pt.y-yoff()));
  457.       } else {
  458.     move((*wrapy)(pt.x-xoff_compact(),pt.y-yoff()), (*wrapx)(pt.x-xoff_compact(),pt.y-yoff())); /* compact map */
  459.       }
  460.       break;
  461.     case DRAG_ABS:
  462.       move(pt.y, pt.x);
  463.       break;
  464.     default:
  465.       break;
  466.     }
  467.     refresh();
  468.   }
  469.   if (flags == DRAG_REL) {
  470.     sprintf(s, "the new point is (%d, %d)", xrel(pt.x,pt.y,user.np->capital),
  471.         yrel(pt.x,pt.y,user.np->capital));
  472.   } else {
  473.     sprintf(s, "the new point is (%d, %d)", pt.x, pt.y);
  474.   }
  475.   statline2(s, "");
  476.   move(LINES-2, 0);
  477.   clrtoeol();
  478.   refresh();
  479.   return pt;
  480. }
  481.  
  482.   /* this routine sees if the screen needs re-centering, and
  483.      re-centers it if necessary.  return 1 if re-centering was done.
  484.      return 0 if there was no need to re-center.
  485.    */
  486. re_center(x, y)
  487.      int x, y;
  488. {
  489.   int change = 0;
  490.   int width, height;
  491.  
  492.   height = LINES-3;
  493.   width = (COLS-2)-2;
  494.  
  495.   if (user.map_style == NORMAL_MAP) {
  496.     if ((*wrapx)(x - xoff(),0) >= width/2) { /* No Y coord to add! -KM */
  497.       user.center.x = x;    /* too much to the right */
  498.       change = 1;
  499.     }
  500.     if ((*wrapx)(x - xoff(),0) <= 0) { /* No Y coord to add! -KM */
  501.       user.center.x = x;    /* too much to the left */
  502.       change = 1;
  503.     }
  504.   } else {
  505.     if ((*wrapx)(x - xoff_compact(),0) >= width) {
  506.       user.center.x = x;    /* too much to the right */
  507.       change = 1;
  508.     }
  509.     if ((*wrapx)(x - xoff_compact(),0) <= 0) {
  510.       user.center.x = x;    /* too much to the left */
  511.       change = 1;
  512.     }
  513.   }
  514.   if ((*wrapy)(0,y - yoff()) >= height) {
  515.     user.center.y = y;        /* too far down */
  516.     change = 1;
  517.   }
  518.   if ((*wrapy)(0,y - yoff()) <= 0) {
  519.     user.center.y = y;        /* too far up */
  520.     change = 1;
  521.   }
  522. #ifdef hpux
  523.   if (change) {
  524.     redraw();
  525.   }
  526. #endif /* hpux */
  527.   return change;
  528. }
  529.  
  530.   /* see if these coordinates would appear under the sector window */
  531. is_under_sectw(x, y)
  532.      int x, y;
  533. {
  534.   int xfirst, yfirst, xlast, ylast;
  535.  
  536.   if (!user.show_sect_win) {
  537.     return 0;
  538.   }
  539.   xfirst = sectw->_begx;
  540.   yfirst = sectw->_begy;
  541.   xlast = xfirst + SECTW_SIZE_X;
  542.   ylast = yfirst + SECTW_SIZE_Y;
  543.   if (x < xfirst ||  x > xlast || y < yfirst || y > ylast) {
  544.     return 0;
  545.   }
  546.   return 1;
  547. }
  548.  
  549.   /* this puts the cursor in the right place */
  550. set_cursor()
  551. {
  552.   int x = user.cursor.x, y = user.cursor.y;
  553.  
  554.   if (user.map_style == NORMAL_MAP) {
  555.     move((*wrapy)(x-xoff(),y-yoff()), 2*(*wrapx)(x-xoff(),y-yoff()));
  556.   } else {
  557.     move((*wrapy)(x-xoff_compact(),y-yoff()), (*wrapx)(x-xoff_compact(),y-yoff()));
  558.   }
  559.   refresh();
  560. }
  561.  
  562.   /* replacement for getch():  first checks if it is a question
  563.      mark, and if it is it calls online_info().
  564.    */
  565. mygetch()
  566. {
  567.   int c;
  568.   if ((c = getch()) == '?') {
  569.     online_info();
  570.   }
  571.   return c;
  572. }
  573.  
  574.   /* gets a string str of max length len; returns 0 on failure; 1 otherwise */
  575. wget_string (w, rets, len)
  576.      WINDOW * w;
  577.      char * rets;
  578.      int len;
  579. {
  580.   char s [80];
  581.   int pos, done;
  582.   int x, y, i;
  583.   int oldpos;        /* Used for ^W */
  584.   noecho ();
  585.  
  586.   if (w == NULL) {
  587.     w = stdscr;
  588.   }
  589.  
  590.   pos = 0;
  591.   done = 0;
  592.  
  593.   getyx (w, y, x);
  594.   wrefresh (w);
  595.  
  596.   while (!done) {
  597.     s [pos] = wgetch (stdscr);
  598.     switch (s[pos]) {
  599.     case '\n':
  600.     case '\r':
  601.       s [pos] = '\0';
  602.       done = 1;
  603.       break;
  604.     case '\b':
  605.     case DEL:
  606.       if (pos > 0) {
  607.     pos--;
  608.     s[pos] = '\0';
  609.     wmove (w, y, x + pos);
  610.     waddch (w, ' ');
  611.     wmove (w, y, x + pos);
  612.       }
  613.       break;
  614.     case CTL('U'):
  615.       wmove (w, y, x);
  616.       for (i=0; i < pos; i++) {
  617.     waddch (w, ' ');
  618.       }
  619.       wmove (w, y, x);
  620.       pos = 0;
  621.       s [pos] = '\0';
  622.       break;
  623.     case CTL('W'):
  624.       oldpos = pos;
  625.       while (pos != 0 && s[pos] == ' ') {
  626.     pos --;
  627.       }
  628.       if (pos) {
  629.     pos --;
  630.       }
  631.       while (pos != 0 && s[pos] != ' ') {
  632.     pos --;
  633.       }
  634.       wmove (w, y, x + pos);
  635.       while (oldpos != pos) {
  636.     oldpos--;
  637.     waddch (w, ' ');
  638.       }      
  639.       wmove (w, y, x + pos);
  640.       break;
  641.     default:
  642.       waddch (w, s [pos]);
  643.       pos++;
  644.       break;
  645.     }
  646.     wrefresh (w);
  647.   }
  648.  
  649.   if (pos == 0) {
  650.     return 0;
  651.   }
  652.   s [len-1] = '\0';
  653.   strcpy (rets, s); 
  654.   return 1;
  655. }
  656.  
  657. /* gets a number from window w; returns 1 if all OK; -1 otherwise */
  658. wget_number (w, num)
  659.      WINDOW * w;
  660.      int * num;
  661. {
  662.   char s [80];
  663.   int pos, done;
  664.   int x, y, i;
  665.   noecho ();
  666.  
  667.   if (w == NULL) {
  668.     w = stdscr;
  669.   }
  670.  
  671.   pos = 0;
  672.   done = 0;
  673.  
  674.   getyx (w, y, x);
  675.   wrefresh (w);
  676.  
  677.   while (!done) {
  678.     s [pos] = wgetch (stdscr);
  679.     switch (s[pos]) {
  680.     case '\n':
  681.     case '\r':
  682.       done = 1;
  683.       break;
  684.     case '\b':
  685.     case DEL:
  686.       if (pos > 0) {
  687.     pos--;
  688.     s[pos] = '\0';
  689.     wmove (w, y, x + pos);
  690.     waddch (w, ' ');
  691.     wmove (w, y, x + pos);
  692.       }
  693.       break;
  694.     case CTL('U'):
  695.       wmove (w, y, x);
  696.       for (i=0; i < pos; i++) {
  697.     waddch (w, ' ');
  698.       }
  699.       wmove (w, y, x);
  700.       pos = 0;
  701.       s [pos] = '\0';
  702.       break;
  703.     default:
  704.       waddch (w, s [pos]);
  705.       pos++;
  706.       break;
  707.     }
  708.     wrefresh (w);
  709.   }
  710.   if (pos == 0) {
  711.     return -1;
  712.   }
  713.   if ((sscanf(s, "%d", num)) < 1) {
  714.     return -1;
  715.   }
  716.   return 1;
  717. }
  718.  
  719. wget_name (w, name)
  720.      WINDOW * w;
  721.      char * name;
  722. {
  723.   char s[80];
  724.   int pos, done;
  725.   int x, y, i;
  726.   int oldpos;        /* Used for ^W */
  727.   noecho();
  728.  
  729.   if (w == NULL) {
  730.     w = stdscr;
  731.   }
  732.  
  733.   pos = 0;
  734.   done = 0;
  735.  
  736.   getyx (w, y, x);
  737.   wrefresh (w);
  738.  
  739.   while (!done) {
  740.     s [pos] = wgetch (stdscr);
  741.     switch (s[pos]) {
  742.     case '\n':
  743.     case '\r':
  744.       s [pos] = '\0';
  745.       done = 1;
  746.       break;
  747.     case '\b':
  748.     case DEL:
  749.       if (pos > 0) {
  750.     pos--;
  751.     s[pos] = '\0';
  752.     wmove (w, y, x + pos);
  753.     waddch (w, ' ');
  754.     wmove (w, y, x + pos);
  755.       }
  756.       break;
  757.     case CTL('U'):
  758.       wmove (w, y, x);
  759.       for (i=0; i < pos; i++) {
  760.     waddch (w, ' ');
  761.       }
  762.       wmove (w, y, x);
  763.       pos = 0;
  764.       s [pos] = '\0';
  765.       break;
  766.     case CTL('W'):
  767.       oldpos = pos;
  768.       while (pos != 0 && s[pos] == ' ') {
  769.     pos --;
  770.       }
  771.       if (pos) {
  772.     pos --;
  773.       }
  774.       while (pos != 0 && s[pos] != ' ') {
  775.     pos --;
  776.       }
  777.       wmove (w, y, x + pos);
  778.       while (oldpos != pos) {
  779.     oldpos--;
  780.     waddch (w, ' ');
  781.       }      
  782.       wmove (w, y, x + pos);
  783.       break;
  784.     default:
  785.       waddch (w, s [pos]);
  786.       pos++;
  787.       break;
  788.     }
  789.     wrefresh (w);
  790.   }
  791.  
  792.   if (pos == 0) {
  793.     return -1;
  794.   }
  795.   strcpy (name, s); 
  796.   return 1;
  797. }
  798.  
  799. #ifdef PMAX  /* Fix for the mvwprintw bug in pmax curses */
  800. #undef mvwprintw
  801. #include <varargs.h>
  802.  
  803. mymvwprintw(va_alist)
  804.      va_dcl
  805. {
  806.     va_list ap;
  807.     reg WINDOW    *win;
  808.     reg int        y, x;
  809.     char        *fmt;
  810.     char    buf[512];
  811.  
  812.     va_start(ap);
  813.     win = va_arg(ap, WINDOW *);
  814.     y = va_arg(ap, int);
  815.     x = va_arg(ap, int);
  816.     fmt = va_arg(ap, char *);
  817.     
  818.     if (wmove(win,y, x) != OK)
  819.       return ERR;
  820.     (void) vsprintf(buf, fmt, ap);
  821.     va_end(ap);
  822.     return waddstr(win, buf);
  823. }
  824. #endif /* PMAX */
  825.