]> granicus.if.org Git - nethack/commitdiff
add some unicode support (trunk only)
authornethack.allison <nethack.allison>
Tue, 17 Oct 2006 23:55:42 +0000 (23:55 +0000)
committernethack.allison <nethack.allison>
Tue, 17 Oct 2006 23:55:42 +0000 (23:55 +0000)
This patch attempts to add some levels of unicode support
to NetHack.

The master on/off switch for any Unicode support is
defining UNICODE_SUPPORT in config.h. Currently
there is code support for two subsets of unicode support:

UNICODE_DRAWING

If UNICODE_DRAWING is defined, then the data
structures used to house drawing symbols are expanded
to the size of wchar_t, big enough to hold unicode characters.
A typdef called `nhsym' is involved and if UNICODE_DRAWING
is defined, it is wchar_t, otherwise it is uchar.

UNICODE_WIDEWINPORT

If UNICODE_WIDEWINPORT is defined, then the data
structures inside the window port are expanded to the size of
wchar_t, big enough to hold unicode characters.  Both map
symbols and text within the window port are expanded, in order
for potential support for displaying multinational characters some
day, but this patch only provides viewing of map symbols.
A typdef called `nhwchar' is involved and if UNICODE_WIDEWINPORT
is defined, it is wchar_t, otherwise it is char.

The only window port with code support for UNICODE_WIDEWINPORT
currently is the TTY port.  Don't enable UNICODE_WIDEWINPORT
unless:
- it is a TTY port
- the underlying platform specific routines can
handle the larger data structures.

Don't enable UNICODE_SUPPORT unless:
- your compiler can handle wchar_t.
- your compiler can accept L'a' characters.
- your compiler can accept L"wide" strings.

Note that if your compiler can handle the above, you could
enable the larger data structures (currently if TTY) even if your
platform can't actually display unicode or UTF-8, by messing
with u_putch() in win/tty/wintty.c to only deal regular chars.
That should be the only function that actually pushes wide characters
out to the display.

If you enable UNICODE_SUPPORT, and your platform is capable
you will need to turn on the unicode run-time option to be able to
load unicode character sets from the symbol file, to be able to
push unicode characters to the display. You'll also want to load
a unicode symbol set once the unicode option is toggled on. In
a config file you would do that via these two lines:
OPTIONS=unicode
OPTIONS=symset:Unicode_non_US

The repository was stamped with NETHACK_PRE_UNICODE
prior to applying this patch, and stamped with
NETHACK_POST_UNICODE afterwards. The code differences
between those two tagged versions are this patch.

22 files changed:
dat/symbols
include/config.h
include/decl.h
include/extern.h
include/flag.h
include/global.h
include/ntconf.h
include/rm.h
include/tradstdc.h
include/wintty.h
src/decl.c
src/drawing.c
src/files.c
src/hacklib.c
src/mapglyph.c
src/options.c
src/pager.c
src/pline.c
sys/winnt/nttty.c
win/tty/getline.c
win/tty/topl.c
win/tty/wintty.c

index 108d761d128d4cb3b440d1dc282089d0df6f8ab4..8f396582bdf5784156c006d07727d3376bdb2077 100644 (file)
@@ -201,6 +201,10 @@ start: RogueEpyx
        S_food: \x05                    # club (as in cards)                    
        S_potion: \xad                  # upside down '!'
        S_scroll: \x0e                  # musical note
+#      S_armor: \x5b
+#      S_ring: \x3d
+#      S_amulet: \x0c
+#      S_tool: \x28
        S_wand: \xe7                    # greek tau
        S_coin: \x0f                    # yes it's the same as gems
        S_gem: \x0f                     # fancy '*'
@@ -393,3 +397,131 @@ start: NHAccess
        S_explode9: \047
 finish
 
+start: Unicode_US
+       Description: Unicode symbols similar to code page 437
+       Restrictions: Unicode
+       S_vwall:     U+2502             # box drawings light vertical
+       S_hwall:     U+2500             # box drawings light horizontal
+       S_tlcorn:    U+250C             # box drawings light down and right
+       S_trcorn:    U+2510             # box drawings light down and left
+       S_blcorn:    U+2514             # box drawings light up and right
+       S_brcorn:    U+2518             # box drawings light up and left
+       S_crwall:    U+253C             # box drawings light up and left
+       S_tuwall:    U+2534             # box drawings light up and horizontal
+       S_tdwall:    U+252C             # box drawings light down and horizontal
+       S_tlwall:    U+2524             # box drawings light vertical and left
+       S_trwall:    U+251C             # box drawings light vertical and right
+       S_ndoor:     U+2556             # box drawings down double and left single
+       S_vodoor:    U+25A0             # black square
+       S_hodoor:    U+25A0             # black square
+       S_bars:      U+2261             # identical to
+       S_tree:      U+00B1             # plus-minus sign
+       S_room:      U+00B7             # middle dot
+       S_corr:      U+2591             # light shade
+       S_litcorr:   U+2592             # medium shade
+       S_fountain:  U+2320             # top half integral 
+       S_pool:      U+2248             # almost equal to
+       S_ice:       U+00B7             # middle dot
+       S_lava:      U+2248             # almost equal to
+       S_vodbridge: U+00B7             # middle dot
+       S_hodbridge: U+00B7             # middle dot
+       S_water:     U+2248             # almost equal to
+       S_vbeam:     U+2502             # box drawings light vertical
+       S_hbeam:     U+2500             # box drawings light horizontal
+       S_sw_ml:     U+2502             # box drawings light vertical
+       S_sw_mr:     U+2502             # box drawings light vertical
+       S_explode4:  U+2502             # box drawings light vertical
+       S_explode6:  U+2502             # box drawings light vertical
+finish
+
+start: Unicode_non_US
+       Description: If default OEM CP for non-Unicode programs is not 437 or 850
+       Restrictions: Unicode
+       S_vwall:    U+2502              # box drawings light vertical
+       S_hwall:    U+2500              # box drawings light horizontal
+       S_tlcorn:   U+250C              # box drawings light down and right
+       S_trcorn:   U+2510              # box drawings light down and left
+       S_blcorn:   U+2514              # box drawings light up and right
+       S_brcorn:   U+2518              # box drawings light up and left
+       S_crwall:   U+253C              # box drawings light up and left
+       S_tuwall:   U+2534              # box drawings light up and horizontal
+       S_tdwall:   U+252C              # box drawings light down and horizontal
+       S_tlwall:   U+2524              # box drawings light vertical and left
+       S_trwall:   U+251C              # box drawings light vertical and right
+       S_vodoor:   U+25A0              # black square
+       S_hodoor:   U+25A0              # black square
+       S_corr:     U+2591              # light shade
+       S_litcorr:  U+2592              # medium shade
+       S_vbeam:    U+2502              # box drawings light vertical
+       S_hbeam:    U+2500              # box drawings light horizontal
+       S_sw_ml:    U+2502              # box drawings light vertical
+       S_sw_mr:    U+2502              # box drawings light vertical
+       S_explode4: U+2502              # box drawings light vertical
+       S_explode6: U+2502              # box drawings light vertical
+       S_coin:     U+20AC              # euro
+finish
+
+start: UnicodeRogueEpyx
+       Description: Unicode Rogue level symbols
+       Restrictions: Unicode
+       Restrictions: Rogue
+       Color: Yes
+       S_weapon:       U+2191          # up arrow
+       S_armor:        U+25d9          # Vert rect with o
+       S_ring:         U+2642          # circle with arrow
+       S_amulet:       U+2640          # "female" symbol
+       S_food:         U+2663          # club (as in cards)                    
+       S_potion:       U+00a1          # upside down '!'
+       S_scroll:       U+266a          # musical note
+       S_wand:         U+03c4          # greek tau
+       S_coin:         U+263c          # yes it's the same as gems
+       S_gem:          U+263c          # fancy '*'
+       S_rock:         U+0060          # grave accent
+       S_ball:         U+0030          # digit 0
+       S_chain:        U+005f          # low line
+       S_venom:        U+002e          # full stop
+       S_book:         U+002b          # + sign
+       S_vwall:        U+2551          # all walls now use
+       S_hwall:        U+2550          #   double line graphics
+       S_tlcorn:       U+2554          # box drawing double down and right 
+       S_trcorn:       U+2557          # box drawing double down and left 
+       S_blcorn:       U+255a          # box drawing double up and right 
+       S_brcorn:       U+255d          # box drawing double up and left 
+       S_crwall:       U+256c          # box drawing double vertical and horizontal 
+       S_tuwall:       U+2569          # box drawing double up and horizontal 
+       S_tdwall:       U+2566          # box drawing double down and horizontal 
+       S_tlwall:       U+2563          # box drawing double vertical and left 
+       S_trwall:       U+2560          # box drawing double vertical and right 
+       S_ndoor:        U+256c          # box drawing double vertical and horizontal 
+       S_vodoor:       U+256c          # box drawing double vertical and horizontal 
+       S_hodoor:       U+256c          # box drawing double vertical and horizontal 
+       S_room:         U+00b7          # centered dot 
+       S_corr:         U+2592          # medium shade
+       S_litcorr:      U+2593          # dark shade
+       S_upstair:      U+001e          # Greek Xi 
+       S_dnstair:      U+001f 
+       S_arrow_trap:   U+2666          # diamond (cards) 
+       S_dart_trap:    U+2666
+       S_falling_rock_trap: U+2666
+       S_squeaky_board: U+2666
+       S_bear_trap:    U+2666
+       S_land_mine:    U+2666
+       S_rolling_boulder_trap: U+2666
+       S_sleeping_gas_trap: U+2666
+       S_rust_trap:    U+2666
+       S_fire_trap:    U+2666 
+       S_pit:          U+2666
+       S_spiked_pit:   U+2666 
+       S_hole:         U+2666
+       S_trap_door:    U+2666
+       S_teleportation_trap: U+2666 
+       S_level_teleporter: U+2666
+       S_magic_portal: U+2666 
+       S_web:          U+2666 
+       S_statue_trap:  U+2666 
+       S_magic_trap:   U+2666
+       S_anti_magic_trap: U+2666 
+       S_polymorph_trap: U+2666
+       S_human:        U+263a          # face
+finish
+
index 8b54d1d677736fd36fe10cde98487ca975734f4f..8b63083e5e05de5373c293d2a8f93ddca0a70a27 100644 (file)
  */
 #endif /* CHDIR */
 
+/*
+ * Enable some UNICODE support.
+ */
+/*#define UNICODE_SUPPORT */           /* master on/off for any unicode support    */
 
 
 /*
@@ -356,7 +360,7 @@ typedef unsigned char       uchar;
  */
 
 /* display features */
-#define LOADSYMSETS    /* loadable symbol sets; only default symbols w/o this */
+#define LOADSYMSETS    /* loadable symbol sets; only default symbols w/o this  */
 /* dungeon features */
 #define SINKS          /* Kitchen sinks - Janet Walz */
 /* dungeon levels */
index 37a3489d60d33067786961dc99c8cbca94a25a59..c4b4db3ed3e4217534ee86384619a1f209578869 100644 (file)
@@ -35,7 +35,7 @@ E NEARDATA int nsubroom;
 E NEARDATA int occtime;
 
 #define WARNCOUNT 6                    /* number of different warning levels */
-E uchar warnsyms[WARNCOUNT];
+E nhsym warnsyms[WARNCOUNT];
 E NEARDATA int warn_obj_cnt;           /* count of monsters meeting criteria */
 
 E int x_maze_max, y_maze_max;
@@ -334,7 +334,8 @@ E NEARDATA winid WIN_MESSAGE;
 E NEARDATA winid WIN_STATUS;
 #endif
 E NEARDATA winid WIN_MAP, WIN_INVEN;
