Disconnect hostapd from building in base
[dragonfly.git] / contrib / dialog / trace.c
1 /*
2  *  $Id: trace.c,v 1.20 2011/10/18 10:47:26 tom Exp $
3  *
4  *  trace.c -- implements screen-dump and keystroke-logging
5  *
6  *  Copyright 2007-2010,2011    Thomas E. Dickey
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU Lesser General Public License, version 2.1
10  *
11  *  This program is distributed in the hope that it will be useful, but
12  *  WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this program; if not, write to
18  *      Free Software Foundation, Inc.
19  *      51 Franklin St., Fifth Floor
20  *      Boston, MA 02110, USA.
21  */
22
23 #include <dialog.h>
24
25 #ifdef HAVE_DLG_TRACE
26
27 #ifdef NEED_WCHAR_H
28 #include <wchar.h>
29 #endif
30
31 #include <dlg_keys.h>
32 #include <time.h>
33
34 #define myFP dialog_state.trace_output
35
36 static void
37 dlg_trace_time(const char *tag)
38 {
39     time_t now = time((time_t *) 0);
40     fprintf(myFP, "%s %s", tag, ctime(&now));
41 }
42
43 void
44 dlg_trace_msg(const char *fmt,...)
45 {
46     if (myFP != 0) {
47         va_list ap;
48         va_start(ap, fmt);
49         vfprintf(myFP, fmt, ap);
50         va_end(ap);
51         fflush(myFP);
52     }
53 }
54
55 void
56 dlg_trace_win(WINDOW *win)
57 {
58     if (myFP != 0) {
59         int y, x;
60         int j, k;
61         WINDOW *top = wgetparent(win);
62
63         while (top != 0 && top != stdscr) {
64             win = top;
65             top = wgetparent(win);
66         }
67
68         if (win != 0) {
69             int rc = getmaxy(win);
70             int cc = getmaxx(win);
71             chtype ch, c2;
72
73             fprintf(myFP, "window %dx%d at %d,%d\n",
74                     rc, cc, getbegy(win), getbegx(win));
75
76             getyx(win, y, x);
77             for (j = 0; j < rc; ++j) {
78                 fprintf(myFP, "%3d:", j);
79                 for (k = 0; k < cc; ++k) {
80 #ifdef USE_WIDE_CURSES
81                     char buffer[80];
82
83                     ch = mvwinch(win, j, k) & (A_CHARTEXT | A_ALTCHARSET);
84                     if (ch & A_ALTCHARSET) {
85                         c2 = dlg_asciibox(ch);
86                         if (c2 != 0) {
87                             ch = c2;
88                         }
89                         buffer[0] = (char) ch;
90                         buffer[1] = '\0';
91                     } else {
92                         cchar_t cch;
93                         wchar_t *uc;
94
95                         if (win_wch(win, &cch) == ERR
96                             || (uc = wunctrl(&cch)) == 0
97                             || uc[1] != 0
98                             || wcwidth(uc[0]) <= 0) {
99                             buffer[0] = '.';
100                             buffer[1] = '\0';
101                         } else {
102                             mbstate_t state;
103                             const wchar_t *ucp = uc;
104
105                             memset(&state, 0, sizeof(state));
106                             wcsrtombs(buffer, &ucp, sizeof(buffer), &state);
107                             k += wcwidth(uc[0]) - 1;
108                         }
109                     }
110                     fputs(buffer, myFP);
111 #else
112                     ch = mvwinch(win, j, k) & (A_CHARTEXT | A_ALTCHARSET);
113                     c2 = dlg_asciibox(ch);
114                     if (c2 != 0) {
115                         ch = c2;
116                     } else if (unctrl(ch) == 0 || strlen(unctrl(ch)) > 1) {
117                         ch = '.';
118                     }
119                     fputc((int) (ch & 0xff), myFP);
120 #endif
121                 }
122                 fputc('\n', myFP);
123             }
124             wmove(win, y, x);
125             fflush(myFP);
126         }
127     }
128 }
129
130 void
131 dlg_trace_chr(int ch, int fkey)
132 {
133     static int last_err = 0;
134
135     /*
136      * Do not bother to trace ERR's indefinitely, since those are usually due
137      * to relatively short polling timeouts.
138      */
139     if (last_err && !fkey && ch == ERR) {
140         ++last_err;
141     } else if (myFP != 0) {
142         const char *fkey_name = "?";
143
144         if (last_err) {
145             fprintf(myFP, "skipped %d ERR's\n", last_err);
146             last_err = 0;
147         }
148
149         if (fkey) {
150             if (fkey > KEY_MAX || (fkey_name = keyname(fkey)) == 0) {
151 #define CASE(name) case name: fkey_name = #name; break
152                 switch ((DLG_KEYS_ENUM) fkey) {
153                     CASE(DLGK_MIN);
154                     CASE(DLGK_OK);
155                     CASE(DLGK_CANCEL);
156                     CASE(DLGK_EXTRA);
157                     CASE(DLGK_HELP);
158                     CASE(DLGK_ESC);
159                     CASE(DLGK_PAGE_FIRST);
160                     CASE(DLGK_PAGE_LAST);
161                     CASE(DLGK_PAGE_NEXT);
162                     CASE(DLGK_PAGE_PREV);
163                     CASE(DLGK_ITEM_FIRST);
164                     CASE(DLGK_ITEM_LAST);
165                     CASE(DLGK_ITEM_NEXT);
166                     CASE(DLGK_ITEM_PREV);
167                     CASE(DLGK_FIELD_FIRST);
168                     CASE(DLGK_FIELD_LAST);
169                     CASE(DLGK_FIELD_NEXT);
170                     CASE(DLGK_FIELD_PREV);
171                     CASE(DLGK_FORM_FIRST);
172                     CASE(DLGK_FORM_LAST);
173                     CASE(DLGK_FORM_NEXT);
174                     CASE(DLGK_FORM_PREV);
175                     CASE(DLGK_GRID_UP);
176                     CASE(DLGK_GRID_DOWN);
177                     CASE(DLGK_GRID_LEFT);
178                     CASE(DLGK_GRID_RIGHT);
179                     CASE(DLGK_DELETE_LEFT);
180                     CASE(DLGK_DELETE_RIGHT);
181                     CASE(DLGK_DELETE_ALL);
182                     CASE(DLGK_ENTER);
183                     CASE(DLGK_BEGIN);
184                     CASE(DLGK_FINAL);
185                     CASE(DLGK_SELECT);
186                     CASE(DLGK_HELPFILE);
187                     CASE(DLGK_TRACE);
188                 }
189             }
190         } else if (ch == ERR) {
191             fkey_name = "ERR";
192             last_err = 1;
193         } else {
194             fkey_name = unctrl((chtype) ch);
195             if (fkey_name == 0)
196                 fkey_name = "UNKNOWN";
197         }
198         fprintf(myFP, "chr %s (ch=%#x, fkey=%d)\n",
199                 fkey_name,
200                 ch, fkey);
201         fflush(myFP);
202     }
203 }
204
205 void
206 dlg_trace(const char *fname)
207 {
208     if (fname != 0) {
209         if (myFP == 0) {
210             myFP = fopen(fname, "a");
211             if (myFP != 0) {
212                 dlg_trace_time("** opened at");
213                 dlg_trace_msg("** dialog %s\n", dialog_version());
214             }
215         }
216     } else if (myFP != 0) {
217         dlg_trace_time("** closed at");
218         fclose(myFP);
219         myFP = 0;
220     }
221 }
222 #else
223 #undef dlg_trace
224 extern void dlg_trace(const char *);
225 void
226 dlg_trace(const char *fname)
227 {
228     (void) fname;
229 }
230 #endif