Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/clipboar.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8796 - (hide annotations) (download) (as text)
Mon Jun 15 02:06:34 2020 UTC (3 years, 9 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 14639 byte(s)
クリップボードからペースト時に本当にテキストかどうか確認

- IsTextW()追加
1 doda 6806 /*
2     * Copyright (C) 1994-1998 T. Teranishi
3 zmatsuo 8459 * (C) 2006-2020 TeraTerm Project
4 doda 6806 * All rights reserved.
5     *
6 doda 6841 * Redistribution and use in source and binary forms, with or without
7     * modification, are permitted provided that the following conditions
8     * are met:
9 doda 6806 *
10 doda 6841 * 1. Redistributions of source code must retain the above copyright
11     * notice, this list of conditions and the following disclaimer.
12     * 2. Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the distribution.
15     * 3. The name of the author may not be used to endorse or promote products
16     * derived from this software without specific prior written permission.
17 doda 6806 *
18 doda 6841 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21     * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 doda 6806 */
29 maya 3227
30     /* TERATERM.EXE, Clipboard routines */
31     #include "teraterm.h"
32     #include "tttypes.h"
33     #include "vtdisp.h"
34 doda 7140 #include "vtterm.h"
35 maya 3227 #include <string.h>
36     #include <stdlib.h>
37     #include <stdio.h>
38 yutakapon 3635 #include <commctrl.h>
39 doda 8445 #define _CRTDBG_MAP_ALLOC
40     #include <crtdbg.h>
41     #include <wchar.h>
42 maya 3227
43     #include "ttwinman.h"
44     #include "ttcommon.h"
45 doda 4769 #include "ttlib.h"
46 zmatsuo 7509 #include "dlglib.h"
47 doda 8445 #include "codeconv.h"
48 maya 3227
49     #include "clipboar.h"
50     #include "tt_res.h"
51 zmatsuo 8586 #include "fileread.h"
52 doda 8445 #include "sendmem.h"
53     #include "clipboarddlg.h"
54 maya 3227
55     // for clipboard paste
56     static HGLOBAL CBMemHandle = NULL;
57     static PCHAR CBMemPtr = NULL;
58     static LONG CBMemPtr2 = 0;
59     static BYTE CBByte;
60     static BOOL CBRetrySend;
61     static BOOL CBRetryEcho;
62     static BOOL CBSendCR;
63 doda 3974 static BOOL CBEchoOnly;
64 doda 5259 static BOOL CBInsertDelay = FALSE;
65 maya 3227
66 doda 8445 static const wchar_t BracketStartW[] = L"\033[200~";
67     static const wchar_t BracketEndW[] = L"\033[201~";
68 doda 6456
69 doda 8445 static void CBEcho(void);
70    
71     /**
72     * ���������M
73     * ���������������g�p����������
74     * - DDE(TTL)
75     * - �u���[�h�L���X�g
76     */
77 doda 6440 void CBStartSend(PCHAR DataPtr, int DataSize, BOOL EchoOnly)
78 maya 3227 {
79 doda 6440 if (! cv.Ready) {
80     return;
81     }
82     if (TalkStatus!=IdTalkKeyb) {
83     return;
84     }
85    
86     CBEchoOnly = EchoOnly;
87    
88 doda 6452 if (CBMemHandle) {
89     GlobalFree(CBMemHandle);
90     }
91 doda 6440 CBMemHandle = NULL;
92     CBMemPtr = NULL;
93     CBMemPtr2 = 0;
94    
95     CBInsertDelay = FALSE;
96    
97     CBRetrySend = FALSE;
98     CBRetryEcho = FALSE;
99     CBSendCR = FALSE;
100    
101 doda 6535 if ((CBMemHandle = GlobalAlloc(GHND, DataSize+1)) != NULL) {
102 doda 6440 if ((CBMemPtr = GlobalLock(CBMemHandle)) != NULL) {
103     memcpy(CBMemPtr, DataPtr, DataSize);
104 doda 6535 // WM_COPYDATA ���������������f�[�^�� NUL Terminate ���������������� NUL ���t������
105     CBMemPtr[DataSize] = 0;
106 doda 6440 GlobalUnlock(CBMemHandle);
107     CBMemPtr=NULL;
108     TalkStatus=IdTalkCB;
109     }
110     }
111     if (TalkStatus != IdTalkCB) {
112     CBEndPaste();
113     }
114     }
115    
116 doda 8445 static void TrimTrailingNLW(wchar_t *src)
117     {
118     wchar_t *tail = src + wcslen(src) - 1;
119     while(tail >= src) {
120     if (*tail != L'\r' && *tail != L'\n') {
121     break;
122     }
123     *tail = L'\0';
124     tail--;
125     }
126     }
127    
128 zmatsuo 8737 /**
129     * ���s�R�[�h�� CR+LF ����������
130     * @return ����������������
131     */
132 doda 8445 static wchar_t *NormalizeLineBreakW(const wchar_t *src_)
133     {
134     const wchar_t *src = src_;
135     wchar_t *dest_top;
136     wchar_t *dest;
137     size_t len, need_len, alloc_len;
138    
139     // �\���t���f�[�^������(len)�A���������K�������f�[�^������(need_len)���J�E���g
140     for (len=0, need_len=0, src=src_; *src != '\0'; src++, len++, need_len++) {
141     if (*src == CR) {
142     need_len++;
143     if (*(src+1) == LF) {
144     len++;
145     src++;
146     }
147     }
148     else if (*src == LF) {
149     need_len++;
150     }
151     }
152    
153     // ���K�������f�[�^�������������� => ���K�����K�v����
154     if (need_len == len) {
155     dest = _wcsdup(src_);
156     return dest;
157     }
158     alloc_len = need_len + 1;
159    
160     dest_top = (wchar_t *)malloc(sizeof(wchar_t) * alloc_len);
161    
162     src = src_ + len - 1;
163     dest = dest_top + need_len;
164     *dest-- = '\0';
165    
166     while (len > 0 && dest_top <= dest) {
167     if (*src == LF) {
168     *dest-- = *src--;
169     if (--len == 0) {
170     *dest = CR;
171     break;
172     }
173     if (*src != CR) {
174     *dest-- = CR;
175 zmatsuo 8737 continue;
176 doda 8445 }
177     }
178     else if (*src == CR) {
179     *dest-- = LF;
180     if (src == dest)
181     break;
182     }
183     *dest-- = *src--;
184     len--;
185     }
186    
187     return dest_top;
188     }
189    
190     /**
191     * �t�@�C�������`���������������Atext���������������������B
192     * ���������� TRUE������
193     */
194     static BOOL search_dictW(char *filename, const wchar_t *text)
195     {
196     BOOL result = FALSE;
197     const wchar_t *buf_top = LoadFileWA(filename, NULL);
198     const wchar_t *buf = buf_top;
199     if (buf == NULL) {
200     return FALSE;
201     }
202    
203     for(;;) {
204     const wchar_t *line_end;
205     size_t len;
206     wchar_t *search_str;
207     if (*buf == 0) {
208     break;
209     }
210     if (*buf == '\r' || *buf == '\n') {
211     buf++;
212     continue;
213     }
214     line_end = wcspbrk(buf, L"\r\n");
215     if (line_end == NULL) {
216     // ���s������
217     len = wcslen(buf);
218     if (len == 0) {
219     // �I��
220     break;
221     }
222     } else {
223     len = line_end - buf;
224     }
225     search_str = (wchar_t *)malloc(sizeof(wchar_t) * (len+1));
226     if (search_str == NULL)
227     continue;
228     memcpy(search_str, buf, sizeof(wchar_t) * len);
229     search_str[len] = 0;
230     buf += len;
231     result = (wcsstr(text, search_str) != NULL);
232     free(search_str);
233     if (result) {
234     result = TRUE;
235     break;
236     }
237     }
238     free((void *)buf_top);
239     return result;
240     }
241    
242 doda 6456 /*
243     * �N���b�v�{�[�h�����e���m�F���A�\���t�����s�����m�F�_�C�A���O���o���B
244     *
245     * �����l:
246     * TRUE -> ���������A�\���t�������{
247     * FALSE -> �\���t�����~
248     */
249 zmatsuo 8736 static BOOL CheckClipboardContentW(HWND HWin, const wchar_t *str_w, BOOL AddCR, wchar_t **out_str_w)
250 doda 6456 {
251 zmatsuo 8736 INT_PTR ret;
252 doda 6456 BOOL confirm = FALSE;
253    
254 zmatsuo 8736 *out_str_w = NULL;
255 doda 6594 if ((ts.PasteFlag & CPF_CONFIRM_CHANGEPASTE) == 0) {
256 doda 6456 return TRUE;
257     }
258    
259     /*
260     * ConfirmChangePasteCR ����������
261     * �����������������������B
262     *
263     * ChangePasteCR !ChangePasteCR
264     * AddCR !AddCR AddCR !AddCR
265     * ���s���� o o x(2) o
266     * ���s���� o(1) x x x
267     *
268     * ChangePasteCR �� AddCR �������m�F���s����(1���m�F����)���������������A
269     * !ChangePasteCR �������l�������AAddCR ���������� CR ����������������
270     * �m�F���s������������ 2 �����������m�F���s�p���������v�\�������������B
271     * 2 ����������������������?
272     */
273     if (AddCR) {
274 doda 6594 if (ts.PasteFlag & CPF_CONFIRM_CHANGEPASTE_CR) {
275 doda 6456 confirm = TRUE;
276     }
277     }
278     else {
279 doda 8445 size_t pos = wcscspn(str_w, L"\r\n"); // ���s����������������
280     if (str_w[pos] != '\0') {
281     confirm = TRUE;
282     }
283     }
284    
285     // �������T�[�`����
286     if (!confirm && search_dictW(ts.ConfirmChangePasteStringFile, str_w)) {
287     confirm = TRUE;
288     }
289    
290     ret = IDOK;
291     if (confirm) {
292     clipboarddlgdata dlg_data;
293     dlg_data.strW_ptr = str_w;
294     dlg_data.UILanguageFile = ts.UILanguageFile;
295     ret = clipboarddlg(hInst, HWin, &dlg_data);
296     *out_str_w = dlg_data.strW_edited_ptr;
297     }
298    
299     if (ret == IDOK) {
300     return TRUE;
301     }
302     else {
303     return FALSE;
304     }
305     }
306    
307     /**
308     * �N���b�v�{�[�h�p�e�L�X�g���M����
309     *
310     * @param str_w �����������|�C���^
311     * malloc()�������o�b�t�@�A���M��������������free()������
312     */
313 zmatsuo 8788 static void CBSendStart(wchar_t *str_w)
314 doda 8445 {
315 zmatsuo 8788 SendMem *sm = SendMemTextW(str_w, 0);
316 doda 8445 if (sm == NULL)
317     return;
318 zmatsuo 8588 if (ts.PasteDelayPerLine == 0) {
319     SendMemInitDelay(sm, SENDMEM_DELAYTYPE_NO_DELAY, 0, 0);
320 doda 8445 }
321 zmatsuo 8588 else {
322     SendMemInitDelay(sm, SENDMEM_DELAYTYPE_PER_LINE, ts.PasteDelayPerLine, 0);
323     }
324 doda 8445 #if 0
325     SendMemInitDialog(sm, hInst, HVTWin, ts.UILanguageFile);
326     SendMemInitDialogCaption(sm, L"from clipboard");
327     SendMemInitDialogFilename(sm, L"Clipboard");
328     #endif
329     SendMemStart(sm);
330     }
331    
332     void CBStartPaste(HWND HWin, BOOL AddCR, BOOL Bracketed)
333     {
334     // unsigned int StrLen = 0;
335     wchar_t *str_w;
336     wchar_t *str_w_edited;
337    
338     if (! cv.Ready) {
339     return;
340     }
341     if (TalkStatus!=IdTalkKeyb) {
342     return;
343     }
344    
345     CBEchoOnly = FALSE;
346    
347     str_w = GetClipboardTextW(HWin, FALSE);
348 zmatsuo 8796 if (str_w == NULL || !IsTextW(str_w, 0)) {
349 doda 8445 // �N���b�v�{�[�h����������������������������
350     CBEndPaste();
351     return;
352     }
353    
354     if (ts.PasteFlag & CPF_TRIM_TRAILING_NL) {
355     // �o�b�t�@���������s������
356     TrimTrailingNLW(str_w);
357     }
358    
359 zmatsuo 8459 {
360 doda 8445 // ���s�����K��
361     wchar_t *dest = NormalizeLineBreakW(str_w);
362     free(str_w);
363     str_w = dest;
364     }
365    
366     if (!CheckClipboardContentW(HWin, str_w, AddCR, &str_w_edited)) {
367 zmatsuo 8738 free(str_w);
368 doda 8445 CBEndPaste();
369     return;
370     }
371     if (str_w_edited != NULL) {
372     // �_�C�A���O�����W������
373     free(str_w);
374     str_w = str_w_edited;
375     }
376    
377     if (AddCR) {
378     size_t str_len = wcslen(str_w) + 2;
379     str_w = realloc(str_w, sizeof(wchar_t) * str_len);
380     str_w[str_len-2] = L'\r';
381     str_w[str_len-1] = 0;
382     }
383    
384     if (Bracketed) {
385     const size_t BracketStartLenW = _countof(BracketStartW) - 1;
386     const size_t BracketEndLenW = _countof(BracketEndW) - 1;
387     size_t str_len = wcslen(str_w);
388     size_t dest_len = str_len + BracketStartLenW + BracketEndLenW;
389     wchar_t *dest = malloc(sizeof(wchar_t) * (dest_len+1));
390     size_t i = 0;
391     wmemcpy(&dest[i], BracketStartW, BracketStartLenW);
392     i += BracketStartLenW;
393     wmemcpy(&dest[i], str_w, str_len);
394     i += str_len;
395     wmemcpy(&dest[i], BracketEndW, BracketEndLenW);
396     i += BracketEndLenW;
397     dest[i] = 0;
398     free(str_w);
399     str_w = dest;
400     }
401    
402 zmatsuo 8788 CBSendStart(str_w);
403 doda 8445 }
404    
405 doda 4769 void CBStartPasteB64(HWND HWin, PCHAR header, PCHAR footer)
406     {
407 doda 8445 size_t mb_len, b64_len, header_len = 0, footer_len = 0;
408     wchar_t *str_w = NULL;
409     char *str_mb = NULL;
410     char *str_b64 = NULL;
411    
412     if (! cv.Ready) {
413     return;
414     }
415     if (TalkStatus!=IdTalkKeyb) {
416     return;
417     }
418    
419     CBEchoOnly = FALSE;
420    
421     str_w = GetClipboardTextW(HWin, FALSE);
422 zmatsuo 8796 if (str_w == NULL || !IsTextW(str_w, 0)) {
423 doda 8445 // �N���b�v�{�[�h����������������������������
424     goto error;
425     }
426    
427     if (ts.Language == IdUtf8 || ts.KanjiCodeSend == IdUTF8) {
428     str_mb = ToU8W(str_w);
429     }
430     else {
431     str_mb = ToCharW(str_w);
432     }
433    
434     if (str_mb == NULL) {
435     goto error;
436     }
437    
438     if (header != NULL) {
439     header_len = strlen(header);
440     }
441     if (footer != NULL) {
442     footer_len = strlen(footer);
443     }
444    
445     mb_len = strlen(str_mb);
446     b64_len = (mb_len + 2) / 3 * 4 + header_len + footer_len + 1;
447    
448     if ((str_b64 = malloc(b64_len)) == NULL) {;
449     goto error;
450     }
451    
452     if (header_len > 0) {
453     strncpy_s(str_b64, b64_len, header, _TRUNCATE);
454     }
455    
456     b64encode(str_b64 + header_len, b64_len - header_len, str_mb, mb_len);
457    
458     if (footer_len > 0) {
459     strncat_s(str_b64, b64_len, footer, _TRUNCATE);
460     }
461    
462     free(str_w);
463     if ((str_w = ToWcharA(str_b64)) == NULL) {
464     goto error;
465     }
466    
467     free(str_mb);
468     free(str_b64);
469    
470     // �\���t�����������������o����
471 zmatsuo 8788 CBSendStart(str_w);
472 doda 8445
473     return;
474    
475     error:
476     free(str_w);
477     free(str_mb);
478     free(str_b64);
479     CBEndPaste();
480     return;
481     }
482    
483 maya 3227 // �����������N���b�v�{�[�h������DDE�f�[�^���[�������������B
484     //
485     // CBMemHandle�n���h�����O���[�o�������������A�����������I�������������A
486     // �����N���b�v�{�[�h������DDE�f�[�^�������������������������i�j�����������\�������j�B
487     // �����A�f�[�^���� null-terminate �����������������O�����������������A�������f�[�^����
488     // �����������B
489     // (2006.11.6 yutaka)
490     void CBSend()
491     {
492 maya 3393 int c;
493     BOOL EndFlag;
494 doda 3688 static DWORD lastcr;
495     DWORD now;
496 maya 3227
497 maya 3393 if (CBMemHandle==NULL) {
498     return;
499     }
500 maya 3227
501 doda 3974 if (CBEchoOnly) {
502     CBEcho();
503     return;
504     }
505    
506 doda 5259 if (CBInsertDelay) {
507     now = GetTickCount();
508     if (now - lastcr < (DWORD)ts.PasteDelayPerLine) {
509     return;
510     }
511 doda 3688 }
512    
513 maya 3393 if (CBRetrySend) {
514     CBRetryEcho = (ts.LocalEcho>0);
515     c = CommTextOut(&cv,(PCHAR)&CBByte,1);
516     CBRetrySend = (c==0);
517     if (CBRetrySend) {
518     return;
519     }
520     }
521 maya 3227
522 maya 3393 if (CBRetryEcho) {
523     c = CommTextEcho(&cv,(PCHAR)&CBByte,1);
524     CBRetryEcho = (c==0);
525     if (CBRetryEcho) {
526     return;
527     }
528     }
529 maya 3227
530 maya 4009 CBMemPtr = GlobalLock(CBMemHandle);
531     if (CBMemPtr==NULL) {
532 maya 3393 return;
533     }
534 maya 3227
535 maya 3393 do {
536     if (CBSendCR && (CBMemPtr[CBMemPtr2]==0x0a)) {
537     CBMemPtr2++;
538     // added PasteDelayPerLine (2009.4.12 maya)
539 doda 5259 if (CBInsertDelay) {
540 doda 3690 lastcr = now;
541     CBSendCR = FALSE;
542     SetTimer(HVTWin, IdPasteDelayTimer, ts.PasteDelayPerLine, NULL);
543     break;
544     }
545 maya 3393 }
546    
547     EndFlag = (CBMemPtr[CBMemPtr2]==0);
548 doda 6449 if (! EndFlag) {
549 maya 3393 CBByte = CBMemPtr[CBMemPtr2];
550     CBMemPtr2++;
551 maya 3227 // Decoding characters which are encoded by MACRO
552     // to support NUL character sending
553     //
554     // [encoded character] --> [decoded character]
555     // 01 01 --> 00
556     // 01 02 --> 01
557 maya 3393 if (CBByte==0x01) { /* 0x01 from MACRO */
558     CBByte = CBMemPtr[CBMemPtr2];
559     CBMemPtr2++;
560     CBByte = CBByte - 1; // character just after 0x01
561     }
562     }
563     else {
564     CBEndPaste();
565     return;
566     }
567 maya 3227
568 maya 3393 if (! EndFlag) {
569     c = CommTextOut(&cv,(PCHAR)&CBByte,1);
570     CBSendCR = (CBByte==0x0D);
571     CBRetrySend = (c==0);
572     if ((! CBRetrySend) &&
573     (ts.LocalEcho>0)) {
574     c = CommTextEcho(&cv,(PCHAR)&CBByte,1);
575     CBRetryEcho = (c==0);
576     }
577     }
578     else {
579     c=0;
580     }
581     }
582     while (c>0);
583 maya 3227
584 maya 4009 if (CBMemPtr!=NULL) {
585 maya 3393 GlobalUnlock(CBMemHandle);
586     CBMemPtr=NULL;
587     }
588 maya 3227 }
589    
590 doda 8445 static void CBEcho()
591 doda 3974 {
592     if (CBMemHandle==NULL) {
593     return;
594     }
595    
596     if (CBRetryEcho && CommTextEcho(&cv,(PCHAR)&CBByte,1) == 0) {
597     return;
598     }
599    
600     if ((CBMemPtr = GlobalLock(CBMemHandle)) == NULL) {
601     return;
602     }
603    
604     do {
605     if (CBSendCR && (CBMemPtr[CBMemPtr2]==0x0a)) {
606     CBMemPtr2++;
607     }
608    
609     if (CBMemPtr[CBMemPtr2] == 0) {
610     CBRetryEcho = FALSE;
611     CBEndPaste();
612     return;
613     }
614    
615     CBByte = CBMemPtr[CBMemPtr2];
616     CBMemPtr2++;
617    
618     // Decoding characters which are encoded by MACRO
619     // to support NUL character sending
620     //
621     // [encoded character] --> [decoded character]
622     // 01 01 --> 00
623     // 01 02 --> 01
624     if (CBByte==0x01) { /* 0x01 from MACRO */
625     CBByte = CBMemPtr[CBMemPtr2];
626     CBMemPtr2++;
627     CBByte = CBByte - 1; // character just after 0x01
628     }
629    
630     CBSendCR = (CBByte==0x0D);
631    
632     } while (CommTextEcho(&cv,(PCHAR)&CBByte,1) > 0);
633    
634     CBRetryEcho = TRUE;
635    
636     if (CBMemHandle != NULL) {
637     GlobalUnlock(CBMemHandle);
638     CBMemPtr=NULL;
639     }
640     }
641    
642 maya 3227 void CBEndPaste()
643     {
644 maya 3393 TalkStatus = IdTalkKeyb;
645 maya 3227
646 maya 3393 if (CBMemHandle!=NULL) {
647     if (CBMemPtr!=NULL) {
648     GlobalUnlock(CBMemHandle);
649     }
650 doda 6449 GlobalFree(CBMemHandle);
651 maya 3393 }
652 maya 3227
653 maya 3393 CBMemHandle = NULL;
654     CBMemPtr = NULL;
655     CBMemPtr2 = 0;
656 doda 3974 CBEchoOnly = FALSE;
657 doda 5259 CBInsertDelay = FALSE;
658 doda 8445 _CrtCheckMemory();
659 maya 3227 }
660    

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26