-E char toplines[];
+E nhwchar toplines[];
+
 #ifndef TCAP_H
 E struct tc_gbl_data { /* also declared in tcap.h */
     char *tc_AS, *tc_AE;       /* graphics start and end (tty font swapping) */
index 7ab7ffcdf4fdd97a4fd11fe5289d300b2568fa0b..f828e7841b79d0111e3a9f10521102698fbe77d3 100644 (file)
@@ -721,6 +721,7 @@ E void NDECL(read_wizkit);
 #ifdef LOADSYMSETS
 E int FDECL(read_sym_file, (int));
 E int FDECL(parse_sym_line, (char *,int));
+E int FDECL(sym_val, (const char *));
 #endif
 E void FDECL(paniclog, (const char *, const char *));
 E int FDECL(validate_prefix_locations, (char *));
@@ -829,6 +830,20 @@ E int NDECL(phase_of_the_moon);
 E boolean NDECL(friday_13th);
 E int NDECL(night);
 E int NDECL(midnight);
+#ifdef UNICODE_WIDEWINPORT
+E nhwchar *FDECL(nhwstrncpy, (nhwchar *,const char *,size_t));
+E nhwchar *FDECL(nhwncpy, (nhwchar *,const nhwchar *,size_t));
+E nhwchar *FDECL(nhwcpy, (nhwchar *,const nhwchar *));
+E nhwchar *FDECL(nhwstrcpy, (nhwchar *,const char *));
+E char *FDECL(strnhwcpy, (char *,const nhwchar *));
+E nhwchar *FDECL(nhwstrcat, (nhwchar *,const char *));
+E nhwchar *FDECL(nhwcat, (nhwchar *,const nhwchar *));
+E nhwchar *FDECL(nhwindex, (const nhwchar *,int));
+E size_t FDECL(nhwlen, (const nhwchar *));
+E int FDECL(nhwcmp, (const nhwchar *,const nhwchar *));
+E int FDECL(nhwncmp, (const nhwchar *,const nhwchar *,int));
+E int FDECL(nhwstrcmp, (const nhwchar *,const char *));
+#endif
 
 /* ### invent.c ### */
 
@@ -1544,7 +1559,6 @@ E void NDECL(free_autopickup_exceptions);
 E int FDECL(load_symset, (const char *,int));
 E void FDECL(parsesymbols, (char *));
 E struct symparse *FDECL(match_sym, (char *));
-E int FDECL(sym_val, (char *));
 #endif
 
 /* ### pager.c ### */
index a9fe3869c39c55ff0a26e9149cfeb04a135857f6..5878c443f196cc86d574ccfef780a1a356832495 100644 (file)
@@ -182,6 +182,8 @@ struct instance_flags {
        boolean  rlecomp;       /* run-length comp of levels when writing savefile */
        uchar    num_pad_mode;
        boolean  echo;          /* 1 to echo characters */
+       boolean  unicodecapable;        /* unicode support is possible on platform */
+       boolean  unicodedisp;   /* unicode support is turned on */
 #if 0
        boolean  DECgraphics;   /* use DEC VT-xxx extended character set */
        boolean  IBMgraphics;   /* use IBM extended character set */
index e761b5d60e32d6fd826fea436f3072341dbfc70f..cee74d9fb663146d5a1b14a1ec4616c9f1774328 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)global.h   3.5     2006/06/28      */
+/*     SCCS Id: @(#)global.h   3.5     2006/10/17      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -61,6 +61,41 @@ typedef xchar        boolean;                /* 0 or 1 */
 #define FALSE  ((boolean)0)
 #endif
 
+/*
+ * UNICODE_SUPPORT
+ * Unicode/wide character related support.
+ */
+#ifdef UNICODE_SUPPORT
+# define UNICODE_DRAWING       /* store drawing symbols in wchar_t data type     */
+# define UNICODE_WIDEWINPORT   /* store and render wide chars in window port     */
+/*# define UNICODE_PLAYERTEXT*/        /* not implemented - player input in wide chars */
+#else
+# undef UNICODE_DRAWING
+# undef UNICODE_WIDEWINPORT
+# undef UNICODE_PLAYERTEXT     
+#endif
+
+#if defined(UNICODE_DRAWING)
+typedef wchar_t nhsym;         /* nhsym is wide char */
+#else
+typedef char nhsym;
+#endif
+
+#if defined(UNICODE_WIDEWINPORT)
+typedef wchar_t nhwchar;       /* nhwchar (window port char) is wide char */
+#else
+typedef char nhwchar;
+#endif
+
+#if 0
+/* Not Implemented presently */
+#if defined(UNICODE_PLAYERTEXT)
+typedef wchar_t nhptext;       /* player input is wide char */
+#else
+typedef char nhptext;
+#endif
+#endif
+
 #ifndef STRNCMPI
 # ifndef __SASC_60             /* SAS/C already shifts to stricmp */
 #  define strcmpi(a,b) strncmpi((a),(b),-1)
index 8323af5970f6bd390f0763bf9769f17b543be837..39c2d4c368ccd55f652d0eea55aa5e8999fdd678 100644 (file)
@@ -187,6 +187,11 @@ extern void NDECL(toggle_mouse_support);
 extern void FDECL(map_subkeyvalue, (char *));
 extern void NDECL(load_keyboard_handler);
 extern void NDECL(raw_clear_screen);
+# ifdef UNICODE_WIDEWINPORT
+extern void FDECL(xputc, (NHWCHAR_P));
+# else
+extern void FDECL(xputc, (int));
+# endif
 #endif
 
 #include <fcntl.h>
index 8c840693e42a10bed04787e9a7f8ca24c91071a0..312ff1929d6daed820d8cd6753cf0c797489e544 100644 (file)
@@ -223,6 +223,13 @@ struct symdef {
 #endif
 };
 
+/*
+ * Graphics sets for display symbols
+ */
+#define PRIMARY                0       /* primary graphics         */
+#define ROGUESET       1       /* rogue graphics           */
+#define NUM_GRAPHICS   2
+
 struct symparse {
        unsigned range;
 #define SYM_CONTROL    1       /* start/finish markers */
@@ -249,30 +256,23 @@ struct symsetentry {
        Bitfield(nocolor,1);         /* don't use color if set               */
        Bitfield(primary,1);         /* restricted for use as primary set    */
        Bitfield(rogue,1);           /* restricted for use as rogue lev set  */
+       Bitfield(unicode,1);         /* restricted for use as a unicode set  */
        /* 5 free bits */
 };
 
-/*
- * Graphics sets for display symbols
- */
-#define DEFAULT_GRAPHICS 0     /* regular characters: '-', '+', &c */
-#define PRIMARY                0       /* primary graphics set        */
-#define ROGUESET       1       /* rogue graphics set          */
-#define NUM_GRAPHICS   2
-
 /*
  * special symbol set handling types ( for invoking callbacks, etc.)
  * Must match the order of the known_handlers strings
  * in drawing.c
  */
-#define H_UNK  0
-#define H_IBM  1
-#define H_DEC  2
+#define H_UNK          0
+#define H_IBM          1
+#define H_DEC          2
 
 extern const struct symdef defsyms[MAXPCHARS]; /* defaults */
 extern const struct symdef def_warnsyms[WARNCOUNT];
 extern int currentgraphics;                              /* from drawing.c */
-extern uchar showsyms[];
+extern nhsym showsyms[];
 
 #ifdef LOADSYMSETS
 extern struct symsetentry symset[NUM_GRAPHICS];                  /* from drawing.c */
index ccd4e7d6764a17ee6121a944dd5cee5b8e4d53f8..02a75bc39361ef55310852b52dde3047f2bf54fc 100644 (file)
@@ -254,6 +254,7 @@ typedef genericptr genericptr_t;    /* (void *) or (char *) */
 #  define BOOLEAN_P boolean
 # endif
 # define ALIGNTYP_P aligntyp
+# define NHWCHAR_P nhwchar
 #else
 # ifdef WIDENED_PROTOTYPES
 #  define CHAR_P int
@@ -263,6 +264,7 @@ typedef genericptr genericptr_t;    /* (void *) or (char *) */
 #  define SHORT_P int
 #  define BOOLEAN_P int
 #  define ALIGNTYP_P int
+#  define NHWCHAR_P int
 # else
    /* Neither widened nor unwidened prototypes.  Argument list expansion
     * by FDECL/VDECL always empty; all xxx_P vanish so defs aren't needed. */
index fc993aa3c0979d4d3534415e92f1a1c1a0c02979..51b491086c74fb0b3d23055263eba6979d18629b 100644 (file)
@@ -34,8 +34,8 @@ struct WinDesc {
                                /* maxcol is also used by WIN_MESSAGE for */
                                /* tracking the ^P command */
     short *datlen;             /* allocation size for *data */
-    char **data;               /* window data [row][column] */
-    char *morestr;             /* string to display instead of default */
+    nhwchar **data;            /* window data [row][column] */
+    nhwchar *morestr;          /* string to display instead of default */
     tty_menu_item *mlist;      /* menu information (MENU) */
     tty_menu_item **plist;     /* menu page pointers (MENU) */
     short plist_size;          /* size of allocated plist (MENU) */
@@ -86,7 +86,7 @@ extern struct WinDesc *wins[MAXWIN];
 extern struct DisplayDesc *ttyDisplay; /* the tty display descriptor */
 
 extern char morc;              /* last character typed to xwaitforspace */
-extern char defmorestr[];      /* default --more-- prompt */
+extern nhwchar defmorestr[];   /* default --more-- prompt */
 
 /* port specific external function references */
 
@@ -107,7 +107,9 @@ E void NDECL(tty_shutdown);
  * actually would be expanded. So here, we have to make an exception. */
 E void FDECL(xputc, (int));
 #else
+# ifndef WIN32CON
 E void FDECL(xputc, (CHAR_P));
+# endif
 #endif
 E void FDECL(xputs, (const char *));
 #if defined(SCREEN_VGA) || defined(SCREEN_8514)
@@ -150,10 +152,10 @@ E int FDECL(has_color,(int color));
 
 /* ### topl.c ### */
 
-E void FDECL(addtopl, (const char *));
+E void FDECL(addtopl, (const nhwchar *));
 E void NDECL(more);
-E void FDECL(update_topl, (const char *));
-E void FDECL(putsyms, (const char*));
+E void FDECL(update_topl, (const nhwchar *));
+E void FDECL(putsyms, (const nhwchar *));
 
 /* ### wintty.c ### */
 #ifdef CLIPPING
@@ -163,6 +165,9 @@ E void FDECL(docorner, (int, int));
 E void NDECL(end_glyphout);
 E void FDECL(g_putch, (int));
 E void NDECL(win_tty_init);
+#ifdef UNICODE_WIDEWINPORT
+E void FDECL(u_putch, (nhwchar));
+#endif
 
 /* external declarations */
 E void FDECL(tty_init_nhwindows, (int *, char **));
index cba20bfc73d7244a2167df6773f6a8cf587094e3..27524c5299b769e2adc59cbf2aa847bb3cb84413 100644 (file)
@@ -261,7 +261,8 @@ NEARDATA winid WIN_MESSAGE = WIN_ERR;
 NEARDATA winid WIN_STATUS = WIN_ERR;
 #endif
 NEARDATA winid WIN_MAP = WIN_ERR, WIN_INVEN = WIN_ERR;
-char toplines[TBUFSZ];
+nhwchar toplines[TBUFSZ];
+
 /* Windowing stuff that's really tty oriented, but present for all ports */
 struct tc_gbl_data tc_gbl_data = { 0,0, 0,0 }; /* AS,AE, LI,CO */
 
index 11d569ad9fcf368c64d31b2052f9c3e5fed1dbe3..161c858f0ce0ac39e04aa1490534f3eee5c619a1 100644 (file)
@@ -23,13 +23,13 @@ struct symsetentry symset[NUM_GRAPHICS];
 
 int currentgraphics = 0;
 
-uchar showsyms[SYM_MAX] = DUMMY;               /* symbols to be displayed */
-uchar l_syms[SYM_MAX] = DUMMY;         /* loaded symbols          */
+nhsym showsyms[SYM_MAX] = DUMMY;       /* symbols to be displayed */
+nhsym l_syms[SYM_MAX]   = DUMMY;       /* loaded symbols          */
 #ifdef REINCARNATION
-uchar r_syms[SYM_MAX] = DUMMY;         /* rogue symbols           */
+nhsym r_syms[SYM_MAX]   = DUMMY;       /* rogue symbols           */
 #endif
 
-uchar warnsyms[WARNCOUNT]  = DUMMY;  /* the current warning display symbols */
+nhsym warnsyms[WARNCOUNT]  = DUMMY;  /* the current warning display symbols */
 const char invisexplain[] = "remembered, unseen, creature";
 
 /* Default object class symbols.  See objclass.h.
@@ -546,6 +546,7 @@ boolean name_too;
        /* initialize restriction bits */
        symset[which_set].primary = 0;
        symset[which_set].rogue   = 0;
+       symset[which_set].unicode = 0;
 
        if (name_too) {
            if (symset[which_set].name)
@@ -583,6 +584,7 @@ const char *known_handling[] = {
 const char *known_restrictions[] = {
        "primary",
        "rogue",
+       "unicode",
        (const char *)0,
 };
 
index 6dedcfed75be0947acc7b5413ec23aa63cfb87a2..1dffde979f8d94899b7d2e08d139e8e9b75a6228 100644 (file)
@@ -2531,6 +2531,7 @@ int which_set;
                return 0;
 
        if (!symset[which_set].name) {
+           int i;
            /* A null symset name indicates that we're just
               building a pick-list of possible symset
               values from the file, so only do that */
@@ -2556,6 +2557,20 @@ int which_set;
                    /* initialize restriction bits */
                    tmpsp->primary = 0;
                    tmpsp->rogue   = 0;
+                   tmpsp->unicode = 0;
+                   break;
+                case 2:
+                   /* handler type identified */
+                   tmpsp = symset_list; /* most recent symset */
+                   tmpsp->handling = H_UNK;
+                   i = 0;
+                   while (known_handling[i]) {
+                       if (!strcmpi(known_handling[i], bufp)) {
+                               tmpsp->handling = i;
+                               break;  /* while loop */
+                       }
+                       i++;
+                   }
                    break;
                 case 3: /* description:something */
                    tmpsp = symset_list; /* most recent symset */
@@ -2573,6 +2588,7 @@ int which_set;
                            switch(i) {
                                case  0: tmpsp->primary = 1; break;
                                case  1: tmpsp->rogue   = 1; break;
+                               case  2: tmpsp->unicode = 1; break;
                            }
                            break;      /* while loop */
                        }
@@ -2594,6 +2610,7 @@ int which_set;
                                /* these init_*() functions clear symset fields too */
 # ifdef REINCARNATION
                                if (which_set == ROGUESET) init_r_symbols();
+                               else
 # endif
                                if (which_set == PRIMARY)  init_l_symbols();
                            }
@@ -2639,18 +2656,32 @@ int which_set;
                                    }
                                    i++;
                                }
-                           }
+                               /* Don't allow unicode set if code can't handle it */
+                               if (symset[which_set].unicode &&
+                                               !iflags.unicodedisp) {
+                                   if (chosen_symset_start)
+                                       chosen_symset_end = FALSE;
+                                   chosen_symset_start = FALSE;
+# ifdef REINCARNATION
+                                   if (which_set == ROGUESET) init_r_symbols();
+                                   else
+# endif
+                                   if (which_set == PRIMARY)  init_l_symbols();
+                               }
+                           }
                            break;
                }
            } else {            /* !SYM_CONTROL */
                val = sym_val(bufp);
                if (chosen_symset_start) {
+                       if (which_set == PRIMARY) {
+                               update_l_symset(symp, val);
+                       }
 # ifdef REINCARNATION
-                       if (which_set == ROGUESET)
-                           update_r_symset(symp, val);
-                       else
+                       else if (which_set == ROGUESET) {
+                               update_r_symset(symp, val);
+                       }
 # endif
-                           update_l_symset(symp, val);
                }
            }
        }
