2014-11-22 03:32:33 +00:00
|
|
|
/* print_stream.c
|
|
|
|
* Routines for print streams.
|
2014-11-22 03:22:54 +00:00
|
|
|
*
|
|
|
|
* Gilbert Ramirez <gram@alumni.rice.edu>
|
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
2018-02-07 11:26:45 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
2014-11-22 03:22:54 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2017-04-25 05:14:42 +00:00
|
|
|
#include <string.h>
|
2014-11-22 03:22:54 +00:00
|
|
|
|
2016-05-06 17:25:02 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include <windows.h>
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
|
|
|
|
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
|
|
|
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
|
|
|
|
#endif /* ENABLE_VIRTUAL_TERMINAL_PROCESSING */
|
|
|
|
#else
|
|
|
|
#include <stdlib.h> /* for getenv() */
|
|
|
|
#include <unistd.h> /* for isatty() */
|
2016-05-06 17:25:02 +00:00
|
|
|
#endif
|
|
|
|
|
2014-11-22 03:22:54 +00:00
|
|
|
#include <glib.h>
|
|
|
|
|
|
|
|
#include <epan/print_stream.h>
|
|
|
|
|
|
|
|
#include <epan/ps.h>
|
|
|
|
|
|
|
|
#include <wsutil/file_util.h>
|
|
|
|
|
2017-04-25 05:14:42 +00:00
|
|
|
#define TERM_SGR_RESET "\x1B[0m" /* SGR - reset */
|
|
|
|
#define TERM_CSI_EL "\x1B[K" /* EL - Erase in Line (to end of line) */
|
|
|
|
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
typedef enum {
|
|
|
|
COLOR_NONE,
|
|
|
|
#ifdef _WIN32
|
|
|
|
COLOR_CONSOLE,
|
|
|
|
#endif
|
|
|
|
COLOR_24BIT_ESCAPE
|
|
|
|
} color_type_t;
|
|
|
|
|
2018-01-05 23:40:19 +00:00
|
|
|
typedef struct {
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
gboolean to_file;
|
|
|
|
FILE *fh;
|
|
|
|
gboolean isatty;
|
|
|
|
const char *to_codeset;
|
|
|
|
color_type_t color_type;
|
2019-04-01 01:17:57 +00:00
|
|
|
#ifdef _WIN32
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
WORD csb_attrs;
|
|
|
|
DWORD console_mode;
|
2019-04-01 01:17:57 +00:00
|
|
|
#endif
|
2018-01-05 23:40:19 +00:00
|
|
|
} output_text;
|
|
|
|
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
/*
|
|
|
|
* The classic Windows Console offers 1-bit color, so you can't set
|
|
|
|
* the red, green, or blue intensities, you can only set
|
|
|
|
* "{foreground, background} contains {red, green, blue}". So
|
|
|
|
* include red, green or blue if the numeric intensity is high
|
|
|
|
* enough.
|
|
|
|
*/
|
2017-04-25 05:14:42 +00:00
|
|
|
static void
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
set_color_console(FILE *fh, const color_t *fg, const color_t *bg)
|
2017-04-25 05:14:42 +00:00
|
|
|
{
|
|
|
|
/* default to white foreground, black background */
|
|
|
|
WORD win_fg_color = FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN;
|
|
|
|
WORD win_bg_color = 0;
|
|
|
|
|
|
|
|
if (fg) {
|
|
|
|
if (((fg->red >> 8) & 0xff) >= 0x80)
|
|
|
|
{
|
|
|
|
win_fg_color |= FOREGROUND_RED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
win_fg_color &= (~FOREGROUND_RED);
|
|
|
|
}
|
|
|
|
if (((fg->green >> 8) & 0xff) >= 0x80)
|
|
|
|
{
|
|
|
|
win_fg_color |= FOREGROUND_GREEN;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
win_fg_color &= (~FOREGROUND_GREEN);
|
|
|
|
}
|
|
|
|
if (((fg->blue >> 8) & 0xff) >= 0x80)
|
|
|
|
{
|
|
|
|
win_fg_color |= FOREGROUND_BLUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
win_fg_color &= (~FOREGROUND_BLUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bg) {
|
|
|
|
if (((bg->red >> 8) & 0xff) >= 0x80)
|
|
|
|
{
|
|
|
|
win_bg_color |= BACKGROUND_RED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
win_bg_color &= (~BACKGROUND_RED);
|
|
|
|
}
|
|
|
|
if (((bg->green >> 8) & 0xff) >= 0x80)
|
|
|
|
{
|
|
|
|
win_bg_color |= BACKGROUND_GREEN;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
win_bg_color &= (~BACKGROUND_GREEN);
|
|
|
|
}
|
|
|
|
if (((bg->blue >> 8) & 0xff) >= 0x80)
|
|
|
|
{
|
|
|
|
win_bg_color |= BACKGROUND_BLUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
win_bg_color &= (~BACKGROUND_BLUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SetConsoleTextAttribute((HANDLE)_get_osfhandle(_fileno(fh)), win_fg_color|win_bg_color);
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Use the SGR escape sequences to specify a 24-bit color.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
set_color_24bit_escape(FILE *fh, const color_t *fg, const color_t *bg)
|
|
|
|
{
|
2017-06-11 22:14:29 +00:00
|
|
|
/*
|
|
|
|
* Use the "select character foreground colour" and "select character
|
|
|
|
* background colour" options to the Select Graphic Rendition control
|
|
|
|
* sequence; those are reserved in ECMA-48, and are specified in ISO
|
|
|
|
* standard 8613-6/ITU-T Recommendation T.416, "Open Document Architecture
|
|
|
|
* (ODA) and Interchange Format: Chararcter Content Architectures",
|
|
|
|
* section 13.1.8 "Select Graphic Rendition (SGR)". We use the
|
|
|
|
* "direct colour in RGB space" option, with a parameter value of 2.
|
|
|
|
*
|
|
|
|
* Those sequences are supported by some UN*X terminal emulators; some
|
|
|
|
* support either : or ; as a separator, others require a ;.
|
|
|
|
*
|
|
|
|
* For more than you ever wanted to know about all of this, see
|
|
|
|
*
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
* https://github.com/termstandard/colors
|
|
|
|
*
|
|
|
|
* and
|
|
|
|
*
|
2017-06-11 22:14:29 +00:00
|
|
|
* https://gist.github.com/XVilka/8346728
|
|
|
|
*
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
* including the discussion following it, and
|
2017-06-11 22:14:29 +00:00
|
|
|
*
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
* https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
|
2017-06-11 22:14:29 +00:00
|
|
|
*
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
* They are also supported by versions of the Windows Console that
|
|
|
|
* allow setting the ENABLE_VIRTUAL_TERMINAL_PROCESSING mode; that
|
|
|
|
* mode tells the console to interpret escape sequences written
|
|
|
|
* to it.
|
2017-06-11 22:14:29 +00:00
|
|
|
*/
|
2017-04-25 05:14:42 +00:00
|
|
|
if (fg) {
|
|
|
|
fprintf(fh, "\x1B[38;2;%u;%u;%um",
|
|
|
|
(fg->red >> 8) & 0xff,
|
|
|
|
(fg->green >> 8) & 0xff,
|
|
|
|
(fg->blue >> 8) & 0xff);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bg) {
|
|
|
|
fprintf(fh, "\x1B[48;2;%u;%u;%um",
|
|
|
|
(bg->red >> 8) & 0xff,
|
|
|
|
(bg->green >> 8) & 0xff,
|
|
|
|
(bg->blue >> 8) & 0xff);
|
|
|
|
}
|
2017-06-12 05:04:42 +00:00
|
|
|
}
|
2017-04-25 05:14:42 +00:00
|
|
|
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
#ifdef _WIN32
|
2017-04-25 05:14:42 +00:00
|
|
|
static void
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
do_color_eol_console(print_stream_t *self)
|
2017-04-25 05:14:42 +00:00
|
|
|
{
|
2018-01-05 23:40:19 +00:00
|
|
|
output_text *output = (output_text *)self->data;
|
|
|
|
FILE *fh = output->fh;
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
|
2019-04-01 01:17:57 +00:00
|
|
|
SetConsoleTextAttribute((HANDLE)_get_osfhandle(_fileno(fh)), output->csb_attrs);
|
2018-01-05 23:40:19 +00:00
|
|
|
fprintf(fh, "\n");
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static void
|
|
|
|
do_color_eol_24bit_escape(print_stream_t *self)
|
|
|
|
{
|
|
|
|
output_text *output = (output_text *)self->data;
|
|
|
|
FILE *fh = output->fh;
|
2018-01-05 23:40:19 +00:00
|
|
|
|
2017-04-25 05:14:42 +00:00
|
|
|
/*
|
|
|
|
* Emit CSI EL to extend current background color all the way to EOL,
|
|
|
|
* otherwise we get a ragged right edge of color wherever the newline
|
|
|
|
* occurs. It's not perfect in every terminal emulator, but it generally
|
|
|
|
* works.
|
|
|
|
*/
|
|
|
|
fprintf(fh, "%s\n%s", TERM_CSI_EL, TERM_SGR_RESET);
|
|
|
|
}
|
|
|
|
|
2014-11-22 03:22:54 +00:00
|
|
|
static FILE *
|
|
|
|
open_print_dest(gboolean to_file, const char *dest)
|
|
|
|
{
|
|
|
|
FILE *fh;
|
|
|
|
|
|
|
|
/* Open the file or command for output */
|
|
|
|
if (to_file)
|
|
|
|
fh = ws_fopen(dest, "w");
|
|
|
|
else
|
|
|
|
fh = popen(dest, "w");
|
|
|
|
|
|
|
|
return fh;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
close_print_dest(gboolean to_file, FILE *fh)
|
|
|
|
{
|
|
|
|
/* Close the file or command */
|
|
|
|
if (to_file)
|
|
|
|
return (fclose(fh) == 0);
|
|
|
|
else
|
|
|
|
return (pclose(fh) == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Some formats need stuff at the beginning of the output */
|
|
|
|
gboolean
|
|
|
|
print_preamble(print_stream_t *self, gchar *filename, const char *version_string)
|
|
|
|
{
|
|
|
|
return self->ops->print_preamble ? (self->ops->print_preamble)(self, filename, version_string) : TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
print_line(print_stream_t *self, int indent, const char *line)
|
|
|
|
{
|
|
|
|
return (self->ops->print_line)(self, indent, line);
|
|
|
|
}
|
|
|
|
|
2017-04-25 05:14:42 +00:00
|
|
|
gboolean
|
|
|
|
print_line_color(print_stream_t *self, int indent, const char *line, const color_t *fg, const color_t *bg)
|
|
|
|
{
|
|
|
|
if (self->ops->print_line_color)
|
|
|
|
return (self->ops->print_line_color)(self, indent, line, fg, bg);
|
|
|
|
else
|
|
|
|
return (self->ops->print_line)(self, indent, line);
|
|
|
|
}
|
|
|
|
|
2014-11-22 03:22:54 +00:00
|
|
|
/* Insert bookmark */
|
|
|
|
gboolean
|
|
|
|
print_bookmark(print_stream_t *self, const gchar *name, const gchar *title)
|
|
|
|
{
|
|
|
|
return self->ops->print_bookmark ? (self->ops->print_bookmark)(self, name, title) : TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
new_page(print_stream_t *self)
|
|
|
|
{
|
|
|
|
return self->ops->new_page ? (self->ops->new_page)(self) : TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Some formats need stuff at the end of the output */
|
|
|
|
gboolean
|
|
|
|
print_finale(print_stream_t *self)
|
|
|
|
{
|
|
|
|
return self->ops->print_finale ? (self->ops->print_finale)(self) : TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
destroy_print_stream(print_stream_t *self)
|
|
|
|
{
|
2017-02-09 17:06:45 +00:00
|
|
|
return (self && self->ops && self->ops->destroy) ? (self->ops->destroy)(self) : TRUE;
|
2014-11-22 03:22:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define MAX_INDENT 160
|
|
|
|
|
2017-04-25 05:14:42 +00:00
|
|
|
/* returns TRUE if the print succeeded, FALSE if there was an error */
|
2014-11-22 03:22:54 +00:00
|
|
|
static gboolean
|
2017-04-25 05:14:42 +00:00
|
|
|
print_line_color_text(print_stream_t *self, int indent, const char *line, const color_t *fg, const color_t *bg)
|
2014-11-22 03:22:54 +00:00
|
|
|
{
|
2017-04-25 05:14:42 +00:00
|
|
|
static char spaces[MAX_INDENT];
|
2014-11-22 03:22:54 +00:00
|
|
|
size_t ret;
|
|
|
|
output_text *output = (output_text *)self->data;
|
|
|
|
unsigned int num_spaces;
|
2019-04-01 01:17:57 +00:00
|
|
|
gboolean emit_color = output->isatty && (fg != NULL || bg != NULL);
|
2014-11-22 03:22:54 +00:00
|
|
|
|
|
|
|
/* should be space, if NUL -> initialize */
|
2017-04-25 05:14:42 +00:00
|
|
|
if (!spaces[0])
|
|
|
|
memset(spaces, ' ', sizeof(spaces));
|
2014-11-22 03:22:54 +00:00
|
|
|
|
2017-04-25 05:14:42 +00:00
|
|
|
if (emit_color) {
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
switch (output->color_type) {
|
|
|
|
|
|
|
|
case COLOR_NONE:
|
|
|
|
break;
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
case COLOR_CONSOLE:
|
|
|
|
set_color_console(output->fh, fg, bg);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
case COLOR_24BIT_ESCAPE:
|
|
|
|
set_color_24bit_escape(output->fh, fg, bg);
|
|
|
|
if (ferror(output->fh))
|
|
|
|
return FALSE;
|
|
|
|
break;
|
|
|
|
}
|
2014-11-22 03:22:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Prepare the tabs for printing, depending on tree level */
|
|
|
|
num_spaces = indent * 4;
|
|
|
|
if (num_spaces > MAX_INDENT)
|
|
|
|
num_spaces = MAX_INDENT;
|
|
|
|
|
|
|
|
ret = fwrite(spaces, 1, num_spaces, output->fh);
|
|
|
|
if (ret == num_spaces) {
|
2019-04-01 01:17:57 +00:00
|
|
|
if (output->isatty && output->to_codeset) {
|
2016-05-06 17:25:02 +00:00
|
|
|
/* XXX Allocating a fresh buffer every line probably isn't the
|
|
|
|
* most efficient way to do this. However, this has the side
|
|
|
|
* effect of scrubbing invalid output.
|
|
|
|
*/
|
2019-04-01 03:28:20 +00:00
|
|
|
gchar *tty_out;
|
|
|
|
|
2019-04-01 01:17:57 +00:00
|
|
|
tty_out = g_convert_with_fallback(line, -1, output->to_codeset, "UTF-8", "?", NULL, NULL, NULL);
|
2016-05-06 17:25:02 +00:00
|
|
|
|
2019-04-01 03:28:20 +00:00
|
|
|
if (tty_out) {
|
2016-05-06 17:25:02 +00:00
|
|
|
#ifdef _WIN32
|
2019-04-01 03:28:20 +00:00
|
|
|
/*
|
|
|
|
* We mapped to little-endian UTF-16, so write to the
|
|
|
|
* console using the Unicode API.
|
|
|
|
*/
|
|
|
|
DWORD out_len = (DWORD) wcslen((wchar_t *) tty_out);
|
|
|
|
WriteConsoleW((HANDLE)_get_osfhandle(_fileno(output->fh)), tty_out, out_len, &out_len, NULL);
|
2016-05-06 17:25:02 +00:00
|
|
|
#else
|
2019-04-01 03:28:20 +00:00
|
|
|
fputs(tty_out, output->fh);
|
2016-05-06 17:25:02 +00:00
|
|
|
#endif
|
2019-04-01 03:28:20 +00:00
|
|
|
g_free(tty_out);
|
|
|
|
} else {
|
|
|
|
fputs(line, output->fh);
|
|
|
|
}
|
2016-05-06 17:25:02 +00:00
|
|
|
} else {
|
2019-04-01 03:28:20 +00:00
|
|
|
/*
|
|
|
|
* Either we're not writing to a terminal/console or we are
|
|
|
|
* but we're just writing UTF-8 there.
|
|
|
|
*/
|
2016-05-06 17:25:02 +00:00
|
|
|
fputs(line, output->fh);
|
|
|
|
}
|
2017-04-25 05:14:42 +00:00
|
|
|
|
2019-04-01 03:28:20 +00:00
|
|
|
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
if (emit_color) {
|
|
|
|
switch (output->color_type) {
|
|
|
|
|
|
|
|
case COLOR_NONE:
|
|
|
|
putc('\n', output->fh);
|
|
|
|
break;
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
case COLOR_CONSOLE:
|
|
|
|
do_color_eol_console(self);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
case COLOR_24BIT_ESCAPE:
|
|
|
|
do_color_eol_24bit_escape(self);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else
|
2017-04-25 05:14:42 +00:00
|
|
|
putc('\n', output->fh);
|
2014-11-22 03:22:54 +00:00
|
|
|
}
|
2017-04-25 05:14:42 +00:00
|
|
|
|
2014-11-22 03:22:54 +00:00
|
|
|
return !ferror(output->fh);
|
|
|
|
}
|
|
|
|
|
2017-04-25 05:14:42 +00:00
|
|
|
static gboolean
|
|
|
|
print_line_text(print_stream_t *self, int indent, const char *line)
|
|
|
|
{
|
|
|
|
return print_line_color_text(self, indent, line, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
2014-11-22 03:22:54 +00:00
|
|
|
static gboolean
|
|
|
|
new_page_text(print_stream_t *self)
|
|
|
|
{
|
|
|
|
output_text *output = (output_text *)self->data;
|
|
|
|
|
|
|
|
fputs("\f", output->fh);
|
|
|
|
return !ferror(output->fh);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
destroy_text(print_stream_t *self)
|
|
|
|
{
|
|
|
|
output_text *output = (output_text *)self->data;
|
|
|
|
gboolean ret;
|
|
|
|
|
2019-04-04 18:01:46 +00:00
|
|
|
switch (output->color_type) {
|
|
|
|
|
|
|
|
case COLOR_NONE:
|
|
|
|
break;
|
|
|
|
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
#ifdef _WIN32
|
2019-04-04 18:01:46 +00:00
|
|
|
case COLOR_CONSOLE:
|
|
|
|
/* Restore the default text attribute. */
|
|
|
|
SetConsoleTextAttribute((HANDLE)_get_osfhandle(_fileno(output->fh)), output->csb_attrs);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
case COLOR_24BIT_ESCAPE:
|
|
|
|
/* Reset the color to the default */
|
|
|
|
fprintf(output->fh, "%s", TERM_SGR_RESET);
|
|
|
|
fflush(output->fh);
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
/*
|
|
|
|
* Restore the console mode before we changed it.
|
|
|
|
* We must do that *after* sending escape sequences,
|
|
|
|
* as this may disable escape sequence processing.
|
|
|
|
*/
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
SetConsoleMode((HANDLE)_get_osfhandle(_fileno(output->fh)), output->console_mode);
|
|
|
|
#endif
|
2019-04-04 18:01:46 +00:00
|
|
|
break;
|
|
|
|
}
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
|
2014-11-22 03:22:54 +00:00
|
|
|
ret = close_print_dest(output->to_file, output->fh);
|
|
|
|
g_free(output);
|
|
|
|
g_free(self);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const print_stream_ops_t print_text_ops = {
|
|
|
|
NULL, /* preamble */
|
|
|
|
print_line_text,
|
|
|
|
NULL, /* bookmark */
|
|
|
|
new_page_text,
|
|
|
|
NULL, /* finale */
|
2017-04-25 05:14:42 +00:00
|
|
|
destroy_text,
|
|
|
|
print_line_color_text,
|
2014-11-22 03:22:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static print_stream_t *
|
|
|
|
print_stream_text_alloc(gboolean to_file, FILE *fh)
|
|
|
|
{
|
|
|
|
print_stream_t *stream;
|
|
|
|
output_text *output;
|
|
|
|
|
|
|
|
output = (output_text *)g_malloc(sizeof *output);
|
|
|
|
output->to_file = to_file;
|
|
|
|
output->fh = fh;
|
|
|
|
|
2019-04-01 03:28:20 +00:00
|
|
|
#ifdef _WIN32
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
/*
|
|
|
|
* On Windows, "_isatty()", which is what ws_isatty() wraps,
|
|
|
|
* "determines whether fd is associated with a character device
|
|
|
|
* (a terminal, console, printer, or serial port)".
|
|
|
|
*
|
|
|
|
* We specifically want to know if it's assciated with a *console*,
|
|
|
|
* as, if it is, we'll be using console-specific APIs.
|
|
|
|
*/
|
|
|
|
CONSOLE_SCREEN_BUFFER_INFO csb_info;
|
|
|
|
DWORD console_mode;
|
2019-04-01 03:28:20 +00:00
|
|
|
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
if (GetConsoleScreenBufferInfo((HANDLE)_get_osfhandle(_fileno(fh)),
|
|
|
|
&csb_info)) {
|
|
|
|
/*
|
|
|
|
* The console-specific API GetConsoleScreenBufferInfo() succeeded,
|
|
|
|
* so we'll assume this is a console.
|
|
|
|
*/
|
|
|
|
output->isatty = TRUE;
|
2019-04-01 03:28:20 +00:00
|
|
|
output->csb_attrs = csb_info.wAttributes;
|
2018-01-05 23:40:19 +00:00
|
|
|
|
2019-04-01 03:28:20 +00:00
|
|
|
/*
|
|
|
|
* Map to little-endian UTF-16; we'll be doing Unicode-API
|
|
|
|
* writes to the console, and that expects the standard flavor
|
|
|
|
* of Unicode on Windows, which is little-endian UTF-16.
|
|
|
|
*/
|
|
|
|
output->to_codeset = "UTF-16LE";
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* As indicated above, the classic Windows Console only offers
|
|
|
|
* 1-bit color, set through special console APIs.
|
|
|
|
*
|
|
|
|
* The console in Windows 10 version 1511 (TH2), build 10586, and
|
|
|
|
* later supports SGR escape sequences:
|
|
|
|
*
|
|
|
|
* http://www.nivot.org/blog/post/2016/02/04/Windows-10-TH2-(v1511)-Console-Host-Enhancements
|
|
|
|
*
|
|
|
|
* but only supports 16 colors. The "undocumented" 0x04 bit to
|
|
|
|
* which they refer is documented in the current version of the
|
|
|
|
* SetConsoleMode() documentation:
|
|
|
|
*
|
|
|
|
* https://docs.microsoft.com/en-us/windows/console/setconsolemode
|
|
|
|
*
|
|
|
|
* as ENABLE_VIRTUAL_TERMINAL_PROCESSING, saying
|
|
|
|
*
|
|
|
|
* When writing with WriteFile or WriteConsole, characters are
|
|
|
|
* parsed for VT100 and similar control character sequences that
|
|
|
|
* control cursor movement, color/font mode, and other operations
|
|
|
|
* that can also be performed via the existing Console APIs. For
|
|
|
|
* more information, see Console Virtual Terminal Sequences.
|
|
|
|
*
|
|
|
|
* Console Virtual Terminal Sequences:
|
|
|
|
*
|
|
|
|
* https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
|
|
|
|
*
|
|
|
|
* documents all the escape sequences the Console supports. It
|
|
|
|
* currently seems to indicate that the ODA versions with 24-bit
|
|
|
|
* color are supported but select the closest color from the
|
|
|
|
* 16-color palette.
|
|
|
|
*
|
|
|
|
* The console in Windows 10 builds 14931 (a preview version of
|
|
|
|
* Windows 10 version 1703) and later supports SGR RGB sequences:
|
|
|
|
*
|
|
|
|
* https://devblogs.microsoft.com/commandline/24-bit-color-in-the-windows-console/
|
|
|
|
*
|
|
|
|
* That page says:
|
|
|
|
*
|
|
|
|
* Thanks to our ability to run Linux apps and scripts using our
|
|
|
|
* new Bash on Ubuntu on Windows environment atop the Windows
|
|
|
|
* Subsystem for Linux (WSL), we can use some Linux scripts and
|
|
|
|
* tools to demonstrate the Console's new 24-bit color support:
|
|
|
|
*
|
|
|
|
* which suggests that, with that version, whatever escape sequences
|
|
|
|
* work on UN*Xes also work on Windows, so maybe they support full
|
|
|
|
* 24-bit color with the ODA sequences.
|
|
|
|
*
|
|
|
|
* So, if ENABLE_VIRTUAL_TERMINAL_PROCESSING is already set on
|
|
|
|
* the console, or if it isn't but we can set it, we use the SGR
|
|
|
|
* sequences to set colors, otherwise, we just use the
|
|
|
|
* SetConsoleTextAttribute calls.
|
|
|
|
*/
|
|
|
|
GetConsoleMode((HANDLE)_get_osfhandle(_fileno(fh)), &output->console_mode);
|
|
|
|
if (output->console_mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) {
|
|
|
|
/*
|
|
|
|
* It's already enabled; assume that means we can use the
|
|
|
|
* 24-bit color escape sequences (although the console might
|
|
|
|
* not support full 24-bit color, and would map the 24-bit
|
|
|
|
* color to the closest color in a smaller palette).
|
|
|
|
*/
|
|
|
|
output->color_type = COLOR_24BIT_ESCAPE;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* See if we can enable it.
|
|
|
|
*/
|
|
|
|
console_mode = output->console_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
|
|
|
if (!SetConsoleMode((HANDLE)_get_osfhandle(_fileno(fh)), console_mode)) {
|
|
|
|
/*
|
|
|
|
* We can't - use console-mode color.
|
|
|
|
*
|
|
|
|
* It's not documented which error is returned if
|
|
|
|
* you try to set a mode bit that's not supported,
|
|
|
|
* but, at least on Windows 7, ERROR_INVALID_PARAMETER
|
|
|
|
* is returned if you try to set
|
|
|
|
* ENABLE_VIRTUAL_TERMINAL_PROCESSING.
|
|
|
|
*
|
|
|
|
* We could check for that error and report other
|
|
|
|
* errors as failures.
|
|
|
|
*/
|
|
|
|
output->color_type = COLOR_CONSOLE;
|
|
|
|
} else {
|
|
|
|
/* We can - use 24-bit color */
|
|
|
|
output->color_type = COLOR_24BIT_ESCAPE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* GetConsoleScreenBufferInfo() failed; it's not documented
|
|
|
|
* whether a particular error means "not a console", so we'll
|
|
|
|
* just assume this means it's not a console.
|
|
|
|
*
|
|
|
|
* The error we see on Windows 7 is ERROR_INVALID_HANDLE, but
|
|
|
|
* "invalid" is vague enough that I'm not sure we should
|
|
|
|
* treat that as meaning "not a console and everything else
|
|
|
|
* as being an error that we should report.
|
|
|
|
*/
|
|
|
|
output->isatty = FALSE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This is not used if we're not on a console, as we're not doing
|
|
|
|
* coloring.
|
|
|
|
*/
|
|
|
|
output->csb_attrs = 0;
|
|
|
|
}
|
2019-04-01 03:28:20 +00:00
|
|
|
#else
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
/*
|
|
|
|
* On UN*X, isatty() tests "whether fildes, an open file descriptor,
|
|
|
|
* is associated with a terminal device", to quote the Single UNIX
|
|
|
|
* Specification, and the documentation for UN*Xes that haven't
|
|
|
|
* been tested against the SUS validation suite say similar things.
|
|
|
|
* It does *not* just test whether it's associated with a character
|
|
|
|
* device that may or may not be a terminal device, so it's what we
|
|
|
|
* want on UN*X.
|
|
|
|
*/
|
|
|
|
output->isatty = isatty(ws_fileno(fh));
|
|
|
|
if (output->isatty) {
|
2019-04-01 03:28:20 +00:00
|
|
|
const gchar *charset;
|
|
|
|
gboolean is_utf8;
|
|
|
|
|
|
|
|
/* Is there a more reliable way to do this? */
|
|
|
|
is_utf8 = g_get_charset(&charset);
|
|
|
|
if (!is_utf8) {
|
|
|
|
/*
|
|
|
|
* The local character set isn't UTF-8, so arrange to
|
|
|
|
* map from UTF-8 to that character set before printing
|
|
|
|
* on the terminal.
|
|
|
|
*/
|
|
|
|
output->to_codeset = charset;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* The local character set is UTF-8, so no mapping is
|
|
|
|
* necessary.
|
|
|
|
*/
|
|
|
|
output->to_codeset = NULL;
|
|
|
|
}
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
|
2019-04-01 03:28:20 +00:00
|
|
|
/*
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
* Not all UN*X terminal emulators support the 24-bit color SGR
|
|
|
|
* sequences (for example, macOS Terminal currently doesn't).
|
|
|
|
*
|
|
|
|
* As per
|
|
|
|
*
|
|
|
|
* https://github.com/termstandard/colors
|
|
|
|
*
|
|
|
|
* terminfo currently doesn't have a flag to indicate 24-bit
|
|
|
|
* color support - a future release will - so we can't use
|
|
|
|
* that to determine if the terminal emulator (or terminal)
|
|
|
|
* supports it.
|
|
|
|
*
|
|
|
|
* That page notes that some terminal emulators set the
|
|
|
|
* COLORTERM environment variable either to "truecolor"
|
|
|
|
* or "24bit" if 24-bit color is supported; we use that
|
|
|
|
* test for now.
|
|
|
|
*
|
|
|
|
* XXX - if there are terminal emulators that use the 24-bit
|
|
|
|
* color escape sequences but don't set COLORTERM, add code
|
|
|
|
* here to look at other environment variables to try to
|
|
|
|
* recognize them.
|
|
|
|
*
|
|
|
|
* XXX - fall back on 8-color or 256-color support if we can
|
|
|
|
* somehow determine that 24-bit color support isn't available
|
|
|
|
* but 8-color or 256-color support is?
|
2019-04-01 03:28:20 +00:00
|
|
|
*/
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
char *colorterm = getenv("COLORTERM");
|
|
|
|
if (colorterm != NULL &&
|
|
|
|
(strcmp(colorterm, "truecolor") == 0 || strcmp(colorterm, "24bit") == 0))
|
|
|
|
output->color_type = COLOR_24BIT_ESCAPE;
|
|
|
|
else
|
|
|
|
output->color_type = COLOR_NONE;
|
|
|
|
}
|
2016-06-29 23:51:37 +00:00
|
|
|
#endif
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
if (!output->isatty) {
|
|
|
|
/*
|
|
|
|
* OK, this was determined *not* to be a terminal, so we won't
|
|
|
|
* be doing coloring or mapping from UTF-8 to a local character
|
|
|
|
* set.
|
|
|
|
*/
|
2019-04-01 03:28:20 +00:00
|
|
|
output->to_codeset = NULL;
|
Clean up color handling.
For Windows:
Don't use ws_isatty() - which is a wrapper around _isatty() - to
determine whether the output is to a Windows console or not; it returns
a non-zero value for *any* character device, not just a console.
Instead, use a console API; if it succeeds, it's a console, otherwise it
isn't.
If we're writing to a console, and the
ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set, or it isn't set but we
can set it, assume the console supports the escape sequences that
request 24-bit color, and use them.
For UN*X:
We can isatty() to determine if the output is to a terminal, as it
doesn't check for character special files, it specifically checks for
terminals (which, in practice, means "device that supports one of the
ioctls to get terminal modes" in most if not all cases; that covers
serial lines, pseudo-ttys, and perhaps some other devices).
Only use the 24-bit color escape sequences if the COLORTERM environment
variable is set to "truecolor" or "24bit".
Bug: 15659
Change-Id: I673667b86bd6b2ab48c06e00ed16b537d6723453
Reviewed-on: https://code.wireshark.org/review/32689
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-04-03 04:47:42 +00:00
|
|
|
output->color_type = COLOR_NONE;
|
2019-04-01 03:28:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
stream = (print_stream_t *)g_malloc(sizeof (print_stream_t));
|
|
|
|
stream->ops = &print_text_ops;
|
|
|
|
stream->data = output;
|
2016-06-29 23:51:37 +00:00
|
|
|
|
2014-11-22 03:22:54 +00:00
|
|
|
return stream;
|
|
|
|
}
|
|
|
|
|
|
|
|
print_stream_t *
|
|
|
|
print_stream_text_new(gboolean to_file, const char *dest)
|
|
|
|
{
|
|
|
|
FILE *fh;
|
|
|
|
|
|
|
|
fh = open_print_dest(to_file, dest);
|
|
|
|
if (fh == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return print_stream_text_alloc(to_file, fh);
|
|
|
|
}
|
|
|
|
|
|
|
|
print_stream_t *
|
|
|
|
print_stream_text_stdio_new(FILE *fh)
|
|
|
|
{
|
|
|
|
return print_stream_text_alloc(TRUE, fh);
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
gboolean to_file;
|
|
|
|
FILE *fh;
|
|
|
|
} output_ps;
|
|
|
|
|
|
|
|
#define MAX_PS_LINE_LENGTH 256
|
|
|
|
|
|
|
|
static
|
|
|
|
void ps_clean_string(char *out, const char *in, int outbuf_size)
|
|
|
|
{
|
|
|
|
int rd, wr;
|
|
|
|
char c;
|
|
|
|
|
|
|
|
if (in == NULL) {
|
|
|
|
out[0] = '\0';
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (rd = 0, wr = 0 ; wr < outbuf_size; rd++, wr++ ) {
|
|
|
|
c = in[rd];
|
|
|
|
switch (c) {
|
|
|
|
case '(':
|
|
|
|
case ')':
|
|
|
|
case '\\':
|
|
|
|
out[wr] = '\\';
|
|
|
|
out[++wr] = c;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
out[wr] = c;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
print_preamble_ps(print_stream_t *self, gchar *filename, const char *version_string)
|
|
|
|
{
|
|
|
|
output_ps *output = (output_ps *)self->data;
|
|
|
|
char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */
|
|
|
|
|
|
|
|
print_ps_preamble(output->fh);
|
|
|
|
|
|
|
|
fputs("%% the page title\n", output->fh);
|
|
|
|
ps_clean_string(psbuffer, filename, MAX_PS_LINE_LENGTH);
|
|
|
|
fprintf(output->fh, "/ws_pagetitle (%s - Wireshark %s) def\n", psbuffer, version_string);
|
|
|
|
fputs("\n", output->fh);
|
|
|
|
return !ferror(output->fh);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
print_line_ps(print_stream_t *self, int indent, const char *line)
|
|
|
|
{
|
|
|
|
output_ps *output = (output_ps *)self->data;
|
|
|
|
char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */
|
|
|
|
|
|
|
|
ps_clean_string(psbuffer, line, MAX_PS_LINE_LENGTH);
|
|
|
|
fprintf(output->fh, "%d (%s) putline\n", indent, psbuffer);
|
|
|
|
return !ferror(output->fh);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
print_bookmark_ps(print_stream_t *self, const gchar *name, const gchar *title)
|
|
|
|
{
|
|
|
|
output_ps *output = (output_ps *)self->data;
|
|
|
|
char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* See the Adobe "pdfmark reference":
|
|
|
|
*
|
|
|
|
* http://partners.adobe.com/asn/acrobat/docs/pdfmark.pdf
|
|
|
|
*
|
|
|
|
* The pdfmark stuff tells code that turns PostScript into PDF
|
|
|
|
* things that it should do.
|
|
|
|
*
|
|
|
|
* The /OUT stuff creates a bookmark that goes to the
|
|
|
|
* destination with "name" as the name and "title" as the title.
|
|
|
|
*
|
|
|
|
* The "/DEST" creates the destination.
|
|
|
|
*/
|
|
|
|
ps_clean_string(psbuffer, title, MAX_PS_LINE_LENGTH);
|
|
|
|
fprintf(output->fh, "[/Dest /%s /Title (%s) /OUT pdfmark\n", name,
|
|
|
|
psbuffer);
|
|
|
|
fputs("[/View [/XYZ -4 currentpoint matrix currentmatrix matrix defaultmatrix\n",
|
|
|
|
output->fh);
|
|
|
|
fputs("matrix invertmatrix matrix concatmatrix transform exch pop 20 add null]\n",
|
|
|
|
output->fh);
|
|
|
|
fprintf(output->fh, "/Dest /%s /DEST pdfmark\n", name);
|
|
|
|
return !ferror(output->fh);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
new_page_ps(print_stream_t *self)
|
|
|
|
{
|
|
|
|
output_ps *output = (output_ps *)self->data;
|
|
|
|
|
|
|
|
fputs("formfeed\n", output->fh);
|
|
|
|
return !ferror(output->fh);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
print_finale_ps(print_stream_t *self)
|
|
|
|
{
|
|
|
|
output_ps *output = (output_ps *)self->data;
|
|
|
|
|
|
|
|
print_ps_finale(output->fh);
|
|
|
|
return !ferror(output->fh);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
destroy_ps(print_stream_t *self)
|
|
|
|
{
|
|
|
|
output_ps *output = (output_ps *)self->data;
|
|
|
|
gboolean ret;
|
|
|
|
|
|
|
|
ret = close_print_dest(output->to_file, output->fh);
|
|
|
|
g_free(output);
|
|
|
|
g_free(self);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const print_stream_ops_t print_ps_ops = {
|
|
|
|
print_preamble_ps,
|
|
|
|
print_line_ps,
|
|
|
|
print_bookmark_ps,
|
|
|
|
new_page_ps,
|
|
|
|
print_finale_ps,
|
2017-04-25 05:14:42 +00:00
|
|
|
destroy_ps,
|
|
|
|
NULL, /* print_line_color */
|
2014-11-22 03:22:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static print_stream_t *
|
|
|
|
print_stream_ps_alloc(gboolean to_file, FILE *fh)
|
|
|
|
{
|
|
|
|
print_stream_t *stream;
|
|
|
|
output_ps *output;
|
|
|
|
|
|
|
|
output = (output_ps *)g_malloc(sizeof *output);
|
|
|
|
output->to_file = to_file;
|
|
|
|
output->fh = fh;
|
2019-04-01 03:28:20 +00:00
|
|
|
|
2014-11-22 03:22:54 +00:00
|
|
|
stream = (print_stream_t *)g_malloc(sizeof (print_stream_t));
|
|
|
|
stream->ops = &print_ps_ops;
|
|
|
|
stream->data = output;
|
|
|
|
|
|
|
|
return stream;
|
|
|
|
}
|
|
|
|
|
|
|
|
print_stream_t *
|
|
|
|
print_stream_ps_new(gboolean to_file, const char *dest)
|
|
|
|
{
|
|
|
|
FILE *fh;
|
|
|
|
|
|
|
|
fh = open_print_dest(to_file, dest);
|
|
|
|
if (fh == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return print_stream_ps_alloc(to_file, fh);
|
|
|
|
}
|
|
|
|
|
|
|
|
print_stream_t *
|
|
|
|
print_stream_ps_stdio_new(FILE *fh)
|
|
|
|
{
|
|
|
|
return print_stream_ps_alloc(TRUE, fh);
|
|
|
|
}
|
2015-01-02 00:45:22 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
|
|
|
*
|
|
|
|
* Local variables:
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* tab-width: 8
|
|
|
|
* indent-tabs-mode: nil
|
|
|
|
* End:
|
|
|
|
*
|
|
|
|
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
|
|
|
* :indentSize=4:tabSize=8:noTabs=true:
|
|
|
|
*/
|