diff -ru putty.orig\PUTTY.H putty\PUTTY.H --- putty.orig\PUTTY.H Mon Oct 07 18:44:26 2002 +++ putty\PUTTY.H Wed Jun 25 12:35:48 2003 @@ -344,6 +344,7 @@ int window_border; char answerback[256]; char printer[128]; + int printclip; /* Colour options */ int try_palette; int bold_colour; diff -ru putty.orig\TERMINAL.C putty\TERMINAL.C --- putty.orig\TERMINAL.C Sat Mar 09 17:59:16 2002 +++ putty\TERMINAL.C Wed Jun 25 14:51:52 2003 @@ -375,7 +375,7 @@ sco_acs = alt_sco_acs = 0; utf = 0; } - if (!*cfg.printer) { + if (!*cfg.printer || cfg.printclip) { term_print_finish(); } } @@ -1018,12 +1018,68 @@ } /* + * Windows clipboard support + * Diomidis Spinellis, June 2003 + */ +static char *clip_b, *clip_bp; /* Buffer, pointer to buffer insertion point */ +static size_t clip_bsiz, clip_remsiz; /* Buffer, size, remaining size */ +static size_t clip_total; /* Total read */ + +#define CLIP_CHUNK 4096 + +static void clipboard_init(void) +{ + if (clip_b) + sfree(clip_b); + clip_bp = clip_b = smalloc(clip_remsiz = clip_bsiz = CLIP_CHUNK); + clip_total = 0; +} + +static void clipboard_data(void *buff, int len) +{ + memcpy(clip_bp, buff, len); + clip_remsiz -= len; + clip_total += len; + clip_bp += len; + if (clip_remsiz < CLIP_CHUNK) { + clip_b = srealloc(clip_b, clip_bsiz *= 2); + clip_remsiz = clip_bsiz - clip_total; + clip_bp = clip_b + clip_total; + } +} + +static void clipboard_copy(void) +{ + HANDLE hglb; + + if (!OpenClipboard(NULL)) + return; // error("Unable to open the clipboard"); + if (!EmptyClipboard()) { + CloseClipboard(); + return; // error("Unable to empty the clipboard"); + } + + hglb = GlobalAlloc(GMEM_DDESHARE, clip_total + 1); + if (hglb == NULL) { + CloseClipboard(); + return; // error("Unable to allocate clipboard memory"); + } + memcpy(hglb, clip_b, clip_total); + ((char *)hglb)[clip_total] = '\0'; + SetClipboardData(CF_TEXT, hglb); + CloseClipboard(); +} + +/* * ANSI printing routines. */ static void term_print_setup(void) { bufchain_clear(&printer_buf); - print_job = printer_start_job(cfg.printer); + if (cfg.printclip) + clipboard_init(); + else + print_job = printer_start_job(cfg.printer); } static void term_print_flush(void) { @@ -1034,7 +1090,10 @@ bufchain_prefix(&printer_buf, &data, &len); if (len > size-5) len = size-5; - printer_job_data(print_job, data, len); + if (cfg.printclip) + clipboard_data(data, len); + else + printer_job_data(print_job, data, len); bufchain_consume(&printer_buf, len); } } @@ -1052,11 +1111,17 @@ bufchain_consume(&printer_buf, size); break; } else { - printer_job_data(print_job, &c, 1); + if (cfg.printclip) + clipboard_data(&c, 1); + else + printer_job_data(print_job, &c, 1); bufchain_consume(&printer_buf, 1); } } - printer_finish_job(print_job); + if (cfg.printclip) + clipboard_copy(); + else + printer_finish_job(print_job); print_job = NULL; printing = only_printing = FALSE; } @@ -1909,7 +1974,7 @@ { int i; if (esc_nargs != 1) break; - if (esc_args[0] == 5 && *cfg.printer) { + if (esc_args[0] == 5 && (*cfg.printer || cfg.printclip)) { printing = TRUE; only_printing = !esc_query; print_state = 0; diff -ru putty.orig\WINDLG.C putty\WINDLG.C --- putty.orig\WINDLG.C Thu Sep 26 19:37:34 2002 +++ putty\WINDLG.C Wed Jun 25 12:37:46 2003 @@ -28,6 +28,7 @@ static struct prefslist cipherlist; #define PRINTER_DISABLED_STRING "None (printing disabled)" +#define PRINT_TO_CLIPBOARD_STRING "Windows clipboard" void force_normal(HWND hwnd) { @@ -1315,14 +1316,20 @@ SendDlgItemMessage(hwnd, IDC_PRINTER, CB_RESETCONTENT, 0, 0); SendDlgItemMessage(hwnd, IDC_PRINTER, CB_ADDSTRING, 0, (LPARAM) PRINTER_DISABLED_STRING); + SendDlgItemMessage(hwnd, IDC_PRINTER, CB_ADDSTRING, + 0, (LPARAM) PRINT_TO_CLIPBOARD_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); + if (*cfg.printer) + SetDlgItemText(hwnd, IDC_PRINTER, cfg.printer); + else if (cfg.printclip) + SetDlgItemText(hwnd, IDC_PRINTER, PRINT_TO_CLIPBOARD_STRING); + else + SetDlgItemText(hwnd, IDC_PRINTER, PRINTER_DISABLED_STRING); } CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE, @@ -3446,8 +3453,13 @@ GetDlgItemText(hwnd, IDC_PRINTER, cfg.printer, sizeof(cfg.printer) - 1); } - if (!strcmp(cfg.printer, PRINTER_DISABLED_STRING)) + if (!strcmp(cfg.printer, PRINTER_DISABLED_STRING)) { + *cfg.printer = '\0'; + cfg.printclip = 0; + } else if (!strcmp(cfg.printer, PRINT_TO_CLIPBOARD_STRING)) { *cfg.printer = '\0'; + cfg.printclip = 1; + } break; case IDC_CAPSLOCKCYR: if (HIWORD(wParam) == BN_CLICKED ||