@@ -2673,6 +2704,72 @@ int which_set;
            i++;
        }
 }
+
+/*
+ *  Produces a single integer value.
+ */
+int
+sym_val(cp)
+const char *cp;
+{
+    unsigned int cval = 0;
+    int        meta = 0, dcount = 0;
+    const char *dp, *hex = "00112233445566778899aAbBcCdDeEfF";
+
+    while (*cp)
+    {
+       if (*cp == '\\' && index("mM", cp[1])) {
+               meta = 1;
+               cp += 2;
+       }
+       if ((*cp == 'U' || *cp == 'u') && cp[1] == '+' && index(hex, cp[2]))
+       {
+           dcount = 0;
+           cp++;
+           for (++cp; *cp && (dp = index(hex, *cp)) && (dcount++ < 4); cp++)
+               cval = (unsigned int)((cval * 16) +
+                       ((unsigned int)(dp - hex) / 2));
+       }
+       else if (*cp == '\\' && index("0123456789xXoO", cp[1]))
+       {
+           dcount = 0;
+           cp++;
+           if (*cp == 'x' || *cp == 'X')
+               for (++cp; *cp && (dp = index(hex, *cp)) && (dcount++ < 4); cp++)
+                   cval = (unsigned int)((cval * 16) +
+                           ((unsigned int)(dp - hex) / 2));
+           else if (*cp == 'o' || *cp == 'O')
+               for (++cp; *cp && (index("01234567",*cp)) && (dcount++ < 5); cp++)
+                   cval = (cval * 8) + (unsigned int)(*cp - '0');
+           else
+               for (; *cp && (index("0123456789",*cp)) && (dcount++ < 5); cp++)
+                   cval = (cval * 10) + (unsigned int)(*cp - '0');
+       }
+       else if (*cp == '\\')           /* C-style character escapes */
+       {
+           switch (*++cp)
+           {
+           case '\\': cval = '\\'; break;
+           case 'n': cval = '\n'; break;
+           case 't': cval = '\t'; break;
+           case 'b': cval = '\b'; break;
+           case 'r': cval = '\r'; break;
+           default: cval = (unsigned int)*cp;
+           }
+           cp++;
+       }
+       else if (*cp == '^')            /* expand control-character syntax */
+       {
+           cval = (unsigned int)(*++cp & 0x1f);
+           cp++;
+       }
+       else
+           cval = (unsigned int)*cp++;
+       if (meta)
+           cval |= 0x80;
+    }
+    return cval;
+}
 #endif /*LOADSYMSETS*/
 
 /* ----------  END CONFIG FILE HANDLING ----------- */
index 6b599822f84ef8c160554d5ae4710d0f11016864..9fd49d71046c6de571addce45dc2229b128f6232 100644 (file)
@@ -624,4 +624,192 @@ midnight()
        return(getlt()->tm_hour == 0);
 }
 
+#ifdef UNICODE_WIDEWINPORT
+nhwchar *
+nhwstrncpy(dest, strSource, cnt)
+nhwchar *dest;
+const char *strSource;
+size_t cnt;
+{
+       nhwchar *d = dest;
+       const char *s = strSource;
+       size_t dcnt = 0;
+
+       while(*s && dcnt < cnt) {
+           *d++ = (nhwchar)*s++;
+           dcnt++;
+       }
+       if (dcnt < cnt) *d = 0;
+       return dest;
+}
+
+nhwchar *
+nhwncpy(dest, src, cnt)
+nhwchar *dest;
+const nhwchar *src;
+size_t cnt;
+{
+       nhwchar *d = dest;
+       const nhwchar *s = src;
+       size_t dcnt = 0;
+
+       while(*s && dcnt < cnt) {
+           *d++ = *s++;
+           dcnt++;
+       }
+       if (dcnt < cnt) *d = 0;
+       return dest;
+}
+
+nhwchar *
+nhwcpy(dest, src)
+nhwchar *dest;
+const nhwchar *src;
+{
+       nhwchar *d = dest;
+       const nhwchar *s = src;
+
+       while(*s) {
+           *d++ = *s++;
+       }
+       *d = 0;
+       return dest;
+}
+
+nhwchar *
+nhwstrcpy(dest, strSource)
+nhwchar *dest;
+const char *strSource;
+{
+       nhwchar *d = dest;
+       const char *s = strSource;
+
+       while(*s) {
+           *d++ = *s++;
+       }
+       *d = 0;
+       return dest;
+}
+
+char *
+strnhwcpy(strDest, src)
+char *strDest;
+const nhwchar *src;
+{
+       char *d = strDest;
+       const nhwchar *s = src;
+
+       while(*s) {
+           *d++ = (char)*s++;
+       }
+       *d = 0;
+       return strDest;
+}
+
+nhwchar *
+nhwstrcat(dest, strSource)
+nhwchar *dest;
+const char *strSource;
+{
+       nhwchar *d = dest;
+       const char *s = strSource;
+
+       while(*d) d++;
+       while(*s) {
+           *d++ = *s++;
+       }
+       *d = 0;
+       return dest;
+}
+
+nhwchar *
+nhwcat(dest, src)
+nhwchar *dest;
+const nhwchar *src;
+{
+       nhwchar *d = dest;
+       const nhwchar *s = src;
+
+       while(*d) d++;
+       while(*s) {
+           *d++ = *s++;
+       }
+       *d = 0;
+       return dest;
+}
+
+nhwchar *
+nhwindex(ss, c)
+const nhwchar *ss;
+int c;
+{
+       const nhwchar *s = ss;
+
+       while (*s) {
+           if (*s == c) return (nhwchar *)s;
+           s++;
+       }
+       if (*s == c) return (nhwchar *)s;
+       return (nhwchar *)0;
+}
+
+size_t nhwlen(src)
+const nhwchar *src;
+{
+       register size_t dl = 0;
+
+       while(*src++) dl++;
+       return dl;
+}
+
+int
+nhwcmp(s1, s2) /* case insensitive counted string comparison */
+register const nhwchar *s1, *s2;
+{                                      /*{ aka strncasecmp }*/
+    register nhwchar t1, t2;
+
+    for (;;) {
+       if (!*s2) return (*s1 != 0);    /* s1 >= s2 */
+       else if (!*s1) return -1;       /* s1  < s2 */
+       t1 = *s1++;
+       t2 = *s2++;
+       if (t1 != t2) return (t1 > t2) ? 1 : -1;
+    }
+    return 0;                          /* s1 == s2 */
+}
+
+int
+nhwncmp(s1, s2, n)     /* case sensitive counted nhwchar (wide string) comparison */
+    register const nhwchar *s1, *s2;
+    register int n; /*(should probably be size_t, which is usually unsigned)*/
+{
+    register nhwchar t1, t2;
+
+    while (n--) {
+       if (!*s2) return (*s1 != 0);    /* s1 >= s2 */
+       else if (!*s1) return -1;       /* s1  < s2 */
+       t1 = *s1++;
+       t2 = *s2++;
+       if (t1 != t2) return (t1 > t2) ? 1 : -1;
+    }
+    return 0;                          /* s1 == s2 */
+}
+
+int
+nhwstrcmp(s1, s2)
+register const nhwchar *s1;
+const char *s2;
+{                                      /*{ aka strncasecmp }*/
+    register nhwchar t1, t2;
+
+    for (;;) {
+       if (!*s2) return (*s1 != 0);    /* s1 >= s2 */
+       else if (!*s1) return -1;       /* s1  < s2 */
+       t1 = *s1++;
+       t2 = (nhwchar)*s2++;
+       if (t1 != t2) return (t1 > t2) ? 1 : -1;
+    }
+    return 0;                          /* s1 == s2 */
+}
+#endif
 /*hacklib.c*/
index a21c81926193a07d4b8d8bf39c7e63e17efb88bd..3ceb1c404a9ecd8ed2e76b0bc6b98ed708bad864 100644 (file)
@@ -67,7 +67,7 @@ unsigned *ospecial;
 #if defined(TEXTCOLOR) || defined(ROGUE_COLOR)
        int color = NO_COLOR;
 #endif
-       uchar ch;
+       nhsym ch;
        unsigned special = 0;
        /* condense multiple tests in macro version down to single */
        boolean has_rogue_ibm_graphics = HAS_ROGUE_IBM_GRAPHICS;
@@ -263,6 +263,7 @@ int glyph;
        return encbuf;
 }
 
+#ifndef UNICODE_WIDEWINPORT
 /*
  * This differs from putstr() because the str parameter can
  * contain a sequence of characters representing:
@@ -304,25 +305,12 @@ genl_putmixed(window, attr, str)
                            gv = (int)((gv * 16) + ((int)(dp - hex) / 2));
                        so = mapglyph(gv, &ch, &oc, &os, 0, 0);
                        *put++ = showsyms[so];
+                       continue;
                    } else {
                        /* possible forgery - leave it the way it is */
                        cp = save_cp;
                    }
                    break;
-# if 0
-               case 'S':       /* symbol offset */
-                   dcount = 0;
-                   for (++cp; *cp && (dp = index(hex, *cp)) && (dcount++ < 4); cp++)
-                       rndchk = (int)((rndchk * 16) + ((int)(dp - hex) / 2));
-
-                   if (rndchk == context.rndencode) {
-                       dcount = 0;
-                       for (; *cp && (dp = index(hex, *cp)) && (dcount++ < 2); cp++)
-                           so = (int)((so * 16) + ((int)(dp - hex) / 2));
-                   }
-                   *put++ = showsyms[so];
-                   break;
-# endif
                case '\\':
                    break;
                }
@@ -333,4 +321,5 @@ genl_putmixed(window, attr, str)
        /* now send it to the normal putstr */
        putstr(window, attr, buf);
 }
+#endif /*!UNICODE_WIDEWINPORT*/
 /*mapglyph.c*/
index a09489339b70995e7fa6fa7e4edbc872dbba42c0..59f38665eb1ab1105cb43618384e6cd35c4584b0 100644 (file)
@@ -195,6 +195,9 @@ static struct Bool_Opt
        {"tombstone",&flags.tombstone, TRUE, SET_IN_GAME},
        {"toptenwin",&flags.toptenwin, FALSE, SET_IN_GAME},
        {"travel", &flags.travelcmd, TRUE, SET_IN_GAME},
+#ifdef UNICODE_SUPPORT
+       {"unicode", &iflags.unicodedisp, FALSE, SET_IN_GAME},
+#endif
 #ifdef WIN32CON
        {"use_inverse",   &iflags.wc_inverse, TRUE, SET_IN_GAME},               /*WC*/
 #else
