From 3facce0ca33e21e80ee272d92f4fed716c7e6255 Mon Sep 17 00:00:00 2001 From: mihmig Date: Tue, 4 Jan 2022 19:09:38 +0300 Subject: [PATCH 1/3] add far2l support --- 0.76_My_PuTTY/settings.c | 4 +- 0.76_My_PuTTY/terminal.c | 623 ++++++++++++++++++++++++++- 0.76_My_PuTTY/terminal.h | 13 +- 0.76_My_PuTTY/windows/MAKEFILE.MINGW | 50 +-- 0.76_My_PuTTY/windows/cdecode.c | 88 ++++ 0.76_My_PuTTY/windows/cdecode.h | 28 ++ 0.76_My_PuTTY/windows/cencode.c | 109 +++++ 0.76_My_PuTTY/windows/cencode.h | 31 ++ 0.76_My_PuTTY/windows/window.c | 165 ++++++- 9 files changed, 1067 insertions(+), 44 deletions(-) create mode 100644 0.76_My_PuTTY/windows/cdecode.c create mode 100644 0.76_My_PuTTY/windows/cdecode.h create mode 100644 0.76_My_PuTTY/windows/cencode.c create mode 100644 0.76_My_PuTTY/windows/cencode.h diff --git a/0.76_My_PuTTY/settings.c b/0.76_My_PuTTY/settings.c index 826ac5b..8a964c1 100644 --- a/0.76_My_PuTTY/settings.c +++ b/0.76_My_PuTTY/settings.c @@ -1295,8 +1295,8 @@ void load_open_settings(settings_r *sesskey, Conf *conf) gppb(sesskey, "HideMousePtr", false, conf, CONF_hide_mouseptr); gppb(sesskey, "SunkenEdge", false, conf, CONF_sunken_edge); gppi(sesskey, "WindowBorder", 1, conf, CONF_window_border); - gppi(sesskey, "CurType", 0, conf, CONF_cursor_type); - gppb(sesskey, "BlinkCur", false, conf, CONF_blink_cur); + gppi(sesskey, "CurType", 1, conf, CONF_cursor_type); + gppb(sesskey, "BlinkCur", true, conf, CONF_blink_cur); /* pedantic compiler tells me I can't use conf, CONF_beep as an int * :-) */ gppi(sesskey, "Beep", 1, conf, CONF_beep); gppi(sesskey, "BeepInd", 0, conf, CONF_beep_ind); diff --git a/0.76_My_PuTTY/terminal.c b/0.76_My_PuTTY/terminal.c index 06c91ca..c91fd6f 100644 --- a/0.76_My_PuTTY/terminal.c +++ b/0.76_My_PuTTY/terminal.c @@ -12,6 +12,9 @@ #include #include "putty.h" #include "terminal.h" +/* far2l base64 */ +#include +#include #ifdef MOD_PERSO #include "charset.h" @@ -2000,6 +2003,10 @@ Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata, TermWin *win) * that need it. */ term = snew(Terminal); + /* far2l */ + term->far2l_ext = 0; + term->is_apc = 0; + term->clip_allowed = -1; term->win = win; term->ucsdata = ucsdata; term->conf = conf_copy(myconf); @@ -3204,6 +3211,608 @@ static void toggle_mode(Terminal *term, int mode, int query, bool state) */ static void do_osc(Terminal *term) { + /* far2l */ + if (term->is_apc) { + + /* + + FIXME + От удаленного far2l может придти строка любой длины, + а длина term->osc_string - фиксированная (2048 байт). + Длинный буфер обмена не пролезет. + + Надо бы сделать какую-нибудь динамическую структуру. + + Хотя бы так: + void *realloc(void *ptr, size_t newsize) + + Пока увеличил до мегабайта и сделал предупреждение, + если не пролезаем :) + + */ + + #ifndef _WINDOWS + #define DWORD unsigned int + #define WORD unsigned short + #endif + + if (strncmp(term->osc_string, "far2l", 5) == 0) { + + if (strncmp(term->osc_string+5, "1", 1) == 0) { + term->far2l_ext = 1; + + char *reply_buf = dupprintf( + "\x1b_far2lok\x07"); + ldisc_send(term->ldisc, reply_buf, strlen(reply_buf), + false); + sfree(reply_buf); + + // reset clipboard state; todo: do it on session init! + term->clip_allowed = -1; + + } else if (strncmp(term->osc_string+5, "0", 1) == 0) { + + term->far2l_ext = 0; + + // reset clipboard state; todo: do it on session init! + term->clip_allowed = -1; + + } else if (strncmp(term->osc_string+5, ":", 1) == 0) { + + base64_decodestate _d_state; + base64_init_decodestate(&_d_state); + char* d_out = malloc(term->osc_strlen); + int d_count = base64_decode_block(term->osc_string+6, term->osc_strlen-6, d_out, &_d_state); + + // last byte is id + BYTE id = d_out[d_count-1]; + char* reply = 0; + int reply_size = 0; + + if (term->osc_strlen == OSC_STR_MAX) { + // it's possibly too large clipboard + + #ifdef _WINDOWS + MessageBox(hwnd, "Too large clipboard :(", "Error", MB_OK); + #endif + + // correct request id is lost forever + // so we can not prevent far2l from hanging + // so sad + + // fixme: good idea is to free all allocated memory here, though + exit(100); + } + + DWORD len; + + // next from the end byte is command + switch (d_out[d_count-2]) { + + case 'f':; + + reply_size = 5; + reply = malloc(reply_size); + + // fixme: unimplemented + DWORD zero = 0; + + memcpy(reply, &zero, sizeof(DWORD)); + + break; + + case 'n':; + + /* // not ready yet + + // todo: generate some reply + // todo: show notification only if window is out of focus + // todo: remove icon after notification timeout or by mouse click + + // title length, source, utf8, no zero-terminate, bytes + DWORD len1; + memcpy(&len1, d_out+d_count-6, sizeof(len1)); + + // text length, source, utf8, no zero-terminate, bytes + DWORD len2; + memcpy(&len2, d_out+d_count-6-4-len1, sizeof(len2)); + + // destination (wide char) + LPWSTR text_wc, title_wc; + int textsz_wc, titlesz_wc; + + // notification may contain file names in non-latin + // or may have localized title + // so we can not assume ascii here and should do + // full utf8->multibyte conversion + + titlesz_wc = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)(d_out+len2+4), len1, 0, 0); + textsz_wc = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)d_out, len2, 0, 0); + + if (titlesz_wc && textsz_wc) { + title_wc = malloc((titlesz_wc+1)*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, (LPCCH)(d_out+len2+4), len1, title_wc, titlesz_wc); + text_wc = malloc((textsz_wc+1)*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, (LPCCH)d_out, len2, text_wc, textsz_wc); + + title_wc[titlesz_wc] = 0; + text_wc[textsz_wc] = 0; + + NOTIFYICONDATAW pnid; + + // todo: do this on window focus also + pnid.cbSize = sizeof(pnid); + pnid.hWnd = hwnd; + pnid.hIcon = LoadIcon(0, IDI_APPLICATION); + pnid.uID = 200; + Shell_NotifyIconW(NIM_DELETE, &pnid); + + // todo: use putty icon + pnid.cbSize = sizeof(pnid); + pnid.hWnd = hwnd; + pnid.hIcon = LoadIcon(0, IDI_APPLICATION); + pnid.uID = 200; + pnid.uFlags = NIF_ICON | NIF_INFO | NIF_MESSAGE; + pnid.uCallbackMessage = (WM_USER + 200); + pnid.dwInfoFlags = NIIF_INFO | NIIF_NOSOUND; + memcpy(pnid.szInfoTitle, title_wc, (titlesz_wc+1)*sizeof(wchar_t)); + memcpy(pnid.szInfo, text_wc, (textsz_wc+1)*sizeof(wchar_t)); + Shell_NotifyIconW(NIM_ADD, &pnid); + + free(text_wc); + free(title_wc); + } + + */ + + break; + + case 'w': + + // get largest console window size + + reply_size = 5; + reply = malloc(reply_size); + + // fixme: unimplemented + // here should be short x and short y + DWORD none = 0; + + memcpy(reply, &none, sizeof(DWORD)); + + break; + + case 'c': + + // clipboard interaction + // next from the end byte is subcommand + switch (d_out[d_count-3]) { + case 'r':; + // register format + + memcpy(&len, d_out + d_count - 3 - 4, sizeof(DWORD)); + d_out[len] = 0; // zero-terminate format name + +#ifdef _WINDOWS + // far2l sends format name as (utf8?) string, which actually containing ascii only + // so we can just call ascii function + uint32_t status = RegisterClipboardFormatA(d_out); +#endif + + /* + FILE *f; f = fopen("putty.log", "a"); + fprintf(f, "status: %d, format: [%s]\n", status, d_out); + fclose(f); + + // status: 49220, format: [FAR_VerticalBlock_Unicode] + */ + + reply_size = 5; + reply = malloc(reply_size); + +#ifdef _WINDOWS + memcpy(reply, &status, sizeof(uint32_t)); +#else + bzero(reply, sizeof(uint32_t)); +#endif + + break; + + case 'e':; + +#ifdef _WINDOWS + char ec_status = 0; + if (term->clip_allowed == 1) { + OpenClipboard(hwnd); + ec_status = EmptyClipboard() ? 1 : 0; + CloseClipboard(); + } +#endif + + reply_size = 2; + reply = malloc(reply_size); + +#ifdef _WINDOWS + reply[0] = ec_status; +#else + reply[0] = 0; +#endif + + break; + + case 'a':; + + uint32_t a_fmt; + memcpy(&a_fmt, d_out + d_count - 3 - 4, sizeof(uint32_t)); + +#ifdef _WINDOWS + char out = IsClipboardFormatAvailable(a_fmt) ? 1 : 0; +#endif + + reply_size = 2; + reply = malloc(reply_size); + +#ifdef _WINDOWS + reply[0] = out; +#else + reply[0] = 0; +#endif + + break; + + case 'o':; + // open + // next from the end 4 bytes is client_id length + memcpy(&len, d_out + d_count - 3 - 4, sizeof(DWORD)); + d_out[len] = 0; // all remaining string is client id, make it zero terminated + + // todo: check/store client id, all that stuff + + reply_size = 2; + reply = malloc(reply_size); + +#ifdef _WINDOWS + if (term->clip_allowed == -1) { + int status = MessageBox(hwnd, + "Allow far2l clipboard sync?", "PyTTY", MB_OKCANCEL); + if (status == IDOK) { + term->clip_allowed = 1; + } else { + // IDCANCEL + term->clip_allowed = 0; + } + } + + // status is first response byte + if (term->clip_allowed == 1) { + reply[0] = 1; + } else { + reply[0] = -1; + } +#else + reply[0] = -1; +#endif + + break; + + case 's':; + // set data + + if (term->clip_allowed == 1 && d_count >= 4 + 4 + 3) { + +#ifdef _WINDOWS + + // Never do like this! It takes char by index and converts to DWORD. + // Not takes two chars to fit DWORD. Really. + //DWORD fmt = (DWORD)d_out[d_count-3-4]; + uint32_t fmt; + char* buffer = NULL; + int BufferSize = 0; + memcpy(&fmt, d_out + d_count - 3 - 4, sizeof(uint32_t)); + + // id, 'c', 's', 4-byte fmt, next goes 4-byte len + memcpy(&len, d_out + d_count - 3 - 4 - 4, sizeof(DWORD)); + if (len > d_count - 3 - 4 - 4) + len = d_count - 3 - 4 - 4; + + if (fmt == CF_TEXT) { + int cnt = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)d_out, len, NULL, 0); + if (cnt > 0) { + buffer = calloc(cnt + 1, sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, (LPCCH)d_out, len, (PWCHAR)buffer, cnt); + } + fmt = CF_UNICODETEXT; + BufferSize = (wcslen((PWCHAR)buffer) + 1) * sizeof(WCHAR); + + } else if (fmt == CF_UNICODETEXT) { + // very stupid utf32->utf16 'conversion' + buffer = calloc((len / sizeof(uint32_t)) + 1, sizeof(wchar_t)); + for (int i=0; i < len / sizeof(uint32_t); ++i) { + memcpy( + &buffer[i * sizeof(wchar_t)], + &d_out[i * sizeof(uint32_t)], + sizeof(wchar_t) + ); + } + BufferSize = (wcslen((PWCHAR)buffer) + 1) * sizeof(WCHAR); + + } else if (fmt >= 0xC000) { + // no transcoding - copy it as is + buffer = malloc(len); + memcpy(buffer, &d_out[0], len); + BufferSize = len; + } + + // clipboard stuff itself + + HGLOBAL hData; + void *GData; + + bool set_successful = 0; + + if (buffer && (hData=GlobalAlloc(GMEM_MOVEABLE,BufferSize))) { + + if ((GData=GlobalLock(hData))) { + + memcpy(GData,buffer,BufferSize); + GlobalUnlock(hData); + + if (OpenClipboard(hwnd)) { + + if (!SetClipboardData(fmt, (HANDLE)hData)) { + GlobalFree(hData); + } else { + set_successful = 1; + } + + CloseClipboard(); + + } else { + GlobalFree(hData); + } + + } else { + GlobalFree(hData); + } + } + + free(buffer); + +#endif + + // prepare reply + reply_size = 2; + reply = malloc(reply_size); + + // first reply byte is status +#ifdef _WINDOWS + reply[0] = set_successful; +#else + reply[0] = 0; +#endif + + } else { + + reply_size = 2; + reply = malloc(reply_size); + + reply[0] = 0; + } + + break; + + case 'g':; + + if (term->clip_allowed == 1) { + +#ifdef _WINDOWS + + uint32_t gfmt; + memcpy(&gfmt, d_out + d_count - 3 - 4, sizeof(uint32_t)); + + // clipboard stuff itself + + void *ClipText = NULL; + int32_t ClipTextSize = 0; + + if ((gfmt == CF_TEXT || gfmt == CF_UNICODETEXT || gfmt >= 0xC000) && + OpenClipboard(hwnd)) + { + HANDLE hClipData = GetClipboardData((gfmt == CF_TEXT) ? CF_UNICODETEXT : gfmt); + + if (hClipData) + { + void *pClipData=GlobalLock(hClipData); + + if (pClipData) + { + size_t n = GlobalSize(hClipData); + + if (gfmt == CF_TEXT) { + + ClipTextSize = WideCharToMultiByte( + CP_UTF8, + 0, + (wchar_t *)pClipData, + n, + NULL, + 0, + NULL, + NULL + ) + 1; + + if (ClipTextSize >= 0) { + n = wcsnlen((wchar_t *)pClipData, n / sizeof(wchar_t)); + ClipText = calloc(ClipTextSize + 1, 1); + if (ClipText) { + WideCharToMultiByte( + CP_UTF8, + 0, + (wchar_t *)pClipData, + n, + (char *)ClipText, + ClipTextSize, + NULL, + NULL + ); + ClipTextSize = strlen((char *)ClipText) + 1; + } + } + + } else if (gfmt == CF_UNICODETEXT) { + n = wcsnlen((wchar_t *)pClipData, n / sizeof(wchar_t)); + ClipText = calloc((n + 1), sizeof(uint32_t)); + if (ClipText) { + for (size_t i = 0; i < n; ++i) { + ((uint32_t *)ClipText)[i] = ((uint16_t *)pClipData)[i]; + } + ClipTextSize = (n + 1) * sizeof(uint32_t); + } + + } else { + ClipText = malloc(n); + if (ClipText) { + memcpy(ClipText, pClipData, n); + ClipTextSize = n; + } + } + + GlobalUnlock(hClipData); + } + + } else { + // todo: process errors + } + CloseClipboard(); + } + + + if (!ClipText || ClipTextSize <= 0) { + + // clipboard is empty + reply_size = 5; // 4 bytes for size and one for id + reply = calloc(1, reply_size); + + } else { + + // + length (4 bytes) + id (1 byte) + reply_size = ClipTextSize + 5; + reply = calloc(1, reply_size); + memcpy(reply, ClipText, ClipTextSize); + + // set size + memcpy(reply + ClipTextSize, &ClipTextSize, sizeof(ClipTextSize)); + } + + free(ClipText); + +#else + reply_size = 5; + reply = calloc(1, reply_size); +#endif + + } else { + + // we should never reach here + // anyway, mimic empty clipboard + + reply_size = 5; + reply = calloc(1, reply_size); + } + + break; + } + + break; + } + + /* + if (reply_size == 0) { + // unsupported sequences + + term->osc_string[term->osc_strlen] = 0; + + FILE *f; f = fopen("putty.log", "a"); + fprintf(f, "string: %.*s, strlen: %d\n", term->osc_strlen, term->osc_string, term->osc_strlen); + fprintf(f, "d_count: %d, d_out: [", d_count); + for(int i=0;i 0) { + // request is correct and we should send reply + + // last byte is always id + reply[reply_size-1] = id; + + // ok, let us try to answer something + + // base64-encode + // result in null-terminated char* out + base64_encodestate _state; + base64_init_encodestate(&_state); + + char* out = malloc(reply_size*2); + int count = base64_encode_block((char*)reply, reply_size, out, &_state); + // finishing '=' characters + char* next_char = out + count; + switch (_state.step) + { + case step_B: + *next_char++ = base64_encode_value(_state.result); + *next_char++ = '='; + *next_char++ = '='; + break; + case step_C: + *next_char++ = base64_encode_value(_state.result); + *next_char++ = '='; + break; + case step_A: + break; + } + count = next_char - out; + out[count] = 0; + + // send escape seq + + char* str = "\x1b_far2l"; + backend_send(term->backend, str, strlen(str)); + + backend_send(term->backend, out, count); + + /* + // log string we sent + FILE *f; f = fopen("putty.log", "a"); + fprintf(f, "send: ["); + for(int i=0;ibackend, str2, strlen(str2)); + + // don't forget to free memory :) + free(reply); + free(out); + + } + } + } + + term->osc_strlen = 0; + term->is_apc = 0; + + } else + if (term->osc_w) { while (term->osc_strlen--) term->wordness[(unsigned char) @@ -4119,7 +4728,15 @@ static void term_out(Terminal *term) term->esc_args[0] = ARG_DEFAULT; term->esc_query = 0; break; - case ']': /* OSC: xterm escape sequences */ + case '_': /* far2l: processing APC is almost the same as processing OSC */ + term->is_apc = 1; + break; + //case SEEN_APC: + /* todo */ + // if (!WriteStr2TC(fdout, enable ? "\x1b_far2l1\x1b\\\x1b[5n" : "\x1b_far2l0\x07\x1b[5n")) + // if (!WriteStr2TC(fdout, enable ? "\x1b_far2l1\x1b\\\x1b[5n" : "\x1b_far2l0\x07\x1b[5n")) + //break; + case ']': /* OSC: xterm escape sequences */ /* Compatibility is nasty here, xterm, linux, decterm yuk! */ compatibility(OTHER); term->termstate = SEEN_OSC; @@ -5340,6 +5957,10 @@ static void term_out(Terminal *term) } else { term->termstate = OSC_STRING; term->osc_strlen = 0; + /* far2l */ + if (term->is_apc) { + term->osc_string[term->osc_strlen++] = (char)c; + } } } break; diff --git a/0.76_My_PuTTY/terminal.h b/0.76_My_PuTTY/terminal.h index bd4c5dd..1d385cd 100644 --- a/0.76_My_PuTTY/terminal.h +++ b/0.76_My_PuTTY/terminal.h @@ -185,11 +185,18 @@ struct terminal_tag { #define ANSI(x,y) ((x)+((y)*256)) #define ANSI_QUE(x) ANSI(x,1) -#define OSC_STR_MAX 2048 +/* far2l */ +//#define OSC_STR_MAX 2048 +#define OSC_STR_MAX 1048576 int osc_strlen; char osc_string[OSC_STR_MAX + 1]; bool osc_w; + /* far2l */ + int far2l_ext; + bool is_apc; + int clip_allowed; + char id_string[1024]; unsigned char *tabs; @@ -205,7 +212,9 @@ struct terminal_tag { SEEN_OSC_P, OSC_STRING, OSC_MAYBE_ST, - VT52_ESC, + /* far2l */ + SEEN_APC, + VT52_ESC, VT52_Y1, VT52_Y2, VT52_FG, diff --git a/0.76_My_PuTTY/windows/MAKEFILE.MINGW b/0.76_My_PuTTY/windows/MAKEFILE.MINGW index 6af2e87..53c9ac0 100644 --- a/0.76_My_PuTTY/windows/MAKEFILE.MINGW +++ b/0.76_My_PuTTY/windows/MAKEFILE.MINGW @@ -67,6 +67,11 @@ # Disables PuTTY's use of SecureZeroMemory(), which is missing # from some environments' header files. # +# - XFLAGS=-DTELNET_DEFAULT +# Causes PuTTY to default to the Telnet protocol (in the absence +# of Default Settings and so on to the contrary). Normally PuTTY +# will default to SSH. +# # - XFLAGS=-DDEBUG # Causes PuTTY to enable internal debugging. # @@ -419,6 +424,7 @@ putty.exe: agentf.o aqsync.o be_all_s.o be_misc.o callback.o cmdline.o \ winselgui.o winser.o winshare.o winstore.o wintime.o \ winucs.o winutils.o winx11.o x11fwd.o \ adb.o \ + cencode.o cdecode.o \ kitty.o kitty_commun.o kitty_crypt.o kitty_image.o kitty_proxy.o kitty_registry.o kitty_ssh.o \ kitty_store.o kitty_tools.o kitty_win.o \ urlhack.o pageant_integrated.o winpgnt_integrated.o winpgen_integrated.o winpzmodem.o \ @@ -445,33 +451,18 @@ putty.exe: agentf.o aqsync.o be_all_s.o be_misc.o callback.o cmdline.o \ windlg.o window.o wingss.o winhandl.o winhelp.o winhsock.o \ winjump.o winmisc.o winmiscs.o winnet.o winnoise.o winnpc.o \ winnps.o winpgntc.o winprint.o winproxy.o winsecur.o \ - winselgui.o winser.o winshare.o winstore.o wintime.o \ - winucs.o winutils.o winx11.o x11fwd.o \ - adb.o \ - kitty.o kitty_commun.o kitty_crypt.o kitty_image.o kitty_proxy.o kitty_registry.o kitty_ssh.o \ - kitty_store.o kitty_tools.o kitty_win.o \ - urlhack.o pageant_integrated.o winpgnt_integrated.o winpgen_integrated.o winpzmodem.o \ - import.o sshrsag.o sshdssg.o sshprime.o sshecdsag.o sshbcrypt.o pockle.o primecandidate.o millerrabin.o mpunsafe.o \ - void.o $(UTF8MOUSE_OBJS) \ - ../../base64/base64.a ../../bcrypt/bcrypt.a ../../blocnote/notepad.a ../../jpeg/libjpeg.a \ - ../../md5/MD5check.a ../../mini/mini.a ../../regex/libregex.a \ - -ladvapi32 -lcomdlg32 -lgdi32 -limm32 -lpsapi -lole32 -lshell32 \ - -luser32 -lwsock32 -lwtsapi32 \ - #-lcrypt32 \ - #/c/Windows/system32/crypt32.dll /c/windows/system32/ncrypt.dll \ - # -lcomctl32 -lwinmm -lwinspool -lole32 - -puttygen.exe: conf.o ecc.o import.o marshal.o memory.o millerrabin.o misc.o \ - mpint.o mpunsafe.o notiming.o pockle.o primecandidate.o \ - puttygen.res.o smallprimes.o sshaes.o sshargon2.o \ - sshauxcrypt.o sshbcrypt.o sshblake2.o sshblowf.o sshdes.o \ - sshdss.o sshdssg.o sshecc.o sshecdsag.o sshhmac.o sshmd5.o \ - sshprime.o sshprng.o sshpubk.o sshrand.o sshrsa.o sshrsag.o \ - sshsh256.o sshsh512.o sshsha.o sshsha3.o stripctrl.o \ - tree234.o utils.o version.o wcwidth.o winctrls.o winhelp.o \ - winmisc.o winmiscs.o winnoise.o winnojmp.o winpgen.o \ - winsecur.o winstore.o wintime.o winutils.o \ - kitty_commun.o kitty_crypt.o kitty_registry.o kitty_keygen.o kitty_store.o kitty_tools.o + winser.o winshare.o winstore.o wintime.o winucs.o winutils.o \ + winx11.o cencode.o cdecode.o x11fwd.o -ladvapi32 -lcomdlg32 -lgdi32 -limm32 \ + -lole32 -lshell32 -luser32 + +puttygen.exe: conf.o ecc.o import.o marshal.o memory.o misc.o mpint.o \ + notiming.o puttygen.res.o sshaes.o sshauxcrypt.o sshbcrypt.o \ + sshblowf.o sshdes.o sshdss.o sshdssg.o sshecc.o sshecdsag.o \ + sshhmac.o sshmd5.o sshprime.o sshprng.o sshpubk.o sshrand.o \ + sshrsa.o sshrsag.o sshsh256.o sshsh512.o sshsha.o \ + stripctrl.o tree234.o utils.o version.o wcwidth.o winctrls.o \ + winhelp.o winmisc.o winmiscs.o winnoise.o winnojmp.o \ + winpgen.o winsecur.o winstore.o wintime.o winutils.o $(CC) -mwindows $(LDFLAGS) -o $@ -Wl,-Map,puttygen.map conf.o ecc.o \ import.o marshal.o memory.o millerrabin.o misc.o mpint.o \ mpunsafe.o notiming.o pockle.o primecandidate.o \ @@ -528,6 +519,11 @@ testcrypt.exe: ecc.o marshal.o memory.o millerrabin.o mpint.o mpunsafe.o \ sshpubk.o sshrsa.o sshrsag.o sshsh256.o sshsh512.o sshsha.o \ sshsha3.o testcrypt.o tree234.o utils.o winmiscs.o +cencode.o: ../windows/cencode.c + $(CC) $(COMPAT) $(CFLAGS) $(XFLAGS) -c ../windows/cencode.c + +cdecode.o: ../windows/cencode.c + $(CC) $(COMPAT) $(CFLAGS) $(XFLAGS) -c ../windows/cdecode.c agentf.o: ../agentf.c ../putty.h ../ssh.h ../pageant.h ../sshchan.h \ ../defs.h ../puttyps.h ../network.h ../misc.h ../marshal.h \ diff --git a/0.76_My_PuTTY/windows/cdecode.c b/0.76_My_PuTTY/windows/cdecode.c new file mode 100644 index 0000000..7b2aad0 --- /dev/null +++ b/0.76_My_PuTTY/windows/cdecode.c @@ -0,0 +1,88 @@ +/* +cdecoder.c - c source to a base64 decoding algorithm implementation + +This is part of the libb64 project, and has been placed in the public domain. +For details, see http://sourceforge.net/projects/libb64 +*/ + +#include + +int base64_decode_value(char value_in) +{ + static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51}; + static const char decoding_size = sizeof(decoding); + value_in -= 43; + if (value_in < 0 || value_in > decoding_size) return -1; + return decoding[(int)value_in]; +} + +void base64_init_decodestate(base64_decodestate* state_in) +{ + state_in->step = step_a; + state_in->plainchar = 0; +} + +int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in) +{ + const char* codechar = code_in; + char* plainchar = plaintext_out; + char fragment; + + *plainchar = state_in->plainchar; + + switch (state_in->step) + { + while (1) + { + case step_a: + do { + if (codechar == code_in+length_in) + { + state_in->step = step_a; + state_in->plainchar = *plainchar; + return plainchar - plaintext_out; + } + fragment = (char)base64_decode_value(*codechar++); + } while (fragment < 0); + *plainchar = (fragment & 0x03f) << 2; + case step_b: + do { + if (codechar == code_in+length_in) + { + state_in->step = step_b; + state_in->plainchar = *plainchar; + return plainchar - plaintext_out; + } + fragment = (char)base64_decode_value(*codechar++); + } while (fragment < 0); + *plainchar++ |= (fragment & 0x030) >> 4; + *plainchar = (fragment & 0x00f) << 4; + case step_c: + do { + if (codechar == code_in+length_in) + { + state_in->step = step_c; + state_in->plainchar = *plainchar; + return plainchar - plaintext_out; + } + fragment = (char)base64_decode_value(*codechar++); + } while (fragment < 0); + *plainchar++ |= (fragment & 0x03c) >> 2; + *plainchar = (fragment & 0x003) << 6; + case step_d: + do { + if (codechar == code_in+length_in) + { + state_in->step = step_d; + state_in->plainchar = *plainchar; + return plainchar - plaintext_out; + } + fragment = (char)base64_decode_value(*codechar++); + } while (fragment < 0); + *plainchar++ |= (fragment & 0x03f); + } + } + /* control should not reach here */ + return plainchar - plaintext_out; +} + diff --git a/0.76_My_PuTTY/windows/cdecode.h b/0.76_My_PuTTY/windows/cdecode.h new file mode 100644 index 0000000..d0d7f48 --- /dev/null +++ b/0.76_My_PuTTY/windows/cdecode.h @@ -0,0 +1,28 @@ +/* +cdecode.h - c header for a base64 decoding algorithm + +This is part of the libb64 project, and has been placed in the public domain. +For details, see http://sourceforge.net/projects/libb64 +*/ + +#ifndef BASE64_CDECODE_H +#define BASE64_CDECODE_H + +typedef enum +{ + step_a, step_b, step_c, step_d +} base64_decodestep; + +typedef struct +{ + base64_decodestep step; + char plainchar; +} base64_decodestate; + +void base64_init_decodestate(base64_decodestate* state_in); + +int base64_decode_value(char value_in); + +int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in); + +#endif /* BASE64_CDECODE_H */ diff --git a/0.76_My_PuTTY/windows/cencode.c b/0.76_My_PuTTY/windows/cencode.c new file mode 100644 index 0000000..872856d --- /dev/null +++ b/0.76_My_PuTTY/windows/cencode.c @@ -0,0 +1,109 @@ +/* +cencoder.c - c source to a base64 encoding algorithm implementation + +This is part of the libb64 project, and has been placed in the public domain. +For details, see http://sourceforge.net/projects/libb64 +*/ + +#include + +const int CHARS_PER_LINE = 72; + +void base64_init_encodestate(base64_encodestate* state_in) +{ + state_in->step = step_A; + state_in->result = 0; + state_in->stepcount = 0; +} + +char base64_encode_value(char value_in) +{ + static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + if (value_in > 63) return '='; + return encoding[(int)value_in]; +} + +int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in) +{ + const char* plainchar = plaintext_in; + const char* const plaintextend = plaintext_in + length_in; + char* codechar = code_out; + char result; + char fragment; + + result = state_in->result; + + switch (state_in->step) + { + while (1) + { + case step_A: + if (plainchar == plaintextend) + { + state_in->result = result; + state_in->step = step_A; + return codechar - code_out; + } + fragment = *plainchar++; + result = (fragment & 0x0fc) >> 2; + *codechar++ = base64_encode_value(result); + result = (fragment & 0x003) << 4; + case step_B: + if (plainchar == plaintextend) + { + state_in->result = result; + state_in->step = step_B; + return codechar - code_out; + } + fragment = *plainchar++; + result |= (fragment & 0x0f0) >> 4; + *codechar++ = base64_encode_value(result); + result = (fragment & 0x00f) << 2; + case step_C: + if (plainchar == plaintextend) + { + state_in->result = result; + state_in->step = step_C; + return codechar - code_out; + } + fragment = *plainchar++; + result |= (fragment & 0x0c0) >> 6; + *codechar++ = base64_encode_value(result); + result = (fragment & 0x03f) >> 0; + *codechar++ = base64_encode_value(result); + + ++(state_in->stepcount); + if (state_in->stepcount == CHARS_PER_LINE/4) + { + //*codechar++ = '\n'; + state_in->stepcount = 0; + } + } + } + /* control should not reach here */ + return codechar - code_out; +} + +int base64_encode_blockend(char* code_out, base64_encodestate* state_in) +{ + char* codechar = code_out; + + switch (state_in->step) + { + case step_B: + *codechar++ = base64_encode_value(state_in->result); + *codechar++ = '='; + *codechar++ = '='; + break; + case step_C: + *codechar++ = base64_encode_value(state_in->result); + *codechar++ = '='; + break; + case step_A: + break; + } + //*codechar++ = '\n'; + + return codechar - code_out; +} + diff --git a/0.76_My_PuTTY/windows/cencode.h b/0.76_My_PuTTY/windows/cencode.h new file mode 100644 index 0000000..c1e3464 --- /dev/null +++ b/0.76_My_PuTTY/windows/cencode.h @@ -0,0 +1,31 @@ +/* +cencode.h - c header for a base64 encoding algorithm + +This is part of the libb64 project, and has been placed in the public domain. +For details, see http://sourceforge.net/projects/libb64 +*/ + +#ifndef BASE64_CENCODE_H +#define BASE64_CENCODE_H + +typedef enum +{ + step_A, step_B, step_C +} base64_encodestep; + +typedef struct +{ + base64_encodestep step; + char result; + int stepcount; +} base64_encodestate; + +void base64_init_encodestate(base64_encodestate* state_in); + +char base64_encode_value(char value_in); + +int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in); + +int base64_encode_blockend(char* code_out, base64_encodestate* state_in); + +#endif /* BASE64_CENCODE_H */ diff --git a/0.76_My_PuTTY/windows/window.c b/0.76_My_PuTTY/windows/window.c index 15a9780..44f8fec 100644 --- a/0.76_My_PuTTY/windows/window.c +++ b/0.76_My_PuTTY/windows/window.c @@ -9,6 +9,9 @@ #include #include #include +/* far2l base64 */ +#include +#include #ifdef __WINE__ #define NO_MULTIMON /* winelib doesn't have this */ @@ -436,7 +439,7 @@ int WINAPI Agent_WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show #endif #ifdef MOD_WTS -typedef enum _WTS_VIRTUAL_CLASS { WTSVirtualClientData, WTSVirtualFileHandle } WTS_VIRTUAL_CLASS; // WTS_VIRTUAL_CLASS n'est pas défini dans le fichier wtsapi32.h !!! +//typedef enum _WTS_VIRTUAL_CLASS { WTSVirtualClientData, WTSVirtualFileHandle } WTS_VIRTUAL_CLASS; // WTS_VIRTUAL_CLASS n'est pas défini dans le fichier wtsapi32.h !!! #include #endif #if (defined MOD_BACKGROUNDIMAGE) && (!defined FLJ) @@ -4827,10 +4830,19 @@ free(cmd); ignore_clip = wParam; /* don't panic on DESTROYCLIPBOARD */ break; case WM_DESTROYCLIPBOARD: - if (!ignore_clip) - term_lost_clipboard_ownership(term, CLIP_SYSTEM); - ignore_clip = false; - return 0; +// if (!ignore_clip) +// term_lost_clipboard_ownership(term, CLIP_SYSTEM); +// ignore_clip = false; + /* far2l */ + // In far2l extensions mode we should not do anything here, + // clipboard is handled by far2l extensions. + if (!(term->far2l_ext == 1) || (!term->clip_allowed)) { + if (!ignore_clip) + term_lost_clipboard_ownership(term, CLIP_SYSTEM); + ignore_clip = false; + } + +return 0; case WM_PAINT: { PAINTSTRUCT p; #if (defined MOD_BACKGROUNDIMAGE) && (!defined FLJ) @@ -5590,14 +5602,143 @@ if( (GetKeyState(VK_MENU)&0x8000) && (wParam==VK_SPACE) ) { * number noise. */ noise_ultralight(NOISE_SOURCE_KEY, lParam); + /* far2l */ + if (term->far2l_ext) { + + // far2l_ext keyboard input event structure + WORD repeat; // 2 + WORD vkc; // 2 + WORD vsc; // 2 + DWORD ctrl; // 4 + DWORD uchar; // 4 + CHAR type; // 1 + + // set repeat, virtual keycode, virtual scancode + repeat = LOWORD(lParam); + vsc = HIWORD(lParam) & 0xFF; + vkc = LOWORD(wParam); + + // this fixes far2l's "editor autocomplete" plugin behavior + if ((vkc == VK_TAB) || (vkc == VK_BACK) || (vkc == VK_ESCAPE) || (vkc == VK_DELETE)) { + vsc = 0; + } - /* - * We don't do TranslateMessage since it disassociates the - * resulting CHAR message from the KEYDOWN that sparked it, - * which we occasionally don't want. Instead, we process - * KEYDOWN, and call the Win32 translator functions so that - * we get the translations under _our_ control. - */ + // fixes strange alt+arrows behavior + if ((vkc == VK_LEFT) || (vkc == VK_RIGHT) || (vkc == VK_UP) || (vkc == VK_DOWN)) { + vsc = 0; + } + + // set control keys state + ctrl = 0; + if (GetAsyncKeyState(VK_LCONTROL)) { ctrl |= LEFT_CTRL_PRESSED; } + if (GetAsyncKeyState(VK_RCONTROL)) { ctrl |= RIGHT_CTRL_PRESSED; } + if (GetAsyncKeyState(VK_LMENU)) { ctrl |= LEFT_ALT_PRESSED; } + if (GetAsyncKeyState(VK_RMENU)) { ctrl |= RIGHT_ALT_PRESSED; } + if (GetAsyncKeyState(VK_SHIFT)) { ctrl |= SHIFT_PRESSED; } + // begin: reserved for future usage + // Console WinAPI does not allow us to distinguish between left and right + // shift keys. But PuTTY is not a console app, so why not to send + // all information about control keys state that we actually have here? + // Using bits not used by any other status for backward compatibility. + #define RIGHT_SHIFT_PRESSED 0x1000 + #define LEFT_SHIFT_PRESSED 0x2000 + if (GetAsyncKeyState(VK_LSHIFT)) { ctrl |= RIGHT_SHIFT_PRESSED; } + if (GetAsyncKeyState(VK_RSHIFT)) { ctrl |= LEFT_SHIFT_PRESSED; } + // end + if ((lParam & ( 1 << 24 )) >> 24) { ctrl |= ENHANCED_KEY; } + if ((((u_short)GetKeyState(VK_NUMLOCK)) & 0xffff) != 0) { ctrl |= NUMLOCK_ON; } + if ((((u_short)GetKeyState(VK_SCROLL)) & 0xffff) != 0) { ctrl |= SCROLLLOCK_ON; } + if ((((u_short)GetKeyState(VK_CAPITAL)) & 0xffff) != 0) { ctrl |= CAPSLOCK_ON; } + + // set unicode character + BYTE kb[256]; + GetKeyboardState(kb); + WCHAR uc[5] = {}; + ToUnicode(wParam, MapVirtualKey(wParam, MAPVK_VK_TO_VSC), kb, uc, 4, 0); + // todo: check result + //int result = ToUnicode(wParam, MapVirtualKey(wParam, MAPVK_VK_TO_VSC), kb, uc, 4, 0); + uchar = uc[0]; + + // set event type + if ((message == WM_KEYDOWN) || (message == WM_SYSKEYDOWN)) { + type = 'K'; + } else { + type = 'k'; + } + + char* kev = malloc(15); // keyboard event structure length + memcpy(kev, &repeat, sizeof(repeat)); + memcpy(kev + 2, &vkc, sizeof(vkc)); + memcpy(kev + 4, &vsc, sizeof(vsc)); + memcpy(kev + 6, &ctrl, sizeof(ctrl)); + memcpy(kev + 10, &uchar, sizeof(uchar)); + memcpy(kev + 14, &type, sizeof(type)); + + /* + FILE *f; f = fopen("putty.log", "a"); + fprintf(f, "r: %d, vkc: %c, vsc: %c, ctrl: %ld, uchar: %ld, type: %lc\n", + repeat, vkc, vsc, ctrl, uchar, type); + fprintf(f, "r: %d, vkc: %d, vsc: %d, ctrl: %ld, uchar: %ld, type: %d\n", + repeat, vkc, vsc, ctrl, uchar, type); + fclose(f); + */ + + // base64-encode kev + // result in null-terminated char* out + base64_encodestate _state; + base64_init_encodestate(&_state); + char* out = malloc(15*2); + int count = base64_encode_block(kev, 15, out, &_state); + // finishing '=' characters + char* next_char = out + count; + switch (_state.step) + { + case step_B: + *next_char++ = base64_encode_value(_state.result); + *next_char++ = '='; + *next_char++ = '='; + break; + case step_C: + *next_char++ = base64_encode_value(_state.result); + *next_char++ = '='; + break; + case step_A: + break; + } + count = next_char - out; + out[count] = 0; + + /* + f = fopen("putty.log", "a"); + fprintf(f, "count: %d, b64: %s\n", count, out); + fclose(f); + */ + + // send escape seq + + char* str = "\x1b_f2l"; + backend_send(backend, str, strlen(str)); + + backend_send(backend, out, count); + + char* str2 = "\x07"; + backend_send(backend, str2, strlen(str2)); + + // don't forget to free memory :) + free(out); + + // we should not do any other key processing in this mode + return 0; + } + + +/* + * We don't do TranslateMessage since it disassociates the + * resulting CHAR message from the KEYDOWN that sparked it, + * which we occasionally don't want. Instead, we process + * KEYDOWN, and call the Win32 translator functions so that + * we get the translations under _our_ control. + */ { unsigned char buf[20]; int len; From 5bd07a4cdcebf9f002119a2ea2d4d0b369e00aae Mon Sep 17 00:00:00 2001 From: mihmig Date: Wed, 5 Jan 2022 09:34:27 +0000 Subject: [PATCH 2/3] fixes for far2l --- 0.76_My_PuTTY/terminal.c | 16 +++++----- 0.76_My_PuTTY/terminal.h | 3 ++ 0.76_My_PuTTY/windows/MAKEFILE.MINGW | 47 +++++++++++++++++----------- 0.76_My_PuTTY/windows/window.c | 3 +- 0.76_My_PuTTY/windows/winseat.h | 2 ++ 5 files changed, 44 insertions(+), 27 deletions(-) diff --git a/0.76_My_PuTTY/terminal.c b/0.76_My_PuTTY/terminal.c index c91fd6f..0b0f6b9 100644 --- a/0.76_My_PuTTY/terminal.c +++ b/0.76_My_PuTTY/terminal.c @@ -3273,7 +3273,7 @@ static void do_osc(Terminal *term) // it's possibly too large clipboard #ifdef _WINDOWS - MessageBox(hwnd, "Too large clipboard :(", "Error", MB_OK); + MessageBox(wgs.term_hwnd, "Too large clipboard :(", "Error", MB_OK); #endif // correct request id is lost forever @@ -3342,14 +3342,14 @@ static void do_osc(Terminal *term) // todo: do this on window focus also pnid.cbSize = sizeof(pnid); - pnid.hWnd = hwnd; + pnid.hWnd = wgs.term_hwnd; pnid.hIcon = LoadIcon(0, IDI_APPLICATION); pnid.uID = 200; Shell_NotifyIconW(NIM_DELETE, &pnid); // todo: use putty icon pnid.cbSize = sizeof(pnid); - pnid.hWnd = hwnd; + pnid.hWnd = wgs.term_hwnd; pnid.hIcon = LoadIcon(0, IDI_APPLICATION); pnid.uID = 200; pnid.uFlags = NIF_ICON | NIF_INFO | NIF_MESSAGE; @@ -3423,7 +3423,7 @@ static void do_osc(Terminal *term) #ifdef _WINDOWS char ec_status = 0; if (term->clip_allowed == 1) { - OpenClipboard(hwnd); + OpenClipboard(wgs.term_hwnd); ec_status = EmptyClipboard() ? 1 : 0; CloseClipboard(); } @@ -3473,7 +3473,7 @@ static void do_osc(Terminal *term) #ifdef _WINDOWS if (term->clip_allowed == -1) { - int status = MessageBox(hwnd, + int status = MessageBox(wgs.term_hwnd, "Allow far2l clipboard sync?", "PyTTY", MB_OKCANCEL); if (status == IDOK) { term->clip_allowed = 1; @@ -3557,7 +3557,7 @@ static void do_osc(Terminal *term) memcpy(GData,buffer,BufferSize); GlobalUnlock(hData); - if (OpenClipboard(hwnd)) { + if (OpenClipboard(wgs.term_hwnd)) { if (!SetClipboardData(fmt, (HANDLE)hData)) { GlobalFree(hData); @@ -3616,7 +3616,7 @@ static void do_osc(Terminal *term) int32_t ClipTextSize = 0; if ((gfmt == CF_TEXT || gfmt == CF_UNICODETEXT || gfmt >= 0xC000) && - OpenClipboard(hwnd)) + OpenClipboard(wgs.term_hwnd)) { HANDLE hClipData = GetClipboardData((gfmt == CF_TEXT) ? CF_UNICODETEXT : gfmt); @@ -4730,7 +4730,7 @@ static void term_out(Terminal *term) break; case '_': /* far2l: processing APC is almost the same as processing OSC */ term->is_apc = 1; - break; + //break; //case SEEN_APC: /* todo */ // if (!WriteStr2TC(fdout, enable ? "\x1b_far2l1\x1b\\\x1b[5n" : "\x1b_far2l0\x07\x1b[5n")) diff --git a/0.76_My_PuTTY/terminal.h b/0.76_My_PuTTY/terminal.h index 1d385cd..b16f299 100644 --- a/0.76_My_PuTTY/terminal.h +++ b/0.76_My_PuTTY/terminal.h @@ -6,6 +6,9 @@ * but for the moment, this will do. */ +#include +extern WinGuiSeat wgs; + #ifndef PUTTY_TERMINAL_H #define PUTTY_TERMINAL_H diff --git a/0.76_My_PuTTY/windows/MAKEFILE.MINGW b/0.76_My_PuTTY/windows/MAKEFILE.MINGW index 53c9ac0..6dcfd48 100644 --- a/0.76_My_PuTTY/windows/MAKEFILE.MINGW +++ b/0.76_My_PuTTY/windows/MAKEFILE.MINGW @@ -67,11 +67,6 @@ # Disables PuTTY's use of SecureZeroMemory(), which is missing # from some environments' header files. # -# - XFLAGS=-DTELNET_DEFAULT -# Causes PuTTY to default to the Telnet protocol (in the absence -# of Default Settings and so on to the contrary). Normally PuTTY -# will default to SSH. -# # - XFLAGS=-DDEBUG # Causes PuTTY to enable internal debugging. # @@ -423,8 +418,8 @@ putty.exe: agentf.o aqsync.o be_all_s.o be_misc.o callback.o cmdline.o \ winnps.o winpgntc.o winprint.o winproxy.o winsecur.o \ winselgui.o winser.o winshare.o winstore.o wintime.o \ winucs.o winutils.o winx11.o x11fwd.o \ + cencode.o cdecode.o \ adb.o \ - cencode.o cdecode.o \ kitty.o kitty_commun.o kitty_crypt.o kitty_image.o kitty_proxy.o kitty_registry.o kitty_ssh.o \ kitty_store.o kitty_tools.o kitty_win.o \ urlhack.o pageant_integrated.o winpgnt_integrated.o winpgen_integrated.o winpzmodem.o \ @@ -451,18 +446,34 @@ putty.exe: agentf.o aqsync.o be_all_s.o be_misc.o callback.o cmdline.o \ windlg.o window.o wingss.o winhandl.o winhelp.o winhsock.o \ winjump.o winmisc.o winmiscs.o winnet.o winnoise.o winnpc.o \ winnps.o winpgntc.o winprint.o winproxy.o winsecur.o \ - winser.o winshare.o winstore.o wintime.o winucs.o winutils.o \ - winx11.o cencode.o cdecode.o x11fwd.o -ladvapi32 -lcomdlg32 -lgdi32 -limm32 \ - -lole32 -lshell32 -luser32 - -puttygen.exe: conf.o ecc.o import.o marshal.o memory.o misc.o mpint.o \ - notiming.o puttygen.res.o sshaes.o sshauxcrypt.o sshbcrypt.o \ - sshblowf.o sshdes.o sshdss.o sshdssg.o sshecc.o sshecdsag.o \ - sshhmac.o sshmd5.o sshprime.o sshprng.o sshpubk.o sshrand.o \ - sshrsa.o sshrsag.o sshsh256.o sshsh512.o sshsha.o \ - stripctrl.o tree234.o utils.o version.o wcwidth.o winctrls.o \ - winhelp.o winmisc.o winmiscs.o winnoise.o winnojmp.o \ - winpgen.o winsecur.o winstore.o wintime.o winutils.o + winselgui.o winser.o winshare.o winstore.o wintime.o \ + winucs.o winutils.o winx11.o x11fwd.o \ + cencode.o cdecode.o \ + adb.o \ + kitty.o kitty_commun.o kitty_crypt.o kitty_image.o kitty_proxy.o kitty_registry.o kitty_ssh.o \ + kitty_store.o kitty_tools.o kitty_win.o \ + urlhack.o pageant_integrated.o winpgnt_integrated.o winpgen_integrated.o winpzmodem.o \ + import.o sshrsag.o sshdssg.o sshprime.o sshecdsag.o sshbcrypt.o pockle.o primecandidate.o millerrabin.o mpunsafe.o \ + void.o $(UTF8MOUSE_OBJS) \ + ../../base64/base64.a ../../bcrypt/bcrypt.a ../../blocnote/notepad.a ../../jpeg/libjpeg.a \ + ../../md5/MD5check.a ../../mini/mini.a ../../regex/libregex.a \ + -ladvapi32 -lcomdlg32 -lgdi32 -limm32 -lpsapi -lole32 -lshell32 \ + -luser32 -lwsock32 -lwtsapi32 \ + #-lcrypt32 \ + #/c/Windows/system32/crypt32.dll /c/windows/system32/ncrypt.dll \ + # -lcomctl32 -lwinmm -lwinspool -lole32 + +puttygen.exe: conf.o ecc.o import.o marshal.o memory.o millerrabin.o misc.o \ + mpint.o mpunsafe.o notiming.o pockle.o primecandidate.o \ + puttygen.res.o smallprimes.o sshaes.o sshargon2.o \ + sshauxcrypt.o sshbcrypt.o sshblake2.o sshblowf.o sshdes.o \ + sshdss.o sshdssg.o sshecc.o sshecdsag.o sshhmac.o sshmd5.o \ + sshprime.o sshprng.o sshpubk.o sshrand.o sshrsa.o sshrsag.o \ + sshsh256.o sshsh512.o sshsha.o sshsha3.o stripctrl.o \ + tree234.o utils.o version.o wcwidth.o winctrls.o winhelp.o \ + winmisc.o winmiscs.o winnoise.o winnojmp.o winpgen.o \ + winsecur.o winstore.o wintime.o winutils.o \ + kitty_commun.o kitty_crypt.o kitty_registry.o kitty_keygen.o kitty_store.o kitty_tools.o $(CC) -mwindows $(LDFLAGS) -o $@ -Wl,-Map,puttygen.map conf.o ecc.o \ import.o marshal.o memory.o millerrabin.o misc.o mpint.o \ mpunsafe.o notiming.o pockle.o primecandidate.o \ diff --git a/0.76_My_PuTTY/windows/window.c b/0.76_My_PuTTY/windows/window.c index 44f8fec..bdee9bd 100644 --- a/0.76_My_PuTTY/windows/window.c +++ b/0.76_My_PuTTY/windows/window.c @@ -615,7 +615,8 @@ static const SeatVtable win_seat_vt = { .interactive = nullseat_interactive_yes, .get_cursor_position = win_seat_get_cursor_position, }; -static WinGuiSeat wgs = { .seat.vt = &win_seat_vt, +//static +WinGuiSeat wgs = { .seat.vt = &win_seat_vt, .logpolicy.vt = &win_gui_logpolicy_vt }; #ifdef MOD_PERSO diff --git a/0.76_My_PuTTY/windows/winseat.h b/0.76_My_PuTTY/windows/winseat.h index b888343..7434f4f 100644 --- a/0.76_My_PuTTY/windows/winseat.h +++ b/0.76_My_PuTTY/windows/winseat.h @@ -3,6 +3,8 @@ * and windlg.c. */ +#pragma once + typedef struct WinGuiSeat WinGuiSeat; struct WinGuiSeat { From baa02fbe5b0eea45d727df171885c0a3884358c5 Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Mon, 10 Jan 2022 12:20:56 +0300 Subject: [PATCH 3/3] Some comments, removed unused debug code, cosmetic --- 0.76_My_PuTTY/terminal.c | 470 +++++++++++++++------------------ 0.76_My_PuTTY/terminal.h | 13 +- 0.76_My_PuTTY/windows/window.c | 76 +++--- 3 files changed, 259 insertions(+), 300 deletions(-) diff --git a/0.76_My_PuTTY/terminal.c b/0.76_My_PuTTY/terminal.c index 0b0f6b9..043894b 100644 --- a/0.76_My_PuTTY/terminal.c +++ b/0.76_My_PuTTY/terminal.c @@ -12,7 +12,8 @@ #include #include "putty.h" #include "terminal.h" -/* far2l base64 */ + +/* base64 library - needed for far2l extensions support */ #include #include @@ -2004,9 +2005,9 @@ Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata, TermWin *win) */ term = snew(Terminal); /* far2l */ - term->far2l_ext = 0; - term->is_apc = 0; - term->clip_allowed = -1; + term->far2l_ext = 0; // far2l extensions mode is enabled? + term->is_apc = 0; // currently processing incoming APC sequence? + term->clip_allowed = -1; // remote clipboard access is enabled? term->win = win; term->ucsdata = ucsdata; term->conf = conf_copy(myconf); @@ -3211,26 +3212,9 @@ static void toggle_mode(Terminal *term, int mode, int query, bool state) */ static void do_osc(Terminal *term) { - /* far2l */ + /* far2l extensions support */ if (term->is_apc) { - /* - - FIXME - От удаленного far2l может придти строка любой длины, - а длина term->osc_string - фиксированная (2048 байт). - Длинный буфер обмена не пролезет. - - Надо бы сделать какую-нибудь динамическую структуру. - - Хотя бы так: - void *realloc(void *ptr, size_t newsize) - - Пока увеличил до мегабайта и сделал предупреждение, - если не пролезаем :) - - */ - #ifndef _WINDOWS #define DWORD unsigned int #define WORD unsigned short @@ -3238,7 +3222,16 @@ static void do_osc(Terminal *term) if (strncmp(term->osc_string, "far2l", 5) == 0) { + // okay, this is far2l terminal extensions APC sequence + + // for more info about far2l terminal extensions please see: + // https://github.com/cyd01/KiTTY/issues/74 + // https://github.com/elfmz/far2l/blob/master/WinPort/FarTTY.h + if (strncmp(term->osc_string+5, "1", 1) == 0) { + + // extensions mode on + term->far2l_ext = 1; char *reply_buf = dupprintf( @@ -3252,6 +3245,8 @@ static void do_osc(Terminal *term) } else if (strncmp(term->osc_string+5, "0", 1) == 0) { + // extensions mode off + term->far2l_ext = 0; // reset clipboard state; todo: do it on session init! @@ -3259,10 +3254,14 @@ static void do_osc(Terminal *term) } else if (strncmp(term->osc_string+5, ":", 1) == 0) { + // processing actual payload + + // base64-decode payload base64_decodestate _d_state; base64_init_decodestate(&_d_state); char* d_out = malloc(term->osc_strlen); - int d_count = base64_decode_block(term->osc_string+6, term->osc_strlen-6, d_out, &_d_state); + int d_count = base64_decode_block( + term->osc_string+6, term->osc_strlen-6, d_out, &_d_state); // last byte is id BYTE id = d_out[d_count-1]; @@ -3270,11 +3269,15 @@ static void do_osc(Terminal *term) int reply_size = 0; if (term->osc_strlen == OSC_STR_MAX) { + // it's possibly too large clipboard - #ifdef _WINDOWS + // we can't deal with it + // until implementing dynamic osc_string allocation + + #ifdef _WINDOWS MessageBox(wgs.term_hwnd, "Too large clipboard :(", "Error", MB_OK); - #endif + #endif // correct request id is lost forever // so we can not prevent far2l from hanging @@ -3289,7 +3292,7 @@ static void do_osc(Terminal *term) // next from the end byte is command switch (d_out[d_count-2]) { - case 'f':; + case 'f':; // FARTTY_INTERRACT_SET_FKEY_TITLES reply_size = 5; reply = malloc(reply_size); @@ -3301,7 +3304,7 @@ static void do_osc(Terminal *term) break; - case 'n':; + case 'n':; // FARTTY_INTERRACT_DESKTOP_NOTIFICATION /* // not ready yet @@ -3367,7 +3370,7 @@ static void do_osc(Terminal *term) break; - case 'w': + case 'w': // FARTTY_INTERRACT_GET_WINDOW_MAXSIZE // get largest console window size @@ -3382,85 +3385,82 @@ static void do_osc(Terminal *term) break; - case 'c': + case 'c': // FARTTY_INTERRACT_CLIPBOARD // clipboard interaction // next from the end byte is subcommand + switch (d_out[d_count-3]) { - case 'r':; + + case 'r':; // FARTTY_INTERRACT_CLIP_REGISTER_FORMAT + // register format memcpy(&len, d_out + d_count - 3 - 4, sizeof(DWORD)); d_out[len] = 0; // zero-terminate format name -#ifdef _WINDOWS - // far2l sends format name as (utf8?) string, which actually containing ascii only - // so we can just call ascii function - uint32_t status = RegisterClipboardFormatA(d_out); -#endif - - /* - FILE *f; f = fopen("putty.log", "a"); - fprintf(f, "status: %d, format: [%s]\n", status, d_out); - fclose(f); - - // status: 49220, format: [FAR_VerticalBlock_Unicode] - */ + #ifdef _WINDOWS + // far2l sends format name as (utf8?) string, + // which actually containing ascii only + // so we can just call ascii function + uint32_t status = RegisterClipboardFormatA(d_out); + #endif reply_size = 5; reply = malloc(reply_size); -#ifdef _WINDOWS + #ifdef _WINDOWS memcpy(reply, &status, sizeof(uint32_t)); -#else + #else bzero(reply, sizeof(uint32_t)); -#endif + #endif break; - case 'e':; + case 'e':; // FARTTY_INTERRACT_CLIP_EMPTY -#ifdef _WINDOWS + #ifdef _WINDOWS char ec_status = 0; - if (term->clip_allowed == 1) { - OpenClipboard(wgs.term_hwnd); - ec_status = EmptyClipboard() ? 1 : 0; - CloseClipboard(); - } -#endif + if (term->clip_allowed == 1) { + OpenClipboard(wgs.term_hwnd); + ec_status = EmptyClipboard() ? 1 : 0; + CloseClipboard(); + } + #endif reply_size = 2; reply = malloc(reply_size); -#ifdef _WINDOWS + #ifdef _WINDOWS reply[0] = ec_status; -#else + #else reply[0] = 0; -#endif + #endif break; - case 'a':; + case 'a':; // FARTTY_INTERRACT_CLIP_ISAVAIL uint32_t a_fmt; memcpy(&a_fmt, d_out + d_count - 3 - 4, sizeof(uint32_t)); -#ifdef _WINDOWS + #ifdef _WINDOWS char out = IsClipboardFormatAvailable(a_fmt) ? 1 : 0; -#endif + #endif reply_size = 2; reply = malloc(reply_size); -#ifdef _WINDOWS + #ifdef _WINDOWS reply[0] = out; -#else + #else reply[0] = 0; -#endif + #endif break; - case 'o':; + case 'o':; // FARTTY_INTERRACT_CLIP_OPEN + // open // next from the end 4 bytes is client_id length memcpy(&len, d_out + d_count - 3 - 4, sizeof(DWORD)); @@ -3471,125 +3471,123 @@ static void do_osc(Terminal *term) reply_size = 2; reply = malloc(reply_size); -#ifdef _WINDOWS + #ifdef _WINDOWS if (term->clip_allowed == -1) { - int status = MessageBox(wgs.term_hwnd, - "Allow far2l clipboard sync?", "PyTTY", MB_OKCANCEL); - if (status == IDOK) { - term->clip_allowed = 1; - } else { - // IDCANCEL - term->clip_allowed = 0; + int status = MessageBox(wgs.term_hwnd, + "Allow far2l clipboard sync?", "PyTTY", MB_OKCANCEL); + if (status == IDOK) { + term->clip_allowed = 1; + } else { + // IDCANCEL + term->clip_allowed = 0; + } } - } - // status is first response byte - if (term->clip_allowed == 1) { - reply[0] = 1; - } else { - reply[0] = -1; - } -#else + // status is first response byte + if (term->clip_allowed == 1) { + reply[0] = 1; + } else { + reply[0] = -1; + } + #else reply[0] = -1; -#endif + #endif break; - case 's':; + case 's':; // FARTTY_INTERRACT_CLIP_SETDATA + // set data if (term->clip_allowed == 1 && d_count >= 4 + 4 + 3) { -#ifdef _WINDOWS - - // Never do like this! It takes char by index and converts to DWORD. - // Not takes two chars to fit DWORD. Really. - //DWORD fmt = (DWORD)d_out[d_count-3-4]; - uint32_t fmt; - char* buffer = NULL; - int BufferSize = 0; - memcpy(&fmt, d_out + d_count - 3 - 4, sizeof(uint32_t)); - - // id, 'c', 's', 4-byte fmt, next goes 4-byte len - memcpy(&len, d_out + d_count - 3 - 4 - 4, sizeof(DWORD)); - if (len > d_count - 3 - 4 - 4) - len = d_count - 3 - 4 - 4; - - if (fmt == CF_TEXT) { - int cnt = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)d_out, len, NULL, 0); - if (cnt > 0) { - buffer = calloc(cnt + 1, sizeof(wchar_t)); - MultiByteToWideChar(CP_UTF8, 0, (LPCCH)d_out, len, (PWCHAR)buffer, cnt); - } - fmt = CF_UNICODETEXT; - BufferSize = (wcslen((PWCHAR)buffer) + 1) * sizeof(WCHAR); - - } else if (fmt == CF_UNICODETEXT) { - // very stupid utf32->utf16 'conversion' - buffer = calloc((len / sizeof(uint32_t)) + 1, sizeof(wchar_t)); - for (int i=0; i < len / sizeof(uint32_t); ++i) { - memcpy( - &buffer[i * sizeof(wchar_t)], - &d_out[i * sizeof(uint32_t)], - sizeof(wchar_t) - ); + #ifdef _WINDOWS + + uint32_t fmt; + char* buffer = NULL; + int BufferSize = 0; + memcpy(&fmt, d_out + d_count - 3 - 4, sizeof(uint32_t)); + + // id, 'c', 's', 4-byte fmt, next goes 4-byte len + memcpy(&len, d_out + d_count - 3 - 4 - 4, sizeof(DWORD)); + if (len > d_count - 3 - 4 - 4) + len = d_count - 3 - 4 - 4; + + if (fmt == CF_TEXT) { + int cnt = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)d_out, len, NULL, 0); + if (cnt > 0) { + buffer = calloc(cnt + 1, sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, (LPCCH)d_out, len, (PWCHAR)buffer, cnt); + } + fmt = CF_UNICODETEXT; + BufferSize = (wcslen((PWCHAR)buffer) + 1) * sizeof(WCHAR); + + } else if (fmt == CF_UNICODETEXT) { + // very stupid utf32->utf16 'conversion' + buffer = calloc((len / sizeof(uint32_t)) + 1, sizeof(wchar_t)); + for (int i=0; i < len / sizeof(uint32_t); ++i) { + memcpy( + &buffer[i * sizeof(wchar_t)], + &d_out[i * sizeof(uint32_t)], + sizeof(wchar_t) + ); + } + BufferSize = (wcslen((PWCHAR)buffer) + 1) * sizeof(WCHAR); + + } else if (fmt >= 0xC000) { + // no transcoding - copy it as is + buffer = malloc(len); + memcpy(buffer, &d_out[0], len); + BufferSize = len; } - BufferSize = (wcslen((PWCHAR)buffer) + 1) * sizeof(WCHAR); - } else if (fmt >= 0xC000) { - // no transcoding - copy it as is - buffer = malloc(len); - memcpy(buffer, &d_out[0], len); - BufferSize = len; - } + // clipboard stuff itself + + HGLOBAL hData; + void *GData; - // clipboard stuff itself + bool set_successful = 0; - HGLOBAL hData; - void *GData; + if (buffer && (hData=GlobalAlloc(GMEM_MOVEABLE,BufferSize))) { - bool set_successful = 0; + if ((GData=GlobalLock(hData))) { - if (buffer && (hData=GlobalAlloc(GMEM_MOVEABLE,BufferSize))) { + memcpy(GData,buffer,BufferSize); + GlobalUnlock(hData); - if ((GData=GlobalLock(hData))) { + if (OpenClipboard(wgs.term_hwnd)) { - memcpy(GData,buffer,BufferSize); - GlobalUnlock(hData); + if (!SetClipboardData(fmt, (HANDLE)hData)) { + GlobalFree(hData); + } else { + set_successful = 1; + } - if (OpenClipboard(wgs.term_hwnd)) { + CloseClipboard(); - if (!SetClipboardData(fmt, (HANDLE)hData)) { - GlobalFree(hData); } else { - set_successful = 1; + GlobalFree(hData); } - CloseClipboard(); - } else { GlobalFree(hData); } - - } else { - GlobalFree(hData); } - } - free(buffer); + free(buffer); -#endif + #endif // prepare reply reply_size = 2; reply = malloc(reply_size); // first reply byte is status -#ifdef _WINDOWS + #ifdef _WINDOWS reply[0] = set_successful; -#else + #else reply[0] = 0; -#endif + #endif } else { @@ -3601,115 +3599,115 @@ static void do_osc(Terminal *term) break; - case 'g':; + case 'g':; // FARTTY_INTERRACT_CLIP_GETDATA if (term->clip_allowed == 1) { -#ifdef _WINDOWS + #ifdef _WINDOWS uint32_t gfmt; - memcpy(&gfmt, d_out + d_count - 3 - 4, sizeof(uint32_t)); - - // clipboard stuff itself + memcpy(&gfmt, d_out + d_count - 3 - 4, sizeof(uint32_t)); - void *ClipText = NULL; - int32_t ClipTextSize = 0; + // clipboard stuff itself - if ((gfmt == CF_TEXT || gfmt == CF_UNICODETEXT || gfmt >= 0xC000) && - OpenClipboard(wgs.term_hwnd)) - { - HANDLE hClipData = GetClipboardData((gfmt == CF_TEXT) ? CF_UNICODETEXT : gfmt); + void *ClipText = NULL; + int32_t ClipTextSize = 0; - if (hClipData) + if ((gfmt == CF_TEXT || gfmt == CF_UNICODETEXT || gfmt >= 0xC000) && + OpenClipboard(wgs.term_hwnd)) { - void *pClipData=GlobalLock(hClipData); + HANDLE hClipData = GetClipboardData((gfmt == CF_TEXT) ? CF_UNICODETEXT : gfmt); - if (pClipData) + if (hClipData) { - size_t n = GlobalSize(hClipData); - - if (gfmt == CF_TEXT) { - - ClipTextSize = WideCharToMultiByte( - CP_UTF8, - 0, - (wchar_t *)pClipData, - n, - NULL, - 0, - NULL, - NULL - ) + 1; - - if (ClipTextSize >= 0) { + void *pClipData=GlobalLock(hClipData); + + if (pClipData) + { + size_t n = GlobalSize(hClipData); + + if (gfmt == CF_TEXT) { + + ClipTextSize = WideCharToMultiByte( + CP_UTF8, + 0, + (wchar_t *)pClipData, + n, + NULL, + 0, + NULL, + NULL + ) + 1; + + if (ClipTextSize >= 0) { + n = wcsnlen((wchar_t *)pClipData, n / sizeof(wchar_t)); + ClipText = calloc(ClipTextSize + 1, 1); + if (ClipText) { + WideCharToMultiByte( + CP_UTF8, + 0, + (wchar_t *)pClipData, + n, + (char *)ClipText, + ClipTextSize, + NULL, + NULL + ); + ClipTextSize = strlen((char *)ClipText) + 1; + } + } + + } else if (gfmt == CF_UNICODETEXT) { n = wcsnlen((wchar_t *)pClipData, n / sizeof(wchar_t)); - ClipText = calloc(ClipTextSize + 1, 1); + ClipText = calloc((n + 1), sizeof(uint32_t)); if (ClipText) { - WideCharToMultiByte( - CP_UTF8, - 0, - (wchar_t *)pClipData, - n, - (char *)ClipText, - ClipTextSize, - NULL, - NULL - ); - ClipTextSize = strlen((char *)ClipText) + 1; + for (size_t i = 0; i < n; ++i) { + ((uint32_t *)ClipText)[i] = ((uint16_t *)pClipData)[i]; + } + ClipTextSize = (n + 1) * sizeof(uint32_t); } - } - } else if (gfmt == CF_UNICODETEXT) { - n = wcsnlen((wchar_t *)pClipData, n / sizeof(wchar_t)); - ClipText = calloc((n + 1), sizeof(uint32_t)); - if (ClipText) { - for (size_t i = 0; i < n; ++i) { - ((uint32_t *)ClipText)[i] = ((uint16_t *)pClipData)[i]; + } else { + ClipText = malloc(n); + if (ClipText) { + memcpy(ClipText, pClipData, n); + ClipTextSize = n; } - ClipTextSize = (n + 1) * sizeof(uint32_t); } - } else { - ClipText = malloc(n); - if (ClipText) { - memcpy(ClipText, pClipData, n); - ClipTextSize = n; - } + GlobalUnlock(hClipData); } - GlobalUnlock(hClipData); + } else { + // todo: process errors } - - } else { - // todo: process errors + CloseClipboard(); } - CloseClipboard(); - } - if (!ClipText || ClipTextSize <= 0) { + if (!ClipText || ClipTextSize <= 0) { - // clipboard is empty - reply_size = 5; // 4 bytes for size and one for id - reply = calloc(1, reply_size); + // clipboard is empty + reply_size = 5; // 4 bytes for size and one for id + reply = calloc(1, reply_size); - } else { + } else { - // + length (4 bytes) + id (1 byte) - reply_size = ClipTextSize + 5; - reply = calloc(1, reply_size); - memcpy(reply, ClipText, ClipTextSize); + // + length (4 bytes) + id (1 byte) + reply_size = ClipTextSize + 5; + reply = calloc(1, reply_size); + memcpy(reply, ClipText, ClipTextSize); - // set size - memcpy(reply + ClipTextSize, &ClipTextSize, sizeof(ClipTextSize)); - } + // set size + memcpy(reply + ClipTextSize, &ClipTextSize, sizeof(ClipTextSize)); + } - free(ClipText); + free(ClipText); -#else + #else reply_size = 5; reply = calloc(1, reply_size); -#endif + #endif } else { @@ -3726,23 +3724,6 @@ static void do_osc(Terminal *term) break; } - /* - if (reply_size == 0) { - // unsupported sequences - - term->osc_string[term->osc_strlen] = 0; - - FILE *f; f = fopen("putty.log", "a"); - fprintf(f, "string: %.*s, strlen: %d\n", term->osc_strlen, term->osc_string, term->osc_strlen); - fprintf(f, "d_count: %d, d_out: [", d_count); - for(int i=0;i 0) { @@ -3786,17 +3767,6 @@ static void do_osc(Terminal *term) backend_send(term->backend, out, count); - /* - // log string we sent - FILE *f; f = fopen("putty.log", "a"); - fprintf(f, "send: ["); - for(int i=0;ibackend, str2, strlen(str2)); diff --git a/0.76_My_PuTTY/terminal.h b/0.76_My_PuTTY/terminal.h index b16f299..44109a7 100644 --- a/0.76_My_PuTTY/terminal.h +++ b/0.76_My_PuTTY/terminal.h @@ -188,17 +188,19 @@ struct terminal_tag { #define ANSI(x,y) ((x)+((y)*256)) #define ANSI_QUE(x) ANSI(x,1) -/* far2l */ +/* far2l extensions support */ //#define OSC_STR_MAX 2048 +// todo: allocate osc_string dynamically #define OSC_STR_MAX 1048576 + int osc_strlen; char osc_string[OSC_STR_MAX + 1]; bool osc_w; /* far2l */ - int far2l_ext; - bool is_apc; - int clip_allowed; + int far2l_ext; // extensions mode on + bool is_apc; // currently processing APC sequence + int clip_allowed; // remote clipboard access is allowed char id_string[1024]; @@ -215,8 +217,7 @@ struct terminal_tag { SEEN_OSC_P, OSC_STRING, OSC_MAYBE_ST, - /* far2l */ - SEEN_APC, + /* far2l extensions support */ SEEN_APC, VT52_ESC, VT52_Y1, VT52_Y2, diff --git a/0.76_My_PuTTY/windows/window.c b/0.76_My_PuTTY/windows/window.c index bdee9bd..010b3ec 100644 --- a/0.76_My_PuTTY/windows/window.c +++ b/0.76_My_PuTTY/windows/window.c @@ -9,7 +9,8 @@ #include #include #include -/* far2l base64 */ + +/* far2l extensions support - base64 encode/decode libs */ #include #include @@ -615,7 +616,8 @@ static const SeatVtable win_seat_vt = { .interactive = nullseat_interactive_yes, .get_cursor_position = win_seat_get_cursor_position, }; -//static +// "static" removed by far2l extensions support patch +// we need to access wgs from terminal.c to open dialog boxes, etc WinGuiSeat wgs = { .seat.vt = &win_seat_vt, .logpolicy.vt = &win_gui_logpolicy_vt }; @@ -4831,10 +4833,8 @@ free(cmd); ignore_clip = wParam; /* don't panic on DESTROYCLIPBOARD */ break; case WM_DESTROYCLIPBOARD: -// if (!ignore_clip) -// term_lost_clipboard_ownership(term, CLIP_SYSTEM); -// ignore_clip = false; - /* far2l */ + /* far2l extensions support */ + // In far2l extensions mode we should not do anything here, // clipboard is handled by far2l extensions. if (!(term->far2l_ext == 1) || (!term->clip_allowed)) { @@ -4843,7 +4843,7 @@ free(cmd); ignore_clip = false; } -return 0; + return 0; case WM_PAINT: { PAINTSTRUCT p; #if (defined MOD_BACKGROUNDIMAGE) && (!defined FLJ) @@ -5603,16 +5603,19 @@ if( (GetKeyState(VK_MENU)&0x8000) && (wParam==VK_SPACE) ) { * number noise. */ noise_ultralight(NOISE_SOURCE_KEY, lParam); - /* far2l */ + + /* far2l extensions support */ if (term->far2l_ext) { + // extensions mode enabled + // far2l_ext keyboard input event structure - WORD repeat; // 2 - WORD vkc; // 2 - WORD vsc; // 2 - DWORD ctrl; // 4 - DWORD uchar; // 4 - CHAR type; // 1 + WORD repeat; // 2 bytes + WORD vkc; // 2 bytes + WORD vsc; // 2 bytes + DWORD ctrl; // 4 bytes + DWORD uchar; // 4 bytes + CHAR type; // 1 byte // set repeat, virtual keycode, virtual scancode repeat = LOWORD(lParam); @@ -5621,12 +5624,12 @@ if( (GetKeyState(VK_MENU)&0x8000) && (wParam==VK_SPACE) ) { // this fixes far2l's "editor autocomplete" plugin behavior if ((vkc == VK_TAB) || (vkc == VK_BACK) || (vkc == VK_ESCAPE) || (vkc == VK_DELETE)) { - vsc = 0; + vsc = 0; } // fixes strange alt+arrows behavior if ((vkc == VK_LEFT) || (vkc == VK_RIGHT) || (vkc == VK_UP) || (vkc == VK_DOWN)) { - vsc = 0; + vsc = 0; } // set control keys state @@ -5662,9 +5665,9 @@ if( (GetKeyState(VK_MENU)&0x8000) && (wParam==VK_SPACE) ) { // set event type if ((message == WM_KEYDOWN) || (message == WM_SYSKEYDOWN)) { - type = 'K'; + type = 'K'; } else { - type = 'k'; + type = 'k'; } char* kev = malloc(15); // keyboard event structure length @@ -5675,15 +5678,6 @@ if( (GetKeyState(VK_MENU)&0x8000) && (wParam==VK_SPACE) ) { memcpy(kev + 10, &uchar, sizeof(uchar)); memcpy(kev + 14, &type, sizeof(type)); - /* - FILE *f; f = fopen("putty.log", "a"); - fprintf(f, "r: %d, vkc: %c, vsc: %c, ctrl: %ld, uchar: %ld, type: %lc\n", - repeat, vkc, vsc, ctrl, uchar, type); - fprintf(f, "r: %d, vkc: %d, vsc: %d, ctrl: %ld, uchar: %ld, type: %d\n", - repeat, vkc, vsc, ctrl, uchar, type); - fclose(f); - */ - // base64-encode kev // result in null-terminated char* out base64_encodestate _state; @@ -5694,27 +5688,21 @@ if( (GetKeyState(VK_MENU)&0x8000) && (wParam==VK_SPACE) ) { char* next_char = out + count; switch (_state.step) { - case step_B: - *next_char++ = base64_encode_value(_state.result); - *next_char++ = '='; - *next_char++ = '='; - break; - case step_C: - *next_char++ = base64_encode_value(_state.result); - *next_char++ = '='; - break; - case step_A: - break; + case step_B: + *next_char++ = base64_encode_value(_state.result); + *next_char++ = '='; + *next_char++ = '='; + break; + case step_C: + *next_char++ = base64_encode_value(_state.result); + *next_char++ = '='; + break; + case step_A: + break; } count = next_char - out; out[count] = 0; - /* - f = fopen("putty.log", "a"); - fprintf(f, "count: %d, b64: %s\n", count, out); - fclose(f); - */ - // send escape seq char* str = "\x1b_f2l";