From: keni Date: Wed, 11 Jan 2012 18:23:35 +0000 (+0000) Subject: WINCHAIN - a framework allowing multiple processors between core and winport X-Git-Tag: MOVE2GIT~93 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7f6ee2f7598029570bb1cc671d51d67de7e0cfa6;p=nethack WINCHAIN - a framework allowing multiple processors between core and winport This is the code I built trying to figure out the large window size issue. It completely compiles out if not needed (see -DWINCHAIN in hints/macos10.7) and except for one call during setup has zero overhead if compiled in and not used. See window.doc for more info. Defs for UNUSED parms. I know this has been controversial, so use is isolated to the chain code and windows.c (where it shouldn't be intrusive and saves about 50 warnings). Hints file for 10.7, but the build process still needs to be migrated from the branch. --- 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,44 +61,86 @@ 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; @@ -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 */