@@ -347,7 +350,7 @@ static struct Comp_Opt
                                 DISP_IN_GAME},
 # endif
 #else
-                                SET_IN_FILE },
+                                SET_IN_FILE},
 #endif
        { "suppress_alert", "suppress alerts about version-specific features",
                                                8, SET_IN_GAME },
@@ -582,6 +585,9 @@ initoptions()
        iflags.msg_history = 20;
 #ifdef TTY_GRAPHICS
        iflags.prevmsg_window = 's';
+#  if defined(UNIX) && defined(UNICODE_WIDEWINPORT)
+       iflags.unicodecapable = TRUE;
+#  endif
 #endif
        iflags.menu_headings = ATR_INVERSE;
 
@@ -2326,7 +2332,7 @@ goodfruit:
 # ifdef LOADSYMSETS
                if (duplicate) complain_about_duplicate(opts,1);
                if (!negated) {
-                   for (i = 0; i < NUM_GRAPHICS; ++i) { 
+                   for (i = PRIMARY; i <= ROGUESET; ++i) { 
                        if (symset[i].name)
                            badflag = TRUE;
                        else {
@@ -3154,25 +3160,31 @@ boolean setinitial,setfromfile;
                if (pick_cnt >= 0) goto ape_again;
        }
 #endif /* AUTOPICKUP_EXCEPTIONS */
-    } else if (!strcmp("symset", optname) ||
-              !strcmp("roguesymset", optname)) {
+    } else if (!strcmp("symset", optname)
+           || !strcmp("roguesymset", optname)) {
        menu_item *symset_pick = (menu_item *)0;
        boolean primaryflag = (*optname == 's'),
-               rogueflag = (*optname == 'r');
+                 rogueflag = (*optname == 'r'),
+               ready_to_switch = FALSE,
+               nothing_to_do = FALSE;
 #ifdef LOADSYMSETS
        int res;
        char *symset_name, fmtstr[20];
        struct symsetentry *sl;
        int setcount = 0;
 #endif
-       int chosen = -2, which_set =
+       int chosen = -2, which_set;
 #ifdef REINCARNATION
-                                       rogueflag ? ROGUESET :
+       if (rogueflag) which_set = ROGUESET;
+       else
 #endif
-                                       PRIMARY;
+       which_set = PRIMARY;
+
 #ifndef REINCARNATION
        if (rogueflag) return TRUE;
 #endif
+
 #ifdef LOADSYMSETS
        /* clear symset[].name as a flag to read_sym_file() to build list */
        symset_name = symset[which_set].name;
@@ -3186,7 +3198,8 @@ boolean setinitial,setfromfile;
                sl = symset_list;
                while (sl) {
                    /* check restrictions */
-                   if ((!rogueflag && sl->rogue)  ||
+                   if ((!rogueflag && sl->rogue)     ||
+                       (!iflags.unicodedisp && sl->unicode) ||
                        (!primaryflag && sl->primary)) {
                        sl = sl->next;
                        continue;
@@ -3199,8 +3212,8 @@ boolean setinitial,setfromfile;
                }
                if (!setcount) {
                        pline("There are no appropriate %ssymbol sets available.",
-                               (rogueflag)   ? "rogue level " :
-                               (primaryflag) ? "primary " :
+                                 (rogueflag) ? "rogue level " :
+                               (primaryflag) ? "primary "     :
                                "");
                        return TRUE;
                }
@@ -3216,6 +3229,7 @@ boolean setinitial,setfromfile;
                while (sl) {
                    /* check restrictions */
                    if ((!rogueflag && sl->rogue) ||
+                       (!iflags.unicodedisp && sl->unicode) ||
                        (!primaryflag && sl->primary)) {
                        sl = sl->next;
                        continue;
@@ -3226,10 +3240,10 @@ boolean setinitial,setfromfile;
                                sl->desc ? sl->desc : "");
                        add_menu(tmpwin, NO_GLYPH, &any, let, 0,
                         ATR_NONE, symsetchoice, MENU_UNSELECTED);
-                       sl = sl->next;
                        if (let == 'z') let = 'A';
                        else let++;
                    }
+                   sl = sl->next;
                }
                end_menu(tmpwin, "Select symbol set:");
                if (select_menu(tmpwin, PICK_ONE, &symset_pick) > 0) {
@@ -3254,7 +3268,7 @@ boolean setinitial,setfromfile;
                            symset[which_set].name =
                                        (char *)alloc(strlen(sl->name)+1);
                            Strcpy(symset[which_set].name, sl->name);
-
+                           ready_to_switch = TRUE;
                            break;
                        }
                        sl = sl->next;
@@ -3268,6 +3282,7 @@ boolean setinitial,setfromfile;
                        symset_name = (char *)0;
                        clear_symsetentry(which_set, TRUE);
                }
+               else nothing_to_do = TRUE;
        } else if (!res) {
                /* The symbols file could not be accessed */
                pline("Unable to access \"%s\" file.", SYMBOLS);
@@ -3292,34 +3307,41 @@ boolean setinitial,setfromfile;
                free((genericptr_t)sl);
        }
 
+       if (nothing_to_do) return TRUE;
+
+       if (!symset[which_set].name && symset_name)
+           symset[which_set].name = symset_name;
+
        /* Set default symbols and clear the handling value */
 # ifdef REINCARNATION
-       if(rogueflag) init_r_symbols();
+       if(rogueflag)
+           init_r_symbols();
        else
 # endif
-           init_l_symbols();
-
-       if (!symset[which_set].name && symset_name)
-               symset[which_set].name = symset_name;
+       init_l_symbols();
 
        if (symset[which_set].name) {
            if (read_sym_file(which_set))
-               switch_symbols(TRUE);
+               ready_to_switch = TRUE;
            else {
                clear_symsetentry(which_set, TRUE);
                return TRUE;
            }
        }
-       
-       switch_symbols(TRUE);
+
+       if (ready_to_switch) switch_symbols(TRUE);
+
 # ifdef REINCARNATION
-       if (Is_rogue_level(&u.uz))
-               assign_graphics(ROGUESET);
-       else
+       if (Is_rogue_level(&u.uz)) {
+               if (rogueflag)
+                   assign_graphics(ROGUESET);
+       } else
 # endif
-               assign_graphics(PRIMARY);
+       if (!rogueflag) assign_graphics(PRIMARY);
        need_redraw = TRUE;
 #endif /*LOADSYMSETS*/
+       return TRUE;
+
     } else {
        /* didn't match any of the special options */
        return FALSE;
@@ -3366,7 +3388,11 @@ char *buf;
 #endif
 #ifdef BACKWARD_COMPAT
        else if (!strcmp(optname, "boulder"))
+# ifdef UNICODE_DRAWING
+               Sprintf(buf, "\\x%04X", iflags.bouldersym ?
+# else
                Sprintf(buf, "%c", iflags.bouldersym ?
+# endif
                        iflags.bouldersym :
                        showsyms[(int)objects[BOULDER].oc_class + SYM_OFF_O]);
 #endif
@@ -3519,14 +3545,17 @@ char *buf;
        else if (!strcmp(optname, "race"))
                Sprintf(buf, "%s", rolestring(flags.initrace, races, noun));
 #ifdef REINCARNATION
-       else if (!strcmp(optname, "roguesymset"))
+       else if (!strcmp(optname, "roguesymset")) {
                Sprintf(buf, "%s",
 # ifdef LOADSYMSETS
                        symset[ROGUESET].name ?
                        symset[ROGUESET].name :
 # endif
                        "default");
+               if (currentgraphics == ROGUESET && symset[ROGUESET].name)
+                       Strcat(buf, ", active");
 #endif
+       }
        else if (!strcmp(optname, "role"))
                Sprintf(buf, "%s", rolestring(flags.initrole, roles, name.m));
        else if (!strcmp(optname, "runmode"))
@@ -3558,13 +3587,16 @@ char *buf;
                        FEATURE_NOTICE_VER_MIN,
                        FEATURE_NOTICE_VER_PATCH);
        }
-       else if (!strcmp(optname, "symset"))
+       else if (!strcmp(optname, "symset")) {
                Sprintf(buf, "%s",
 #ifdef LOADSYMSETS
                        symset[PRIMARY].name ?
                        symset[PRIMARY].name :
 #endif
                        "default");
+               if (currentgraphics == PRIMARY && symset[PRIMARY].name)
+                       Strcat(buf, ", active");
+       }
        else if (!strcmp(optname, "tile_file"))
                Sprintf(buf, "%s", iflags.wc_tile_file ? iflags.wc_tile_file : defopt);
        else if (!strcmp(optname, "tile_height")) {
@@ -3818,15 +3850,6 @@ char *buf;
        }
        return (struct symparse *)0;
 }
-
-int sym_val(strval)
-char *strval;
-{
-       char buf[QBUFSZ];
-       buf[0] = '\0';
-       escapes(strval, buf);
-       return (int)*buf;
-}
 #endif /*LOADSYMSETS*/
 
 /* data for option_help() */
