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 8736 - (hide annotations) (download) (as text)
Sat Apr 25 15:58:34 2020 UTC (3 years, 11 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 14752 byte(s)
未使用コード削除

- UNICODE_INTERNAL_BUFFを見ないようにした
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 doda 6595
129 doda 8445 static wchar_t *NormalizeLineBreakW(const wchar_t *src_)
130     {
131     const wchar_t *src = src_;
132     wchar_t *dest_top;
133     wchar_t *dest;
134     size_t len, need_len, alloc_len;
135    
136     // �\���t���f�[�^������(len)�A���������K�������f�[�^������(need_len)���J�E���g
137     for (len=0, need_len=0, src=src_; *src != '\0'; src++, len++, need_len++) {
138     if (*src == CR) {
139     need_len++;
140     if (*(src+1) == LF) {
141     len++;
142     src++;
143     }
144     }
145     else if (*src == LF) {
146     need_len++;
147     }
148     }
149    
150     // ���K�������f�[�^�������������� => ���K�����K�v����
151     if (need_len == len) {
152     dest = _wcsdup(src_);
153     return dest;
154     }
155     alloc_len = need_len + 1;
156    
157     dest_top = (wchar_t *)malloc(sizeof(wchar_t) * alloc_len);
158    
159     src = src_ + len - 1;
160     dest = dest_top + need_len;
161     *dest-- = '\0';
162     len = need_len;
163    
164     while (len > 0 && dest_top <= dest) {
165     if (*src == LF) {
166     *dest-- = *src--;
167     if (--len == 0) {
168     *dest = CR;
169     break;
170     }
171     if (*src != CR) {
172     *dest-- = CR;
173     if (dest <= dest_top) {
174     break;
175     }
176     else {
177     continue;
178     }
179     }
180     }
181     else if (*src == CR) {
182     *dest-- = LF;
183     if (src == dest)
184     break;
185     }
186     *dest-- = *src--;
187     len--;
188     }
189    
190     return dest_top;
191     }
192    
193     /**
194     * �t�@�C�������`���������������Atext���������������������B
195     * ���������� TRUE������
196     */
197     static BOOL search_dictW(char *filename, const wchar_t *text)
198     {
199     BOOL result = FALSE;
200     const wchar_t *buf_top = LoadFileWA(filename, NULL);
201     const wchar_t *buf = buf_top;
202     if (buf == NULL) {
203     return FALSE;
204     }
205    
206     for(;;) {
207     const wchar_t *line_end;
208     size_t len;
209     wchar_t *search_str;
210     if (*buf == 0) {
211     break;
212     }
213     if (*buf == '\r' || *buf == '\n') {
214     buf++;
215     continue;
216     }
217     line_end = wcspbrk(buf, L"\r\n");
218     if (line_end == NULL) {
219     // ���s������
220     len = wcslen(buf);
221     if (len == 0) {
222     // �I��
223     break;
224     }
225     } else {
226     len = line_end - buf;
227     }
228     search_str = (wchar_t *)malloc(sizeof(wchar_t) * (len+1));
229     if (search_str == NULL)
230     continue;
231     memcpy(search_str, buf, sizeof(wchar_t) * len);
232     search_str[len] = 0;
233     buf += len;
234     result = (wcsstr(text, search_str) != NULL);
235     free(search_str);
236     if (result) {
237     result = TRUE;
238     break;
239     }
240     }
241     free((void *)buf_top);
242     return result;
243     }
244    
245 doda 6456 /*
246     * �N���b�v�{�[�h�����e���m�F���A�\���t�����s�����m�F�_�C�A���O���o���B
247     *
248     * �����l:
249     * TRUE -> ���������A�\���t�������{
250     * FALSE -> �\���t�����~
251     */
252 zmatsuo 8736 static BOOL CheckClipboardContentW(HWND HWin, const wchar_t *str_w, BOOL AddCR, wchar_t **out_str_w)
253 doda 6456 {
254 zmatsuo 8736 INT_PTR ret;
255 doda 6456 BOOL confirm = FALSE;
256    
257 zmatsuo 8736 *out_str_w = NULL;
258 doda 6594 if ((ts.PasteFlag & CPF_CONFIRM_CHANGEPASTE) == 0) {
259 doda 6456 return TRUE;
260     }
261    
262     /*
263     * ConfirmChangePasteCR ����������
264     * �����������������������B
265     *
266     * ChangePasteCR !ChangePasteCR
267     * AddCR !AddCR AddCR !AddCR
268     * ���s���� o o x(2) o
269     * ���s���� o(1) x x x
270     *
271     * ChangePasteCR �� AddCR �������m�F���s����(1���m�F����)���������������A
272     * !ChangePasteCR �������l�������AAddCR ���������� CR ����������������
273     * �m�F���s������������ 2 �����������m�F���s�p���������v�\�������������B
274     * 2 ����������������������?
275     */
276     if (AddCR) {
277 doda 6594 if (ts.PasteFlag & CPF_CONFIRM_CHANGEPASTE_CR) {
278 doda 6456 confirm = TRUE;
279     }
280     }
281     else {
282 doda 8445 size_t pos = wcscspn(str_w, L"\r\n"); // ���s����������������
283     if (str_w[pos] != '\0') {
284     confirm = TRUE;
285     }
286     }
287    
288     // �������T�[�`����
289     if (!confirm && search_dictW(ts.ConfirmChangePasteStringFile, str_w)) {
290     confirm = TRUE;
291     }
292    
293     ret = IDOK;
294     if (confirm) {
295     clipboarddlgdata dlg_data;
296     dlg_data.strW_ptr = str_w;
297     dlg_data.UILanguageFile = ts.UILanguageFile;
298     ret = clipboarddlg(hInst, HWin, &dlg_data);
299     *out_str_w = dlg_data.strW_edited_ptr;
300     }
301    
302     if (ret == IDOK) {
303     return TRUE;
304     }
305     else {
306     return FALSE;
307     }
308     }
309    
310     /**
311     * �N���b�v�{�[�h�p�e�L�X�g���M����
312     *
313     * @param str_w �����������|�C���^
314     * malloc()�������o�b�t�@�A���M��������������free()������
315     * @param str_len ������(wchar_t�P��)
316 zmatsuo 8456 * 0 �������� L'\0' ����
317 doda 8445 */
318     static void CBSendStart(wchar_t *str_w, size_t str_len)
319     {
320     SendMem *sm;
321     if (str_len == 0) {
322     str_len = wcslen(str_w);
323     }
324 zmatsuo 8456 sm = SendMemTextW(str_w, str_len);
325 doda 8445 if (sm == NULL)
326     return;
327 zmatsuo 8588 if (ts.PasteDelayPerLine == 0) {
328     SendMemInitDelay(sm, SENDMEM_DELAYTYPE_NO_DELAY, 0, 0);
329 doda 8445 }
330 zmatsuo 8588 else {
331     SendMemInitDelay(sm, SENDMEM_DELAYTYPE_PER_LINE, ts.PasteDelayPerLine, 0);
332     }
333 doda 8445 #if 0
334     SendMemInitDialog(sm, hInst, HVTWin, ts.UILanguageFile);
335     SendMemInitDialogCaption(sm, L"from clipboard");
336     SendMemInitDialogFilename(sm, L"Clipboard");
337     #endif
338     SendMemStart(sm);
339     }
340    
341     void CBStartPaste(HWND HWin, BOOL AddCR, BOOL Bracketed)
342     {
343     // unsigned int StrLen = 0;
344     wchar_t *str_w;
345     wchar_t *str_w_edited;
346    
347     if (! cv.Ready) {
348     return;
349     }
350     if (TalkStatus!=IdTalkKeyb) {
351     return;
352     }
353    
354     CBEchoOnly = FALSE;
355    
356     str_w = GetClipboardTextW(HWin, FALSE);
357     if (str_w == NULL) {
358     // �N���b�v�{�[�h����������������������������
359     CBEndPaste();
360     return;
361     }
362    
363     if (ts.PasteFlag & CPF_TRIM_TRAILING_NL) {
364     // �o�b�t�@���������s������
365     TrimTrailingNLW(str_w);
366     }
367    
368 zmatsuo 8459 {
369 doda 8445 // ���s�����K��
370     wchar_t *dest = NormalizeLineBreakW(str_w);
371     free(str_w);
372     str_w = dest;
373     }
374    
375     if (!CheckClipboardContentW(HWin, str_w, AddCR, &str_w_edited)) {
376     CBEndPaste();
377     return;
378     }
379     if (str_w_edited != NULL) {
380     // �_�C�A���O�����W������
381     free(str_w);
382     str_w = str_w_edited;
383     }
384    
385     if (AddCR) {
386     size_t str_len = wcslen(str_w) + 2;
387     str_w = realloc(str_w, sizeof(wchar_t) * str_len);
388     str_w[str_len-2] = L'\r';
389     str_w[str_len-1] = 0;
390     }
391    
392     if (Bracketed) {
393     const size_t BracketStartLenW = _countof(BracketStartW) - 1;
394     const size_t BracketEndLenW = _countof(BracketEndW) - 1;
395     size_t str_len = wcslen(str_w);
396     size_t dest_len = str_len + BracketStartLenW + BracketEndLenW;
397     wchar_t *dest = malloc(sizeof(wchar_t) * (dest_len+1));
398     size_t i = 0;
399     wmemcpy(&dest[i], BracketStartW, BracketStartLenW);
400     i += BracketStartLenW;
401     wmemcpy(&dest[i], str_w, str_len);
402     i += str_len;
403     wmemcpy(&dest[i], BracketEndW, BracketEndLenW);
404     i += BracketEndLenW;
405     dest[i] = 0;
406     free(str_w);
407     str_w = dest;
408     }
409    
410     CBSendStart(str_w, 0);
411     }
412    
413 doda 4769 void CBStartPasteB64(HWND HWin, PCHAR header, PCHAR footer)
414     {
415 doda 8445 size_t mb_len, b64_len, header_len = 0, footer_len = 0;
416     wchar_t *str_w = NULL;
417     char *str_mb = NULL;
418     char *str_b64 = NULL;
419    
420     if (! cv.Ready) {
421     return;
422     }
423     if (TalkStatus!=IdTalkKeyb) {
424     return;
425     }
426    
427     CBEchoOnly = FALSE;
428    
429     str_w = GetClipboardTextW(HWin, FALSE);
430     if (str_w == NULL) {
431     // �N���b�v�{�[�h����������������������������
432     goto error;
433     }
434    
435     if (ts.Language == IdUtf8 || ts.KanjiCodeSend == IdUTF8) {
436     str_mb = ToU8W(str_w);
437     }
438     else {
439     str_mb = ToCharW(str_w);
440     }
441    
442     if (str_mb == NULL) {
443     goto error;
444     }
445    
446     if (header != NULL) {
447     header_len = strlen(header);
448     }
449     if (footer != NULL) {
450     footer_len = strlen(footer);
451     }
452    
453     mb_len = strlen(str_mb);
454     b64_len = (mb_len + 2) / 3 * 4 + header_len + footer_len + 1;
455    
456     if ((str_b64 = malloc(b64_len)) == NULL) {;
457     goto error;
458     }
459    
460     if (header_len > 0) {
461     strncpy_s(str_b64, b64_len, header, _TRUNCATE);
462     }
463    
464     b64encode(str_b64 + header_len, b64_len - header_len, str_mb, mb_len);
465    
466     if (footer_len > 0) {
467     strncat_s(str_b64, b64_len, footer, _TRUNCATE);
468     }
469    
470     free(str_w);
471     if ((str_w = ToWcharA(str_b64)) == NULL) {
472     goto error;
473     }
474    
475     free(str_mb);
476     free(str_b64);
477    
478     // �\���t�����������������o����
479     CBSendStart(str_w, 0);
480    
481     return;
482    
483     error:
484     free(str_w);
485     free(str_mb);
486     free(str_b64);
487     CBEndPaste();
488     return;
489     }
490    
491 maya 3227 // �����������N���b�v�{�[�h������DDE�f�[�^���[�������������B
492     //
493     // CBMemHandle�n���h�����O���[�o�������������A�����������I�������������A
494     // �����N���b�v�{�[�h������DDE�f�[�^�������������������������i�j�����������\�������j�B
495     // �����A�f�[�^���� null-terminate �����������������O�����������������A�������f�[�^����
496     // �����������B
497     // (2006.11.6 yutaka)
498     void CBSend()
499     {
500 maya 3393 int c;
501     BOOL EndFlag;
502 doda 3688 static DWORD lastcr;
503     DWORD now;
504 maya 3227
505 maya 3393 if (CBMemHandle==NULL) {
506     return;
507     }
508 maya 3227
509 doda 3974 if (CBEchoOnly) {
510     CBEcho();
511     return;
512     }
513    
514 doda 5259 if (CBInsertDelay) {
515     now = GetTickCount();
516     if (now - lastcr < (DWORD)ts.PasteDelayPerLine) {
517     return;
518     }
519 doda 3688 }
520    
521 maya 3393 if (CBRetrySend) {
522     CBRetryEcho = (ts.LocalEcho>0);
523     c = CommTextOut(&cv,(PCHAR)&CBByte,1);
524     CBRetrySend = (c==0);
525     if (CBRetrySend) {
526     return;
527     }
528     }
529 maya 3227
530 maya 3393 if (CBRetryEcho) {
531     c = CommTextEcho(&cv,(PCHAR)&CBByte,1);
532     CBRetryEcho = (c==0);
533     if (CBRetryEcho) {
534     return;
535     }
536     }
537 maya 3227
538 maya 4009 CBMemPtr = GlobalLock(CBMemHandle);
539     if (CBMemPtr==NULL) {
540 maya 3393 return;
541     }
542 maya 3227
543 maya 3393 do {
544     if (CBSendCR && (CBMemPtr[CBMemPtr2]==0x0a)) {
545     CBMemPtr2++;
546     // added PasteDelayPerLine (2009.4.12 maya)
547 doda 5259 if (CBInsertDelay) {
548 doda 3690 lastcr = now;
549     CBSendCR = FALSE;
550     SetTimer(HVTWin, IdPasteDelayTimer, ts.PasteDelayPerLine, NULL);
551     break;
552     }
553 maya 3393 }
554    
555     EndFlag = (CBMemPtr[CBMemPtr2]==0);
556 doda 6449 if (! EndFlag) {
557 maya 3393 CBByte = CBMemPtr[CBMemPtr2];
558     CBMemPtr2++;
559 maya 3227 // Decoding characters which are encoded by MACRO
560     // to support NUL character sending
561     //
562     // [encoded character] --> [decoded character]
563     // 01 01 --> 00
564     // 01 02 --> 01
565 maya 3393 if (CBByte==0x01) { /* 0x01 from MACRO */
566     CBByte = CBMemPtr[CBMemPtr2];
567     CBMemPtr2++;
568     CBByte = CBByte - 1; // character just after 0x01
569     }
570     }
571     else {
572     CBEndPaste();
573     return;
574     }
575 maya 3227
576 maya 3393 if (! EndFlag) {
577     c = CommTextOut(&cv,(PCHAR)&CBByte,1);
578     CBSendCR = (CBByte==0x0D);
579     CBRetrySend = (c==0);
580     if ((! CBRetrySend) &&
581     (ts.LocalEcho>0)) {
582     c = CommTextEcho(&cv,(PCHAR)&CBByte,1);
583     CBRetryEcho = (c==0);
584     }
585     }
586     else {
587     c=0;
588     }
589     }
590     while (c>0);
591 maya 3227
592 maya 4009 if (CBMemPtr!=NULL) {
593 maya 3393 GlobalUnlock(CBMemHandle);
594     CBMemPtr=NULL;
595     }
596 maya 3227 }
597    
598 doda 8445 static void CBEcho()
599 doda 3974 {
600     if (CBMemHandle==NULL) {
601     return;
602     }
603    
604     if (CBRetryEcho && CommTextEcho(&cv,(PCHAR)&CBByte,1) == 0) {
605     return;
606     }
607    
608     if ((CBMemPtr = GlobalLock(CBMemHandle)) == NULL) {
609     return;
610     }
611    
612     do {
613     if (CBSendCR && (CBMemPtr[CBMemPtr2]==0x0a)) {
614     CBMemPtr2++;
615     }
616    
617     if (CBMemPtr[CBMemPtr2] == 0) {
618     CBRetryEcho = FALSE;
619     CBEndPaste();
620     return;
621     }
622    
623     CBByte = CBMemPtr[CBMemPtr2];
624     CBMemPtr2++;
625    
626     // Decoding characters which are encoded by MACRO
627     // to support NUL character sending
628     //
629     // [encoded character] --> [decoded character]
630     // 01 01 --> 00
631     // 01 02 --> 01
632     if (CBByte==0x01) { /* 0x01 from MACRO */
633     CBByte = CBMemPtr[CBMemPtr2];
634     CBMemPtr2++;
635     CBByte = CBByte - 1; // character just after 0x01
636     }
637    
638     CBSendCR = (CBByte==0x0D);
639    
640     } while (CommTextEcho(&cv,(PCHAR)&CBByte,1) > 0);
641    
642     CBRetryEcho = TRUE;
643    
644     if (CBMemHandle != NULL) {
645     GlobalUnlock(CBMemHandle);
646     CBMemPtr=NULL;
647     }
648     }
649    
650 maya 3227 void CBEndPaste()
651     {
652 maya 3393 TalkStatus = IdTalkKeyb;
653 maya 3227
654 maya 3393 if (CBMemHandle!=NULL) {
655     if (CBMemPtr!=NULL) {
656     GlobalUnlock(CBMemHandle);
657     }
658 doda 6449 GlobalFree(CBMemHandle);
659 maya 3393 }
660 maya 3227
661 maya 3393 CBMemHandle = NULL;
662     CBMemPtr = NULL;
663     CBMemPtr2 = 0;
664 doda 3974 CBEchoOnly = FALSE;
665 doda 5259 CBInsertDelay = FALSE;
666 doda 8445 _CrtCheckMemory();
667 maya 3227 }
668    

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