~ubuntu-branches/ubuntu/natty/ibm-3270/natty

« back to all changes in this revision

Viewing changes to x3270/print.c

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2009-12-14 11:48:53 UTC
  • mfrom: (1.1.4 upstream) (2.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20091214114853-mywixml32hct9jr1
Tags: 3.3.10ga4-2
* Fix section to match override.
* Use debhelper compat level 7.
* Use 3.0 (quilt) source format.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2004, 2005, 2007 by Paul
3
 
 *   Mattes.
4
 
 *  Permission to use, copy, modify, and distribute this software and its
5
 
 *  documentation for any purpose and without fee is hereby granted,
6
 
 *  provided that the above copyright notice appear in all copies and that
7
 
 *  both that copyright notice and this permission notice appear in
8
 
 *  supporting documentation.
9
 
 *
10
 
 * x3270, c3270, s3270 and tcl3270 are distributed in the hope that they will
11
 
 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the file LICENSE
13
 
 * for more details.
 
2
 * Copyright (c) 1994-2009, Paul Mattes.
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions are met:
 
7
 *     * Redistributions of source code must retain the above copyright
 
8
 *       notice, this list of conditions and the following disclaimer.
 
9
 *     * Redistributions in binary form must reproduce the above copyright
 
10
 *       notice, this list of conditions and the following disclaimer in the
 
11
 *       documentation and/or other materials provided with the distribution.
 
12
 *     * Neither the names of Paul Mattes nor the names of his contributors
 
13
 *       may be used to endorse or promote products derived from this software
 
14
 *       without specific prior written permission.
 
15
 *
 
16
 * THIS SOFTWARE IS PROVIDED BY PAUL MATTES "AS IS" AND ANY EXPRESS OR IMPLIED
 
17
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 
18
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 
19
 * EVENT SHALL PAUL MATTES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
20
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
21
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 
22
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 
23
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 
24
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 
25
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
26
 */
15
27
 
16
28
/*
38
50
#include "resources.h"
39
51
 
40
52
#include "actionsc.h"
 
53
#include "charsetc.h"
41
54
#include "popupsc.h"
42
55
#include "printc.h"
 
56
#include "unicodec.h"
43
57
#include "utf8c.h"
44
58
#include "utilc.h"
45
 
#if defined(X3270_DBCS) /*[*/
46
 
#include "widec.h"
47
 
#endif /*]*/
 
59
 
48
60
#if defined(_WIN32) /*[*/
 
61
#include <windows.h>
49
62
#include <io.h>
50
63
#include <fcntl.h>
51
64
#include <sys/stat.h>
52
65
#endif /*]*/
53
66
 
 
67
#if defined(_MSC_VER) /*[*/
 
68
#include "Msc/deprecated.h"
 
69
#endif /*]*/
 
70
 
 
71
/* Globals */
 
72
#if defined(X3270_DISPLAY) /*[*/
 
73
char *print_text_command = NULL;
 
74
Boolean ptc_changed = FALSE;
 
75
#endif /*]*/
 
76
 
54
77
/* Statics */
55
78
 
56
79
#if defined(X3270_DISPLAY) /*[*/
57
80
static Widget print_text_shell = (Widget)NULL;
58
81
static Widget save_text_shell = (Widget)NULL;
59
82
static Widget print_window_shell = (Widget)NULL;
60
 
static char *print_window_command = CN;
 
83
char *print_window_command = CN;
61
84
#endif /*]*/
62
85
 
63
86
 
70
93
color_from_fa(unsigned char fa)
71
94
{
72
95
        static int field_colors[4] = {
73
 
                COLOR_GREEN,        /* default */
74
 
                COLOR_RED,          /* intensified */
75
 
                COLOR_BLUE,         /* protected */
76
 
                COLOR_WHITE         /* protected, intensified */
 
96
                HOST_COLOR_GREEN,        /* default */
 
97
                HOST_COLOR_RED,          /* intensified */
 
98
                HOST_COLOR_BLUE,         /* protected */
 
99
                HOST_COLOR_WHITE         /* protected, intensified */
77
100
#       define DEFCOLOR_MAP(f) \
78
101
                ((((f) & FA_PROTECT) >> 4) | (((f) & FA_INT_HIGH_SEL) >> 3))
79
102
        };
81
104
        if (appres.m3279)
82
105
                return field_colors[DEFCOLOR_MAP(fa)];
83
106
        else
84
 
                return COLOR_GREEN;
 
107
                return HOST_COLOR_GREEN;
85
108
}
86
109
 
87
110
/*
108
131
                "grey",
109
132
                "white"
110
133
        };
111
 
        if (color >= COLOR_NEUTRAL_BLACK && color <= COLOR_WHITE)
 
134
        if (color >= HOST_COLOR_NEUTRAL_BLACK && color <= HOST_COLOR_WHITE)
112
135
                return html_color_map[color];
113
136
        else
114
137
                return "black";
115
138
}
116
139
 
 
140
/* Convert a caption string to UTF-8 RTF. */
 
141
static char *
 
142
rtf_caption(const char *caption)
 
143
{
 
144
        ucs4_t u;
 
145
        int consumed;
 
146
        enum me_fail error;
 
147
        char *result = Malloc(1);
 
148
        int rlen = 1;
 
149
        char uubuf[64];
 
150
        char mb[16];
 
151
        int nmb;
 
152
 
 
153
        result[0] = '\0';
 
154
 
 
155
        while (*caption) {
 
156
                u = multibyte_to_unicode(caption, strlen(caption), &consumed,
 
157
                        &error);
 
158
                if (u == 0)
 
159
                        break;
 
160
                if (u & ~0x7f) {
 
161
                        sprintf(uubuf, "\\u%u?", u);
 
162
                } else {
 
163
                        nmb = unicode_to_multibyte(u, mb, sizeof(mb));
 
164
                        if (mb[0] == '\\' ||
 
165
                            mb[0] == '{' ||
 
166
                            mb[0] == '}')
 
167
                                sprintf(uubuf, "\\%c", mb[0]);
 
168
                        else if (mb[0] == '-')
 
169
                                sprintf(uubuf, "\\_");
 
170
                        else if (mb[0] == ' ')
 
171
                                sprintf(uubuf, "\\~");
 
172
                        else {
 
173
                                uubuf[0] = mb[0];
 
174
                                uubuf[1] = '\0';
 
175
                        }
 
176
                }
 
177
                result = Realloc(result, rlen + strlen(uubuf));
 
178
                strcat(result, uubuf);
 
179
                rlen += strlen(uubuf);
 
180
 
 
181
                caption += consumed;
 
182
        }
 
183
        return result;
 
184
}
 
185
 
 
186
/* Convert a caption string to UTF-8 HTML. */
 
187
static char *
 
188
html_caption(const char *caption)
 
189
{
 
190
        ucs4_t u;
 
191
        int consumed;
 
192
        enum me_fail error;
 
193
        char *result = Malloc(1);
 
194
        int rlen = 1;
 
195
        char u8buf[16];
 
196
        int nu8;
 
197
 
 
198
        result[0] = '\0';
 
199
 
 
200
        while (*caption) {
 
201
                u = multibyte_to_unicode(caption, strlen(caption), &consumed,
 
202
                        &error);
 
203
                if (u == 0)
 
204
                        break;
 
205
                switch (u) {
 
206
                case '<':
 
207
                        result = Realloc(result, rlen + 4);
 
208
                        strcat(result, "&lt;");
 
209
                        rlen += 4;
 
210
                        break;
 
211
                case '>':
 
212
                        result = Realloc(result, rlen + 4);
 
213
                        strcat(result, "&gt;");
 
214
                        rlen += 4;
 
215
                        break;
 
216
                case '&':
 
217
                        result = Realloc(result, rlen + 5);
 
218
                        strcat(result, "&amp;");
 
219
                        rlen += 5;
 
220
                        break;
 
221
                default:
 
222
                        nu8 = unicode_to_utf8(u, u8buf);
 
223
                        result = Realloc(result, rlen + nu8);
 
224
                        memcpy(result + rlen - 1, u8buf, nu8);
 
225
                        rlen += nu8;
 
226
                        result[rlen - 1] = '\0';
 
227
                        break;
 
228
                }
 
229
                caption += consumed;
 
230
        }
 
231
        return result;
 
232
}
117
233
 
118
234
/*
119
235
 * Print the ASCIIfied contents of the screen onto a stream.
120
236
 * Returns True if anything printed, False otherwise.
121
237
 * 
122
 
 * If 'use_html' is True, then HTML is generated, which preserves colors, but
123
 
 * little else (for now).
 
238
 * 'ptype' can specify:
 
239
 *  P_TEXT: Ordinary text
 
240
 *  P_HTML: HTML
 
241
 *  P_RTF: Windows rich text
 
242
 *
 
243
 * 'opts' is an OR of:
 
244
 *  FPS_EVEN_IF_EMPTY   Create a file even if the screen is clear
 
245
 *  FPS_MODIFIED_ITALIC Print modified fields in italic
 
246
 *    font-style:normal|italic
124
247
 */
125
248
Boolean
126
 
fprint_screen(FILE *f, Boolean even_if_empty, Boolean use_html)
 
249
fprint_screen(FILE *f, ptype_t ptype, unsigned opts, char *caption)
127
250
{
128
251
        register int i;
129
 
        char c;
 
252
        unsigned long uc;
130
253
        int ns = 0;
131
254
        int nr = 0;
132
255
        Boolean any = False;
133
256
        int fa_addr = find_field_attribute(0);
134
257
        unsigned char fa = ea_buf[fa_addr].fa;
135
 
        int fa_color, current_color;
 
258
        int fa_fg, current_fg;
 
259
        int fa_bg, current_bg;
136
260
        Bool fa_high, current_high;
137
 
 
138
 
        if (use_html) {
139
 
                even_if_empty = True;
 
261
        Bool fa_ital, current_ital;
 
262
        Bool mi = ((opts & FPS_MODIFIED_ITALIC)) != 0;
 
263
        char *xcaption = NULL;
 
264
 
 
265
        if (caption != NULL) {
 
266
                char *ts = strstr(caption, "%T%");
 
267
 
 
268
                if (ts != NULL) {
 
269
                        time_t t = time(NULL);
 
270
                        struct tm *tm = localtime(&t);
 
271
 
 
272
                        xcaption = Malloc(strlen(caption) + 1 - 3 + 19);
 
273
                        strncpy(xcaption, caption, ts - caption);
 
274
                        sprintf(xcaption + (ts - caption),
 
275
                                "%04d-%02d-%02d %02d:%02d:%02d",
 
276
                                tm->tm_year + 1900,
 
277
                                tm->tm_mon + 1,
 
278
                                tm->tm_mday,
 
279
                                tm->tm_hour,
 
280
                                tm->tm_min,
 
281
                                tm->tm_sec);
 
282
                        strcat(xcaption, ts + 3);
 
283
                } else {
 
284
                        xcaption = NewString(caption);
 
285
                }
 
286
        }
 
287
 
 
288
        if (ptype != P_TEXT) {
 
289
                opts |= FPS_EVEN_IF_EMPTY;
140
290
        }
141
291
 
142
292
        if (ea_buf[fa_addr].fg)
143
 
                fa_color = ea_buf[fa_addr].fg & 0x0f;
144
 
        else
145
 
                fa_color = color_from_fa(fa);
146
 
        current_color = fa_color;
 
293
                fa_fg = ea_buf[fa_addr].fg & 0x0f;
 
294
        else
 
295
                fa_fg = color_from_fa(fa);
 
296
        current_fg = fa_fg;
 
297
 
 
298
        if (ea_buf[fa_addr].bg)
 
299
                fa_bg = ea_buf[fa_addr].bg & 0x0f;
 
300
        else
 
301
                fa_bg = HOST_COLOR_BLACK;
 
302
        current_bg = fa_bg;
147
303
 
148
304
        if (ea_buf[fa_addr].gr & GR_INTENSIFY)
149
305
                fa_high = True;
150
306
        else
151
307
                fa_high = FA_IS_HIGH(fa);
152
308
        current_high = fa_high;
 
309
        fa_ital = mi && FA_IS_MODIFIED(fa);
 
310
        current_ital = fa_ital;
 
311
 
 
312
        if (ptype == P_RTF) {
 
313
                char *pt_font = get_resource(ResPrintTextFont);
 
314
                char *pt_size = get_resource(ResPrintTextSize);
 
315
                int pt_nsize;
 
316
 
 
317
                if (pt_font == CN)
 
318
                        pt_font = "Courier New";
 
319
                if (pt_size == CN)
 
320
                        pt_size = "8";
 
321
                pt_nsize = atoi(pt_size);
 
322
                if (pt_nsize <= 0)
 
323
                        pt_nsize = 8;
 
324
 
 
325
                fprintf(f, "{\\rtf1\\ansi\\ansicpg%u\\deff0\\deflang1033{\\fonttbl{\\f0\\fmodern\\fprq1\\fcharset0 %s;}}\n"
 
326
                            "\\viewkind4\\uc1\\pard\\f0\\fs%d ",
 
327
#if defined(_WIN32) /*[*/
 
328
                            GetACP(),
 
329
#else /*][*/
 
330
                            1252, /* the number doesn't matter */
 
331
#endif /*]*/
 
332
                            pt_font, pt_nsize * 2);
 
333
                if (xcaption != NULL) {
 
334
                        char *hcaption = rtf_caption(xcaption);
 
335
 
 
336
                        fprintf(f, "%s\\par\\par\n", hcaption);
 
337
                        Free(hcaption);
 
338
                }
 
339
                if (current_high)
 
340
                        fprintf(f, "\\b ");
 
341
        }
 
342
 
 
343
        if (ptype == P_HTML) {
 
344
                char *hcaption = NULL;
 
345
 
 
346
                /* Make the caption HTML-safe. */
 
347
                if (xcaption != NULL)
 
348
                        hcaption = html_caption(xcaption);
 
349
 
 
350
                /* Print the preamble. */
 
351
                fprintf(f, "<html>\n"
 
352
                           "<head>\n"
 
353
                           " <meta http-equiv=\"Content-Type\" "
 
354
                             "content=\"text/html; charset=UTF-8\">\n"
 
355
                           "</head>\n"
 
356
                           " <body>\n");
 
357
                if (hcaption)
 
358
                        fprintf(f, "<p>%s</p>\n", hcaption);
 
359
                fprintf(f, "  <table border=0>"
 
360
                           "<tr bgcolor=black><td>"
 
361
                           "<pre><span style=\"color:%s;"
 
362
                                               "background:%s;"
 
363
                                               "font-weight:%s;"
 
364
                                               "font-style:%s\">",
 
365
                           html_color(current_fg),
 
366
                           html_color(current_bg),
 
367
                           current_high? "bold": "normal",
 
368
                           current_ital? "italic": "normal");
 
369
                if (hcaption != NULL)
 
370
                        Free(hcaption);
 
371
        }
 
372
 
 
373
        if (ptype == P_TEXT) {
 
374
                if (xcaption != NULL)
 
375
                        fprintf(f, "%s\n\n", xcaption);
 
376
        }
153
377
 
154
378
        for (i = 0; i < ROWS*COLS; i++) {
155
 
#if defined(X3270_DBCS) /*[*/
156
379
                char mb[16];
157
 
                Boolean is_dbcs = False;
158
 
#endif /*]*/
 
380
                int nmb;
 
381
 
 
382
                uc = 0;
159
383
 
160
384
                if (i && !(i % COLS)) {
161
 
                        nr++;
 
385
                        if (ptype == P_HTML)
 
386
                                (void) fputc('\n', f);
 
387
                        else
 
388
                                nr++;
162
389
                        ns = 0;
163
390
                }
164
391
                if (ea_buf[i].fa) {
165
 
                        c = ' ';
 
392
                        uc = ' ';
166
393
                        fa = ea_buf[i].fa;
167
394
                        if (ea_buf[i].fg)
168
 
                                fa_color = ea_buf[i].fg & 0x0f;
169
 
                        else
170
 
                                fa_color = color_from_fa(fa);
 
395
                                fa_fg = ea_buf[i].fg & 0x0f;
 
396
                        else
 
397
                                fa_fg = color_from_fa(fa);
 
398
                        if (ea_buf[i].bg)
 
399
                                fa_bg = ea_buf[i].bg & 0x0f;
 
400
                        else
 
401
                                fa_bg = HOST_COLOR_BLACK;
171
402
                        if (ea_buf[i].gr & GR_INTENSIFY)
172
403
                                fa_high = True;
173
404
                        else
174
405
                                fa_high = FA_IS_HIGH(fa);
 
406
                        fa_ital = mi && FA_IS_MODIFIED(fa);
175
407
                }
176
 
                if (FA_IS_ZERO(fa))
177
 
                        c = ' ';
178
 
#if defined(X3270_DBCS) /*[*/
179
 
                else {
180
 
                        /* XXX: DBCS/html interactions are not done */
 
408
                if (FA_IS_ZERO(fa)) {
 
409
#if defined(X3270_DBCS) /*[*/
 
410
                        if (ctlr_dbcs_state(i) == DBCS_LEFT)
 
411
                                uc = 0x3000;
 
412
                        else
 
413
#endif /*]*/
 
414
                                uc = ' ';
 
415
                } else {
 
416
                        /* Convert EBCDIC to Unicode. */
 
417
#if defined(X3270_DBCS) /*[*/
181
418
                        switch (ctlr_dbcs_state(i)) {
182
419
                        case DBCS_NONE:
183
420
                        case DBCS_SB:
184
 
                                c = ebc2asc[ea_buf[i].cc];
 
421
                                uc = ebcdic_to_unicode(ea_buf[i].cc,
 
422
                                        ea_buf[i].cs, EUO_NONE);
 
423
                                if (uc == 0)
 
424
                                        uc = ' ';
185
425
                                break;
186
426
                        case DBCS_LEFT:
187
 
                                dbcs_to_mb(ea_buf[i].cc, ea_buf[i + 1].cc, mb);
188
 
                                is_dbcs = True;
189
 
                                c = 'x';
 
427
                                uc = ebcdic_to_unicode(
 
428
                                        (ea_buf[i].cc << 8) |
 
429
                                         ea_buf[i + 1].cc,
 
430
                                        CS_BASE, EUO_NONE);
 
431
                                if (uc == 0)
 
432
                                        uc = 0x3000;
190
433
                                break;
 
434
                        case DBCS_RIGHT:
 
435
                                /* skip altogether, we took care of it above */
 
436
                                continue;
191
437
                        default:
192
 
                                c = ' ';
 
438
                                uc = ' ';
193
439
                                break;
194
440
                        }
195
 
                }
196
441
#else /*][*/
197
 
                else
198
 
                        c = ebc2asc[ea_buf[i].cc];
 
442
                        uc = ebcdic_to_unicode(ea_buf[i].cc, ea_buf[i].cs,
 
443
                                EUO_NONE);
 
444
                        if (uc == 0)
 
445
                                uc = ' ';
199
446
#endif /*]*/
200
 
                if (c == ' ')
 
447
                }
 
448
 
 
449
                /* Translate to a type-specific format and write it out. */
 
450
                if (uc == ' ' && ptype != P_HTML)
201
451
                        ns++;
 
452
#if defined(X3270_DBCS) /*[*/
 
453
                else if (uc == 0x3000) {
 
454
                        if (ptype == P_HTML)
 
455
                                fprintf(f, "  ");
 
456
                        else
 
457
                                ns += 2;
 
458
                }
 
459
#endif /*]*/
202
460
                else {
203
461
                        while (nr) {
 
462
                                if (ptype == P_RTF)
 
463
                                        fprintf(f, "\\par");
204
464
                                (void) fputc('\n', f);
205
465
                                nr--;
206
466
                        }
207
467
                        while (ns) {
208
 
                                (void) fputc(' ', f);
 
468
                                if (ptype == P_RTF)
 
469
                                        fprintf(f, "\\~");
 
470
                                else
 
471
                                        (void) fputc(' ', f);
209
472
                                ns--;
210
473
                        }
211
 
                        if (use_html) {
212
 
                                int color;
 
474
                        if (ptype == P_RTF) {
 
475
                                Bool high;
 
476
 
 
477
                                if (ea_buf[i].gr & GR_INTENSIFY)
 
478
                                        high = True;
 
479
                                else
 
480
                                        high = fa_high;
 
481
                                if (high != current_high) {
 
482
                                        if (high)
 
483
                                                fprintf(f, "\\b ");
 
484
                                        else
 
485
                                                fprintf(f, "\\b0 ");
 
486
                                        current_high = high;
 
487
                                }
 
488
                        }
 
489
                        if (ptype == P_HTML) {
 
490
                                int fg_color, bg_color;
213
491
                                Bool high;
214
492
 
215
493
                                if (ea_buf[i].fg)
216
 
                                        color = ea_buf[i].fg & 0x0f;
217
 
                                else
218
 
                                        color = fa_color;
219
 
                                if (color != current_color) {
220
 
                                        if (any)
221
 
                                                fprintf(f, "</font><font color=%s>",
222
 
                                                        html_color(color));
223
 
                                        current_color = color;
 
494
                                        fg_color = ea_buf[i].fg & 0x0f;
 
495
                                else
 
496
                                        fg_color = fa_fg;
 
497
                                if (ea_buf[i].bg)
 
498
                                        bg_color = ea_buf[i].bg & 0x0f;
 
499
                                else
 
500
                                        bg_color = fa_bg;
 
501
                                if (ea_buf[i].gr & GR_REVERSE) {
 
502
                                        int tmp;
 
503
 
 
504
                                        tmp = fg_color;
 
505
                                        fg_color = bg_color;
 
506
                                        bg_color = tmp;
 
507
                                }
 
508
 
 
509
                                if (i == cursor_addr) {
 
510
                                        fg_color = (bg_color == HOST_COLOR_RED)?
 
511
                                                        HOST_COLOR_BLACK: bg_color;
 
512
                                        bg_color = HOST_COLOR_RED;
224
513
                                }
225
514
                                if (ea_buf[i].gr & GR_INTENSIFY)
226
515
                                        high = True;
227
516
                                else
228
517
                                        high = fa_high;
229
 
                                if (high != current_high) {
230
 
                                        if (any) {
231
 
                                                if (high)
232
 
                                                        fprintf(f, "<b>");
233
 
                                                else
234
 
                                                        fprintf(f, "</b>");
 
518
 
 
519
                                if (fg_color != current_fg ||
 
520
                                    bg_color != current_bg ||
 
521
                                    high != current_high ||
 
522
                                    fa_ital != current_ital) {
 
523
                                        fprintf(f,
 
524
                                                "</span><span "
 
525
                                                "style=\"color:%s;"
 
526
                                                "background:%s;"
 
527
                                                "font-weight:%s;"
 
528
                                                "font-style:%s\">",
 
529
                                                html_color(fg_color),
 
530
                                                html_color(bg_color),
 
531
                                                high? "bold": "normal",
 
532
                                                fa_ital? "italic": "normal");
 
533
                                        current_fg = fg_color;
 
534
                                        current_bg = bg_color;
 
535
                                        current_high = high;
 
536
                                        current_ital = fa_ital;
 
537
                                }
 
538
                        }
 
539
                        any = True;
 
540
                        if (ptype == P_RTF) {
 
541
                                if (uc & ~0x7f) {
 
542
                                        fprintf(f, "\\u%ld?", uc);
 
543
                                } else {
 
544
                                        nmb = unicode_to_multibyte(uc,
 
545
                                                mb, sizeof(mb));
 
546
                                        if (mb[0] == '\\' ||
 
547
                                                mb[0] == '{' ||
 
548
                                                mb[0] == '}')
 
549
                                                fprintf(f, "\\%c",
 
550
                                                        mb[0]);
 
551
                                        else if (mb[0] == '-')
 
552
                                                fprintf(f, "\\_");
 
553
                                        else if (mb[0] == ' ')
 
554
                                                fprintf(f, "\\~");
 
555
                                        else
 
556
                                                fputc(mb[0], f);
 
557
                                }
 
558
                        } else if (ptype == P_HTML) {
 
559
                                if (uc == '<')
 
560
                                        fprintf(f, "&lt;");
 
561
                                else if (uc == '&')
 
562
                                        fprintf(f, "&amp;");
 
563
                                else if (uc == '>')
 
564
                                        fprintf(f, "&gt;");
 
565
                                else {
 
566
                                        nmb = unicode_to_utf8(uc, mb);
 
567
                                        {
 
568
                                            int k;
 
569
 
 
570
                                            for (k = 0; k < nmb; k++) {
 
571
                                                fputc(mb[k], f);
 
572
                                            }
235
573
                                        }
236
 
                                        current_high = high;
237
 
                                }
238
 
                                if (!any) {
239
 
                                        fprintf(f, "<html>\n"
240
 
                                                   "<head>\n"
241
 
                                                   " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\">\n"
242
 
                                                   "</head>\n"
243
 
                                                   " <body>\n"
244
 
                                                   "  <table border=0>"
245
 
                                                   "<tr bgcolor=black><td>"
246
 
                                                   "<pre><font color=%s>%s",
247
 
                                                   locale_codeset,
248
 
                                                   html_color(current_color),
249
 
                                                   current_high? "<b>": "");
250
 
                                }
251
 
                        }
252
 
                        any = True;
253
 
#if defined(X3270_DBCS) /*[*/
254
 
                        if (is_dbcs) {
 
574
                                }
 
575
                        } else {
 
576
                                nmb = unicode_to_multibyte(uc,
 
577
                                        mb, sizeof(mb));
255
578
                                (void) fputs(mb, f);
256
 
                                i++;
257
 
                        }
258
 
                        else
259
 
#endif /*]*/
260
 
                        {
261
 
                                if (use_html && c == '<')
262
 
                                        fprintf(f, "&lt;");
263
 
                                else
264
 
                                        (void) fputs(utf8_expand(c), f);
265
579
                        }
266
580
                }
267
581
        }
268
 
        nr++;
269
 
        if (!any && !even_if_empty)
 
582
 
 
583
        if (xcaption != NULL)
 
584
                Free(xcaption);
 
585
 
 
586
        if (ptype == P_HTML)
 
587
                (void) fputc('\n', f);
 
588
        else
 
589
                nr++;
 
590
        if (!any && !(opts & FPS_EVEN_IF_EMPTY) && ptype == P_TEXT)
270
591
                return False;
271
592
        while (nr) {
272
 
                (void) fputc('\n', f);
 
593
                if (ptype == P_RTF)
 
594
                        fprintf(f, "\\par");
 
595
                if (ptype == P_TEXT)
 
596
                        (void) fputc('\n', f);
273
597
                nr--;
274
598
        }
275
 
        if (use_html && any) {
276
 
                fprintf(f, "%s</font></pre></td></tr>\n"
 
599
        if (ptype == P_RTF) {
 
600
                fprintf(f, "\n}\n%c", 0);
 
601
        }
 
602
        if (ptype == P_HTML) {
 
603
                fprintf(f, "%s</span></pre></td></tr>\n"
277
604
                           "  </table>\n"
278
605
                           " </body>\n"
279
606
                           "</html>\n",
282
609
        return True;
283
610
}
284
611
 
 
612
#if !defined(_WIN32) /*[*/
285
613
/* Termination code for print text process. */
286
614
static void
287
615
print_text_done(FILE *f, Boolean do_popdown
288
616
#if defined(X3270_DISPLAY) /*[*/
289
 
                                            unused
 
617
                                            _is_unused
290
618
#endif /*]*/
291
619
                                                  )
292
620
{
300
628
#if defined(X3270_DISPLAY) /*[*/
301
629
                if (do_popdown)
302
630
                        XtPopdown(print_text_shell);
 
631
#endif /*]*/
 
632
#if defined(X3270_DISPLAY) || defined(C3270) /*[*/
303
633
                if (appres.do_confirms)
304
634
                        popup_an_info("Screen image printed.");
305
635
#endif /*]*/
306
636
        }
307
637
 
308
638
}
 
639
#endif /*]*/
309
640
 
310
641
#if defined(X3270_DISPLAY) /*[*/
311
642
/* Callback for "OK" button on the print text popup. */
312
643
static void
313
 
print_text_callback(Widget w unused, XtPointer client_data,
314
 
    XtPointer call_data unused)
 
644
print_text_callback(Widget w _is_unused, XtPointer client_data,
 
645
    XtPointer call_data _is_unused)
315
646
{
316
647
        char *filter;
317
648
        FILE *f;
325
656
                popup_an_errno(errno, "popen(%s)", filter);
326
657
                return;
327
658
        }
328
 
        (void) fprint_screen(f, True, False);
 
659
        if (print_text_command == NULL ||
 
660
                strcmp(print_text_command, filter)) {
 
661
            Replace(print_text_command, filter);
 
662
            ptc_changed = True;
 
663
        }
 
664
        (void) fprint_screen(f, P_TEXT, FPS_EVEN_IF_EMPTY, NULL);
329
665
        print_text_done(f, True);
330
666
}
331
667
 
332
668
/* Callback for "Plain Text" button on save text popup. */
333
669
static void
334
 
save_text_plain_callback(Widget w unused, XtPointer client_data,
335
 
    XtPointer call_data unused)
 
670
save_text_plain_callback(Widget w _is_unused, XtPointer client_data,
 
671
    XtPointer call_data _is_unused)
336
672
{
337
673
        char *filename;
338
674
        FILE *f;
346
682
                popup_an_errno(errno, "%s", filename);
347
683
                return;
348
684
        }
349
 
        (void) fprint_screen(f, True, False);
 
685
        (void) fprint_screen(f, P_TEXT, FPS_EVEN_IF_EMPTY, NULL);
350
686
        fclose(f);
351
687
        XtPopdown(save_text_shell);
352
688
        if (appres.do_confirms)
355
691
 
356
692
/* Callback for "HTML" button on save text popup. */
357
693
static void
358
 
save_text_html_callback(Widget w unused, XtPointer client_data,
359
 
    XtPointer call_data unused)
 
694
save_text_html_callback(Widget w _is_unused, XtPointer client_data,
 
695
    XtPointer call_data _is_unused)
360
696
{
361
697
        char *filename;
362
698
        FILE *f;
370
706
                popup_an_errno(errno, "%s", filename);
371
707
                return;
372
708
        }
373
 
        (void) fprint_screen(f, True, True);
 
709
        (void) fprint_screen(f, P_HTML, FPS_EVEN_IF_EMPTY, NULL);
374
710
        fclose(f);
375
711
        XtPopdown(save_text_shell);
376
712
        if (appres.do_confirms)
410
746
}
411
747
#endif /*]*/
412
748
 
 
749
#if defined(_WIN32) /*[*/
 
750
/*
 
751
 * A Windows version of something like mkstemp().  Creates a temporary
 
752
 * file in $TEMP, returning its path and an open file descriptor.
 
753
 */
 
754
int
 
755
win_mkstemp(char **path, ptype_t ptype)
 
756
{
 
757
        char *s;
 
758
        int fd;
 
759
 
 
760
        s = getenv("TEMP");
 
761
        if (s == NULL)
 
762
                s = getenv("TMP");
 
763
        if (s == NULL)
 
764
                s = "C:";
 
765
        *path = xs_buffer("%s\\x3h%u.%s", s, getpid(),
 
766
                            (ptype == P_RTF)? "rtf": "txt");
 
767
        fd = open(*path, O_CREAT | O_RDWR, S_IREAD | S_IWRITE);
 
768
        if (fd < 0) {
 
769
            Free(*path);
 
770
            *path = NULL;
 
771
        }
 
772
        return fd;
 
773
}
 
774
 
 
775
/*
 
776
 * Find WORDPAD.EXE.
 
777
 */
 
778
#define PROGRAMFILES "%ProgramFiles%"
 
779
char *
 
780
find_wordpad(void)
 
781
{
 
782
        char data[1024];
 
783
        DWORD dlen;
 
784
        char *slash;
 
785
        static char *wp = NULL;
 
786
        HKEY key;
 
787
 
 
788
        if (wp != NULL)
 
789
            return wp;
 
790
 
 
791
        /* Get the shell print command for RTF files. */
 
792
        if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
 
793
                    "Software\\Classes\\rtffile\\shell\\print\\command",
 
794
                    0,
 
795
                    KEY_READ,
 
796
                    &key) != ERROR_SUCCESS) {
 
797
                return NULL;
 
798
        }
 
799
        dlen = sizeof(data);
 
800
        if (RegQueryValueEx(key,
 
801
                    NULL,
 
802
                    NULL,
 
803
                    NULL,
 
804
                    (LPVOID)data,
 
805
                    &dlen) != ERROR_SUCCESS) {
 
806
                RegCloseKey(key);
 
807
                return NULL;
 
808
        }
 
809
        RegCloseKey(key);
 
810
 
 
811
        if (data[0] == '"') {
 
812
            char data2[1024];
 
813
            char *q2;
 
814
 
 
815
            /* The first token is quoted; that's the path. */
 
816
            strcpy(data2, data + 1);
 
817
            q2 = strchr(data2, '"');
 
818
            if (q2 == NULL) {
 
819
                return NULL;
 
820
            }
 
821
            *q2 = '\0';
 
822
            strcpy(data, data2);
 
823
        } else if ((slash = strchr(data, '/')) != NULL) {
 
824
            /* Find the "/p". */
 
825
            *slash = '\0';
 
826
            if (*(slash - 1) == ' ')
 
827
                *(slash - 1) = '\0';
 
828
        }
 
829
 
 
830
        if (!strncasecmp(data, PROGRAMFILES, strlen(PROGRAMFILES))) {
 
831
            char *pf = getenv("PROGRAMFILES");
 
832
 
 
833
            /* Substitute %ProgramFiles%. */
 
834
            if (pf == NULL) {
 
835
                return NULL;
 
836
            }
 
837
            wp = xs_buffer("%s\\%s", pf, data + strlen(PROGRAMFILES));
 
838
        } else {
 
839
            wp = NewString(data);
 
840
        }
 
841
        if (GetShortPathName(wp, data, sizeof(data)) != 0) {
 
842
            Free(wp);
 
843
            wp = NewString(data);
 
844
        }
 
845
        return wp;
 
846
}
 
847
#endif /*]*/
 
848
 
413
849
/* Print or save the contents of the screen as text. */
414
850
void
415
 
PrintText_action(Widget w unused, XEvent *event, String *params,
 
851
PrintText_action(Widget w _is_unused, XEvent *event, String *params,
416
852
    Cardinal *num_params)
417
853
{
418
 
        int i;
 
854
        Cardinal i;
419
855
        char *filter = CN;
420
856
        Boolean secure = appres.secure;
421
 
        Boolean use_html = False;
 
857
        ptype_t ptype = P_TEXT;
422
858
        Boolean use_file = False;
423
859
        Boolean use_string = False;
 
860
        char *temp_name = NULL;
 
861
        unsigned opts = FPS_EVEN_IF_EMPTY;
 
862
        char *caption = NULL;
424
863
 
425
864
        action_debug(PrintText_action, event, params, num_params);
426
865
 
430
869
         *            must be the last keyword
431
870
         *  html     generates HTML output instead of ASCII text (and implies
432
871
         *            'file')
 
872
         *  rtf      generates RTF output instead of ASCII text (and implies
 
873
         *            'file')
 
874
         *  modi     print modified fields in italics
 
875
         *  caption "text"
 
876
         *           Adds caption text above the screen
 
877
         *           %T% is replaced by a timestamp
433
878
         *  secure   disables the pop-up dialog, if this action is invoked from
434
879
         *            a keymap
435
880
         *  command  directs the output to a command (this is the default, but
443
888
                        i++;
444
889
                        break;
445
890
                } else if (!strcasecmp(params[i], "html")) {
446
 
                        use_html = True;
 
891
                        ptype = P_HTML;
 
892
                        use_file = True;
 
893
                } else if (!strcasecmp(params[i], "rtf")) {
 
894
                        ptype = P_RTF;
447
895
                        use_file = True;
448
896
                } else if (!strcasecmp(params[i], "secure")) {
449
897
                        secure = True;
450
898
                } else if (!strcasecmp(params[i], "command")) {
451
 
                        if (use_html || use_file) {
 
899
                        if ((ptype != P_TEXT) || use_file) {
452
900
                                popup_an_error("%s: contradictory options",
453
901
                                    action_name(PrintText_action));
454
902
                                return;
464
912
                        }
465
913
                        use_string = True;
466
914
                        use_file = True;
 
915
                } else if (!strcasecmp(params[i], "modi")) {
 
916
                        opts |= FPS_MODIFIED_ITALIC;
 
917
                } else if (!strcasecmp(params[i], "caption")) {
 
918
                        if (i == *num_params - 1) {
 
919
                                popup_an_error("%s: mising caption parameter",
 
920
                                        action_name(PrintText_action));
 
921
                                return;
 
922
                        }
 
923
                        caption = params[++i];
467
924
                } else {
468
925
                        break;
469
926
                }
471
928
        switch (*num_params - i) {
472
929
        case 0:
473
930
                /* Use the default. */
474
 
                if (!use_file)
 
931
                if (!use_file) {
 
932
#if !defined(_WIN32) /*[*/
475
933
                        filter = get_resource(ResPrintTextCommand);
 
934
#else /*][*/
 
935
                        filter = get_resource(ResPrinterName); /* XXX */
 
936
#endif /*]*/
 
937
                }
476
938
                break;
477
939
        case 1:
478
940
                if (use_string) {
488
950
                return;
489
951
        }
490
952
 
 
953
#if defined(_WIN32) /*[*/
 
954
        /* On Windows, use rich text. */
 
955
        if (!use_string && !use_file && ptype != P_HTML)
 
956
            ptype = P_RTF;
 
957
#endif /*]*/
 
958
 
491
959
        if (filter != CN && filter[0] == '@') {
492
960
                /*
493
961
                 * Starting the PrintTextCommand resource value with '@'
498
966
                filter++;
499
967
        }
500
968
        if (!use_file && (filter == CN || !*filter))
 
969
#if !defined(_WIN32) /*[*/
501
970
                filter = "lpr";
 
971
#else /*][*/
 
972
                filter = CN;
 
973
#endif /*]*/
502
974
 
503
975
#if defined(X3270_DISPLAY) /*[*/
504
976
        if (secure ||
513
985
                /* Invoked non-interactively. */
514
986
                if (use_file) {
515
987
                        if (use_string) {
516
 
                                char temp_name[15];
517
 
 
518
988
#if defined(_WIN32) /*[*/
519
 
                                strcpy(temp_name, "x3hXXXXXX");
520
 
                                mktemp(temp_name);
521
 
                                fd = _open(temp_name, _O_RDWR,
522
 
                                        _S_IREAD | _S_IWRITE);
 
989
                                fd = win_mkstemp(&temp_name, ptype);
523
990
#else /*][*/
524
 
                                strcpy(temp_name, "/tmp/x3hXXXXXX");
 
991
                                temp_name = NewString("/tmp/x3hXXXXXX");
525
992
                                fd = mkstemp(temp_name);
526
993
#endif /*]*/
527
994
                                if (fd < 0) {
528
995
                                        popup_an_errno(errno, "mkstemp");
529
996
                                        return;
530
997
                                }
531
 
                                (void) unlink(temp_name);
532
998
                                f = fdopen(fd, "w+");
533
999
                        } else {
534
1000
                                if (filter == CN || !*filter) {
538
1004
                                }
539
1005
                                f = fopen(filter, "a");
540
1006
                        }
541
 
                } else
 
1007
                } else {
 
1008
#if !defined(_WIN32) /*[*/
542
1009
                        f = popen(filter, "w");
 
1010
#else /*][*/
 
1011
                        fd = win_mkstemp(&temp_name, ptype);
 
1012
                        if (fd < 0) {
 
1013
                                popup_an_errno(errno, "mkstemp");
 
1014
                                return;
 
1015
                        }
 
1016
                        f = fdopen(fd, "w+");
 
1017
#endif /*]*/
 
1018
                }
543
1019
                if (f == NULL) {
544
1020
                        popup_an_errno(errno, "%s: %s",
545
1021
                                        action_name(PrintText_action),
547
1023
                        if (fd >= 0) {
548
1024
                                (void) close(fd);
549
1025
                        }
 
1026
                        if (temp_name) {
 
1027
                                unlink(temp_name);
 
1028
                                Free(temp_name);
 
1029
                        }
550
1030
                        return;
551
1031
                }
552
 
                (void) fprint_screen(f, True, use_html);
 
1032
                (void) fprint_screen(f, ptype, opts, caption);
553
1033
                if (use_string) {
554
1034
                        char buf[8192];
555
1035
 
556
1036
                        rewind(f);
557
1037
                        while (fgets(buf, sizeof(buf), f) != NULL)
558
 
                                action_output(buf);
 
1038
                                action_output("%s", buf);
559
1039
                }
560
1040
                if (use_file)
561
1041
                        fclose(f);
562
 
                else
 
1042
                else {
 
1043
#if !defined(_WIN32) /*[*/
563
1044
                        print_text_done(f, False);
 
1045
#else /*][*/
 
1046
                        char *wp;
 
1047
 
 
1048
                        fclose(f);
 
1049
                        wp = find_wordpad();
 
1050
                        if (wp == NULL) {
 
1051
                                popup_an_error("%s: Can't find WORDPAD.EXE",
 
1052
                                        action_name(PrintText_action));
 
1053
                        } else {
 
1054
                                char *cmd;
 
1055
 
 
1056
                                if (filter != CN)
 
1057
                                    cmd = xs_buffer("start /wait /min %s "
 
1058
                                                    "/pt \"%s\" \"%s\"",
 
1059
                                                    wp, temp_name, filter);
 
1060
                                else
 
1061
                                    cmd = xs_buffer("start /wait /min %s "
 
1062
                                                    "/p \"%s\"",
 
1063
                                                    wp, temp_name);
 
1064
                                system(cmd);
 
1065
                                Free(cmd);
 
1066
                        }
 
1067
#if !defined(S3270) /*[*/
 
1068
                        if (appres.do_confirms)
 
1069
                                popup_an_info("Screen image printed.\n");
 
1070
#endif /*]*/
 
1071
#endif /*]*/
 
1072
                }
 
1073
                if (temp_name) {
 
1074
                        unlink(temp_name);
 
1075
                        Free(temp_name);
 
1076
                }
564
1077
                return;
565
1078
        }
566
1079
 
580
1093
 
581
1094
/* Callback for Print Text menu option. */
582
1095
void
583
 
print_text_option(Widget w, XtPointer client_data unused,
584
 
    XtPointer call_data unused)
 
1096
print_text_option(Widget w, XtPointer client_data _is_unused,
 
1097
    XtPointer call_data _is_unused)
585
1098
{
586
1099
        char *filter = get_resource(ResPrintTextCommand);
587
1100
        Boolean secure = appres.secure;
588
 
        Boolean use_html = False;
 
1101
        ptype_t ptype = P_TEXT;
 
1102
 
 
1103
        if (print_text_command != NULL)
 
1104
                filter = print_text_command;
 
1105
        else {
 
1106
                filter = get_resource(ResPrintTextCommand);
 
1107
                if (filter == NULL || !*filter)
 
1108
                        filter = "lpr";
 
1109
                print_text_command = XtNewString(filter);
 
1110
        }
589
1111
 
590
1112
        /* Decode the filter. */
591
1113
        if (filter != CN && *filter == '@') {
603
1125
                        popup_an_errno(errno, "popen(%s)", filter);
604
1126
                        return;
605
1127
                }
606
 
                (void) fprint_screen(f, True, use_html);
 
1128
                (void) fprint_screen(f, ptype, FPS_EVEN_IF_EMPTY, NULL);
607
1129
                print_text_done(f, False);
608
1130
        } else {
609
1131
                /* Pop up a dialog to confirm or modify their choice. */
613
1135
 
614
1136
/* Callback for Save Text menu option. */
615
1137
void
616
 
save_text_option(Widget w, XtPointer client_data unused,
617
 
    XtPointer call_data unused)
 
1138
save_text_option(Widget w, XtPointer client_data _is_unused,
 
1139
    XtPointer call_data _is_unused)
618
1140
{
619
1141
        /* Pop up a dialog to confirm or modify their choice. */
620
1142
        popup_save_text(CN);
654
1176
 
655
1177
/* Timeout callback for window print. */
656
1178
static void
657
 
snap_it(XtPointer closure unused, XtIntervalId *id unused)
 
1179
snap_it(XtPointer closure _is_unused, XtIntervalId *id _is_unused)
658
1180
{
659
1181
        if (!print_window_command)
660
1182
                return;
661
1183
        XSync(display, 0);
662
1184
        print_window_done(system(print_window_command));
663
 
        print_window_command = CN;
664
1185
}
665
1186
 
666
1187
/* Callback for "OK" button on print window popup. */
667
1188
static void
668
 
print_window_callback(Widget w unused, XtPointer client_data,
669
 
    XtPointer call_data unused)
 
1189
print_window_callback(Widget w _is_unused, XtPointer client_data,
 
1190
    XtPointer call_data _is_unused)
670
1191
{
671
1192
        print_window_command = XawDialogGetValueString((Widget)client_data);
672
1193
        XtPopdown(print_window_shell);
676
1197
 
677
1198
/* Print the contents of the screen as a bitmap. */
678
1199
void
679
 
PrintWindow_action(Widget w unused, XEvent *event, String *params,
 
1200
PrintWindow_action(Widget w _is_unused, XEvent *event, String *params,
680
1201
    Cardinal *num_params)
681
1202
{
682
1203
        char *filter = get_resource(ResPrintWindowCommand);
717
1238
#if defined(X3270_MENUS) /*[*/
718
1239
/* Callback for menu Print Window option. */
719
1240
void
720
 
print_window_option(Widget w, XtPointer client_data unused,
721
 
    XtPointer call_data unused)
 
1241
print_window_option(Widget w, XtPointer client_data _is_unused,
 
1242
    XtPointer call_data _is_unused)
722
1243
{
723
1244
        Cardinal zero = 0;
724
1245
 
727
1248
#endif /*]*/
728
1249
 
729
1250
#endif /*]*/
 
1251