index 138c254e8ca2c4e7f38972c8e0d94d48f2aec024..430167a7fd0e3005c880638e009092ac99394468 100644 (file)
@@ -581,7 +581,7 @@ do_look(mode, click_cc)
        for (i = 0; i < MAXMCLASSES; i++) {
            if (sym == ((from_screen || clicklook) ?
                        showsyms[i + SYM_OFF_M] : def_monsyms[i].sym) &&
-               def_monsyms[i].explain) {
+                       def_monsyms[i].explain) {
                need_to_look = TRUE;
                if (!found) {
                    Sprintf(out_str, "%s        %s",
index 313d07bd6fd7b53d74c7b7e33f9178212223d68f..3fb5f4d3970fdafff67242f6eb092ff0399d21f2 100644 (file)
@@ -58,7 +58,11 @@ pline VA_DECL(const char *, line)
            return;
        }
 #ifndef MAC
-       if (no_repeat && !strcmp(line, toplines))
+# ifdef UNICODE_WIDEWINPORT
+       if (no_repeat && !nhwstrcmp(toplines, line))
+# else
+       if (no_repeat && !strcmp(toplines, line))
+# endif
            return;
 #endif /* MAC */
        if (vision_full_recalc) vision_recalc(0);
index 1c641c1f82683a2b955dabbe97f5dfe4aebe54be..412d37747f47a91fff38898f48638a0fbcfec8df 100644 (file)
@@ -1,4 +1,4 @@
- /*    SCCS Id: @(#)nttty.c    3.5     $Date$   */
+/*     SCCS Id: @(#)nttty.c    3.5     $Date$   */
 /* Copyright (c) NetHack PC Development Team 1993    */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -61,9 +61,6 @@ int GUILaunched;
 extern int redirect_stdout;
 static BOOL FDECL(CtrlHandler, (DWORD));
 
-/* Flag for whether unicode is supported */
-static boolean has_unicode;
-
 #ifdef PORT_DEBUG
 static boolean display_cursor_info = FALSE;
 #endif
@@ -146,6 +143,12 @@ static void NDECL(init_ttycolor);
 # endif
 static void NDECL(really_move_cursor);
 
+#ifdef UNICODE_WIDEWINPORT
+void FDECL(xputc_core,(NHWCHAR_P));
+#else
+void FDECL(xputc_core,(int));
+#endif
+
 #define MAX_OVERRIDES  256
 unsigned char key_overrides[MAX_OVERRIDES];
 
@@ -193,11 +196,14 @@ const char *s;
 void
 setftty()
 {
+       static int cp = 0;
+       if (!cp) cp = GetConsoleOutputCP();
+       /* SetConsoleOutputCP(1250); */
 #ifdef CHANGE_COLOR
        if (altered_palette) adjust_palette();
 #endif
        start_screen();
-       has_unicode = ((GetVersion() & 0x80000000) == 0);
+       iflags.unicodecapable = ((GetVersion() & 0x80000000) == 0);
 }
 
 void
@@ -448,24 +454,61 @@ int x,y;
        ttyDisplay->cury = y;
 }
 
+#ifdef UNICODE_WIDEWINPORT
+#define T(x) L##x
+#else
+#define T(x) x
+#endif
+
 void
-xputc_core(ch)
-char ch;
+xputc_core(ich)
+#ifdef UNICODE_WIDEWINPORT
+nhwchar ich;
+#else
+int ich;
+#endif
 {
+       static uchar c[2] = {0,0};
+       char ch = (char)ich;
+
+#if 0
+       /*EURO symbol*/
+       if (ich == 0x20AC) {
+               if (!c[0]) {
+                       wchar_t t[2]={0x20ac, 0x0000};
+                       int cp = GetConsoleOutputCP();
+                       (void) WideCharToMultiByte(cp,
+                                      0,
+                                      t, 1,
+                                      c, 2,
+                                       (LPCSTR)0,
+                                       (LPBOOL)0);
+               }
+               ich = (nhwchar)c[0];
+       }
+#endif
+#ifdef UNICODE_WIDEWINPORT
+       switch(ich) {
+#else
        switch(ch) {
-           case '\n':
+#endif
+           case T('\n'):
                        cursor.Y++;
                        /* fall through */
-           case '\r':
+           case T('\r'):
                        cursor.X = 1;
                        break;
-           case '\b':
+           case T('\b'):
                        cursor.X--;
                        break;
            default:
                        WriteConsoleOutputAttribute(hConOut,&attr,1,
                                                        cursor,&acount);
-                       if (has_unicode) {
+                       if (iflags.unicodedisp) {
+#ifdef UNICODE_WIDEWINPORT
+                               WriteConsoleOutputCharacterW(hConOut,&ich,1,
+                                               cursor,&ccount);
+#else
                                /* Avoid bug in ANSI API on WinNT */
                                WCHAR c2[2];
                                int rc;
@@ -476,6 +519,7 @@ char ch;
                                       c2, 2);
                                WriteConsoleOutputCharacterW(hConOut,c2,rc,
                                                cursor,&ccount);
+#endif
                        }
                        else {
                                WriteConsoleOutputCharacterA(hConOut,&ch,1,
@@ -487,7 +531,11 @@ char ch;
 
 void
 xputc(ch)
-char ch;
+#ifdef UNICODE_WIDEWINPORT
+nhwchar ch;
+#else
+int ch;
+#endif
 {
        cursor.X = ttyDisplay->curx;
        cursor.Y = ttyDisplay->cury;
@@ -518,8 +566,8 @@ const char *s;
  * for win32. It is used for glyphs only, not text.
  */
 void
-g_putch(in_ch)
-int in_ch;
+g_putch(in_sym)
+int in_sym;
 {
        /* CP437 to Unicode mapping according to the Unicode Consortium */
        static const WCHAR cp437[] =
@@ -557,12 +605,17 @@ int in_ch;
                0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
                0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
        };
-       unsigned char ch = (unsigned char)in_ch;
+       uchar ch = (uchar)in_sym;
 
        cursor.X = ttyDisplay->curx;
        cursor.Y = ttyDisplay->cury;
        WriteConsoleOutputAttribute(hConOut,&attr,1,cursor,&acount);
-       if (has_unicode)
+#ifdef UNICODE_DRAWING
+       if (symset[currentgraphics].name && iflags.unicodedisp)
+           WriteConsoleOutputCharacterW(hConOut,(LPCWSTR)&in_sym,1,cursor,&ccount);
+       else
+#endif
+       if (SYMHANDLING(H_IBM))
            WriteConsoleOutputCharacterW(hConOut,&cp437[ch],1,cursor,&ccount);
        else
            WriteConsoleOutputCharacterA(hConOut,&ch,1,cursor,&ccount);
index fbe4d85dceea3b9b583c13367be2ee9f4170ad24..6987cd7c4c69a903bac7aa991d73e330cadf5318 100644 (file)
@@ -23,6 +23,12 @@ extern int NDECL(extcmd_via_menu);   /* cmd.c */
 
 extern char erase_char, kill_char;     /* from appropriate tty.c file */
 
+#ifdef UNICODE_WIDEWINPORT
+#define T(x) L##x
+#else
+#define T(x) x
+#endif
+
 /*
  * Read a line closed with '\n' into the array char bufp[BUFSZ].
  * (The '\n' is not stored. The string is closed with a '\0'.)
@@ -47,6 +53,9 @@ getlin_hook_proc hook;
        register int c;
        struct WinDesc *cw = wins[WIN_MESSAGE];
        boolean doprev = 0;
+#ifdef UNICODE_WIDEWINPORT
+       nhwchar wbuf[BUFSZ];
+#endif
 
        if(ttyDisplay->toplin == 1 && !(cw->flags & WIN_STOP)) more();
        cw->flags &= ~WIN_STOP;
@@ -55,9 +64,18 @@ getlin_hook_proc hook;
        pline("%s ", query);
        *obufp = 0;
        for(;;) {
+#ifdef UNICODE_WIDEWINPORT
+               char buf[BUFSZ];
+               (void) fflush(stdout);
+               Sprintf(buf, "%s ", query);
+               Strcat(buf, obufp);
+               nhwstrcpy(wbuf, buf);
+               (void)nhwcpy(toplines, wbuf);
+#else
                (void) fflush(stdout);
                Sprintf(toplines, "%s ", query);
                Strcat(toplines, obufp);
+#endif
                if((c = Getchar()) == EOF) c = '\033';
                if(c == '\033') {
                        *obufp = c;
@@ -76,10 +94,19 @@ getlin_hook_proc hook;
                        ttyDisplay->inread = sav;
                        tty_clear_nhwindow(WIN_MESSAGE);
                        cw->maxcol = cw->maxrow;
+#ifdef UNICODE_WIDEWINPORT
+                       nhwstrcpy(wbuf, query);
+                       addtopl(wbuf);
+                       addtopl(L" ");
+                       *bufp = 0;
+                       nhwstrcpy(wbuf, obufp);
+                       addtopl(wbuf);
+#else
                        addtopl(query);
                        addtopl(" ");
                        *bufp = 0;
                        addtopl(obufp);
+#endif
                    } else {
                        if (!doprev)
                            (void) tty_doprev_message();/* need two initially */
@@ -91,10 +118,22 @@ getlin_hook_proc hook;
                    tty_clear_nhwindow(WIN_MESSAGE);
                    cw->maxcol = cw->maxrow;
                    doprev = 0;
+#ifdef UNICODE_WIDEWINPORT
+                   nhwstrcpy(wbuf, query);
+                   addtopl(wbuf);
+                   addtopl(L" ");
+#else
                    addtopl(query);
                    addtopl(" ");
+#endif
+
                    *bufp = 0;
+#ifdef UNICODE_WIDEWINPORT
+                   nhwstrcpy(wbuf, obufp);
+                   addtopl(wbuf);
+#else
                    addtopl(obufp);
+#endif
                }
                if(c == erase_char || c == '\b') {
                        if(bufp != obufp) {
@@ -104,11 +143,11 @@ getlin_hook_proc hook;
 #endif /* NEWAUTOCOMP */
                                bufp--;
 #ifndef NEWAUTOCOMP
-                               putsyms("\b \b");/* putsym converts \b */
+                               putsyms(T("\b \b"));/* putsym converts \b */
 #else /* NEWAUTOCOMP */
-                               putsyms("\b");
-                               for (i = bufp; *i; ++i) putsyms(" ");
-                               for (; i > bufp; --i) putsyms("\b");
+                               putsyms(T("\b"));
+                               for (i = bufp; *i; ++i) putsyms(T(" "));
+                               for (; i > bufp; --i) putsyms(T("\b"));
                                *bufp = 0;
 #endif /* NEWAUTOCOMP */
                        } else  tty_nhbell();
@@ -131,21 +170,31 @@ getlin_hook_proc hook;
 #endif /* NEWAUTOCOMP */
                        *bufp = c;
                        bufp[1] = 0;
+#ifdef UNICODE_WIDEWINPORT
+                       nhwstrcpy(wbuf, bufp);
+                       putsyms(wbuf);
+#else
                        putsyms(bufp);
+#endif
                        bufp++;
                        if (hook && (*hook)(obufp)) {
+#ifdef UNICODE_WIDEWINPORT
+                           nhwstrcpy(wbuf, bufp);
+                           putsyms(wbuf);
+#else
                            putsyms(bufp);
+#endif
 #ifndef NEWAUTOCOMP
                            bufp = eos(bufp);
 #else /* NEWAUTOCOMP */
                            /* pointer and cursor left where they were */
-                           for (i = bufp; *i; ++i) putsyms("\b");
+                           for (i = bufp; *i; ++i) putsyms(T("\b"));
                        } else if (i > bufp) {
                            char *s = i;
 
                            /* erase rest of prior guess */
-                           for (; i > bufp; --i) putsyms(" ");
-                           for (; s > bufp; --s) putsyms("\b");
+                           for (; i > bufp; --i) putsyms(T(" "));
+                           for (; s > bufp; --s) putsyms(T("\b"));
 #endif /* NEWAUTOCOMP */
                        }
                } else if(c == kill_char || c == '\177') { /* Robert Viduya */
@@ -153,11 +202,11 @@ getlin_hook_proc hook;
 #ifndef NEWAUTOCOMP
                        while(bufp != obufp) {
                                bufp--;
-                               putsyms("\b \b");
+                               putsyms(T("\b \b"));
                        }
 #else /* NEWAUTOCOMP */
-                       for (; *bufp; ++bufp) putsyms(" ");
-                       for (; bufp != obufp; --bufp) putsyms("\b \b");
+                       for (; *bufp; ++bufp) putsyms(T(" "));
+                       for (; bufp != obufp; --bufp) putsyms(T("\b \b"));
                        *bufp = 0;
 #endif /* NEWAUTOCOMP */
                } else
@@ -168,6 +217,8 @@ getlin_hook_proc hook;
        clear_nhwindow(WIN_MESSAGE);    /* clean up after ourselves */
 }
 
+#undef T
+
 void
 xwaitforspace(s)
 register const char *s;        /* chars allowed besides return */
index c896c5ff3f9649451ea08be432e974c09525c391..4f8135b37dd70f009bd9d48f98d8c356cd91f650 100644 (file)
 #define C(c)   (0x1f & (c))
 #endif
 
-STATIC_DCL void FDECL(redotoplin, (const char*));
-STATIC_DCL void FDECL(topl_putsym, (CHAR_P));
+STATIC_DCL void FDECL(redotoplin, (const nhwchar*));
+STATIC_DCL void FDECL(topl_putsym, (NHWCHAR_P));
 STATIC_DCL void NDECL(remember_topl);
 STATIC_DCL void FDECL(removetopl, (int));
 
+extern nhwchar emptysym[];
+
 int
 tty_doprev_message()
 {
@@ -26,6 +28,9 @@ tty_doprev_message()
 
     winid prevmsg_win;
     int i;
+#ifdef UNICODE_WIDEWINPORT
+    char buf[BUFSZ];
+#endif
     if ((iflags.prevmsg_window != 's') && !ttyDisplay->inread) { /* not single */
         if(iflags.prevmsg_window == 'f') { /* full */
             prevmsg_win = create_nhwindow(NHW_MENU);
@@ -34,11 +39,23 @@ tty_doprev_message()
             cw->maxcol = cw->maxrow;
             i = cw->maxcol;
             do {
-                if(cw->data[i] && strcmp(cw->data[i], "") )
+#ifdef UNICODE_WIDEWINPORT
+                if(cw->data[i] && nhwstrcmp(cw->data[i], "") ) {
+                   strnhwcpy(buf, cw->data[i]);
+                    putstr(prevmsg_win, 0, buf);
+#else
+                if(cw->data[i] && strcmp(cw->data[i], "") ) {
                     putstr(prevmsg_win, 0, cw->data[i]);
+#endif
+                }
                 i = (i + 1) % cw->rows;
             } while (i != cw->maxcol);
+#ifdef UNICODE_WIDEWINPORT
+           strnhwcpy(buf, toplines);
+            putstr(prevmsg_win, 0, buf);
+#else
             putstr(prevmsg_win, 0, toplines);
+#endif
             display_nhwindow(prevmsg_win, TRUE);
             destroy_nhwindow(prevmsg_win);
         } else if (iflags.prevmsg_window == 'c') {             /* combination */
@@ -65,11 +82,24 @@ tty_doprev_message()
                     cw->maxcol = cw->maxrow;
                     i = cw->maxcol;
                     do {
-                        if(cw->data[i] && strcmp(cw->data[i], "") )
+#ifdef UNICODE_WIDEWINPORT
+                        if(cw->data[i] && nhwstrcmp(cw->data[i], "") ) {
+                           strnhwcpy(buf, cw->data[i]);
+                            putstr(prevmsg_win, 0, buf);
+#else
+                        if(cw->data[i] && strcmp(cw->data[i], "") ) {
                             putstr(prevmsg_win, 0, cw->data[i]);
+#endif
+                       }
                         i = (i + 1) % cw->rows;
                     } while (i != cw->maxcol);
+
+#ifdef UNICODE_WIDEWINPORT
+                   strnhwcpy(buf, toplines);
+                    putstr(prevmsg_win, 0, buf);
+#else
                     putstr(prevmsg_win, 0, toplines);
+#endif
                     display_nhwindow(prevmsg_win, TRUE);
                     destroy_nhwindow(prevmsg_win);
                 }
@@ -81,11 +111,22 @@ tty_doprev_message()
             prevmsg_win = create_nhwindow(NHW_MENU);
             putstr(prevmsg_win, 0, "Message History");
             putstr(prevmsg_win, 0, "");
+#ifdef UNICODE_WIDEWINPORT
+            strnhwcpy(buf, toplines);
+            putstr(prevmsg_win, 0, buf);
+#else
             putstr(prevmsg_win, 0, toplines);
+#endif
             cw->maxcol=cw->maxrow-1;
             if(cw->maxcol < 0) cw->maxcol = cw->rows-1;
             do {
-                putstr(prevmsg_win, 0, cw->data[cw->maxcol]);
+#ifdef UNICODE_WIDEWINPORT
+               strnhwcpy(buf, cw->data[cw->maxcol]);
+                putstr(prevmsg_win, 0, buf);
+#else
+               putstr(prevmsg_win, 0, cw->data[cw->maxcol]);
+
+#endif
                 cw->maxcol--;
                 if (cw->maxcol < 0) cw->maxcol = cw->rows-1;
                 if (!cw->data[cw->maxcol])
@@ -116,19 +157,23 @@ tty_doprev_message()
 }
 
 STATIC_OVL void
-redotoplin(str)
-    const char *str;
+redotoplin(symstr)
+    const nhwchar *symstr;
 {
        int otoplin = ttyDisplay->toplin;
        home();
-       if(*str & 0x80) {
+#ifdef UNICODE_WIDEWINPORT
+       if(*symstr >= 0x80) {
+#else
+       if(*symstr & 0x80) {
+#endif
                /* kludge for the / command, the only time we ever want a */
                /* graphics character on the top line */
-               g_putch((int)*str++);
+               g_putch((int)*symstr++);
                ttyDisplay->curx++;
        }
        end_glyphout(); /* in case message printed during graphics output */
-       putsyms(str);
+       putsyms(symstr);
        cl_end();
        ttyDisplay->toplin = 1;
        if(ttyDisplay->cury && otoplin != 3)
@@ -140,21 +185,29 @@ remember_topl()
 {
     register struct WinDesc *cw = wins[WIN_MESSAGE];
     int idx = cw->maxrow;
+#ifdef UNICODE_WIDEWINPORT
+    unsigned len = nhwlen(toplines) + 1;
+#else
     unsigned len = strlen(toplines) + 1;
+#endif
 
     if (len > (unsigned)cw->datlen[idx]) {
        if (cw->data[idx]) free(cw->data[idx]);
        len += (8 - (len & 7));         /* pad up to next multiple of 8 */
-       cw->data[idx] = (char *)alloc(len);
+       cw->data[idx] = (nhwchar *)alloc(sizeof(nhwchar) * len);
        cw->datlen[idx] = (short)len;
     }
+#ifdef UNICODE_WIDEWINPORT
+    (void)nhwcpy(cw->data[idx], toplines);
+#else
     Strcpy(cw->data[idx], toplines);
+#endif
     cw->maxcol = cw->maxrow = (idx + 1) % cw->rows;
 }
 
 void
 addtopl(s)
-const char *s;
+const nhwchar *s;
 {
     register struct WinDesc *cw = wins[WIN_MESSAGE];
 
@@ -175,7 +228,12 @@ more()
 
     if(ttyDisplay->toplin) {
        tty_curs(BASE_WINDOW, cw->curx+1, cw->cury);
-       if(cw->curx >= CO - 8) topl_putsym('\n');
+       if(cw->curx >= CO - 8)
+#ifdef UNICODE_WIDEWINPORT
+               topl_putsym(L'\n');
+#else
+               topl_putsym('\n');
+#endif
     }
 
     if(flags.standout)
@@ -204,22 +262,33 @@ more()
 
 void
 update_topl(bp)
-       register const char *bp;
+       register const nhwchar *bp;
 {
-       register char *tl, *otl;
+       register nhwchar *tl, *otl;
        register int n0;
        int notdied = 1;
        struct WinDesc *cw = wins[WIN_MESSAGE];
 
        /* If there is room on the line, print message on same line */
        /* But messages like "You die..." deserve their own line */
+#ifdef UNICODE_WIDEWINPORT
+       n0 = nhwlen(bp);
+#else
        n0 = strlen(bp);
+#endif
        if ((ttyDisplay->toplin == 1 || (cw->flags & WIN_STOP)) &&
            cw->cury == 0 &&
+#ifdef UNICODE_WIDEWINPORT
+           n0 + (int)nhwlen(toplines) + 3 < CO-8 &&  /* room for --More-- */
+           (notdied = nhwncmp(bp, L"You die", 7))) {
+               (void)nhwcat(toplines, L"  ");
+               (void)nhwcat(toplines, bp);
+#else
            n0 + (int)strlen(toplines) + 3 < CO-8 &&  /* room for --More-- */
            (notdied = strncmp(bp, "You die", 7))) {
                Strcat(toplines, "  ");
                Strcat(toplines, bp);
+#endif
                cw->curx += 2;
                if(!(cw->flags & WIN_STOP))
                    addtopl(bp);
@@ -232,7 +301,11 @@ update_topl(bp)
            }
        }
        remember_topl();
+#ifdef UNICODE_WIDEWINPORT
+       (void) nhwncpy(toplines, bp, TBUFSZ);
+#else
        (void) strncpy(toplines, bp, TBUFSZ);
+#endif
        toplines[TBUFSZ - 1] = 0;
 
        for(tl = toplines; n0 >= CO; ){
@@ -240,34 +313,49 @@ update_topl(bp)
            for(tl+=CO-1; tl != otl && !isspace(*tl); --tl) ;
            if(tl == otl) {
                /* Eek!  A huge token.  Try splitting after it. */
+#ifdef UNICODE_WIDEWINPORT
+               tl = nhwindex(otl, ' ');
+#else
                tl = index(otl, ' ');
+#endif
                if (!tl) break;    /* No choice but to spit it out whole. */
            }
+#ifdef UNICODE_WIDEWINPORT
+           *tl++ = (nhwchar)'\n';
+           n0 = nhwlen(tl);
+#else
            *tl++ = '\n';
            n0 = strlen(tl);
+#endif
        }
        if(!notdied) cw->flags &= ~WIN_STOP;
        if(!(cw->flags & WIN_STOP)) redotoplin(toplines);
 }
 
+#ifdef UNICODE_WIDEWINPORT
+#define T(x) L##x
+#else
+#define T(x) x
+#endif
+
 STATIC_OVL
 void
 topl_putsym(c)
-    char c;
+    nhwchar c;
 {
     register struct WinDesc *cw = wins[WIN_MESSAGE];
 
     if(cw == (struct WinDesc *) 0) panic("Putsym window MESSAGE nonexistant");
        
     switch(c) {
-    case '\b':
+    case T('\b'):
        if(ttyDisplay->curx == 0 && ttyDisplay->cury > 0)
            tty_curs(BASE_WINDOW, CO, (int)ttyDisplay->cury-1);
        backsp();
        ttyDisplay->curx--;
        cw->curx = ttyDisplay->curx;
        return;
-    case '\n':
+    case T('\n'):
        cl_end();
        ttyDisplay->curx = 0;
        ttyDisplay->cury++;
@@ -278,7 +366,7 @@ topl_putsym(c)
        break;
     default:
        if(ttyDisplay->curx == CO-1)
-           topl_putsym('\n'); /* 1 <= curx <= CO; avoid CO */
+           topl_putsym(T('\n')); /* 1 <= curx <= CO; avoid CO */
 #ifdef WIN32CON
     (void) putchar(c);
 #endif
@@ -291,12 +379,14 @@ topl_putsym(c)
 #endif
 }
 
+#undef T
+
 void
-putsyms(str)
-    const char *str;
+putsyms(symstr)
+    const nhwchar *symstr;
 {
-    while(*str)
-       topl_putsym(*str++);
+    while(*symstr)
+       topl_putsym(*symstr++);
 }
 
 STATIC_OVL void
@@ -304,7 +394,12 @@ removetopl(n)
 register int n;
 {
     /* assume addtopl() has been done, so ttyDisplay->toplin is already set */
-    while (n-- > 0) putsyms("\b \b");
+    while (n-- > 0)
+#ifdef UNICODE_WIDEWINPORT
+       putsyms(L"\b \b");
+#else
+       putsyms("\b \b");
+#endif
 }
 
 extern char erase_char;                /* from xxxtty.c; don't need kill_char */
@@ -331,6 +426,9 @@ char def;
        struct WinDesc *cw = wins[WIN_MESSAGE];
        boolean doprev = 0;
        char prompt[QBUFSZ];
+#ifdef UNICODE_WIDEWINPORT
+       nhwchar wprompt[QBUFSZ];
+#endif
 
        if(ttyDisplay->toplin == 1 && !(cw->flags & WIN_STOP)) more();
        cw->flags &= ~WIN_STOP;
@@ -362,7 +460,12 @@ char def;
                    ttyDisplay->inread = sav;
                    tty_clear_nhwindow(WIN_MESSAGE);
                    cw->maxcol = cw->maxrow;
+#ifdef UNICODE_WIDEWINPORT
+                   nhwstrcpy(wprompt, prompt);
+                   addtopl(wprompt);
+#else
                    addtopl(prompt);
+#endif
                } else {
                    if(!doprev)
                        (void) tty_doprev_message(); /* need two initially */
@@ -378,7 +481,12 @@ char def;
                tty_clear_nhwindow(WIN_MESSAGE);
                cw->maxcol = cw->maxrow;
                doprev = 0;
+#ifdef UNICODE_WIDEWINPORT
+               nhwstrcpy(wprompt, prompt);
+               addtopl(wprompt);
+#else
                addtopl(prompt);
+#endif
                q = '\0';       /* force another loop iteration */
                continue;
            }
@@ -399,13 +507,18 @@ char def;
                tty_nhbell();
                q = (char)0;
            } else if (q == '#' || digit_ok) {
-               char z, digit_string[2];
+               char z;
+               nhwchar digit_string[2];
                int n_len = 0;
                long value = 0;
+#ifdef UNICODE_WIDEWINPORT
+               addtopl(L"#"),  n_len++;
+#else
                addtopl("#"),  n_len++;
-               digit_string[1] = '\0';
+#endif
+               digit_string[1] = (nhwchar)0;
                if (q != '#') {
-                   digit_string[0] = q;
+                   digit_string[0] = (nhwchar)q;
                    addtopl(digit_string),  n_len++;
                    value = q - '0';
                    q = '#';
@@ -415,7 +528,7 @@ char def;
                    if (digit(z)) {
                        value = (10 * value) + (z - '0');
                        if (value < 0) break;   /* overflow: try again */
-                       digit_string[0] = z;
+                       digit_string[0] = (nhwchar)z;
                        addtopl(digit_string),  n_len++;
                    } else if (z == 'y' || index(quitchars, z)) {
                        if (z == '\033')  value = -1;   /* abort */
@@ -440,7 +553,12 @@ char def;
 
        if (q != '#') {
                Sprintf(rtmp, "%c", q);
+#ifdef UNICODE_WIDEWINPORT
+               nhwstrcpy(wprompt, rtmp);   /* rtmp[40] -> wprompt[128] ok */
+               addtopl(wprompt);
+#else
                addtopl(rtmp);
+#endif
        }
     clean_up:
        ttyDisplay->inread--;
@@ -468,6 +586,7 @@ boolean init;
        static boolean doneinit = FALSE;
        register struct WinDesc *cw = wins[WIN_MESSAGE];
        char *retstr = (char *)0;
+       static char buf[BUFSZ];
 
        if (!cw) return (char *)0;      /* bail */
        /*
@@ -483,11 +602,24 @@ boolean init;
        if (doneinit && state < 2) {
                if (state == 1) {
                        ++state;
+#ifdef UNICODE_WIDEWINPORT
+                       strnhwcpy(buf,toplines);
+                       return buf;
+#else
                        return toplines;
+#endif
                }
                do {
+#ifdef UNICODE_WIDEWINPORT
+                       if(cw->data[idx] && nhwcmp(cw->data[idx], emptysym) ) {
+                               strnhwcpy(buf, cw->data[idx]);
+                               retstr = buf;
+                       }
+#else
                        if(cw->data[idx] && strcmp(cw->data[idx], "") )
                                retstr = cw->data[idx];
+
+#endif
                        idx = (idx + 1) % cw->rows;
                } while (idx != cw->maxrow && !retstr);
                if (idx == cw->maxrow) ++state;
@@ -513,10 +645,14 @@ const char *msg;
        if (len > (unsigned)cw->datlen[idx]) {
                if (cw->data[idx]) free(cw->data[idx]);
                len += (8 - (len & 7));         /* pad up to next multiple of 8 */
-               cw->data[idx] = (char *)alloc(len);
+               cw->data[idx] = (nhwchar *)alloc(sizeof(nhwchar) * len);
                cw->datlen[idx] = (short)len;
         }
+#ifdef UNICODE_WIDEWINPORT
+       (void)nhwstrcpy(cw->data[idx], msg);
+#else
        Strcpy(cw->data[idx], msg);
+#endif
        cw->maxcol = cw->maxrow = (idx + 1) % cw->rows;
 }
 #endif /* TTY_GRAPHICS */
index dc44a507a68c91fb54a7c3b9cfbaab9c7fbae30e..82e5eacd9b83cb64584e96a102098ed741dd2a15 100644 (file)
@@ -43,6 +43,11 @@ extern char mapped_menu_cmds[]; /* from options.c */
 /* this is only needed until tty_status_* routines are written */
 extern NEARDATA winid WIN_STATUS;
 
+#ifdef UNICODE_WIDEWINPORT
+void FDECL(tty_putmixed,(winid,int,const char *));
+void FDECL(tty_putstr_core,(winid,int,const nhwchar *));
+#endif
+
 /* Interface definition, for windows.c */
 struct window_procs tty_procs = {
     "tty",
@@ -70,7 +75,11 @@ struct window_procs tty_procs = {
     tty_destroy_nhwindow,
     tty_curs,
     tty_putstr,
+#ifdef UNICODE_WIDEWINPORT
+    tty_putmixed,
+#else
     genl_putmixed,
+#endif
     tty_display_file,
     tty_start_menu,
     tty_add_menu,
@@ -141,7 +150,12 @@ static char obuf[BUFSIZ];  /* BUFSIZ is defined in stdio.h */
 #endif
 
 static char winpanicstr[] = "Bad window id %d";
-char defmorestr[] = "--More--";
+#ifdef UNICODE_WIDEWINPORT
+nhwchar defmorestr[] = L"--More--";
+#else
+nhwchar defmorestr[] = "--More--";
+#endif
+nhwchar emptysym[1] = {0};
 
 #ifdef CLIPPING
 # if defined(USE_TILES) && defined(MSDOS)
@@ -181,8 +195,9 @@ STATIC_DCL void FDECL(process_menu_window, (winid,struct WinDesc *));
 STATIC_DCL void FDECL(process_text_window, (winid,struct WinDesc *));
 STATIC_DCL tty_menu_item *FDECL(reverse, (tty_menu_item *));
 STATIC_DCL const char * FDECL(compress_str, (const char *));
-STATIC_DCL void FDECL(tty_putsym, (winid, int, int, CHAR_P));
+STATIC_DCL void FDECL(tty_putsym, (winid, int, int, NHWCHAR_P));
 static char *FDECL(copy_of, (const char *));
+static nhwchar *FDECL(nhwchar_copy_of, (const nhwchar *));
 STATIC_DCL void FDECL(bail, (const char *));   /* __attribute__((noreturn)) */
 
 /*
@@ -260,7 +275,11 @@ winch()
                    for(i=WIN_INVEN; i < MAXWIN; i++)
                        if(wins[i] && wins[i]->active) {
                            /* cop-out */
+#ifdef UNICODE_WIDEWINPORT
+                           addtopl(L"Press Return to continue: ");
+#else
                            addtopl("Press Return to continue: ");
+#endif
                            break;
                        }
                (void) fflush(stdout);
@@ -953,24 +972,24 @@ tty_create_nhwindow(type)
 
     if(newwin->maxrow) {
        newwin->data =
-               (char **) alloc(sizeof(char *) * (unsigned)newwin->maxrow);
+               (nhwchar **) alloc(sizeof(nhwchar *) * (unsigned)newwin->maxrow);
        newwin->datlen =
                (short *) alloc(sizeof(short) * (unsigned)newwin->maxrow);
        if(newwin->maxcol) {
            for (i = 0; i < newwin->maxrow; i++) {
-               newwin->data[i] = (char *) alloc((unsigned)newwin->maxcol);
+               newwin->data[i] = (nhwchar *) alloc(sizeof(nhwchar) * (unsigned)newwin->maxcol);
                newwin->datlen[i] = newwin->maxcol;
            }
        } else {
            for (i = 0; i < newwin->maxrow; i++) {
-               newwin->data[i] = (char *) 0;
+               newwin->data[i] = (nhwchar *) 0;
                newwin->datlen[i] = 0;
            }
        }
        if(newwin->type == NHW_MESSAGE)
            newwin->maxrow = 0;
     } else {
-       newwin->data = (char **)0;
+       newwin->data = (nhwchar **)0;
        newwin->datlen = (short *)0;
     }
 
@@ -1008,12 +1027,12 @@ free_window_info(cw, free_data)
        for(i=0; i<cw->maxrow; i++)
            if(cw->data[i]) {
                free((genericptr_t)cw->data[i]);
-               cw->data[i] = (char *)0;
+               cw->data[i] = (nhwchar *)0;
                if (cw->datlen) cw->datlen[i] = 0;
            }
        if (free_data) {
            free((genericptr_t)cw->data);
-           cw->data = (char **)0;
+           cw->data = (nhwchar **)0;
            if (cw->datlen) free((genericptr_t)cw->datlen);
            cw->datlen = (short *)0;
            cw->rows = 0;
@@ -1087,15 +1106,25 @@ dmore(cw, s)
     register struct WinDesc *cw;
     const char *s;                     /* valid responses */
 {
-    const char *prompt = cw->morestr ? cw->morestr : defmorestr;
+#ifdef UNICODE_WIDEWINPORT
+    char buf[BUFSZ];
+#endif
+    const nhwchar *prompt = cw->morestr ? cw->morestr : defmorestr;
+
     int offset = (cw->type == NHW_TEXT) ? 1 : 2;
 
     tty_curs(BASE_WINDOW,
             (int)ttyDisplay->curx + offset, (int)ttyDisplay->cury);
     if(flags.standout)
        standoutbeg();
+#ifdef UNICODE_WIDEWINPORT
+    strnhwcpy(buf, prompt);
+    xputs(buf);
+    ttyDisplay->curx += strlen(buf);    
+#else
     xputs(prompt);
     ttyDisplay->curx += strlen(prompt);
+#endif
     if(flags.standout)
        standoutend();
 
@@ -1210,13 +1239,13 @@ struct WinDesc *cw;
     long count;
     int n, curr_page, page_lines;
     boolean finished, counting, reset_count;
-    char *cp, *rp, resp[QBUFSZ], gacc[QBUFSZ],
-        *msave, *morestr;
+    char *cp, *rp, resp[QBUFSZ], gacc[QBUFSZ];
+    nhwchar *msave, *morestr;
 
     curr_page = page_lines = 0;
     page_start = page_end = 0;
     msave = cw->morestr;       /* save the morestr */
-    cw->morestr = morestr = (char*) alloc((unsigned) QBUFSZ);
+    cw->morestr = morestr = (nhwchar*) alloc(sizeof(nhwchar) * (unsigned) QBUFSZ);
     counting = FALSE;
     count = 0L;
     reset_count = TRUE;
@@ -1332,20 +1361,41 @@ struct WinDesc *cw;
            Strcat(resp, gacc);                 /* group accelerators */
            Strcat(resp, mapped_menu_cmds);
 
-           if (cw->npages > 1)
+           if (cw->npages > 1) {
+#ifdef UNICODE_WIDEWINPORT
+               char buf[BUFSZ];
+               Sprintf(buf, "(%d of %d)",
+                       curr_page + 1, (int) cw->npages);
+               (void)nhwstrcpy(cw->morestr, buf);
+#else
                Sprintf(cw->morestr, "(%d of %d)",
                        curr_page + 1, (int) cw->npages);
-           else if (msave)
+#endif
+           } else if (msave) {
+#ifdef UNICODE_WIDEWINPORT
+               (void)nhwcpy(cw->morestr, msave);
+#else
                Strcpy(cw->morestr, msave);
-           else
+#endif
+           } else {
+#ifdef UNICODE_WIDEWINPORT
+               (void)nhwcpy(cw->morestr, defmorestr);
+#else
                Strcpy(cw->morestr, defmorestr);
-
+#endif
+           }
            tty_curs(window, 1, page_lines);
            cl_end();
            dmore(cw, resp);
        } else {
            /* just put the cursor back... */
-           tty_curs(window, (int) strlen(cw->morestr) + 2, page_lines);
+           tty_curs(window, 
+#ifdef UNICODE_WIDEWINPORT
+                       (int) nhwlen(cw->morestr) + 2,
+#else
+                       (int) strlen(cw->morestr) + 2, 
+#endif
+                       page_lines);
            xwaitforspace(resp);
        }
 
@@ -1509,7 +1559,7 @@ winid window;
 struct WinDesc *cw;
 {
     int i, n, attr;
-    register char *cp;
+    register nhwchar *cp;
 
     for (n = 0, i = 0; i < cw->maxrow; i++) {
        if (!cw->offx && (n + cw->offy == ttyDisplay->rows - 1)) {
@@ -1543,7 +1593,11 @@ struct WinDesc *cw;
                    *cp && (int) ttyDisplay->curx < (int) ttyDisplay->cols;
                    cp++, ttyDisplay->curx++)
 #endif
+#ifdef UNICODE_WIDEWINPORT
+               u_putch(*cp);
+#else
                (void) putchar(*cp);
+#endif
            term_end_attr(attr);
        }
     }
@@ -1772,7 +1826,7 @@ STATIC_OVL void
 tty_putsym(window, x, y, ch)
     winid window;
     int x, y;
-    char ch;
+    nhwchar ch;
 {
     register struct WinDesc *cw = 0;
 
@@ -1784,7 +1838,11 @@ tty_putsym(window, x, y, ch)
     case NHW_MAP:
     case NHW_BASE:
        tty_curs(window, x, y);
+#ifdef UNICODE_WIDEWINPORT
+       u_putch(ch);
+#else
        (void) putchar(ch);
+#endif
        ttyDisplay->curx++;
        cw->curx++;
        break;
@@ -1827,9 +1885,14 @@ tty_putstr(window, attr, str)
     const char *str;
 {
     register struct WinDesc *cw = 0;
-    register char *ob;
-    register const char *nb;
+#ifdef UNICODE_WIDEWINPORT
+    nhwchar symbuf[BUFSZ];
+    register const nhwchar *symstr = symbuf;
+#else
+    register const nhwchar *nb;
+    register nhwchar *ob;
     register int i, j, n0;
+#endif
 
     /* Assume there's a real problem if the window is missing --
      * probably a panic message
@@ -1844,21 +1907,52 @@ tty_putstr(window, attr, str)
        return;
     if(cw->type != NHW_MESSAGE)
        str = compress_str(str);
+#if defined(USER_SOUNDS) && defined(WIN32CON)
+    else 
+       play_sound_for_message(str);
+#endif
+
+#ifdef UNICODE_WIDEWINPORT
+    nhwstrcpy(symbuf, str);
+    tty_putstr_core(window, attr, symstr);
+}
+
+void
+tty_putstr_core(window, attr, symstr)
+    winid window;
+    int attr;
+    const nhwchar *symstr;
+{
+    register struct WinDesc *cw = wins[window];
+    register const nhwchar *nb;
+    register nhwchar *ob;
+    register int i, j, n0;
+#endif
 
     ttyDisplay->lastwin = window;
 
     switch(cw->type) {
     case NHW_MESSAGE:
        /* really do this later */
-#if defined(USER_SOUNDS) && defined(WIN32CON)
-       play_sound_for_message(str);
-#endif
+#ifdef UNICODE_WIDEWINPORT
+       update_topl(symstr);
+#else
        update_topl(str);
+#endif
        break;
 
     case NHW_STATUS:
        ob = &cw->data[cw->cury][j = cw->curx];
        if(context.botlx) *ob = 0;
+#ifdef UNICODE_WIDEWINPORT
+       if(!cw->cury && (int)nhwlen(symstr) >= CO) {
+           /* the characters before "St:" are unnecessary */
+           nb = nhwindex(symstr, L':');
+           if(nb && nb > symstr+2)
+               symstr = nb - 2;
+       }
+       nb = symstr;
+#else
        if(!cw->cury && (int)strlen(str) >= CO) {
            /* the characters before "St:" are unnecessary */
            nb = index(str, ':');
@@ -1866,6 +1960,8 @@ tty_putstr(window, attr, str)
                str = nb - 2;
        }
        nb = str;
+#endif
+
        for(i = cw->curx+1, n0 = cw->cols; i < n0; i++, nb++) {
            if(!*nb) {
                if(*ob || context.botlx) {
@@ -1880,19 +1976,31 @@ tty_putstr(window, attr, str)
            if(*ob) ob++;
        }
 
+#ifdef UNICODE_WIDEWINPORT
+       (void) nhwncpy(&cw->data[cw->cury][j], symstr, cw->cols - j - 1);
+#else
        (void) strncpy(&cw->data[cw->cury][j], str, cw->cols - j - 1);
-       cw->data[cw->cury][cw->cols-1] = '\0'; /* null terminate */
+#endif
+       cw->data[cw->cury][cw->cols-1] = (nhwchar)0; /* null terminate */
        cw->cury = (cw->cury+1) % 2;
        cw->curx = 0;
        break;
     case NHW_MAP:
        tty_curs(window, cw->curx+1, cw->cury);
        term_start_attr(attr);
+#ifdef UNICODE_WIDEWINPORT
+       while(*symstr && (int) ttyDisplay->curx < (int) ttyDisplay->cols-1) {
+           u_putch(*symstr);
+           symstr++;
+           ttyDisplay->curx++;
+       }
+#else
        while(*str && (int) ttyDisplay->curx < (int) ttyDisplay->cols-1) {
            (void) putchar(*str);
            str++;
            ttyDisplay->curx++;
        }
+#endif
        cw->curx = 0;
        cw->cury++;
        term_end_attr(attr);
@@ -1900,14 +2008,23 @@ tty_putstr(window, attr, str)
     case NHW_BASE:
        tty_curs(window, cw->curx+1, cw->cury);
        term_start_attr(attr);
+#ifdef UNICODE_WIDEWINPORT
+       while (*symstr) {
+#else
        while (*str) {
+#endif
            if ((int) ttyDisplay->curx >= (int) ttyDisplay->cols-1) {
                cw->curx = 0;
                cw->cury++;
                tty_curs(window, cw->curx+1, cw->cury);
            }
+#ifdef UNICODE_WIDEWINPORT
+           u_putch(*symstr);
+           symstr++;
+#else
            (void) putchar(*str);
            str++;
+#endif
            ttyDisplay->curx++;
        }
        cw->curx = 0;
@@ -1929,10 +2046,10 @@ tty_putstr(window, attr, str)
        }
        /* always grows one at a time, but alloc 12 at a time */
        if(cw->cury >= cw->rows) {
-           char **tmp;
+           nhwchar **tmp;
 
            cw->rows += 12;
-           tmp = (char **) alloc(sizeof(char *) * (unsigned)cw->rows);
+           tmp = (nhwchar **) alloc(sizeof(nhwchar *) * (unsigned)cw->rows);
            for(i=0; i<cw->maxrow; i++)
                tmp[i] = cw->data[i];
            if(cw->data)
@@ -1944,10 +2061,19 @@ tty_putstr(window, attr, str)
        }
        if(cw->data[cw->cury])
            free((genericptr_t)cw->data[cw->cury]);
+#ifdef UNICODE_WIDEWINPORT
+       n0 = nhwlen(symstr) + 1;
+#else
        n0 = strlen(str) + 1;
-       ob = cw->data[cw->cury] = (char *)alloc((unsigned)n0 + 1);
-       *ob++ = (char)(attr + 1);       /* avoid nuls, for convenience */
+#endif
+
+       ob = cw->data[cw->cury] = (nhwchar *)alloc(sizeof(nhwchar) * (unsigned)n0 + 1);
+       *ob++ = (nhwchar)(attr + 1);    /* avoid nuls, for convenience */
+#ifdef UNICODE_WIDEWINPORT
+       (void)nhwcpy(ob, symstr);
+#else
        Strcpy(ob, str);
+#endif
 
        if(n0 > cw->maxcol)
            cw->maxcol = n0;
@@ -1955,11 +2081,19 @@ tty_putstr(window, attr, str)
            cw->maxrow = cw->cury;
        if(n0 > CO) {
            /* attempt to break the line */
+#ifdef UNICODE_WIDEWINPORT
+           for(i = CO-1; i && symstr[i] != L' ' && symstr[i] != L'\n';)
+#else
            for(i = CO-1; i && str[i] != ' ' && str[i] != '\n';)
+#endif
                i--;
            if(i) {
-               cw->data[cw->cury-1][++i] = '\0';
+               cw->data[cw->cury-1][++i] = (nhwchar)0;
+#ifdef UNICODE_WIDEWINPORT
+               tty_putstr_core(window, attr, &symstr[i]);
+#else
                tty_putstr(window, attr, &str[i]);
+#endif
            }
 
        }
@@ -1967,6 +2101,60 @@ tty_putstr(window, attr, str)
     }
 }
 
+#ifdef UNICODE_WIDEWINPORT
+/*
+ * This differs from putstr() because the str parameter can
+ * contain a sequence of characters representing:
+ *        \GXXXXNNNN   a glyph value, encoded by encglyph().
+ *
+ */
+void
+tty_putmixed(window, attr, str)
+    winid window;
+    int attr;
+    const char *str;
+{
+       nhwchar wbuf[BUFSZ];
+       const char *cp = str;
+       nhwchar *put = wbuf;
+       while (*cp) {
+           if (*cp == '\\') {
+               int rndchk = 0, so = 0, gv = 0, ch, oc, dcount;
+               unsigned os;
+               const char *dp, *hex = "00112233445566778899aAbBcCdDeEfF";
+               const char *save_cp = cp;
+               
+               cp++;
+               switch(*cp) {
+               case 'G':       /* glyph value \GXXXXNNNN*/
+                   dcount = 0;
+                   for (++cp; *cp && (dp = index(hex, *cp)) && (dcount++ < 4); cp++)
+                       rndchk = (int)((rndchk * 16) + ((int)(dp - hex) / 2));
+
+                   if (rndchk == context.rndencode) {
+                       dcount = 0;
+                       for (; *cp && (dp = index(hex, *cp)) && (dcount++ < 4); cp++)
+                           gv = (int)((gv * 16) + ((int)(dp - hex) / 2));
+                       so = mapglyph(gv, &ch, &oc, &os, 0, 0);
+                       *put++ = (nhwchar)showsyms[so];
+                       continue;
+                   } else {
+                       /* possible forgery - leave it the way it is */
+                       cp = save_cp;
+                   }
+                   break;
+               case '\\':
+                   break;
+               }
+           }
+           *put++ = (nhwchar)*cp++;
+       }
+       *put = (nhwchar)0;
+       /* now send it to tty_putstr_core() */
+       tty_putstr_core(window, attr, wbuf);
+}
+#endif /*UNICODE_WIDEWINPORT*/
+
 void
 tty_display_file(fname, complain)
 const char *fname;
@@ -2149,7 +2337,7 @@ tty_end_menu(window, prompt)
     /* Reverse the list so that items are in correct order. */
     cw->mlist = reverse(cw->mlist);
 
-    /* Put the promt at the beginning of the menu. */
+    /* Put the prompt at the beginning of the menu. */
     if (prompt) {
        anything any;
 
@@ -2200,10 +2388,19 @@ tty_end_menu(window, prompt)
        /* produce the largest demo string */
        Sprintf(buf, "(%d of %d) ", cw->npages, cw->npages);
        len = strlen(buf);
+#ifdef UNICODE_WIDEWINPORT
+       cw->morestr = nhwchar_copy_of(emptysym);
+#else
        cw->morestr = copy_of("");
+#endif
     } else {
+#ifdef UNICODE_WIDEWINPORT
+       cw->morestr = nhwchar_copy_of(L"(end) ");
+       len = nhwlen(cw->morestr);
+#else
        cw->morestr = copy_of("(end) ");
        len = strlen(cw->morestr);
+#endif
     }
 
     if (len > (int)ttyDisplay->cols) {
@@ -2323,7 +2520,11 @@ tty_wait_synch()
     } else {
        tty_display_nhwindow(WIN_MAP, FALSE);
        if(ttyDisplay->inmore) {
+#ifdef UNICODE_WIDEWINPORT
+           addtopl(L"--More--");
+#else
            addtopl("--More--");
+#endif
            (void) fflush(stdout);
        } else if(ttyDisplay->inread > program_state.gameover) {
            /* this can only happen if we were reading and got interrupted */
@@ -2395,6 +2596,58 @@ end_glyphout()
 #endif
 }
 
+#ifdef UNICODE_WIDEWINPORT
+/*
+ * Parts of u_putch() were contributed by Adam Wozniak, 2005.
+ */
+void
+u_putch(sym)
+nhwchar sym;
+{
+    unsigned long unicode = sym;
+    if (!iflags.unicodedisp)
+       putchar((char)sym);
+    else {
+#if defined(UNIX) || defined(VMS)
+       /* send utf8 to display */
+       if (unicode < 0x80) {
+               (void) putchar(unicode);
+       } else if (unicode < 0x00000800) {
+               (void) putchar(0xC0 | (unicode >> 6));
+               (void) putchar(0x80 | (unicode & 0x3F));
+       } else if (unicode < 0x00010000) {
+               (void) putchar(0xE0 | (unicode >> 12));
+               (void) putchar(0x80 | ((unicode >> 6) & 0x3F));
+               (void) putchar(0x80 | (unicode & 0x3F));
+       } else if (unicode < 0x00200000) {
+               (void) putchar(0xF0 | (unicode >> 18));
+               (void) putchar(0x80 | ((unicode >> 12) & 0x3F));
+               (void) putchar(0x80 | ((unicode >> 6) & 0x3F));
+               (void) putchar(0x80 | (unicode & 0x3F));
+       } else if (unicode < 0x04000000) {
+               (void) putchar(0xF8 | (unicode >> 24));
+               (void) putchar(0x80 | ((unicode >> 18) & 0x3F));
+               (void) putchar(0x80 | ((unicode >> 12) & 0x3F));
+               (void) putchar(0x80 | ((unicode >> 6) & 0x3F));
+               (void) putchar(0x80 | (unicode & 0x3F));
+       } else {
+               (void) putchar(0xFC | (unicode >> 30));
+               (void) putchar(0x80 | ((unicode >> 24) & 0x3F));
+               (void) putchar(0x80 | ((unicode >> 18) & 0x3F));
+               (void) putchar(0x80 | ((unicode >> 12) & 0x3F));
+               (void) putchar(0x80 | ((unicode >> 6) & 0x3F));
+               (void) putchar(0x80 | (unicode & 0x3F));
+       }
+#else
+       /* it is assumed that whatever is being substituted for
+          putchar() can handle unicode characters directly at
+          this point (nttty's xputc() for example) */
+       (void) putchar(sym);
+#endif
+    }
+}
+#endif /*UNICODE_WIDEWINPORT*/
+
 #ifndef WIN32
 void
 g_putch(in_ch)
@@ -2403,6 +2656,11 @@ int in_ch;
     register char ch = (char)in_ch;
 
 # if defined(ASCIIGRAPH) && !defined(NO_TERMS)
+#  if defined(UNICODE_WIDEWINPORT) && defined(UNICODE_DRAWING)
+    if (iflags.unicodedisp && symset[currentgraphics].name) {
+       u_putch(in_ch);
+    } else
+#  endif
     if (SYMHANDLING(H_IBM) || iflags.eight_bit_tty) {
        /* IBM-compatible displays don't need other stuff */
        (void) putchar(ch);
@@ -2486,9 +2744,9 @@ tty_print_glyph(window, x, y, glyph)
     xchar x, y;
     int glyph;
 {
-    int ch;
+    int ch, idx;
     boolean reverse_on = FALSE;
-    int            color;
+    int        color;
     unsigned special;
     
 #ifdef CLIPPING
@@ -2498,7 +2756,7 @@ tty_print_glyph(window, x, y, glyph)
     }
 #endif
     /* map glyph to character and color */
-    (void)mapglyph(glyph, &ch, &color, &special, x, y);
+    idx = mapglyph(glyph, &ch, &color, &special, x, y);
 
     /* Move the cursor. */
     tty_curs(window, x,y);
@@ -2531,6 +2789,11 @@ tty_print_glyph(window, x, y, glyph)
     if (iflags.grmode && iflags.tile_view)
       xputg(glyph,ch,special);
     else
+#endif
+#if defined(UNICODE_WIDEWINPORT) && defined(UNICODE_DRAWING)
+    if (iflags.unicodedisp && symset[currentgraphics].name)
+       g_putch(showsyms[idx]); /* use the unicode symset */
+    else
 #endif
        g_putch(ch);            /* print the character */
 
@@ -2683,6 +2946,15 @@ copy_of(s)
     return strcpy((char *) alloc((unsigned) (strlen(s) + 1)), s);
 }
 
+# ifdef UNICODE_WIDEWINPORT
+static nhwchar *
+nhwchar_copy_of(s)
+    const nhwchar *s;
+{
+    if (!s) s = emptysym;
+    return nhwcpy((nhwchar *) alloc(sizeof(nhwchar) * (unsigned) (nhwlen(s) + 1)), s);
+}
+# endif /*UNICODE_WIDEWINPORT*/
 #endif /* TTY_GRAPHICS */
 
 /*wintty.c*/