forked from aburch/simutrans
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclipboard_w32.cc
122 lines (105 loc) · 3.16 KB
/
clipboard_w32.cc
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
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/**
* Copyright (c) 2010 Knightly
*
* Clipboard functions for copy and paste of text
*
* This file is part of the Simutrans project under the artistic license.
* (see license.txt)
*/
#include <windows.h>
#include <string.h>
#include "simsys.h"
#include "display/simgraph.h"
#include "simdebug.h"
#include "dataobj/translator.h"
#define MAX_SIZE (4096)
static char buffer[MAX_SIZE] = "";
/**
* Copy text to the clipboard
* @param source : pointer to the start of the source text
* @param length : number of character bytes to copy
* @author Knightly
*/
void dr_copy(const char *source, size_t length)
{
// convert utf-8 strings into utf-16
assert( (length<<1)<MAX_SIZE );
utf16 *utf16_buffer = (utf16 *)buffer;
size_t utf16_count = 0;
utf16 char_code;
size_t offset = 0;
while( (char_code=utf8_to_utf16((const utf8*)(source+offset), &offset)) && offset<=length ) {
*utf16_buffer++ = char_code;
++utf16_count;
}
*utf16_buffer = 0;
source = buffer;
length = (utf16_count << 1) + 1;
// create a memory block and copy the text
HGLOBAL hText; // handle to the memory block for holding the text
char *pText; // pointer to the start of the memory block
if( (hText=GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,length+1)) && (pText=(char*)GlobalLock(hText)) ) {
while( (length--)>0 ) {
*pText++ = *source++;
}
*pText = 0;
GlobalUnlock(hText);
}
else {
if( hText ) {
GlobalFree(hText);
}
return;
}
// open the clipboard and set the clipboard data
if( OpenClipboard(NULL) ) {
if( EmptyClipboard() ) {
SetClipboardData(CF_UNICODETEXT, hText);
}
CloseClipboard();
}
}
/**
* Paste text from the clipboard
* @param target : pointer to the insertion position in the target text
* @param max_length : maximum number of character bytes which could be inserted
* @return number of character bytes actually inserted -> for cursor advancing
* @author Knightly
*/
size_t dr_paste(char *target, size_t max_length)
{
size_t inserted_length = 0;
HGLOBAL hText; // handle to the memory block for holding the text
const char *pText; // pointer to the start of the memory block
if( OpenClipboard(NULL) ) {
if( (hText=GetClipboardData(CF_UNICODETEXT)) && (pText=(const char*)GlobalLock(hText)) ) {
// convert clipboard text from utf-16 to utf-8
const utf16 *utf16_text = (const utf16 *)pText;
utf8 *utf8_buffer = (utf8 *)buffer;
size_t tmp_length = 0;
size_t byte_count;
while( *utf16_text && tmp_length+(byte_count=utf16_to_utf8(*utf16_text, utf8_buffer))<=max_length ) {
tmp_length += byte_count;
utf8_buffer += byte_count;
++utf16_text;
}
pText = buffer;
max_length = tmp_length;
inserted_length = max_length;
// move the text to free up space for inserting the clipboard content
char *target_old_end = target + strlen(target);
char *target_new_end = target_old_end + max_length;
while( target_old_end>=target ) {
*target_new_end-- = *target_old_end--;
}
// insert the clipboard content
while( (max_length--)>0 ) {
*target++ = *pText++;
}
GlobalUnlock(hText);
}
CloseClipboard();
}
// return the inserted length for cursor advancing
return inserted_length;
}