mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
ANSI remote printer support. Raw mode only.
[originally from svn r1581]
This commit is contained in:
parent
04fba1e540
commit
ae476d5567
1
Makefile
1
Makefile
@ -94,6 +94,7 @@ RES=res
|
||||
##-- objects putty puttytel
|
||||
GOBJS1 = window.$(OBJ) windlg.$(OBJ) winctrls.$(OBJ) terminal.$(OBJ)
|
||||
GOBJS2 = sizetip.$(OBJ) wcwidth.$(OBJ) unicode.$(OBJ) logging.$(OBJ)
|
||||
GOBJS3 = printing.$(OBJ)
|
||||
##-- objects putty puttytel plink
|
||||
LOBJS1 = telnet.$(OBJ) raw.$(OBJ) rlogin.$(OBJ) ldisc.$(OBJ) winnet.$(OBJ)
|
||||
##-- objects putty plink
|
||||
|
@ -1,4 +1,4 @@
|
||||
\versionid $Id: config.but,v 1.28 2002/03/09 11:47:39 simon Exp $
|
||||
\versionid $Id: config.but,v 1.29 2002/03/09 17:59:15 simon Exp $
|
||||
|
||||
\C{config} Configuring PuTTY
|
||||
|
||||
@ -380,6 +380,38 @@ this configuration option to override its choice: you can force
|
||||
local line editing to be turned on, or force it to be turned off,
|
||||
instead of relying on the automatic detection.
|
||||
|
||||
\S{config-printing} Remote-controlled printing
|
||||
|
||||
\cfg{winhelp-topic}{terminal.printing}
|
||||
|
||||
A lot of VT100-compatible terminals support printing under control
|
||||
of the remote server. PuTTY supports this feature as well, but it is
|
||||
turned off by default.
|
||||
|
||||
To enable remote-controlled printing, choose a printer from the
|
||||
\q{Printer to send ANSI printer output to} drop-down list box. This
|
||||
should allow you to select from all the printers you have installed
|
||||
drivers for on your computer. Alternatively, you can type the
|
||||
network name of a networked printer (for example,
|
||||
\c{\\\\printserver\\printer1}) even if you haven't already
|
||||
installed a driver for it on your own machine.
|
||||
|
||||
When the remote server attempts to print some data, PuTTY will send
|
||||
that data to the printer \e{raw} - without translating it,
|
||||
attempting to format it, or doing anything else to it. It is up to
|
||||
you to ensure your remote server knows what type of printer it is
|
||||
talking to.
|
||||
|
||||
Since PuTTY sends data to the printer raw, it cannot offer options
|
||||
such as portrait versus landscape, print quality, or paper tray
|
||||
selection. All these things would be done by your PC printer driver
|
||||
(which PuTTY bypasses); if you need them done, you will have to find
|
||||
a way to configure your remote server to do them.
|
||||
|
||||
To disable remote printing again, choose \q{None (printing
|
||||
disabled)} from the printer selection list. This is the default
|
||||
state.
|
||||
|
||||
\H{config-keyboard} The Keyboard panel
|
||||
|
||||
The Keyboard configuration panel allows you to control the behaviour
|
||||
|
13
putty.h
13
putty.h
@ -336,6 +336,7 @@ typedef struct {
|
||||
int sunken_edge;
|
||||
int window_border;
|
||||
char answerback[256];
|
||||
char printer[128];
|
||||
/* Colour options */
|
||||
int try_palette;
|
||||
int bold_colour;
|
||||
@ -609,4 +610,16 @@ extern int console_batch_mode;
|
||||
extern char *console_password;
|
||||
int console_get_line(const char *prompt, char *str, int maxlen, int is_pw);
|
||||
|
||||
/*
|
||||
* Exports from printing.c.
|
||||
*/
|
||||
typedef struct printer_enum_tag printer_enum;
|
||||
typedef struct printer_job_tag printer_job;
|
||||
printer_enum *printer_start_enum(int *nprinters);
|
||||
char *printer_get_name(printer_enum *, int);
|
||||
void printer_finish_enum(printer_enum *);
|
||||
printer_job *printer_start_job(char *printer);
|
||||
void printer_job_data(printer_job *, void *, int);
|
||||
void printer_finish_job(printer_job *);
|
||||
|
||||
#endif
|
||||
|
@ -261,6 +261,7 @@ void save_settings(char *section, int do_host, Config * cfg)
|
||||
write_setting_s(sesskey, buf, buf2);
|
||||
}
|
||||
write_setting_s(sesskey, "LineCodePage", cfg->line_codepage);
|
||||
write_setting_s(sesskey, "Printer", cfg->printer);
|
||||
write_setting_i(sesskey, "CapsLockCyr", cfg->xlat_capslockcyr);
|
||||
write_setting_i(sesskey, "ScrollBar", cfg->scrollbar);
|
||||
write_setting_i(sesskey, "ScrollBarFullScreen", cfg->scrollbar_in_fullscreen);
|
||||
@ -503,6 +504,7 @@ void load_settings(char *section, int do_host, Config * cfg)
|
||||
*/
|
||||
gpps(sesskey, "LineCodePage", "", cfg->line_codepage,
|
||||
sizeof(cfg->line_codepage));
|
||||
gpps(sesskey, "Printer", "", cfg->printer, sizeof(cfg->printer));
|
||||
gppi (sesskey, "CapsLockCyr", 0, &cfg->xlat_capslockcyr);
|
||||
gppi(sesskey, "ScrollBar", 1, &cfg->scrollbar);
|
||||
gppi(sesskey, "ScrollBarFullScreen", 0, &cfg->scrollbar_in_fullscreen);
|
||||
|
112
terminal.c
112
terminal.c
@ -115,6 +115,10 @@ static int vt52_bold; /* Force bold on non-bold colours */
|
||||
static int utf_state; /* Is there a pending UTF-8 character */
|
||||
static int utf_char; /* and what is it so far. */
|
||||
static int utf_size; /* The size of the UTF character. */
|
||||
static int printing, only_printing; /* Are we doing ANSI printing? */
|
||||
static int print_state; /* state of print-end-sequence scan */
|
||||
static bufchain printer_buf; /* buffered data for printer */
|
||||
static printer_job *print_job;
|
||||
|
||||
static int xterm_mouse; /* send mouse messages to app */
|
||||
|
||||
@ -206,6 +210,7 @@ static void erase_lots(int, int, int);
|
||||
static void swap_screen(int);
|
||||
static void update_sbar(void);
|
||||
static void deselect(void);
|
||||
static void term_print_finish(void);
|
||||
|
||||
/*
|
||||
* Resize a line to make it `cols' columns wide.
|
||||
@ -302,6 +307,7 @@ static void power_on(void)
|
||||
blink_is_real = cfg.blinktext;
|
||||
erase_char = ERASE_CHAR;
|
||||
alt_which = 0;
|
||||
term_print_finish();
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 256; i++)
|
||||
@ -352,8 +358,9 @@ void term_pwron(void)
|
||||
|
||||
/*
|
||||
* When the user reconfigures us, we need to check the forbidden-
|
||||
* alternate-screen config option, and also disable raw mouse mode
|
||||
* if the user has disabled mouse reporting.
|
||||
* alternate-screen config option, disable raw mouse mode if the
|
||||
* user has disabled mouse reporting, and abandon a print job if
|
||||
* the user has disabled printing.
|
||||
*/
|
||||
void term_reconfig(void)
|
||||
{
|
||||
@ -368,6 +375,9 @@ void term_reconfig(void)
|
||||
sco_acs = alt_sco_acs = 0;
|
||||
utf = 0;
|
||||
}
|
||||
if (!*cfg.printer) {
|
||||
term_print_finish();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1007,6 +1017,50 @@ static void do_osc(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ANSI printing routines.
|
||||
*/
|
||||
static void term_print_setup(void)
|
||||
{
|
||||
bufchain_clear(&printer_buf);
|
||||
print_job = printer_start_job(cfg.printer);
|
||||
}
|
||||
static void term_print_flush(void)
|
||||
{
|
||||
void *data;
|
||||
int len;
|
||||
int size;
|
||||
while ((size = bufchain_size(&printer_buf)) > 5) {
|
||||
bufchain_prefix(&printer_buf, &data, &len);
|
||||
if (len > size-5)
|
||||
len = size-5;
|
||||
printer_job_data(print_job, data, len);
|
||||
bufchain_consume(&printer_buf, len);
|
||||
}
|
||||
}
|
||||
static void term_print_finish(void)
|
||||
{
|
||||
void *data;
|
||||
int len, size;
|
||||
char c;
|
||||
|
||||
term_print_flush();
|
||||
while ((size = bufchain_size(&printer_buf)) > 0) {
|
||||
bufchain_prefix(&printer_buf, &data, &len);
|
||||
c = *(char *)data;
|
||||
if (c == '\033' || c == '\233') {
|
||||
bufchain_consume(&printer_buf, size);
|
||||
break;
|
||||
} else {
|
||||
printer_job_data(print_job, &c, 1);
|
||||
bufchain_consume(&printer_buf, 1);
|
||||
}
|
||||
}
|
||||
printer_finish_job(print_job);
|
||||
print_job = NULL;
|
||||
printing = only_printing = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove everything currently in `inbuf' and stick it up on the
|
||||
* in-memory display. There's a big state machine in here to
|
||||
@ -1051,6 +1105,40 @@ void term_out(void)
|
||||
* of i18n.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If we're printing, add the character to the printer
|
||||
* buffer.
|
||||
*/
|
||||
if (printing) {
|
||||
char cc = c;
|
||||
bufchain_add(&printer_buf, &c, 1);
|
||||
|
||||
/*
|
||||
* If we're in print-only mode, we use a much simpler
|
||||
* state machine designed only to recognise the ESC[4i
|
||||
* termination sequence.
|
||||
*/
|
||||
if (only_printing) {
|
||||
if (c == '\033')
|
||||
print_state = 1;
|
||||
else if (c == (unsigned char)'\233')
|
||||
print_state = 2;
|
||||
else if (c == '[' && print_state == 1)
|
||||
print_state = 2;
|
||||
else if (c == '4' && print_state == 2)
|
||||
print_state = 3;
|
||||
else if (c == 'i' && print_state == 3)
|
||||
print_state = 4;
|
||||
else
|
||||
print_state = 0;
|
||||
if (print_state == 4) {
|
||||
printing = only_printing = FALSE;
|
||||
term_print_finish();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* First see about all those translations. */
|
||||
if (termstate == TOPLEVEL) {
|
||||
if (in_utf)
|
||||
@ -1815,6 +1903,24 @@ void term_out(void)
|
||||
toggle_mode(esc_args[i], esc_query, TRUE);
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
case ANSI_QUE('i'):
|
||||
compatibility(VT100);
|
||||
{
|
||||
int i;
|
||||
if (esc_nargs != 1) break;
|
||||
if (esc_args[0] == 5 && *cfg.printer) {
|
||||
printing = TRUE;
|
||||
only_printing = !esc_query;
|
||||
print_state = 0;
|
||||
term_print_setup();
|
||||
} else if (esc_args[0] == 4 && printing) {
|
||||
printing = FALSE;
|
||||
only_printing = FALSE;
|
||||
term_print_finish();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'l': /* toggle modes to low */
|
||||
case ANSI_QUE('l'):
|
||||
compatibility(VT100);
|
||||
@ -2657,6 +2763,8 @@ void term_out(void)
|
||||
check_selection(curs, cursplus);
|
||||
}
|
||||
}
|
||||
|
||||
term_print_flush();
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
48
windlg.c
48
windlg.c
@ -27,6 +27,8 @@ static int requested_help;
|
||||
|
||||
static struct prefslist cipherlist;
|
||||
|
||||
#define PRINTER_DISABLED_STRING "None (printing disabled)"
|
||||
|
||||
void force_normal(HWND hwnd)
|
||||
{
|
||||
static int recurse = 0;
|
||||
@ -307,6 +309,7 @@ enum { IDCX_ABOUT =
|
||||
IDC_TITLE_TERMINAL,
|
||||
IDC_BOX_TERMINAL1,
|
||||
IDC_BOX_TERMINAL2,
|
||||
IDC_BOX_TERMINAL3,
|
||||
IDC_WRAPMODE,
|
||||
IDC_DECOM,
|
||||
IDC_LFHASCR,
|
||||
@ -322,6 +325,8 @@ enum { IDCX_ABOUT =
|
||||
IDC_EDITBACKEND,
|
||||
IDC_EDITYES,
|
||||
IDC_EDITNO,
|
||||
IDC_PRINTERSTATIC,
|
||||
IDC_PRINTER,
|
||||
terminalpanelend,
|
||||
|
||||
featurespanelstart,
|
||||
@ -724,6 +729,9 @@ char *help_context_cmd(int id)
|
||||
case IDC_EDITYES:
|
||||
case IDC_EDITNO:
|
||||
return "JI(`',`terminal.localedit')";
|
||||
case IDC_PRINTERSTATIC:
|
||||
case IDC_PRINTER:
|
||||
return "JI(`',`terminal.printing')";
|
||||
|
||||
case IDC_BELLSTATIC:
|
||||
case IDC_BELL_DISABLED:
|
||||
@ -1203,7 +1211,25 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
|
||||
}
|
||||
SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
int i, nprinters;
|
||||
printer_enum *pe;
|
||||
pe = printer_start_enum(&nprinters);
|
||||
strcpy(cfg.line_codepage, cp_name(decode_codepage(cfg.line_codepage)));
|
||||
SendDlgItemMessage(hwnd, IDC_PRINTER, CB_RESETCONTENT, 0, 0);
|
||||
SendDlgItemMessage(hwnd, IDC_PRINTER, CB_ADDSTRING,
|
||||
0, (LPARAM) PRINTER_DISABLED_STRING);
|
||||
for (i = 0; i < nprinters; i++) {
|
||||
char *printer_name = printer_get_name(pe, i);
|
||||
SendDlgItemMessage(hwnd, IDC_PRINTER, CB_ADDSTRING,
|
||||
0, (LPARAM) printer_name);
|
||||
}
|
||||
printer_finish_enum(pe);
|
||||
SetDlgItemText(hwnd, IDC_PRINTER,
|
||||
*cfg.printer ? cfg.printer : PRINTER_DISABLED_STRING);
|
||||
}
|
||||
|
||||
CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE,
|
||||
cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
|
||||
cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
|
||||
@ -1330,7 +1356,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
|
||||
}
|
||||
|
||||
if (panel == terminalpanelstart) {
|
||||
/* The Terminal panel. Accelerators used: [acgoh] wdren lts */
|
||||
/* The Terminal panel. Accelerators used: [acgoh] wdren lts p */
|
||||
struct ctlpos cp;
|
||||
ctlposinit(&cp, hwnd, 80, 3, 13);
|
||||
bartitle(&cp, "Options controlling the terminal emulation",
|
||||
@ -1354,6 +1380,11 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
|
||||
"Auto", IDC_EDITBACKEND,
|
||||
"Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
|
||||
endbox(&cp);
|
||||
|
||||
beginbox(&cp, "Remote-controlled printing", IDC_BOX_TERMINAL3);
|
||||
combobox(&cp, "&Printer to send ANSI printer output to:",
|
||||
IDC_PRINTERSTATIC, IDC_PRINTER);
|
||||
endbox(&cp);
|
||||
}
|
||||
|
||||
if (panel == featurespanelstart) {
|
||||
@ -3109,6 +3140,19 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
|
||||
SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
|
||||
}
|
||||
break;
|
||||
case IDC_PRINTER:
|
||||
if (HIWORD(wParam) == CBN_SELCHANGE) {
|
||||
int index = SendDlgItemMessage(hwnd, IDC_PRINTER,
|
||||
CB_GETCURSEL, 0, 0);
|
||||
SendDlgItemMessage(hwnd, IDC_PRINTER, CB_GETLBTEXT,
|
||||
index, (LPARAM)cfg.printer);
|
||||
} else if (HIWORD(wParam) == CBN_EDITCHANGE) {
|
||||
GetDlgItemText(hwnd, IDC_PRINTER, cfg.printer,
|
||||
sizeof(cfg.printer) - 1);
|
||||
}
|
||||
if (!strcmp(cfg.printer, PRINTER_DISABLED_STRING))
|
||||
*cfg.printer = '\0';
|
||||
break;
|
||||
case IDC_CAPSLOCKCYR:
|
||||
if (HIWORD(wParam) == BN_CLICKED ||
|
||||
HIWORD(wParam) == BN_DOUBLECLICKED) {
|
||||
|
Loading…
Reference in New Issue
Block a user