Skip to content

Commit

Permalink
- Refactored keyboard processing code, added more modifiers
Browse files Browse the repository at this point in the history
- Fixed hangs on multiple continious copy-to-clipboard attempts
- Slightly more error proof code
- Preliminary work on notifications support
- Fresh binary
  • Loading branch information
unxed committed Dec 14, 2019
1 parent 5109a87 commit 9e577d8
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 58 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
*.o
windows/putty.map
windows/putty.map
windows/make__quickrun.sh
windows/putty.log
119 changes: 104 additions & 15 deletions terminal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1677,6 +1677,7 @@ Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata, TermWin *win)
term->far2l_ext = 0;
term->is_apc = 0;
term->clip_allowed = -1;
term->clip_empty_pending = 0;

term->win = win;
term->ucsdata = ucsdata;
Expand Down Expand Up @@ -2821,6 +2822,72 @@ static void do_osc(Terminal *term)
// next from the end byte is command
switch (d_out[d_count-2]) {

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
Expand Down Expand Up @@ -2868,18 +2935,29 @@ static void do_osc(Terminal *term)

case 'e':;

OpenClipboard(hwnd);
char ec_status = EmptyClipboard() ? 1 : 0;
CloseClipboard();
char ec_status;
/*
// EmptyClipboard() behaves VERY strange if called from here
// (test case: many continious Ctrl+Ins presses
// with selected text string of 174 characters in size),
// but works well if called just before SetClipboardData().
// So deferreing a call to it.
if (term->clip_allowed == -1) {
OpenClipboard(hwnd);
ec_status = EmptyClipboard() ? 1 : 0;
CloseClipboard();
}
*/
term->clip_empty_pending = 1;
ec_status = 1; // simulate "ok"

reply_size = 2;
reply = malloc(reply_size);

memcpy(reply, &ec_status, sizeof(char));
reply[0] = ec_status;

break;


case 'a':;

DWORD a_fmt = (DWORD)d_out[d_count-7];
Expand Down Expand Up @@ -2960,19 +3038,27 @@ static void do_osc(Terminal *term)
memcpy(GData,buffer,BufferSize);
GlobalUnlock(hData);

OpenClipboard(hwnd);
if (OpenClipboard(hwnd)) {

if (term->clip_empty_pending) {
EmptyClipboard(); // todo: check errors
term->clip_empty_pending = 0;
}

if (!SetClipboardData(fmt, (HANDLE)hData)) {

if (SetClipboardData(fmt, (HANDLE)hData)) {
GlobalFree(hData);
}

CloseClipboard();

} else {
} else {

GlobalFree(hData);
}
}
else
{

} else {

GlobalFree(hData);
}
}
Expand Down Expand Up @@ -3004,11 +3090,13 @@ static void do_osc(Terminal *term)

// clipboard stuff itself

wchar_t *ClipText=NULL;
wchar_t *ClipText = NULL;
HANDLE hClipData = NULL;

OpenClipboard(hwnd);
HANDLE hClipData=GetClipboardData(gfmt);
CloseClipboard();
if (OpenClipboard(hwnd)) {
hClipData = GetClipboardData(gfmt);
CloseClipboard();
}

if (hClipData)
{
Expand All @@ -3025,6 +3113,7 @@ static void do_osc(Terminal *term)

GlobalUnlock(hClipData);
}

} else {
// todo: process errors
}
Expand Down
1 change: 1 addition & 0 deletions terminal.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ struct terminal_tag {
int far2l_ext;
bool is_apc;
int clip_allowed;
bool clip_empty_pending;

char id_string[1024];

Expand Down
Binary file modified windows/putty.exe
Binary file not shown.
75 changes: 33 additions & 42 deletions windows/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -3217,19 +3217,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
/* far2l */
if (term->far2l_ext) {

// out base64 library splits long strings with \n
// do we actuall need this behavour?

// get unicode char
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);

// far2l_ext keyboard input event structure
DWORD repeat; // 4
WORD vkc; // 2
Expand All @@ -3243,38 +3230,35 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
vkc = LOWORD(wParam);
vsc = HIWORD(lParam) & 0xFF;

// set control keys state
ctrl = 0;

if (GetAsyncKeyState(VK_CONTROL)) {
ctrl |= LEFT_CTRL_PRESSED;
}
if (GetAsyncKeyState(VK_RCONTROL)) {
ctrl |= RIGHT_CTRL_PRESSED;
}
if (GetAsyncKeyState(VK_MENU)) {
ctrl |= LEFT_ALT_PRESSED;
}
if (GetAsyncKeyState(VK_SHIFT)) {
ctrl |= SHIFT_PRESSED;
}

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;
}
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
Expand All @@ -3292,6 +3276,13 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
memcpy(kev + 12, &uchar, sizeof(uchar));
memcpy(kev + 16, &type, sizeof(type));

/*
FILE *f; f = fopen("putty.log", "a");
fprintf(f, "r: %ld, vkc: %c, vsc: %c, ctrl: %ld, uchar: %ld, type: %lc\n",
repeat, vkc, vsc, ctrl, uchar, type);
fclose(f);
*/

// base64-encode kev
// result in null-terminated char* out
base64_encodestate _state;
Expand Down

0 comments on commit 9e577d8

Please sign in to comment.