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 9048 - (hide annotations) (download) (as text)
Wed Dec 16 12:24:13 2020 UTC (3 years, 3 months ago) by nmaya
File MIME type: text/x-csrc
File size: 13637 byte(s)
ソースファイルの著作権表記の "最後の発行の年" を削除

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

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