diff --git a/doc/window.doc b/doc/window.doc index 0e40178a1..1f5544f58 100644 --- a/doc/window.doc +++ b/doc/window.doc @@ -22,6 +22,7 @@ Contents: VII. Game startup VIII. Conventions IX. Implementation and Multi-window support + X. WINCHAIN I. Window Types and Terminology @@ -994,3 +995,33 @@ One caveat. Unfortunately, if you incorrectly specify the DEFAULT_WINDOW_SYS, NetHack will dump core (or whatever) without printing any message, because raw_print() cannot function without first setting the window-port. + + +X. WINCHAIN + +WINCHAIN is an optional facility that allows the SYSCF_FILE to specify a +series of processors that will see each call from the core to the window +port (and the resulting return chain). Processors are specified one at a +time from the start of the chain (the core end) towards the window port as: + OPTIONS=windowchain:+PROC +where PROC is the name of the processor to add to the chain. The '+' is +required and is part of the name of the processor (this distinguishes +processors from window ports; in addition the '-' character is reserved for +WINCHAIN internals). + +If WINCHAIN is not compiled into the NetHack binary, there is no overhead. + +If WINCHAIN is compiled into the NetHack binary but not used, overhead is +limited to one function call during game setup and a trivial amount of data. + +Note that raw_print* calls will not go through the chain until initialization +is complete (when *main.c calls commit_windowchain()). + +The only processor currently available is '+trace' which is a debugging +facility for window ports. See the code in win/chain/wc_trace.c for +details on where to find the log file and how to write to it from other parts +of the code. + +A processor may be specified more than once; this is expected to be most +useful for surrounding a processor being developed with before and after +calls to +trace. diff --git a/include/config.h b/include/config.h index 7221271d9..23b2b35bf 100644 --- a/include/config.h +++ b/include/config.h @@ -445,6 +445,7 @@ typedef unsigned char uchar; #define STATUS_VIA_WINDOWPORT /* re-work of the status line updating process */ #define STATUS_HILITES /* support hilites of status fields */ #define DUNGEON_OVERVIEW /* dungeon overview by Hojita Discordia */ +/* #define WINCHAIN*/ /* stacked window systems */ /* End of Section 5 */ #include "global.h" /* Define everything else according to choices above */ diff --git a/include/extern.h b/include/extern.h index d58d18314..4f894ef78 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2600,6 +2600,10 @@ E boolean FDECL(mwelded, (struct obj *)); /* ### windows.c ### */ E void FDECL(choose_windows, (const char *)); +#ifdef WINCHAIN +void FDECL(addto_windowchain, (const char *s)); +void NDECL(commit_windowchain); +#endif E boolean NDECL(genl_can_suspend_no); E boolean NDECL(genl_can_suspend_yes); E char FDECL(genl_message_menu, (CHAR_P,int,const char *)); diff --git a/include/tradstdc.h b/include/tradstdc.h index 07dae7c9a..1cd0adb82 100644 --- a/include/tradstdc.h +++ b/include/tradstdc.h @@ -334,11 +334,18 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */ */ #ifdef __GNUC__ # if __GNUC__ >= 2 -#define PRINTF_F(f,v) __attribute__ ((format (printf, f, v))) +# define PRINTF_F(f,v) __attribute__ ((format (printf, f, v))) +# endif +# if __GNUC__ >= 3 +# define UNUSED __attribute__ ((unused)) # endif #endif + #ifndef PRINTF_F -#define PRINTF_F(f,v) +# define PRINTF_F(f,v) +#endif +#ifndef UNUSED +# define UNUSED #endif #endif /* TRADSTDC_H */ diff --git a/include/winprocs.h b/include/winprocs.h index c90de0b68..eac4e9c42 100644 --- a/include/winprocs.h +++ b/include/winprocs.h @@ -7,8 +7,11 @@ #include "botl.h" +/* NB: this MUST match chain_procs below */ struct window_procs { - const char *name; + const char *name; /* Names should start with [a-z]. Names must + * not start with '-'. Names starting with + * '+' are reserved for processors. */ unsigned long wincap; /* window port capability options supported */ unsigned long wincap2; /* additional window port capability options supported */ void FDECL((*win_init_nhwindows), (int *, char **)); @@ -268,4 +271,101 @@ struct wc_Opt { #define WININIT 0 #define WININIT_UNDO 1 +#ifdef WINCHAIN +/* Setup phases for window chain elements. + void * rv = X_procs_chain(int, int, void *, void *, void *); + Xprivate* ALLOC n 0 0 0 + - INIT n self next nextdata + where: + Xprivate* is anything window chain entry type X wants back + n is the link count (starting with 1) + self is the Xprivate* returned earlier + next is struct winprocs * or struct chainprocs * for the next link + nextdata is the Xprivate* for the next link in the chain +*/ +#define WINCHAIN_ALLOC 0 +#define WINCHAIN_INIT 1 + +#define CARGS void * + +extern FILE *wc_tracelogf; /* Expose log file for additional debugging. */ + +struct chain_procs { + const char *name; /* Names should start with [a-z]. Names must + * not start with '-'. Names starting with + * '+' are reserved for processors. */ + unsigned long wincap; /* window port capability options supported */ + unsigned long wincap2; /* additional window port capability options supported */ + void FDECL((*win_init_nhwindows), (CARGS, int *, char **)); + void FDECL((*win_player_selection), (CARGS)); + void FDECL((*win_askname), (CARGS)); + void FDECL((*win_get_nh_event), (CARGS)) ; + void FDECL((*win_exit_nhwindows), (CARGS, const char *)); + void FDECL((*win_suspend_nhwindows), (CARGS, const char *)); + void FDECL((*win_resume_nhwindows), (CARGS)); + winid FDECL((*win_create_nhwindow), (CARGS, int)); + void FDECL((*win_clear_nhwindow), (CARGS, winid)); + void FDECL((*win_display_nhwindow), (CARGS, winid, BOOLEAN_P)); + void FDECL((*win_destroy_nhwindow), (CARGS, winid)); + void FDECL((*win_curs), (CARGS, winid,int,int)); + void FDECL((*win_putstr), (CARGS, winid, int, const char *)); + void FDECL((*win_putmixed), (CARGS, winid, int, const char *)); + void FDECL((*win_display_file), (CARGS, const char *, BOOLEAN_P)); + void FDECL((*win_start_menu), (CARGS, winid)); + void FDECL((*win_add_menu), (CARGS, winid,int,const ANY_P *, + CHAR_P,CHAR_P,int,const char *, BOOLEAN_P)); + void FDECL((*win_end_menu), (CARGS, winid, const char *)); + int FDECL((*win_select_menu), (CARGS, winid, int, MENU_ITEM_P **)); + char FDECL((*win_message_menu), (CARGS, CHAR_P,int,const char *)); + void FDECL((*win_update_inventory), (CARGS)); + void FDECL((*win_mark_synch), (CARGS)); + void FDECL((*win_wait_synch), (CARGS)); +#ifdef CLIPPING + void FDECL((*win_cliparound), (CARGS, int, int)); +#endif +#ifdef POSITIONBAR + void FDECL((*win_update_positionbar), (CARGS, char *)); +#endif + void FDECL((*win_print_glyph), (CARGS, winid,XCHAR_P,XCHAR_P,int)); + void FDECL((*win_raw_print), (CARGS, const char *)); + void FDECL((*win_raw_print_bold), (CARGS, const char *)); + int FDECL((*win_nhgetch), (CARGS)); + int FDECL((*win_nh_poskey), (CARGS, int *, int *, int *)); + void FDECL((*win_nhbell), (CARGS)); + int FDECL((*win_doprev_message), (CARGS)); + char FDECL((*win_yn_function), (CARGS, const char *, const char *, CHAR_P)); + void FDECL((*win_getlin), (CARGS, const char *,char *)); + int FDECL((*win_get_ext_cmd), (CARGS)); + void FDECL((*win_number_pad), (CARGS, int)); + void FDECL((*win_delay_output), (CARGS)); +#ifdef CHANGE_COLOR + void FDECL((*win_change_color), (CARGS, int,long,int)); +#ifdef MAC + void FDECL((*win_change_background), (CARGS, int)); + short FDECL((*win_set_font_name), (CARGS, winid, char *)); +#endif + char * FDECL((*win_get_color_string), (CARGS)); +#endif + + /* other defs that really should go away (they're tty specific) */ + void FDECL((*win_start_screen), (CARGS)); + void FDECL((*win_end_screen), (CARGS)); + + void FDECL((*win_outrip), (CARGS, winid,int)); + void FDECL((*win_preference_update), (CARGS, const char *)); + char * FDECL((*win_getmsghistory), (CARGS, BOOLEAN_P)); + void FDECL((*win_putmsghistory), (CARGS, const char *,BOOLEAN_P)); +#ifdef STATUS_VIA_WINDOWPORT + void FDECL((*win_status_init), (CARGS)); + void FDECL((*win_status_finish), (CARGS)); + void FDECL((*win_status_enablefield), (CARGS, int,const char *,const char *,BOOLEAN_P)); + void FDECL((*win_status_update), (CARGS, int,genericptr_t,int,int)); +# ifdef STATUS_HILITES + void FDECL((*win_status_threshold), (CARGS, int,int,anything,int,int,int)); +# endif +#endif + boolean FDECL((*win_can_suspend), (CARGS)); +}; +#endif /* WINCHAIN */ + #endif /* WINPROCS_H */ diff --git a/src/options.c b/src/options.c index ac5c9517e..220506ff8 100644 --- a/src/options.c +++ b/src/options.c @@ -400,6 +400,9 @@ static struct Comp_Opt { "windowcolors", "the foreground/background colors of windows", /*WC*/ 80, DISP_IN_GAME }, { "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME }, +#ifdef WINCHAIN + { "windowchain", "window processor to use", WINTYPELEN, SET_IN_SYS }, +#endif #ifdef BACKWARD_COMPAT {"DECgraphics", "load DECGraphics display symbols", 70, SET_IN_FILE}, {"IBMgraphics", "load IBMGraphics display symbols", 70, SET_IN_FILE}, @@ -2394,6 +2397,20 @@ goodfruit: } return; } +#ifdef WINCHAIN + fullname = "windowchain"; + if (match_optname(opts, fullname, 3, TRUE)) { + if (negated) { + bad_negation(fullname, FALSE); + return; + } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) { + char buf[WINTYPELEN]; + nmcpy(buf, op, WINTYPELEN); + addto_windowchain(buf); + } + return; + } +#endif /* WINCAP * setting window colors diff --git a/src/windows.c b/src/windows.c index 969f63be2..47cd4485d 100644 --- a/src/windows.c +++ b/src/windows.c @@ -23,7 +23,7 @@ extern struct window_procs mac_procs; #endif #ifdef BEOS_GRAPHICS extern struct window_procs beos_procs; -extern void FDECL(be_win_init, (int)); FAIL /* be_win_init doesn't exist? */ +extern void FDECL(be_win_init, (int)); FAIL /* be_win_init doesn't exist? XXX*/ #endif #ifdef AMIGA_INTUITION extern struct window_procs amii_procs; @@ -40,6 +40,19 @@ extern struct window_procs Gnome_procs; #ifdef MSWIN_GRAPHICS extern struct window_procs mswin_procs; #endif +#ifdef WINCHAIN +extern struct window_procs chainin_procs; +extern void FDECL(chainin_procs_init, (int)); +extern void *FDECL(chainin_procs_chain, (int, int, void *, void *, void *)); + +extern struct chain_procs chainout_procs; +extern void FDECL(chainout_procs_init, (int)); +extern void *FDECL(chainout_procs_chain, (int, int, void *, void *, void *)); + +extern struct chain_procs trace_procs; +extern void FDECL(trace_procs_init, (int)); +extern void *FDECL(trace_procs_chain, (int, int, void *, void *, void *)); +#endif STATIC_DCL void FDECL(def_raw_print, (const char *s)); @@ -48,45 +61,87 @@ volatile #endif NEARDATA struct window_procs windowprocs; +#ifdef WINCHAIN +# define CHAINR(x) ,x +#else +# define CHAINR(x) +#endif + static struct win_choices { struct window_procs *procs; void FDECL((*ini_routine), (int)); /* optional (can be 0) */ +#ifdef WINCHAIN + void *FDECL((*chain_routine),(int, int, void *, void *, void *)); +#endif } winchoices[] = { #ifdef TTY_GRAPHICS - { &tty_procs, win_tty_init }, + { &tty_procs, win_tty_init CHAINR(0) }, #endif #ifdef X11_GRAPHICS - { &X11_procs, win_X11_init }, + { &X11_procs, win_X11_init CHAINR(0) }, #endif #ifdef QT_GRAPHICS - { &Qt_procs, 0 }, + { &Qt_procs, 0 CHAINR(0) }, #endif #ifdef GEM_GRAPHICS - { &Gem_procs, win_Gem_init }, + { &Gem_procs, win_Gem_init CHAINR(0) }, #endif #ifdef MAC - { &mac_procs, 0 }, + { &mac_procs, 0 CHAINR(0) }, #endif #ifdef BEOS_GRAPHICS - { &beos_procs, be_win_init }, + { &beos_procs, be_win_init CHAINR(0) }, #endif #ifdef AMIGA_INTUITION - { &amii_procs, ami_wininit_data }, /* Old font version of the game */ - { &amiv_procs, ami_wininit_data }, /* Tile version of the game */ + { &amii_procs, ami_wininit_data CHAINR(0) }, /* Old font version of the game */ + { &amiv_procs, ami_wininit_data CHAINR(0) }, /* Tile version of the game */ #endif #ifdef WIN32_GRAPHICS - { &win32_procs, 0 }, + { &win32_procs, 0 CHAINR(0) }, #endif #ifdef GNOME_GRAPHICS - { &Gnome_procs, 0 }, + { &Gnome_procs, 0 CHAINR(0) }, #endif #ifdef MSWIN_GRAPHICS - { &mswin_procs, 0 }, + { &mswin_procs, 0 CHAINR(0) }, #endif - { 0, 0 } /* must be last */ +#ifdef WINCHAIN + { &chainin_procs, chainin_procs_init, chainin_procs_chain }, + { (struct window_procs *)&chainout_procs, chainout_procs_init, chainout_procs_chain }, + + { (struct window_procs *)&trace_procs, trace_procs_init, trace_procs_chain }, +#endif + { 0, 0 CHAINR(0) } /* must be last */ }; +#ifdef WINCHAIN +struct winlink { + struct winlink *nextlink; + struct win_choices *wincp; + void *linkdata; +}; +/* NB: this chain does not contain the terminal real window system pointer */ + +static struct winlink *chain = 0; + +static struct winlink *wl_new(){ + return calloc(1, sizeof(struct winlink)); +} +static void wl_addhead(struct winlink *wl){ + wl->nextlink = chain; + chain = wl; +} +static void wl_addtail(struct winlink *wl){ + struct winlink *p = chain; + + if(!chain){ chain = wl; return; } + while(p->nextlink){ p=p->nextlink; } + p->nextlink = wl; + return; +} +#endif + static struct win_choices *last_winchoice = 0; boolean @@ -107,6 +162,24 @@ const char *s; puts(s); } +#ifdef WINCHAIN +static struct win_choices * +win_choices_find(s) +const char *s; +{ + register int i; + + for(i=0; winchoices[i].procs; i++){ + if(!strcmpi(s, winchoices[i].procs->name)){ + return &winchoices[i]; + } + } + + return NULL; + +} +#endif + void choose_windows(s) const char *s; @@ -114,6 +187,8 @@ const char *s; register int i; for(i=0; winchoices[i].procs; i++){ + if ('+' == winchoices[i].procs->name[0]) continue; + if ('-' == winchoices[i].procs->name[0]) continue; if (!strcmpi(s, winchoices[i].procs->name)) { windowprocs = *winchoices[i].procs; @@ -139,6 +214,8 @@ const char *s; } else { raw_printf("Window type %s not recognized. Choices are:", s); for(i=0; winchoices[i].procs; i++){ + if ('+' == winchoices[i].procs->name[0]) continue; + if ('-' == winchoices[i].procs->name[0]) continue; raw_printf(" %s", winchoices[i].procs->name); } } @@ -148,6 +225,112 @@ const char *s; wait_synch(); } +#ifdef WINCHAIN +void +addto_windowchain(s) +const char *s; +{ + register int i; + + for(i=0; winchoices[i].procs; i++) { + if ('+' != winchoices[i].procs->name[0]) continue; + if (!strcmpi(s, winchoices[i].procs->name)) { + struct winlink *p = wl_new(); + p->wincp = &winchoices[i]; + wl_addtail(p); + /* NB: The ini_routine() will be called during commit. */ + return; + } + } + + windowprocs.win_raw_print = def_raw_print; + + raw_printf("Window processor %s not recognized. Choices are:", s); + for(i=0; winchoices[i].procs; i++) { + if ('+' != winchoices[i].procs->name[0]) continue; + raw_printf(" %s", winchoices[i].procs->name); + } + + exit(EXIT_FAILURE); +} + +void +commit_windowchain(){ + struct winlink *p; + int n; + int wincap, wincap2; + + if(!chain) return; + + /* Save wincap* from the real window system - we'll restore it below. */ + wincap = windowprocs.wincap; + wincap2 = windowprocs.wincap2; + + /* add -chainin at head and -chainout at tail */ + p=wl_new(); + p->wincp = win_choices_find("-chainin"); + if(! p->wincp){ + raw_printf("Can't locate processor '-chainin'"); + exit(EXIT_FAILURE); + } + wl_addhead(p); + + p=wl_new(); + p->wincp = win_choices_find("-chainout"); + if(! p->wincp){ + raw_printf("Can't locate processor '-chainout'"); + exit(EXIT_FAILURE); + } + wl_addtail(p); + + /* Now alloc() init() similar to Objective-C. */ + for(n=1,p=chain;p;n++,p=p->nextlink){ + p->linkdata = (*p->wincp->chain_routine)(WINCHAIN_ALLOC,n,0,0,0); + } + + for(n=1,p=chain;p;n++,p=p->nextlink){ + if(p->nextlink){ + (void)(*p->wincp->chain_routine)( + WINCHAIN_INIT,n, + p->linkdata,p->nextlink->wincp->procs, + p->nextlink->linkdata + ); + } else { + (void)(*p->wincp->chain_routine)( + WINCHAIN_INIT,n, + p->linkdata,last_winchoice->procs, + 0 + ); + } + } + + /* Restore the saved wincap* values. We do it here to give the + * ini_routine()s a chance to change or check them. */ + chain->wincp->procs->wincap = wincap; + chain->wincp->procs->wincap2 = wincap2; + + /* Call the init procs. Do not re-init the terminal real win. */ + p=chain; + while(p->nextlink){ + if(p->wincp->ini_routine){ + (*p->wincp->ini_routine)(WININIT); + } + p=p->nextlink; + } + + /* Install the chain into window procs very late so ini_routine()s + * can raw_print on error. */ + windowprocs = *chain->wincp->procs; + + p=chain; + while(p){ + struct winlink *np = p->nextlink; + free(p); + p = np; /* assignment, not proof */ + } +} +#endif + /* * tty_message_menu() provides a means to get feedback from the * --More-- prompt; other interfaces generally don't need that. @@ -155,8 +338,8 @@ const char *s; /*ARGSUSED*/ char genl_message_menu(let, how, mesg) -char let; -int how; +char let UNUSED; +int how UNUSED; const char *mesg; { pline1(mesg); @@ -166,7 +349,7 @@ const char *mesg; /*ARGSUSED*/ void genl_preference_update(pref) -const char *pref; +const char *pref UNUSED; { /* window ports are expected to provide their own preference update routine @@ -178,7 +361,7 @@ const char *pref; char * genl_getmsghistory(init) -boolean init; +boolean init UNUSED; { /* window ports can provide their own getmsghistory() routine to @@ -197,8 +380,8 @@ boolean init; /*ARGSUSED*/ void genl_putmsghistory(msg, is_restoring) -const char *msg; -boolean is_restoring; +const char *msg UNUSED; +boolean is_restoring UNUSED; { /* window ports can provide their own putmsghistory() routine to @@ -392,7 +575,7 @@ hup_nhgetch( VOID_ARGS ) /*ARGSUSED*/ static char hup_yn_function(prompt, resp, deflt) -const char *prompt, *resp; +const char *prompt UNUSED, *resp UNUSED; char deflt; { if (!deflt) deflt = '\033'; @@ -402,7 +585,7 @@ char deflt; /*ARGSUSED*/ static int hup_nh_poskey(x, y, mod) -int *x, *y, *mod; +int *x UNUSED, *y UNUSED, *mod UNUSED; { return '\033'; } @@ -410,7 +593,7 @@ int *x, *y, *mod; /*ARGSUSED*/ static void hup_getlin(prompt, outbuf) -const char *prompt; +const char *prompt UNUSED; char *outbuf; { Strcpy(outbuf, "\033"); @@ -419,8 +602,8 @@ char *outbuf; /*ARGSUSED*/ static void hup_init_nhwindows(argc_p, argv) -int *argc_p; -char **argv; +int *argc_p UNUSED; +char **argv UNUSED; { iflags.window_inited = 1; } @@ -428,7 +611,7 @@ char **argv; /*ARGUSED*/ static winid hup_create_nhwindow(type) -int type; +int type UNUSED; { return WIN_ERR; } @@ -436,9 +619,9 @@ int type; /*ARGSUSED*/ static int hup_select_menu(window, how, menu_list) -winid window; -int how; -struct mi **menu_list; +winid window UNUSED; +int how UNUSED; +struct mi **menu_list UNUSED; { return -1; } @@ -446,12 +629,12 @@ struct mi **menu_list; /*ARGSUSED*/ static void hup_add_menu(window, glyph, identifier, sel, grpsel, attr, txt, preselected) -winid window; -int glyph, attr; -const anything *identifier; -char sel, grpsel; -const char *txt; -boolean preselected; +winid window UNUSED; +int glyph UNUSED, attr UNUSED; +const anything *identifier UNUSED; +char sel UNUSED, grpsel UNUSED; +const char *txt UNUSED; +boolean preselected UNUSED; { return; } @@ -459,8 +642,8 @@ boolean preselected; /*ARGSUSED*/ static void hup_end_menu(window, prompt) -winid window; -const char *prompt; +winid window UNUSED; +const char *prompt UNUSED; { return; } @@ -468,9 +651,9 @@ const char *prompt; /*ARGSUSED*/ static void hup_putstr(window, attr, text) -winid window; -int attr; -const char *text; +winid window UNUSED; +int attr UNUSED; +const char *text UNUSED; { return; } @@ -478,9 +661,9 @@ const char *text; /*ARGSUSED*/ static void hup_print_glyph(window, x, y, glyph) -winid window; -xchar x, y; -int glyph; +winid window UNUSED; +xchar x UNUSED, y UNUSED; +int glyph UNUSED; { return; } @@ -488,8 +671,8 @@ int glyph; /*ARGSUSED*/ static void hup_outrip(tmpwin, how) -winid tmpwin; -int how; +winid tmpwin UNUSED; +int how UNUSED; { return; } @@ -497,8 +680,8 @@ int how; /*ARGSUSED*/ static void hup_curs(window, x, y) -winid window; -int x, y; +winid window UNUSED; +int x UNUSED, y UNUSED; { return; } @@ -506,8 +689,8 @@ int x, y; /*ARGSUSED*/ static void hup_display_nhwindow(window, blocking) -winid window; -boolean blocking; +winid window UNUSED; +boolean blocking UNUSED; { return; } @@ -515,8 +698,8 @@ boolean blocking; /*ARGSUSED*/ static void hup_display_file(fname, complain) -const char *fname; -boolean complain; +const char *fname UNUSED; +boolean complain UNUSED; { return; } @@ -525,7 +708,7 @@ boolean complain; /*ARGSUSED*/ static void hup_cliparound(x, y) -int x, y; +int x UNUSED, y UNUSED; { return; } @@ -563,8 +746,8 @@ hup_get_color_string(VOID_ARGS) /*ARGSUSED*/ static void hup_status_update(idx, ptr, chg, percent) -int idx, chg, percent; -genericptr_t ptr; +int idx UNUSED, chg UNUSED, percent UNUSED; +genericptr_t ptr UNUSED; { return; } @@ -589,7 +772,7 @@ hup_void_ndecl(VOID_ARGS) /*ARGUSED*/ static void hup_void_fdecl_int(arg) -int arg; +int arg UNUSED; { return; } @@ -597,7 +780,7 @@ int arg; /*ARGUSED*/ static void hup_void_fdecl_winid(window) -winid window; +winid window UNUSED; { return; } @@ -605,7 +788,7 @@ winid window; /*ARGUSED*/ static void hup_void_fdecl_constchar_p(string) -const char *string; +const char *string UNUSED; { return; } diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index ea5873aaa..3e8748daf 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -349,11 +349,16 @@ WINCSRC = $(WINTTYSRC) $(WINX11SRC) $(WINGNOMESRC) $(WINGEMSRC) # all windowing-system-dependent .cpp (for dependencies and such) WINCXXSRC = $(WINQTSRC) $(WINBESRC) +# Files for window system chaining. Requires SYSCF; include via HINTSRC/HINTOBJ +CHAINSRC=../win/chain/wc_chainin.c ../win/chain/wc_chainout.c \ + ../win/chain/wc_trace.c +CHAINOBJ=wc_chainin.o wc_chainout.o wc_trace.o + # .c files for this version (for date.h) VERSOURCES = $(HACKCSRC) $(SYSSRC) $(WINSRC) $(GENCSRC) # .c files for all versions using this Makefile (for lint and tags) -CSOURCES = $(HACKCSRC) $(SYSSRC) $(WINCSRC) $(GENCSRC) +CSOURCES = $(HACKCSRC) $(SYSSRC) $(WINCSRC) $(GENCSRC) $(HINTSRC) # all .h files except date.h, onames.h, pm.h, and vis_tab.h which would @@ -392,7 +397,7 @@ HOBJ = $(FIRSTOBJ) allmain.o alloc.o apply.o artifact.o attrib.o ball.o \ steal.o steed.o teleport.o timeout.o topten.o track.o trap.o u_init.o \ uhitm.o vault.o vision.o vis_tab.o weapon.o were.o wield.o windows.o \ wizard.o worm.o worn.o write.o zap.o \ - $(RANDOBJ) $(SYSOBJ) $(WINOBJ) version.o + $(RANDOBJ) $(SYSOBJ) $(WINOBJ) $(HINTOBJ) version.o # the .o files from the HACKCSRC, SYSSRC, and WINSRC lists $(GAME): $(SYSTEM) @@ -702,6 +707,12 @@ qt_clust.o: ../win/Qt/qt_clust.cpp ../include/qt_clust.h $(CXX) $(CXXFLAGS) -c ../win/Qt/qt_clust.cpp qttableview.o: ../win/Qt/qttableview.cpp ../include/qttableview.h $(CXX) $(CXXFLAGS) -c ../win/Qt/qttableview.cpp +wc_chainin.o: ../win/chain/wc_chainin.c $(HACK_H) + $(CC) $(CFLAGS) -c ../win/chain/wc_chainin.c +wc_chainout.o: ../win/chain/wc_chainout.c $(HACK_H) + $(CC) $(CFLAGS) -c ../win/chain/wc_chainout.c +wc_trace.o: ../win/chain/wc_trace.c $(HACK_H) ../include/func_tab.h + $(CC) $(CFLAGS) -c ../win/chain/wc_trace.c monstr.o: monstr.c $(CONFIG_H) vis_tab.o: vis_tab.c $(CONFIG_H) ../include/vis_tab.h allmain.o: allmain.c $(HACK_H) diff --git a/sys/unix/hints/macosx10.7 b/sys/unix/hints/macosx10.7 new file mode 100644 index 000000000..4b485f1c1 --- /dev/null +++ b/sys/unix/hints/macosx10.7 @@ -0,0 +1,303 @@ +# +# NetHack 3.5 macosx10.7 $Date$ $Revision$ +# Copyright (c) Kenneth Lorber, Kensington, Maryland, 2009. +# NetHack may be freely redistributed. See license for details. +# +#-PRE +# Mac OS X (Darwin) hints file +# This is for Mac OS X 10.7.2. If this doesn't work for some other version +# of Mac OS X, make a new file for that OS, don't change this one. And +# let us know about it. +# Useful info: http://www.opensource.apple.com/darwinsource/index.html + +# This hints file can build several different types of installations. +# Edit the next section to match the type of build you need. + +# 1. Which window system(s) should be included in this binary? +WANT_WIN_TTY=1 +#WANT_WIN_X11=1 +#WANT_WIN_QT=1 + +# 1a. What is the default window system? +WANT_DEFAULT=tty +#WANT_DEFAULT=x11 +#WANT_DEFAULT=qt + +# 1b. If you set WANT_WIN_QT, you need to +# A) set QTDIR either here or in the environment to point to the Qt2 or Qt3 +# library installation root. (Qt4 will not work; Qt3 does not presently +# compile under Leopard (MacOSX 10.5) out-of-the-box.) +# B) set XPMLIB to point to the Xpm library +ifdef WANT_WIN_QT +QTDIR=/Developer/Qt +LIBXPM= -L/Developer/SDKs/MacOSX10.3.9.sdk/usr/X11R6/lib -lXpm +endif # WANT_WIN_QT + +# 2. Is this a build for a binary that will be shared among different users +# or will it be private to you? +# If it is shared: +# - it will be owned by the user and group listed +# - if the user does not exist, you MUST create it before installing +# NetHack +# - if the group does not exist, it will be created. +# NB: if the group already exists and is being used for something +# besides games, you probably want to specify a new group instead +# NB: the group will be created locally; if your computer is centrally +# administered this may not be what you (or your admin) want. +# Consider a non-shared install (WANT_SHARE_INSTALL=0) instead. +# - 'make install' must be run as "sudo make install" +#WANT_SHARE_INSTALL=1 +GAMEUID = $(USER) +GAMEGRP = games +# build to run in the source tree - primarily for development. Build with "make all" +#WANT_SOURCE_INSTALL=1 + +#CC=gcc -W -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wcast-qual -Wwrite-strings -DGCC_WARN +CC=gcc -Wall -Wextra -Wno-missing-field-initializers -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -DGCC_WARN -ansi -pedantic + +# At the moment this is just for debugging, but in the future it could be +# useful for other things. Requires SYSCF and an ANSI compiler. +#WANT_WIN_CHAIN=1 + +# +# You shouldn't need to change anything below here. +# + +# XXX -g vs -O should go here, -I../include goes in the makefile +CFLAGS=-g -I../include +#CFLAGS+=-DNOCLIPPING +CFLAGS+= -DNOMAIL -DNOTPARMDECL -DHACKDIR=\"$(HACKDIR)\" +CFLAGS+= -DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" -DDLB + +CFLAGS+= -DGREPPATH=\"/usr/bin/grep\" + +ifdef WANT_WIN_CHAIN +CFLAGS+= -DWINCHAIN +HINTSRC=$(CHAINSRC) +HINTOBJ=$(CHAINOBJ) +endif + +ifdef WANT_WIN_TTY +WINSRC = $(WINTTYSRC) +WINOBJ = $(WINTTYOBJ) +WINLIB = $(WINTTYLIB) +WINTTYLIB=-lncurses +else # !WANT_WIN_TTY +CFLAGS += -DNOTTYGRAPHICS +endif # !WANT_WIN_TTY + +ifdef WANT_WIN_X11 +WINSRC += $(WINX11SRC) +WINOBJ += $(WINX11OBJ) +WINLIB += $(WINX11LIB) +LFLAGS=-L/usr/X11R6/lib +VARDATND = x11tiles NetHack.ad pet_mark.xbm +POSTINSTALL+= bdftopcf win/X11/nh10.bdf > $(HACKDIR)/nh10.pcf; (cd $(HACKDIR); mkfontdir); +CFLAGS += -DX11_GRAPHICS +endif # WANT_WIN_X11 + +ifdef WANT_WIN_QT +CFLAGS += -DQT_GRAPHICS -DNOUSER_SOUNDS +CFLAGS += -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 +LINK=g++ +WINSRC += $(WINQTSRC) +WINLIB += $(WINQTLIB) $(LIBXPM) +WINLIB += -framework Carbon -framework QuickTime -lz -framework OpenGL +WINLIB += -framework AGL +ifdef WANT_WIN_X11 + # prevent duplicate tile.o in WINOBJ +WINOBJ = $(sort $(WINQTOBJ) $(WINX11OBJ)) +ifdef WANT_WIN_TTY +WINOBJ += $(WINTTYOBJ) +endif # WANT_WIN_TTY +else # !WANT_WIN_X11 +WINOBJ += $(WINQTOBJ) +endif # !WANT_WIN_X11 + +# XXX if /Developer/qt exists and QTDIR not set, use that +ifndef QTDIR +$(error QTDIR not defined in the environment or Makefile) +endif # QTDIR +# XXX make sure QTDIR points to something reasonable +else # !WANT_WIN_QT +LINK=$(CC) +endif # !WANT_WIN_QT + +ifdef WANT_SHARE_INSTALL +# if $GAMEUID is root, we install into roughly proper Mac locations, otherwise +# we install into ~/nethackdir +ifeq ($(GAMEUID),root) +PREFIX:=/Library/NetHack +SHELLDIR=/usr/local/bin +HACKDIR=$(PREFIX)/nethackdir +CHOWN=chown +CHGRP=chgrp +# We run sgid so the game has access to both HACKDIR and user preferences. +GAMEPERM = 02755 +else # ! root +PREFIX:=/Users/$(GAMEUID) +SHELLDIR=$(PREFIX)/bin +HACKDIR=$(PREFIX)/nethackdir +CHOWN=touch +CHGRP=touch +GAMEPERM = 0500 +endif # ! root +VARFILEPERM = 0664 +VARDIRPERM = 0775 +ROOTCHECK= [[ `id -u` == 0 ]] || ( echo "Must run install with sudo."; exit 1) +# XXX it's nice we don't write over sysconf, but we've already erased it +# make sure we have group GAMEUID and group GAMEGRP +PREINSTALL= . sys/unix/hints/macosx.sh user2 $(GAMEUID); . sys/unix/hints/macosx.sh group2 $(GAMEGRP); mkdir $(SHELLDIR); chown $(GAMEUID) $(SHELLDIR) +POSTINSTALL+= cp -n sys/unix/sysconf $(HACKDIR)/sysconf; $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; chmod $(VARFILEPERM) $(HACKDIR)/sysconf; +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +else ifdef WANT_SOURCE_INSTALL +PREFIX=$(abspath $(NHSROOT)) +# suppress nethack.sh +#SHELLDIR= +HACKDIR=$(PREFIX)/playground +CHOWN=touch +CHGRP=touch +GAMEPERM = 0700 +VARFILEPERM = 0600 +VARDIRPERM = 0700 +# We can use "make all" to build the whole thing - but it misses some things: +MOREALL=$(MAKE) install +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +else # !WANT_SOURCE_INSTALL +PREFIX:=$(wildcard ~) +SHELLDIR=$(PREFIX)/bin +HACKDIR=$(PREFIX)/nethackdir +CHOWN=true +CHGRP=true +GAMEPERM = 0700 +VARFILEPERM = 0600 +VARDIRPERM = 0700 +ifdef WANT_WIN_X11 +# install nethack.rc as ~/.nethackrc if no ~/.nethackrc exists +PREINSTALL= cp -n win/X11/nethack.rc ~/.nethackrc +endif # WANT_WIN_X11 +POSTINSTALL+= cp -n sys/unix/sysconf $(HACKDIR)/sysconf; $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; chmod $(VARFILEPERM) $(HACKDIR)/sysconf; +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +endif # !WANT_SOURCE_INSTALL + + +# ~/Library/Preferences/NetHack Defaults +# OPTIONS=name:player,number_pad,menustyle:partial,!time,showexp +# OPTIONS=hilite_pet,toptenwin,msghistory:200,windowtype:Qt +# +# Install.Qt mentions a patch for macos - it's not there (it seems to be in the Qt binary +# package under the docs directory). + +#-POST +ifdef MAKEFILE_TOP +### +### Packaging +### +# Notes: +# 1) The Apple developer utilities must be installed in the default location. +# 2) Do a normal build before trying to package the game. +# 3) This matches the 3.4.3 Term package, but there are some things that should +# be changed. + +ifdef WANT_WIN_TTY +DEVUTIL=/Developer/Applications/Utilities +PKGR=$(DEVUTIL)/PackageMaker.app/Contents/MacOS/PackageMaker +SVS=$(shell $(NHSROOT)/util/makedefs --svs) +SVSDOT=$(shell $(NHSROOT)/util/makedefs --svs .) + +PKGROOT_UG = PKGROOT/usr/games +PKGROOT_UGLN = PKGROOT/usr/games/lib/nethackdir +build_tty_pkg: +ifneq (,$(WANT_WIN_X11)$(WANT_WIN_QT)) + -echo build_tty_pkg only works for a tty-only build + exit 1 +else + rm -rf NetHack-$(SVS)-mac-Term.pkg NetHack-$(SVS)-mac-Term.dmg + $(MAKE) build_package_root + rm -rf RESOURCES + mkdir RESOURCES + #enscript --language=rtf -o - < dat/license >RESOURCES/License.rtf + sys/unix/hints/macosx.sh descplist > RESOURCES/Description.plist + sys/unix/hints/macosx.sh infoplist > Info.plist + + mkdir PKGROOT/Applications + #osacompile -o NetHackQt/NetHackQt.app/nethackdir/NetHackRecover.app \ + # win/macosx/NetHackRecover.applescript + #cp win/macosx/recover.pl NetHackQt/NetHackQt.app/nethackdir + osacompile -o PKGROOT/Applications/NetHackRecover.app \ + win/macosx/NetHackRecover.applescript + cp win/macosx/recover.pl $(PKGROOT_UGLN) + + osacompile -o PKGROOT/Applications/NetHackTerm.app \ + win/macosx/NetHackTerm.applescript + + # XXX integrate into Makefile.doc + (cd doc; cat Guidebook.mn | ../util/makedefs --grep --input - --output - \ + | tbl tmac.n - | groff |ps2pdf - > Guidebook.pdf) + cp doc/Guidebook.pdf $(PKGROOT_UG)/doc/NetHackGuidebook.pdf + + osacompile -o PKGROOT/Applications/NetHackGuidebook.app \ + win/macosx/NetHackGuidebook.applescript + + $(PKGR) --root PKGROOT --info Info.plist -e RESOURCES -v -o NetHack-$(SVS)-mac-Term.pkg + hdiutil create -verbose -srcfolder NetHack-$(SVS)-mac-Term.pkg NetHack-$(SVS)-mac-Term.dmg + +build_package_root: + cd src/.. # make sure we are at TOP + rm -rf PKGROOT + mkdir -p $(PKGROOT_UG)/lib $(PKGROOT_UG)/bin $(PKGROOT_UG)/man/man6 $(PKGROOT_UG)/doc $(PKGROOT_UGLN) + install -p src/nethack $(PKGROOT_UG)/bin + # XXX should this be called nethackrecover? + install -p util/recover $(PKGROOT_UG)/bin + install -p doc/nethack.6 $(PKGROOT_UG)/man/man6 + install -p doc/recover.6 $(PKGROOT_UG)/man/man6 + install -p doc/Guidebook $(PKGROOT_UG)/doc + install -p dat/nhdat $(PKGROOT_UGLN) + cd dat; install -p $(DATNODLB) ../$(PKGROOT_UGLN) +# XXX these files should be somewhere else for good Mac form + touch $(PKGROOT_UGLN)/perm $(PKGROOT_UGLN)/record $(PKGROOT_UGLN)/logfile +# XXX may need postinstall script to get perms right for sgid, etc. + mkdir $(PKGROOT_UGLN)/save +# XXX what about a news file? +endif # end of build_tty_pkg +endif # WANT_WIN_TTY for packaging + +ifdef WANT_WIN_QT +# XXX untested and incomplete (see below) +build_qt_pkg: +ifneq (,$(WANT_WIN_X11)$(WANT_WIN_TTY)) + -echo build_qt_pkg only works for a qt-only build + exit 1 +else + $(MAKE) build_package_root + rm -rf NetHackQt + mkdir -p NetHackQt/NetHackQt.app/nethackdir/save + mkdir NetHackQt/Documentation + cp doc/Guidebook.txt doc/nethack.txt doc/recover.txt NetHackQt/Documentation + + osacompile -o NetHackQt/NetHackQt.app/nethackdir/NetHackRecover.app \ + win/macosx/NetHackRecover.applescript + cp win/macosx/recover.pl NetHackQt/NetHackQt.app/nethackdir + + mkdir -p NetHackQt/NetHackQt.app/Contents/Frameworks + cp $(QTDIR)/libqt-mt.3.dylib NetHackQt/NetHackQt.app/Contents/Frameworks + + mkdir NetHackQt/NetHackQt.app/Contents/MacOS + mv PKGROOT/nethack NetHackQt/NetHackQt.app/Contents/MacOS + + mv PKGROOT/lib/nethackdir NetHackQt/NetHackQt.app/nethackdir + +# XXX still missing: +#NetHackQt/NetHackQt.app +# /Contents +# Info.plist +# Resources/nethack.icns +#NetHackQt/Documentation +#NetHackQtRecover.txt +#NetHack Defaults.txt +#changes.patch XXX is this still needed? why isn't it part of the tree? +# doesn't go here + hdiutil create -verbose -srcfolder NetHackQt NetHack-$(SVS)-macosx-qt.dmg +endif # end of build_qt_pkg +endif # WANT_WIN_QT for packaging +endif # MAKEFILE_TOP diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 8caa24b9b..55a429f4e 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -182,6 +182,9 @@ char *argv[]; #endif process_options(argc, argv); /* command line options */ +#ifdef WINCHAIN + commit_windowchain(); +#endif init_nhwindows(&argc, argv); /* now we can set up window system */ #ifdef _M_UNIX init_sco_cons(); diff --git a/win/chain/wc_chainin.c b/win/chain/wc_chainin.c new file mode 100644 index 000000000..c1bc50cbc --- /dev/null +++ b/win/chain/wc_chainin.c @@ -0,0 +1,598 @@ +/* NetHack 3.5 wc_chainin.c $Date$ $Revision$ */ +/* Copyright (c) Kenneth Lorber, 2012 */ +/* NetHack may be freely redistributed. See license for details. */ + +/* -chainin is an internal processor that changes the flow from window_procs + * to chain_procs. */ + +#include "hack.h" + +struct chainin_data { + struct chain_procs *nprocs; + void *ndata; + + int linknum; +}; + +/* Normally, a processor gets this information from the first parm of each + * call, but here we are keeping the original API, so that parm doesn't exist, + * so we use this instead. */ +static struct chainin_data *cibase; + +void * +chainin_procs_chain(cmd, n, me, nextprocs, nextdata) + int cmd; + int n; + void *me; + void *nextprocs; + void *nextdata; +{ + switch(cmd){ + case WINCHAIN_ALLOC: { + struct chainin_data *tdp = calloc(1, sizeof(struct chainin_data)); + tdp->linknum = n; + cibase = tdp; + return tdp; + } + case WINCHAIN_INIT: { + struct chainin_data *tdp = me; + tdp->nprocs = nextprocs; + tdp->ndata = nextdata; + return tdp; + } + default: + raw_printf("chainin_procs_chain: bad cmd\n"); + exit(EXIT_FAILURE); + } +} + +/* XXX if we don't need this, take it out of the table */ +void +chainin_procs_init(dir) + int dir UNUSED; +{ +} + +/*** + *** winprocs + ***/ + +void +chainin_init_nhwindows(argcp, argv) + int *argcp; + char **argv; +{ + (*cibase->nprocs->win_init_nhwindows)(cibase->ndata, argcp, argv); +} + + +void +chainin_player_selection() +{ + (*cibase->nprocs->win_player_selection)(cibase->ndata); +} + +void +chainin_askname() +{ + (*cibase->nprocs->win_askname)(cibase->ndata); +} + +void +chainin_get_nh_event() +{ + (*cibase->nprocs->win_get_nh_event)(cibase->ndata); +} + +void +chainin_exit_nhwindows(str) + const char *str; +{ + (*cibase->nprocs->win_exit_nhwindows)(cibase->ndata, str); +} + +void +chainin_suspend_nhwindows(str) + const char *str; +{ + (*cibase->nprocs->win_suspend_nhwindows)(cibase->ndata, str); +} + +void +chainin_resume_nhwindows() +{ + (*cibase->nprocs->win_resume_nhwindows)(cibase->ndata); +} + +winid +chainin_create_nhwindow(type) + int type; +{ + winid rv; + + rv = (*cibase->nprocs->win_create_nhwindow)(cibase->ndata, type); + + return rv; +} + +void +chainin_clear_nhwindow(window) + winid window; +{ + (*cibase->nprocs->win_clear_nhwindow)(cibase->ndata, window); +} + +void +chainin_display_nhwindow(window, blocking) + winid window; + BOOLEAN_P blocking; +{ + (*cibase->nprocs->win_display_nhwindow)(cibase->ndata, window, blocking); +} + +void +chainin_destroy_nhwindow(window) + winid window; +{ + (*cibase->nprocs->win_destroy_nhwindow)(cibase->ndata, window); +} + +void +chainin_curs(window, x, y) + winid window; + int x; + int y; +{ + (*cibase->nprocs->win_curs)(cibase->ndata, window, x, y); +} + +void +chainin_putstr(window, attr, str) + winid window; + int attr; + const char *str; +{ + (*cibase->nprocs->win_putstr)(cibase->ndata, window, attr, str); +} + +void +chainin_putmixed(window, attr, str) + winid window; + int attr; + const char *str; +{ + (*cibase->nprocs->win_putmixed)(cibase->ndata, window, attr, str); +} + +void +chainin_display_file(fname, complain) + const char *fname; + boolean complain; +{ + (*cibase->nprocs->win_display_file)(cibase->ndata, fname, complain); +} + +void +chainin_start_menu(window) + winid window; +{ + (*cibase->nprocs->win_start_menu)(cibase->ndata, window); +} + +void +chainin_add_menu(window, glyph, identifier, ch, gch, attr, str, preselected) + winid window; /* window to use, must be of type NHW_MENU */ + int glyph; /* glyph to display with item (unused) */ + const anything *identifier; /* what to return if selected */ + char ch; /* keyboard accelerator (0 = pick our own) */ + char gch; /* group accelerator (0 = no group) */ + int attr; /* attribute for string (like tty_putstr()) */ + const char *str; /* menu string */ + boolean preselected; /* item is marked as selected */ +{ + (*cibase->nprocs->win_add_menu)(cibase->ndata, window, glyph, identifier, + ch, gch, attr, str, preselected); +} + +void +chainin_end_menu(window, prompt) + winid window; + const char *prompt; +{ + (*cibase->nprocs->win_end_menu)(cibase->ndata, window, prompt); +} + +int +chainin_select_menu(window, how, menu_list) + winid window; + int how; + menu_item **menu_list; +{ + int rv; + + rv = (*cibase->nprocs->win_select_menu)(cibase->ndata, window, how, + (void *)menu_list); + + return rv; +} + +char +chainin_message_menu(let, how, mesg) + char let; + int how; + const char *mesg; +{ + char rv; + + rv = (*cibase->nprocs->win_message_menu)(cibase->ndata, let, how, mesg); + + return rv; +} + +void +chainin_update_inventory() +{ + (*cibase->nprocs->win_update_inventory)(cibase->ndata); +} + +void +chainin_mark_synch() +{ + (*cibase->nprocs->win_mark_synch)(cibase->ndata); +} + +void +chainin_wait_synch() +{ + (*cibase->nprocs->win_wait_synch)(cibase->ndata); +} + +#ifdef CLIPPING +void +chainin_cliparound(x, y) + int x; + int y; +{ + (*cibase->nprocs->win_cliparound)(cibase->ndata, x, y); +} +#endif + +#ifdef POSITIONBAR +void +chainin_update_positionbar(posbar) + char *posbar; +{ + (*cibase->nprocs->win_update_positionbar)(cibase->ndata, posbar); +} +#endif + +/* XXX can we decode the glyph in a meaningful way? */ +void +chainin_print_glyph(window, x, y, glyph) + winid window; + xchar x, y; + int glyph; +{ + (*cibase->nprocs->win_print_glyph)(cibase->ndata, window, x, y, glyph); +} + +void +chainin_raw_print(str) + const char *str; +{ + (*cibase->nprocs->win_raw_print)(cibase->ndata, str); +} + +void +chainin_raw_print_bold(str) + const char *str; +{ + (*cibase->nprocs->win_raw_print_bold)(cibase->ndata, str); +} + +int +chainin_nhgetch() +{ + int rv; + + rv = (*cibase->nprocs->win_nhgetch)(cibase->ndata); + + return rv; +} + +int +chainin_nh_poskey(x, y, mod) + int *x; + int *y; + int *mod; +{ + int rv; + + rv = (*cibase->nprocs->win_nh_poskey)(cibase->ndata, x, y, mod); + + return rv; +} + +void +chainin_nhbell() +{ + (*cibase->nprocs->win_nhbell)(cibase->ndata); +} + +int +chainin_doprev_message() +{ + int rv; + + rv = (*cibase->nprocs->win_doprev_message)(cibase->ndata); + + return rv; +} + +char +chainin_yn_function(query, resp, def) + const char *query, *resp; + char def; +{ + int rv; + + rv = (*cibase->nprocs->win_yn_function)(cibase->ndata, query, resp, def); + + return rv; +} + + +void +chainin_getlin(query, bufp) + const char *query; + char *bufp; +{ + (*cibase->nprocs->win_getlin)(cibase->ndata, query, bufp); +} + +int +chainin_get_ext_cmd() +{ + int rv; + + rv = (*cibase->nprocs->win_get_ext_cmd)(cibase->ndata); + + return rv; +} + +void +chainin_number_pad(state) + int state; +{ + (*cibase->nprocs->win_number_pad)(cibase->ndata, state); +} + +void +chainin_delay_output() +{ + (*cibase->nprocs->win_delay_output)(cibase->ndata); +} + +#ifdef CHANGE_COLOR +void +chainin_change_color(color, value, reverse) + int color; + long value; + int reverse; +{ + (*cibase->nprocs->win_change_color)(cibase->ndata, color, value, reverse); +} + +#ifdef MAC +void +chainin_change_background(bw) + int bw; +{ + (*cibase->nprocs->win_change_background)(cibase->ndata, bw); +} + +short +chainin_set_font_name(window, font) + winid window; + char *font; +{ + short rv; + + rv = (*cibase->nprocs->win_set_font_name)(cibase->ndata, window, font); + + return rv; +} +#endif + +char *trace_get_color_string() +{ + char *rv; + + rv = (*cibase->nprocs->win_get_color_string)(cibase->ndata); + + return rv; +} + +#endif + +/* other defs that really should go away (they're tty specific) */ +void +chainin_start_screen() +{ + (*cibase->nprocs->win_start_screen)(cibase->ndata); +} + +void +chainin_end_screen() +{ + (*cibase->nprocs->win_end_screen)(cibase->ndata); +} + +void +chainin_outrip(tmpwin, how) + winid tmpwin; + int how; +{ + (*cibase->nprocs->win_outrip)(cibase->ndata, tmpwin, how); +} + +void +chainin_preference_update(pref) + const char *pref; +{ + (*cibase->nprocs->win_preference_update)(cibase->ndata, pref); +} + + +char * +chainin_getmsghistory(init) +boolean init; +{ + char *rv; + + rv = (*cibase->nprocs->win_getmsghistory)(cibase->ndata,init); + + return rv; +} + +void +chainin_putmsghistory(msg, is_restoring) +const char *msg; +boolean is_restoring; +{ + (*cibase->nprocs->win_putmsghistory)(cibase->ndata, msg, is_restoring); +} + +#ifdef STATUS_VIA_WINDOWPORT +void +chainin_status_init() +{ + (*cibase->nprocs->win_status_init)(cibase->ndata); +} + +void +chainin_status_finish() +{ + (*cibase->nprocs->win_status_finish)(cibase->ndata); +} + +void +chainin_status_enablefield(fieldidx, nm, fmt, enable) +int fieldidx; +const char *nm; +const char *fmt; +boolean enable; +{ + (*cibase->nprocs->win_status_enablefield)(cibase->ndata, fieldidx, nm, + fmt, enable); +} + +void +chainin_status_update(idx, ptr, chg, percent) +int idx, chg, percent; +genericptr_t ptr; +{ + (*cibase->nprocs->win_status_update)(cibase->ndata, idx, ptr, chg, percent); +} + +# ifdef STATUS_HILITES +void +chainin_status_threshold(fldidx, thresholdtype, threshold, behavior, under, over) +int fldidx,thresholdtype; +int behavior, under, over; +anything threshold; +{ + (*cibase->nprocs->win_status_threshold)(cibase->ndata,fldidx, thresholdtype, + threshold, behavior, under, over); +} +# endif +#endif + +boolean +chainin_can_suspend() +{ + boolean rv; + + rv = (*cibase->nprocs->win_can_suspend)(cibase->ndata); + + return rv; +} + +struct window_procs chainin_procs = { + "-chainin", + 0, /* wincap */ + 0, /* wincap2 */ +/* +XXX problem - the above need to come from the real window port, possibly +modified. May need to do something to call an additional init fn later +or if this is the only place like this the choose_windows fn can do the fixup +(but not if the value can be modified by the stack?) TBD +*/ + chainin_init_nhwindows, + chainin_player_selection, + chainin_askname, + chainin_get_nh_event, + chainin_exit_nhwindows, + chainin_suspend_nhwindows, + chainin_resume_nhwindows, + chainin_create_nhwindow, + chainin_clear_nhwindow, + chainin_display_nhwindow, + chainin_destroy_nhwindow, + chainin_curs, + chainin_putstr, + chainin_putmixed, + chainin_display_file, + chainin_start_menu, + chainin_add_menu, + chainin_end_menu, + chainin_select_menu, + chainin_message_menu, + chainin_update_inventory, + chainin_mark_synch, + chainin_wait_synch, +#ifdef CLIPPING + chainin_cliparound, +#endif +#ifdef POSITIONBAR + chainin_update_positionbar, +#endif + chainin_print_glyph, + chainin_raw_print, + chainin_raw_print_bold, + chainin_nhgetch, + chainin_nh_poskey, + chainin_nhbell, + chainin_doprev_message, + chainin_yn_function, + chainin_getlin, + chainin_get_ext_cmd, + chainin_number_pad, + chainin_delay_output, +#ifdef CHANGE_COLOR + chainin_change_color, +#ifdef MAC + chainin_change_background, + chainin_set_font_name, +#endif + chainin_get_color_string, +#endif + + chainin_start_screen, + chainin_end_screen, + + chainin_outrip, + chainin_preference_update, + chainin_getmsghistory, + chainin_putmsghistory, +#ifdef STATUS_VIA_WINDOWPORT + chainin_status_init, + chainin_status_finish, + chainin_status_enablefield, + chainin_status_update, +# ifdef STATUS_HILITES + chainin_status_threshold, +# endif +#endif + chainin_can_suspend, +}; diff --git a/win/chain/wc_chainout.c b/win/chain/wc_chainout.c new file mode 100644 index 000000000..be9bb894d --- /dev/null +++ b/win/chain/wc_chainout.c @@ -0,0 +1,737 @@ +/* NetHack 3.5 wc_chainout.c $Date$ $Revision$ */ +/* Copyright (c) Kenneth Lorber, 2012 */ +/* NetHack may be freely redistributed. See license for details. */ + +/* -chainout is an internal processor that changes the flow from chain_procs + * back to window_procs. */ + +#include "hack.h" + +struct chainout_data { + struct window_procs *nprocs; +#if 0 + void *ndata; + +#endif + int linknum; +}; + +void * +chainout_procs_chain(cmd, n, me, nextprocs, nextdata) + int cmd; + int n; + void *me; + void *nextprocs; + void *nextdata UNUSED; +{ + switch(cmd){ + case WINCHAIN_ALLOC: { + struct chainout_data *tdp = calloc(1, sizeof(struct chainout_data)); + tdp->linknum = n; + return tdp; + } + case WINCHAIN_INIT: { + struct chainout_data *tdp = me; + tdp->nprocs = nextprocs; + return tdp; + } + default: + raw_printf("chainout_procs_chain: bad cmd\n"); + exit(EXIT_FAILURE); + } +} + +/* XXX if we don't need this, take it out of the table */ +void +chainout_procs_init(dir) + int dir UNUSED; +{ +} + +/*** + *** winprocs + ***/ + +void +chainout_init_nhwindows(vp, argcp, argv) + void *vp; + int *argcp; + char **argv; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_init_nhwindows)(argcp, argv); +} + + +void +chainout_player_selection(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_player_selection)(); +} + +void +chainout_askname(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_askname)(); +} + +void +chainout_get_nh_event(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_get_nh_event)(); +} + +void +chainout_exit_nhwindows(vp, str) + void *vp; + const char *str; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_exit_nhwindows)(str); +} + +void +chainout_suspend_nhwindows(vp, str) + void *vp; + const char *str; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_suspend_nhwindows)(str); +} + +void +chainout_resume_nhwindows(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_resume_nhwindows)(); +} + +winid +chainout_create_nhwindow(vp, type) + void *vp; + int type; +{ + struct chainout_data *tdp = vp; + winid rv; + + rv = (*tdp->nprocs->win_create_nhwindow)(type); + + return rv; +} + +void +chainout_clear_nhwindow(vp, window) + void *vp; + winid window; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_clear_nhwindow)(window); +} + +void +chainout_display_nhwindow(vp, window, blocking) + void *vp; + winid window; + BOOLEAN_P blocking; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_display_nhwindow)(window, blocking); +} + +void +chainout_destroy_nhwindow(vp, window) + void *vp; + winid window; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_destroy_nhwindow)(window); +} + +void +chainout_curs(vp, window, x, y) + void *vp; + winid window; + int x; + int y; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_curs)(window, x, y); +} + +void +chainout_putstr(vp, window, attr, str) + void *vp; + winid window; + int attr; + const char *str; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_putstr)(window, attr, str); +} + +void +chainout_putmixed(vp, window, attr, str) + void *vp; + winid window; + int attr; + const char *str; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_putmixed)(window, attr, str); +} + +void +chainout_display_file(vp, fname, complain) + void *vp; + const char *fname; + boolean complain; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_display_file)(fname, complain); +} + +void +chainout_start_menu(vp, window) + void *vp; + winid window; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_start_menu)(window); +} + +void +chainout_add_menu(vp, window, glyph, identifier, ch, gch, attr, str, preselected) + void *vp; + winid window; /* window to use, must be of type NHW_MENU */ + int glyph; /* glyph to display with item (unused) */ + const anything *identifier; /* what to return if selected */ + char ch; /* keyboard accelerator (0 = pick our own) */ + char gch; /* group accelerator (0 = no group) */ + int attr; /* attribute for string (like tty_putstr()) */ + const char *str; /* menu string */ + boolean preselected; /* item is marked as selected */ +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_add_menu)(window, glyph, identifier, + ch, gch, attr, str, preselected); +} + +void +chainout_end_menu(vp, window, prompt) + void *vp; + winid window; + const char *prompt; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_end_menu)(window, prompt); +} + +int +chainout_select_menu(vp, window, how, menu_list) + void *vp; + winid window; + int how; + menu_item **menu_list; +{ + struct chainout_data *tdp = vp; + int rv; + + rv = (*tdp->nprocs->win_select_menu)(window, how, (void *)menu_list); + + return rv; +} + +char +chainout_message_menu(vp, let, how, mesg) + void *vp; + char let; + int how; + const char *mesg; +{ + struct chainout_data *tdp = vp; + char rv; + + rv = (*tdp->nprocs->win_message_menu)(let, how, mesg); + + return rv; +} + +void +chainout_update_inventory(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_update_inventory)(); +} + +void +chainout_mark_synch(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_mark_synch)(); +} + +void +chainout_wait_synch(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_wait_synch)(); +} + +#ifdef CLIPPING +void +chainout_cliparound(vp, x, y) + void *vp; + int x; + int y; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_cliparound)(x, y); +} +#endif + +#ifdef POSITIONBAR +void +chainout_update_positionbar(vp, posbar) + void *vp; + char *posbar; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_update_positionbar)(posbar); +} +#endif + +void +chainout_print_glyph(vp, window, x, y, glyph) + void *vp; + winid window; + xchar x, y; + int glyph; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_print_glyph)(window, x, y, glyph); +} + +void +chainout_raw_print(vp, str) + void *vp; + const char *str; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_raw_print)(str); +} + +void +chainout_raw_print_bold(vp, str) + void *vp; + const char *str; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_raw_print_bold)(str); +} + +int +chainout_nhgetch(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + int rv; + + rv = (*tdp->nprocs->win_nhgetch)(); + + return rv; +} + +int +chainout_nh_poskey(vp, x, y, mod) + void *vp; + int *x; + int *y; + int *mod; +{ + struct chainout_data *tdp = vp; + int rv; + + rv = (*tdp->nprocs->win_nh_poskey)(x, y, mod); + + return rv; +} + +void +chainout_nhbell(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_nhbell)(); +} + +int +chainout_doprev_message(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + int rv; + + rv = (*tdp->nprocs->win_doprev_message)(); + + return rv; +} + +char +chainout_yn_function(vp, query, resp, def) + void *vp; + const char *query, *resp; + char def; +{ + struct chainout_data *tdp = vp; + int rv; + + rv = (*tdp->nprocs->win_yn_function)(query, resp, def); + + return rv; +} + +void +chainout_getlin(vp, query, bufp) + void *vp; + const char *query; + char *bufp; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_getlin)(query, bufp); +} + + +int +chainout_get_ext_cmd(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + int rv; + + rv = (*tdp->nprocs->win_get_ext_cmd)(); + + return rv; +} + +void +chainout_number_pad(vp, state) + void *vp; + int state; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_number_pad)(state); +} + +void +chainout_delay_output(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_delay_output)(); +} + +#ifdef CHANGE_COLOR +void +chainout_change_color(vp, color, value, reverse) + void *vp; + int color; + long value; + int reverse; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_change_color)(color, value, reverse); +} + +#ifdef MAC +void +chainout_change_background(vp, bw) + void *vp; + int bw; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_change_background)(bw); +} + +short +chainout_set_font_name(vp, window, font) + void *vp; + winid window; + char *font; +{ + struct chainout_data *tdp = vp; + short rv; + + rv = (*tdp->nprocs->win_set_font_name)(window, font); + + return rv; +} +#endif + +char *trace_get_color_string(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + char *rv; + + rv = (*tdp->nprocs->win_get_color_string)(); + + return rv; +} + +#endif + +/* other defs that really should go away (they're tty specific) */ +void +chainout_start_screen(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_start_screen)(); +} + +void +chainout_end_screen(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_end_screen)(); +} + +void +chainout_outrip(vp, tmpwin, how) + void *vp; + winid tmpwin; + int how; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_outrip)(tmpwin, how); +} + +void +chainout_preference_update(vp, pref) + void *vp; + const char *pref; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_preference_update)(pref); +} + + +char * +chainout_getmsghistory(vp, init) + void *vp; +boolean init; +{ + struct chainout_data *tdp = vp; + char *rv; + + rv = (*tdp->nprocs->win_getmsghistory)(init); + + return rv; +} + +void +chainout_putmsghistory(vp, msg, is_restoring) + void *vp; +const char *msg; +boolean is_restoring; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_putmsghistory)(msg, is_restoring); +} + +#ifdef STATUS_VIA_WINDOWPORT +void +chainout_status_init(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_status_init)(); +} + +void +chainout_status_finish(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_status_finish)(); +} + +void +chainout_status_enablefield(vp, fieldidx, nm, fmt, enable) + void *vp; +int fieldidx; +const char *nm; +const char *fmt; +boolean enable; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_status_enablefield)(fieldidx, nm, fmt, enable); +} + +void +chainout_status_update(vp, idx, ptr, chg, percent) + void *vp; +int idx, chg, percent; +genericptr_t ptr; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_status_update)(idx, ptr, chg, percent); +} + +# ifdef STATUS_HILITES +void +chainout_status_threshold(vp, fldidx, thresholdtype, threshold, behavior, under, over) + void *vp; +int fldidx,thresholdtype; +int behavior, under, over; +anything threshold; +{ + struct chainout_data *tdp = vp; + + (*tdp->nprocs->win_status_threshold)(fldidx, thresholdtype, + threshold, behavior, under, over); +} +# endif +#endif + +boolean +chainout_can_suspend(vp) + void *vp; +{ + struct chainout_data *tdp = vp; + boolean rv; + + rv = (*tdp->nprocs->win_can_suspend)(); + + return rv; +} + +struct chain_procs chainout_procs = { + "-chainout", + 0, /* wincap */ + 0, /* wincap2 */ +/* +XXX problem - the above need to come from the real window port, possibly +modified. May need to do something to call an additional init fn later +or if this is the only place like this the choose_windows fn can do the fixup +(but not if the value can be modified by the stack?) TBD +*/ + chainout_init_nhwindows, + chainout_player_selection, + chainout_askname, + chainout_get_nh_event, + chainout_exit_nhwindows, + chainout_suspend_nhwindows, + chainout_resume_nhwindows, + chainout_create_nhwindow, + chainout_clear_nhwindow, + chainout_display_nhwindow, + chainout_destroy_nhwindow, + chainout_curs, + chainout_putstr, + chainout_putmixed, + chainout_display_file, + chainout_start_menu, + chainout_add_menu, + chainout_end_menu, + chainout_select_menu, + chainout_message_menu, + chainout_update_inventory, + chainout_mark_synch, + chainout_wait_synch, +#ifdef CLIPPING + chainout_cliparound, +#endif +#ifdef POSITIONBAR + chainout_update_positionbar, +#endif + chainout_print_glyph, + chainout_raw_print, + chainout_raw_print_bold, + chainout_nhgetch, + chainout_nh_poskey, + chainout_nhbell, + chainout_doprev_message, + chainout_yn_function, + chainout_getlin, + chainout_get_ext_cmd, + chainout_number_pad, + chainout_delay_output, +#ifdef CHANGE_COLOR + chainout_change_color, +#ifdef MAC + chainout_change_background, + chainout_set_font_name, +#endif + chainout_get_color_string, +#endif + + chainout_start_screen, + chainout_end_screen, + + chainout_outrip, + chainout_preference_update, + chainout_getmsghistory, + chainout_putmsghistory, +#ifdef STATUS_VIA_WINDOWPORT + chainout_status_init, + chainout_status_finish, + chainout_status_enablefield, + chainout_status_update, +# ifdef STATUS_HILITES + chainout_status_threshold, +# endif +#endif + chainout_can_suspend, +}; diff --git a/win/chain/wc_trace.c b/win/chain/wc_trace.c new file mode 100644 index 000000000..acf96a5b3 --- /dev/null +++ b/win/chain/wc_trace.c @@ -0,0 +1,1197 @@ +/* NetHack 3.5 wc_trace.c $Date$ $Revision$ */ +/* Copyright (c) Kenneth Lorber, 2012 */ +/* NetHack may be freely redistributed. See license for details. */ + +#include "hack.h" +#include "wintty.h" +#include "func_tab.h" + +#include +#include + +FILE *wc_tracelogf; /* Should be static, but it's just too useful to have + * access to this logfile from arbitrary other files. */ +static unsigned int indent_level; /* Some winfuncs call other winfuncs, so + * we need to support nesting. */ + +static char indentdata[10] = " "; +#define ISCALE 1 +#if 1 +#define INDENT &indentdata[ \ + ((indent_level*ISCALE)<(sizeof(indentdata))) \ + ? ((sizeof(indentdata)-1)-(indent_level*ISCALE)) \ + : 0 \ + ] +#else +/* for debugging this file */ +#define INDENT \ + ({ \ + static char buf[50]; \ + sprintf(buf, "[%s:%d %d]\t", __func__,__LINE__,indent_level); \ + buf; \ + }) +#endif +#define PRE indent_level++ +#define POST indent_level-- + +struct trace_data { + struct chain_procs *nprocs; + void *ndata; + + int linknum; +}; + +void * +trace_procs_chain(cmd, n, me, nextprocs, nextdata) + int cmd; + int n; + void *me; + void *nextprocs; + void *nextdata; +{ + switch(cmd){ + case WINCHAIN_ALLOC: { + struct trace_data *tdp = calloc(1, sizeof(struct trace_data)); + tdp->linknum = n; + return tdp; + } + case WINCHAIN_INIT: { + struct trace_data *tdp = me; + tdp->nprocs = nextprocs; + tdp->ndata = nextdata; + return tdp; + } + default: + raw_printf("trace_procs_chain: bad cmd\n"); + exit(EXIT_FAILURE); + } +} + +void +trace_procs_init(dir) + int dir; +{ + char fname[200]; + + /* processors shouldn't need this test, but just in case */ + if(dir != WININIT) return; + + sprintf(fname, "%s/tlog.%d", HACKDIR, getpid()); + wc_tracelogf = fopen(fname, "w"); + if(wc_tracelogf == NULL){ + fprintf(stderr, "Can't open trace log file %s: %s\n", + fname, strerror(errno)); + exit(EXIT_FAILURE); + } + setvbuf(wc_tracelogf, (char *)NULL, _IONBF, 0); + fprintf(wc_tracelogf, "Trace log started for pid %d\n", getpid()); + + indent_level = 0; +} + +/*** + *** winprocs + ***/ + +void +trace_init_nhwindows(vp, argcp, argv) + void *vp; + int *argcp; + char **argv; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%sinit_nhwindows(%d,*)\n", INDENT, *argcp); + + PRE; + (*tdp->nprocs->win_init_nhwindows)(tdp->ndata, argcp, argv); + POST; +} + + +void +trace_player_selection(vp) + void *vp; +{ + struct trace_data *tdp = vp; + fprintf(wc_tracelogf, "%splayer_selection()\n", INDENT); + + PRE; + (*tdp->nprocs->win_player_selection)(tdp->ndata); + POST; +} + +void +trace_askname(vp) + void *vp; +{ + struct trace_data *tdp = vp; + fprintf(wc_tracelogf, "%saskname()\n", INDENT); + + PRE; + (*tdp->nprocs->win_askname)(tdp->ndata); + POST; +} + +void +trace_get_nh_event(vp) + void *vp; +{ + struct trace_data *tdp = vp; + fprintf(wc_tracelogf, "%sget_nh_event()\n", INDENT); + + PRE; + (*tdp->nprocs->win_get_nh_event)(tdp->ndata); + POST; +} + +void +trace_exit_nhwindows(vp, str) + void *vp; + const char *str; +{ + struct trace_data *tdp = vp; + fprintf(wc_tracelogf, "%sexit_nhwindows(%s)\n", INDENT, str); + + PRE; + (*tdp->nprocs->win_exit_nhwindows)(tdp->ndata, str); + POST; +} + +void +trace_suspend_nhwindows(vp, str) + void *vp; + const char *str; +{ + struct trace_data *tdp = vp; + fprintf(wc_tracelogf, "%ssuspend_nhwindows(%s)\n", INDENT, str); + + PRE; + (*tdp->nprocs->win_suspend_nhwindows)(tdp->ndata, str); + POST; +} + +void +trace_resume_nhwindows(vp) + void *vp; +{ + struct trace_data *tdp = vp; + fprintf(wc_tracelogf, "%sresume_nhwindows()\n", INDENT); + + PRE; + (*tdp->nprocs->win_resume_nhwindows)(tdp->ndata); + POST; +} + +static const char * +NHWname(type) + int type; +{ + switch(type){ + case NHW_MESSAGE: return "MESSAGE"; + case NHW_STATUS: return "STATUS"; + case NHW_MAP: return "MAP"; + case NHW_MENU: return "MENU"; + case NHW_TEXT: return "TEXT"; + case NHW_BASE: return "BASE"; + default: { + static char b[20]; + sprintf(b, "(%d)",type); + return b; + } + } +} + +winid +trace_create_nhwindow(vp, type) + void *vp; + int type; +{ + struct trace_data *tdp = vp; + const char *typestring = NHWname(type); + winid rv; + + fprintf(wc_tracelogf, "%screate_nhwindow(%s)\n", INDENT, typestring); + + PRE; + rv = (*tdp->nprocs->win_create_nhwindow)(tdp->ndata, type); + POST; + + fprintf(wc_tracelogf, "%s=> %d\n", INDENT, rv); + return rv; +} + +void +trace_clear_nhwindow(vp, window) + void *vp; + winid window; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%sclear_nhwindow(%d)\n", INDENT, window); + + PRE; + (*tdp->nprocs->win_clear_nhwindow)(tdp->ndata, window); + POST; +} + +void +trace_display_nhwindow(vp, window, blocking) + void *vp; + winid window; + BOOLEAN_P blocking; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%sdisplay_nhwindow(%d, %d)\n", INDENT, window, blocking); + + PRE; + (*tdp->nprocs->win_display_nhwindow)(tdp->ndata, window, blocking); + POST; +} + +void +trace_destroy_nhwindow(vp, window) + void *vp; + winid window; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%sdestroy_nhwindow(%d)\n", INDENT, window); + + PRE; + (*tdp->nprocs->win_destroy_nhwindow)(tdp->ndata, window); + POST; +} + +void +trace_curs(vp, window, x, y) + void *vp; + winid window; + int x; + int y; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%scurs(%d, %d, %d)\n", INDENT, window, x, y); + + PRE; + (*tdp->nprocs->win_curs)(tdp->ndata, window, x, y); + POST; +} + +void +trace_putstr(vp, window, attr, str) + void *vp; + winid window; + int attr; + const char *str; +{ + struct trace_data *tdp = vp; + + if(str){ + fprintf(wc_tracelogf, "%sputstr(%d, %d, '%s'(%d))\n", INDENT, window, attr, str, + (int)strlen(str)); + } else { + fprintf(wc_tracelogf, "%sputstr(%d, %d, NULL)\n", INDENT, window, attr); + } + + PRE; + (*tdp->nprocs->win_putstr)(tdp->ndata, window, attr, str); + POST; +} + +void +trace_putmixed(vp, window, attr, str) + void *vp; + winid window; + int attr; + const char *str; +{ + struct trace_data *tdp = vp; + + if(str){ + fprintf(wc_tracelogf, "%sputmixed(%d, %d, '%s'(%d))\n", INDENT, window, attr, + str, (int)strlen(str)); + } else { + fprintf(wc_tracelogf, "%sputmixed(%d, %d, NULL)\n", INDENT, window, attr); + } + + PRE; + (*tdp->nprocs->win_putmixed)(tdp->ndata, window, attr, str); + POST; +} + +void +trace_display_file(vp, fname, complain) + void *vp; + const char *fname; + boolean complain; +{ + struct trace_data *tdp = vp; + + if(fname){ + fprintf(wc_tracelogf, "%sdisplay_file('%s'(%d), %d)\n", INDENT, + fname, (int)strlen(fname), complain); + } else { + fprintf(wc_tracelogf, "%sdisplay_file(NULL, %d)\n", INDENT, complain); + } + + PRE; + (*tdp->nprocs->win_display_file)(tdp->ndata, fname, complain); + POST; +} + +void +trace_start_menu(vp, window) + void *vp; + winid window; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%sstart_menu(%d)\n", INDENT, window); + + PRE; + (*tdp->nprocs->win_start_menu)(tdp->ndata, window); + POST; +} + +void +trace_add_menu(vp, window, glyph, identifier, ch, gch, attr, str, preselected) + void *vp; + winid window; /* window to use, must be of type NHW_MENU */ + int glyph; /* glyph to display with item (unused) */ + const anything *identifier; /* what to return if selected */ + char ch; /* keyboard accelerator (0 = pick our own) */ + char gch; /* group accelerator (0 = no group) */ + int attr; /* attribute for string (like tty_putstr()) */ + const char *str; /* menu string */ + boolean preselected; /* item is marked as selected */ +{ + struct trace_data *tdp = vp; + + char buf_ch[10]; + char buf_gch[10]; + + if(isprint(ch)){ + sprintf(buf_ch, "'%c'(%d)", ch, ch); + } else { + sprintf(buf_ch, "(%d)", ch); + } + + if(isprint(gch)){ + sprintf(buf_gch, "'%c'(%d)", gch, gch); + } else { + sprintf(buf_gch, "(%d)", gch); + } + + if(str){ + fprintf(wc_tracelogf, "%sadd_menu(%d, %d, %p, %s, %s, %d, '%s'(%d), %d)\n", INDENT, + window, glyph, (void *)identifier, buf_ch, + buf_gch, attr, str, (int)strlen(str), preselected); + } else { + fprintf(wc_tracelogf, "%sadd_menu(%d, %d, %p, %s, %s, %d, NULL, %d)\n", INDENT, + window, glyph, (void *)identifier, buf_ch, + buf_gch, attr, preselected); + } + + PRE; + (*tdp->nprocs->win_add_menu)(tdp->ndata, window, glyph, identifier, + ch, gch, attr, str, preselected); + POST; +} + +void +trace_end_menu(vp, window, prompt) + void *vp; + winid window; + const char *prompt; +{ + struct trace_data *tdp = vp; + + if(prompt){ + fprintf(wc_tracelogf, "%send_menu(%d, '%s'(%d))\n", INDENT, window, + prompt, (int)strlen(prompt)); + } else { + fprintf(wc_tracelogf, "%send_menu(%d, NULL)\n", INDENT, window); + } + + PRE; + (*tdp->nprocs->win_end_menu)(tdp->ndata, window, prompt); + POST; +} + +int +trace_select_menu(vp, window, how, menu_list) + void *vp; + winid window; + int how; + menu_item **menu_list; +{ + struct trace_data *tdp = vp; + int rv; + + fprintf(wc_tracelogf, "%sselect_menu(%d, %d, %p)\n", INDENT, window, how, + (void *)menu_list); + + PRE; + rv = (*tdp->nprocs->win_select_menu)(tdp->ndata, window, how, + (void *)menu_list); + POST; + + fprintf(wc_tracelogf, "%s=> %d\n", INDENT, rv); + return rv; +} + +char +trace_message_menu(vp, let, how, mesg) + void *vp; + char let; + int how; + const char *mesg; +{ + struct trace_data *tdp = vp; + char buf_let[10]; + char rv; + + if(isprint(let)){ + sprintf(buf_let, "'%c'(%d)", let, let); + } else { + sprintf(buf_let, "(%d)", let); + } + + if(mesg){ + fprintf(wc_tracelogf, "%smessage_menu(%s, %d, '%s'(%d))\n", INDENT, + buf_let, how, mesg, (int)strlen(mesg)); + } else { + fprintf(wc_tracelogf, "%smessage_menu(%s, %d, NULL)\n", INDENT, + buf_let, how); + } + + PRE; + rv = (*tdp->nprocs->win_message_menu)(tdp->ndata, let, how, mesg); + POST; + + if(isprint(rv)){ + sprintf(buf_let, "'%c'(%d)", rv, rv); + } else { + sprintf(buf_let, "(%d)", rv); + } + fprintf(wc_tracelogf, "%s=> %s\n", INDENT, buf_let); + + return rv; +} + +void +trace_update_inventory(vp) + void *vp; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%supdate_inventory()\n", INDENT); + + PRE; + (*tdp->nprocs->win_update_inventory)(tdp->ndata); + POST; +} + +void +trace_mark_synch(vp) + void *vp; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%smark_synch()\n", INDENT); + + PRE; + (*tdp->nprocs->win_mark_synch)(tdp->ndata); + POST; +} + +void +trace_wait_synch(vp) + void *vp; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%swait_synch()\n", INDENT); + + PRE; + (*tdp->nprocs->win_wait_synch)(tdp->ndata); + POST; +} + +#ifdef CLIPPING +void +trace_cliparound(vp, x, y) + void *vp; + int x; + int y; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%scliparound(%d, %d)\n", INDENT, x, y); + + PRE; + (*tdp->nprocs->win_cliparound)(tdp->ndata, x, y); + POST; +} +#endif + +#ifdef POSITIONBAR +void +trace_update_positionbar(vp, posbar) + void *vp; + char *posbar; +{ + struct trace_data *tdp = vp; + + if(posbar){ + fprintf(wc_tracelogf, "%supdate_positionbar('%s'(%d))\n", INDENT, + posbar, (int)strlen(posbar)); + } else { + fprintf(wc_tracelogf, "%supdate_positionbar(NULL)\n"); + } + PRE; + (*tdp->nprocs->win_update_positionbar)(tdp->ndata, posbar); + POST; +} +#endif + +/* XXX can we decode the glyph in a meaningful way? see mapglyph()? + genl_putmixed? */ +void +trace_print_glyph(vp, window, x, y, glyph) + void *vp; + winid window; + xchar x, y; + int glyph; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%sprint_glyph(%d, %d, %d, %d)\n", INDENT, window, x, y, glyph); + + PRE; + (*tdp->nprocs->win_print_glyph)(tdp->ndata, window, x, y, glyph); + POST; +} + +void +trace_raw_print(vp, str) + void *vp; + const char *str; +{ + struct trace_data *tdp = vp; + + if(str){ + fprintf(wc_tracelogf, "%sraw_print('%s'(%d))\n", INDENT, str, (int)strlen(str)); + } else { + fprintf(wc_tracelogf, "%sraw_print(NULL)\n", INDENT); + } + + PRE; + (*tdp->nprocs->win_raw_print)(tdp->ndata, str); + POST; +} + +void +trace_raw_print_bold(vp, str) + void *vp; + const char *str; +{ + struct trace_data *tdp = vp; + + if(str){ + fprintf(wc_tracelogf, "%sraw_print_bold('%s'(%d))\n", INDENT, str, (int)strlen(str)); + } else { + fprintf(wc_tracelogf, "%sraw_print_bold(NULL)\n", INDENT); + } + + PRE; + (*tdp->nprocs->win_raw_print_bold)(tdp->ndata, str); + POST; +} + +int +trace_nhgetch(vp) + void *vp; +{ + struct trace_data *tdp = vp; + int rv; + char buf[10]; + + fprintf(wc_tracelogf, "%snhgetch()\n", INDENT); + + PRE; + rv = (*tdp->nprocs->win_nhgetch)(tdp->ndata); + POST; + + if(rv > 0 && rv < 256 && isprint(rv)){ + sprintf(buf, "'%c'(%d)", rv, rv); + } else { + sprintf(buf, "(%d)", rv); + } + fprintf(wc_tracelogf, "%s=> %s\n", INDENT, buf); + + return rv; +} + +int +trace_nh_poskey(vp, x, y, mod) + void *vp; + int *x; + int *y; + int *mod; +{ + struct trace_data *tdp = vp; + int rv; + char buf[10]; + + fprintf(wc_tracelogf, "%snh_poskey(%d, %d, %d)\n", INDENT, *x, *y, *mod); + + PRE; + rv = (*tdp->nprocs->win_nh_poskey)(tdp->ndata, x, y, mod); + POST; + if(rv > 0 && rv < 256 && isprint(rv)){ + sprintf(buf, "'%c'(%d)", rv, rv); + } else { + sprintf(buf, "(%d)", rv); + } + fprintf(wc_tracelogf, "%s=> %s (%d, %d, %d)\n", INDENT, buf, *x, *y, *mod); + + return rv; +} + +void +trace_nhbell(vp) + void *vp; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%snhbell()\n", INDENT); + + PRE; + (*tdp->nprocs->win_nhbell)(tdp->ndata); + POST; +} + +int +trace_doprev_message(vp) + void *vp; +{ + struct trace_data *tdp = vp; + int rv; + + fprintf(wc_tracelogf, "%sdoprev_message()\n", INDENT); + + PRE; + rv = (*tdp->nprocs->win_doprev_message)(tdp->ndata); + POST; + + fprintf(wc_tracelogf, "%s=> %d\n", INDENT, rv); + + return rv; +} + +char +trace_yn_function(vp, query, resp, def) + void *vp; + const char *query, *resp; + char def; +{ + struct trace_data *tdp = vp; + char rv; + char buf[10]; + + if(query){ + fprintf(wc_tracelogf, "%syn_function('%s'(%d), ", INDENT, + query, (int)strlen(query)); + } else { + fprintf(wc_tracelogf, "%syn_function(NULL, ", INDENT); + } + + if(resp){ + fprintf(wc_tracelogf, "'%s'(%d), ", resp, (int)strlen(resp)); + } else { + fprintf(wc_tracelogf, "NULL, "); + } + + if(isprint(def)){ + sprintf(buf, "'%c'(%d)", def, def); + } else { + sprintf(buf, "(%d)", def); + } + + fprintf(wc_tracelogf, "%s)\n", buf); + + PRE; + rv = (*tdp->nprocs->win_yn_function)(tdp->ndata, query, resp, def); + POST; + + if(isprint(rv)){ + sprintf(buf, "'%c'(%d)", rv, rv); + } else { + sprintf(buf, "(%d)", rv); + } + + fprintf(wc_tracelogf, "%s=> %s\n", INDENT, buf); + + return rv; +} + +void +trace_getlin(vp, query, bufp) + void *vp; + const char *query; + char *bufp; +{ + struct trace_data *tdp = vp; + + if(query){ + fprintf(wc_tracelogf, "%sgetlin('%s'(%d), ", INDENT, + query, (int)strlen(query)); + } else { + fprintf(wc_tracelogf, "%sgetlin(NULL, ", INDENT); + } + + if(bufp){ + fprintf(wc_tracelogf, "%p)\n", bufp); + } else { + fprintf(wc_tracelogf, "NULL)\n"); + } + + PRE; + (*tdp->nprocs->win_getlin)(tdp->ndata, query, bufp); + POST; +} + +int +trace_get_ext_cmd(vp) + void *vp; +{ + struct trace_data *tdp = vp; + int rv; + int ecl_size; + + /* this is ugly, but the size isn't exposed */ + const struct ext_func_tab *efp; + for(efp = extcmdlist; efp->ef_txt; efp++) ecl_size++; + + fprintf(wc_tracelogf, "%sget_ext_cmd()\n", INDENT); + + PRE; + rv = (*tdp->nprocs->win_get_ext_cmd)(tdp->ndata); + POST; + + if(rv < 0 || rv >= ecl_size){ + fprintf(wc_tracelogf, "%s=> (%d)\n", INDENT, rv); + } else { + fprintf(wc_tracelogf, "%s=> %d/%s\n", INDENT, rv, extcmdlist[rv].ef_txt); + } + + return rv; +} + +void +trace_number_pad(vp, state) + void *vp; + int state; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%snumber_pad(%d)\n", INDENT, state); + + PRE; + (*tdp->nprocs->win_number_pad)(tdp->ndata, state); + POST; +} + +void +trace_delay_output(vp) + void *vp; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%sdelay_output()\n", INDENT); + + PRE; + (*tdp->nprocs->win_delay_output)(tdp->ndata); + POST; +} + +#ifdef CHANGE_COLOR +void +trace_change_color(vp, color, value, reverse) + void *vp; + int color; + long value; + int reverse; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%schange_color(%d, $%lx, %d)\n", INDENT, color, value, reverse); + + PRE; + (*tdp->nprocs->win_change_color)(tdp->ndata, color, value, reverse); + POST; +} + +#ifdef MAC +void +trace_change_background(vp, bw) + void *vp; + int bw; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%schange_background(%d)\n", INDENT, bw); + + PRE; + (*tdp->nprocs->win_change_background)(tdp->ndata, bw); + POST; +} + +short +trace_set_font_name(vp, window, font) + void *vp; + winid window; + char *font; +{ + struct trace_data *tdp = vp; + short rv; + + if(font){ + fprintf(wc_tracelogf, "%sset_font_name(%d, '%s'(%d))\n", INDENT, + window, font, (int)(strlen(font))); + } else { + fprintf(wc_tracelogf, "%sset_font_name(%d, NULL)\n", INDENT, window); + } + + PRE; + rv = (*tdp->nprocs->win_set_font_name)(tdp->ndata, window, font); + POST; + + fprintf(wc_tracelogf, "%s=> %d\n", INDENT, rv); + + return rv; +} +#endif + +char *trace_get_color_string(vp) + void *vp; +{ + struct trace_data *tdp = vp; + char *rv; + + fprintf(wc_tracelogf, "%sget_color_string()\n"); + + PRE; + rv = (*tdp->nprocs->win_get_color_string)(tdp->ndata); + POST; + + if(rv){ + fprintf(wc_tracelogf, "%s=> '%s'(%d)\n", INDENT, rv, (int)strlen(rv)); + } else { + fprintf(wc_tracelogf, "%s=> NULL\n"); + } + + return rv; +} + +#endif + +/* other defs that really should go away (they're tty specific) */ +void +trace_start_screen(vp) + void *vp; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%sstart_screen()\n", INDENT); + + PRE; + (*tdp->nprocs->win_start_screen)(tdp->ndata); + POST; +} + +void +trace_end_screen(vp) + void *vp; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%send_screen()\n", INDENT); + + PRE; + (*tdp->nprocs->win_end_screen)(tdp->ndata); + POST; +} + +void +trace_outrip(vp, tmpwin, how) + void *vp; + winid tmpwin; + int how; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%soutrip(%d, %d)\n", INDENT, tmpwin, how); + + PRE; + (*tdp->nprocs->win_outrip)(tdp->ndata, tmpwin, how); + POST; +} + +void +trace_preference_update(vp, pref) + void *vp; + const char *pref; +{ + struct trace_data *tdp = vp; + + if(pref){ + fprintf(wc_tracelogf, "%spreference_update('%s'(%d))\n", INDENT, + pref, (int)strlen(pref)); + } else { + fprintf(wc_tracelogf, "%spreference_update(NULL)\n", INDENT); + } + + PRE; + (*tdp->nprocs->win_preference_update)(tdp->ndata, pref); + POST; +} + + +char * +trace_getmsghistory(vp, init) + void *vp; +boolean init; +{ + struct trace_data *tdp = vp; + char *rv; + + fprintf(wc_tracelogf, "%sgetmsghistory(%d)\n", INDENT, init); + + PRE; + rv = (*tdp->nprocs->win_getmsghistory)(tdp->ndata,init); + POST; + + if(rv){ + fprintf(wc_tracelogf, "%s=> '%s'(%d)\n", INDENT, rv, (int)strlen(rv)); + } else { + fprintf(wc_tracelogf, "%s=> NULL\n", INDENT); + } + + return rv; +} + +void +trace_putmsghistory(vp, msg, is_restoring) + void *vp; +const char *msg; +boolean is_restoring; +{ + struct trace_data *tdp = vp; + + if(msg){ + fprintf(wc_tracelogf, "%sputmsghistory('%s'(%d), %d)\n", INDENT, + msg, (int)strlen(msg), is_restoring); + } else { + fprintf(wc_tracelogf, "%sputmghistory(NULL, %d)\n", INDENT, is_restoring); + } + + PRE; + (*tdp->nprocs->win_putmsghistory)(tdp->ndata, msg, is_restoring); + POST; +} + +#ifdef STATUS_VIA_WINDOWPORT +void +trace_status_init(vp) + void *vp; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%sstatus_init()\n", INDENT); + + PRE; + (*tdp->nprocs->win_status_init)(tdp->ndata); + POST; +} + +void +trace_status_finish(vp) + void *vp; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%sstatus_finish()\n", INDENT); + + PRE; + (*tdp->nprocs->win_status_finish)(tdp->ndata); + POST; +} + +void +trace_status_enablefield(vp, fieldidx, nm, fmt, enable) + void *vp; +int fieldidx; +const char *nm; +const char *fmt; +boolean enable; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%sstatus_enablefield(%d, ", INDENT, fieldidx); + if(nm){ + fprintf(wc_tracelogf, "'%s'(%d), ", nm, (int)strlen(nm)); + } else { + fprintf(wc_tracelogf, "NULL, "); + } + if(fmt){ + fprintf(wc_tracelogf, "'%s'(%d), ", fmt, (int)strlen(fmt)); + } else { + fprintf(wc_tracelogf, "NULL, "); + } + fprintf(wc_tracelogf, "%d)\n", enable); + + PRE; + (*tdp->nprocs->win_status_enablefield)(tdp->ndata, fieldidx, nm, + fmt, enable); + POST; +} + +void +trace_status_update(vp, idx, ptr, chg, percent) + void *vp; +int idx, chg, percent; +genericptr_t ptr; +{ + struct trace_data *tdp = vp; + + fprintf(wc_tracelogf, "%sstatus_update(%d, %p, %d, %d)\n", INDENT, idx, ptr, chg, + percent); + + PRE; + (*tdp->nprocs->win_status_update)(tdp->ndata, idx, ptr, chg, percent); + POST; +} + +# ifdef STATUS_HILITES +void +trace_status_threshold(vp, fldidx, thresholdtype, threshold, behavior, under, over) + void *vp; +int fldidx,thresholdtype; +int behavior, under, over; +anything threshold; +{ + struct trace_data *tdp = vp; + + /* XXX how do we print an anything? We don't. */ + fprintf(wc_tracelogf, "%sstatus_threshold(%d, %d, -, %d, %d, %d)\n", INDENT, + fldidx, thresholdtype, behavior, under, over); + + PRE; + (*tdp->nprocs->win_status_threshold)(tdp->ndata,fldidx, thresholdtype, + threshold, behavior, under, over); + POST; +} +# endif +#endif + +boolean +trace_can_suspend(vp) + void *vp; +{ + struct trace_data *tdp = vp; + boolean rv; + + fprintf(wc_tracelogf, "%scan_suspend()\n", INDENT); + + PRE; + rv = (*tdp->nprocs->win_can_suspend)(tdp->ndata); + POST; + + fprintf(wc_tracelogf, "%s=> %d\n", INDENT, rv); + + return rv; +} + +struct chain_procs trace_procs = { + "+trace", + 0, /* wincap */ + 0, /* wincap2 */ +/* +XXX problem - the above need to come from the real window port, possibly +modified. May need to do something to call an additional init fn later +or if this is the only place like this the choose_windows fn can do the fixup +(but not if the value can be modified by the stack?) TBD +*/ + trace_init_nhwindows, + trace_player_selection, + trace_askname, + trace_get_nh_event, + trace_exit_nhwindows, + trace_suspend_nhwindows, + trace_resume_nhwindows, + trace_create_nhwindow, + trace_clear_nhwindow, + trace_display_nhwindow, + trace_destroy_nhwindow, + trace_curs, + trace_putstr, + trace_putmixed, + trace_display_file, + trace_start_menu, + trace_add_menu, + trace_end_menu, + trace_select_menu, + trace_message_menu, + trace_update_inventory, + trace_mark_synch, + trace_wait_synch, +#ifdef CLIPPING + trace_cliparound, +#endif +#ifdef POSITIONBAR + trace_update_positionbar, +#endif + trace_print_glyph, + trace_raw_print, + trace_raw_print_bold, + trace_nhgetch, + trace_nh_poskey, + trace_nhbell, + trace_doprev_message, + trace_yn_function, + trace_getlin, + trace_get_ext_cmd, + trace_number_pad, + trace_delay_output, +#ifdef CHANGE_COLOR + trace_change_color, +#ifdef MAC + trace_change_background, + trace_set_font_name, +#endif + trace_get_color_string, +#endif + + trace_start_screen, + trace_end_screen, + + trace_outrip, + trace_preference_update, + trace_getmsghistory, + trace_putmsghistory, +#ifdef STATUS_VIA_WINDOWPORT + trace_status_init, + trace_status_finish, + trace_status_enablefield, + trace_status_update, +# ifdef STATUS_HILITES + trace_status_threshold, +# endif +#endif + trace_can_suspend, +}; diff --git a/win/tty/wintty.c b/win/tty/wintty.c index fc61da8b8..752950448 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -15,6 +15,12 @@ #include #include "hack.h" + +/* Support for logging SIGWINCH. */ +#ifdef WINCHAIN +# include "winprocs.h" +#endif + #include "dlb.h" #include "date.h" #ifdef SHORT_FILENAMES @@ -247,7 +253,24 @@ winch() int oldLI = LI, oldCO = CO, i; register struct WinDesc *cw; +# ifdef WINCHAIN + { +# define WINCH_MESSAGE "(SIGWINCH)" +if(wc_tracelogf) + (void)write(fileno(wc_tracelogf), WINCH_MESSAGE, strlen(WINCH_MESSAGE)); +# undef WINCH_MESSAGE + } +# endif getwindowsz(); + /* For long running events such as multi-page menus and + * display_file(), we note the signal's occurance and + * hope the code there decides to handle the situation + * and reset the flag. There will be race conditions + * when handling this - code handlers so it doesn't matter. + */ +# ifdef notyet + winch_seen = TRUE; +# endif if((oldLI != LI || oldCO != CO) && ttyDisplay) { ttyDisplay->rows = LI; ttyDisplay->cols = CO; @@ -1805,10 +1828,6 @@ tty_display_nhwindow(window, blocking) case NHW_MENU: cw->active = 1; #ifdef H2344_BROKEN -/* XXX this is the block that messes up corner win for player selection - (at least when undoing the patch one piece at a time from the start - of the file) -*/ cw->offx = (cw->type==NHW_TEXT) ? 0 : min( min(82,ttyDisplay->cols/2), ttyDisplay->cols - cw->maxcol - 1); @@ -2356,6 +2375,9 @@ boolean complain; terminate(EXIT_FAILURE); } (void) close(fd); +# ifdef notyet + winch_seen = 0; +# endif } #else /* DEF_PAGER */ { @@ -2517,6 +2539,7 @@ tty_end_menu(window, prompt) tty_add_menu(window, NO_GLYPH, &any, 0, 0, ATR_NONE, prompt, MENU_UNSELECTED); } + /* XXX another magic number? 52 */ lmax = min(52, (int)ttyDisplay->rows - 1); /* # lines per page */ cw->npages = (cw->nitems + (lmax - 1)) / lmax; /* # of pages */