-
Notifications
You must be signed in to change notification settings - Fork 0
/
StdClipboard.cpp
443 lines (306 loc) · 10.3 KB
/
StdClipboard.cpp
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
#include "StdFuncs.h"
#include <string.h>
#include "StdClipboard.h"
#include "StdWindow.h"
#ifdef __amigaos4__
#include <proto/textclip.h>
#elif defined(__amigaos__)
#include <proto/iffparse.h>
#define ID_FTXT MAKE_ID('F','T','X','T')
#define ID_CHRS MAKE_ID('C','H','R','S')
#elif defined(QT_GUI_LIB)
#include <QtWidgets/QApplication>
#include <QtGui/QClipboard>
#endif /* QT_GUI_LIB */
/* Written: Tuesday 06-Jul-2010 7:42 am */
TInt RClipboard::open(CWindow *a_poWindow)
{
TInt RetVal;
ASSERTM((a_poWindow != NULL), "RClipboard::open() => Window passed in is not open");
ASSERTM((a_poWindow->m_poWindow != NULL), "RClipboard::open() => Native window passed in is not open");
#if defined(__amigaos__) || defined(QT_GUI_LIB)
(void) a_poWindow;
#if defined(__amigaos__) && !defined(__amigaos4__)
RetVal = KErrGeneral;
if ((m_poHandle = AllocIFF()) != NULL)
{
if ((m_poHandle->iff_Stream = (ULONG) OpenClipboard(PRIMARY_CLIP)) != 0)
{
RetVal = KErrNone;
InitIFFasClip(m_poHandle);
}
}
#else /* ! defined(__amigaos__) && !defined(__amigaos4__) */
RetVal = KErrNone;
#endif /* ! defined(__amigaos__) && !defined(__amigaos4__) */
#else /* ! defined(__amigaos__) || defined(QT_GUI_LIB) */
RetVal = (OpenClipboard(a_poWindow->m_poWindow)) ? KErrNone : KErrGeneral;
if (RetVal != KErrNone)
{
Utils::info("RClipboard::open() => Unable to open clipboard");
}
#endif /* ! defined(__amigaos__) || defined(QT_GUI_LIB) */
return(RetVal);
}
/* Written: Tuesday 06-Jul-2010 7:44 am */
void RClipboard::close()
{
#if defined(__amigaos__) && !defined(__amigaos4__)
if (m_poHandle)
{
if (m_poHandle->iff_Stream)
{
CloseClipboard((ClipboardHandle *) m_poHandle->iff_Stream);
}
FreeIFF(m_poHandle);
}
#endif /* defined(__amigaos__) && !defined(__amigaos4__) */
#if defined(WIN32) && !defined(QT_GUI_LIB)
DEBUGCHECK(CloseClipboard(), "RClipboard::close() => Unable to close clipboard");
#endif /* if defined(WIN32) && !defined(QT_GUI_LIB) */
}
/* Written: Wednesday 07-Jul-2010 6:37 am */
const char *RClipboard::GetNextLine(TInt *a_piLength, TBool *a_bHasEOL)
{
const char *NextChar, *RetVal;
ASSERTM((m_pccGetData != NULL), "RClipboard::GetDataEnd() => GetDataStart() must be called first");
/* Assume we are going to return the current line and that it has no EOL characters */
NextChar = RetVal = m_pccCurrentGetData;
*a_bHasEOL = EFalse;
/* Find the end of the current line, being either NULL terminated or the EOL characters */
while ((*NextChar) && (*NextChar != 0x0d) && (*NextChar != 0x0a))
{
++NextChar;
}
/* Save the length for the calling code */
*a_piLength = (TInt) (NextChar - m_pccCurrentGetData);
/* Check for CR and LF characters and if present, note their presence and skip them */
if (*NextChar == 0x0d)
{
*a_bHasEOL = ETrue;
++NextChar;
}
if (*NextChar == 0x0a)
{
*a_bHasEOL = ETrue;
++NextChar;
}
/* If neither characters nor any EOL characters were found then we are at the end of the */
/* clipboard data so return that there are no more lines */
if (NextChar == RetVal)
{
RetVal = NULL;
}
/* Save the current position in the string for use in the next call */
m_pccCurrentGetData = NextChar;
return(RetVal);
}
/* Written: Thursday 08-Jul-2010 7:06 am */
int RClipboard::SetDataStart(size_t a_stMaxLength)
{
int RetVal;
/* Assume failure */
RetVal = KErrNoMemory;
#if defined(__amigaos__) || defined(QT_GUI_LIB)
/* Allocate a temporary buffer into which the client can write its data */
if ((m_pcSetData = new char[a_stMaxLength + 1]) != NULL)
{
RetVal = KErrNone;
m_stDataSize = a_stMaxLength;
/* Qt needs char * strings to be NULL terminated in order to convert them */
/* into a QString so we allocate an extra byte and terminate it here */
m_pcSetData[m_stDataSize] = '\0';
}
#else /* ! defined(__amigaos__) || defined(QT_GUI_LIB) */
/* Empty the clipboard of its previous contents, thus also taking ownership of it */
if (EmptyClipboard())
{
/* Allocate a global moveable memory block into which to copy the data being inserted, */
/* lock it temporarily into memory and copy the data into it. We allocate an extra */
/* byte to NULL terminate the memory block to indicate the end, or Windows will to do */
/* funny things to the end of the data, like overwriting an LF with a NULL terminator */
if ((m_poHandle = GlobalAlloc(GMEM_MOVEABLE, (a_stMaxLength + 1))) != NULL)
{
if ((m_pcSetData = (char *) GlobalLock(m_poHandle)) != NULL)
{
RetVal = KErrNone;
m_pcSetData[a_stMaxLength] = '\0';
}
else
{
Utils::info("RClipboard::SetDataStart() => Unable to copy clipboard data");
GlobalFree(m_poHandle);
m_poHandle = NULL;
}
}
else
{
Utils::info("RClipboard::SetDataStart() => Unable to allocate memory for clipboard");
}
}
else
{
Utils::info("RClipboard::SetDataStart() => Unable to claim ownership of clipboard");
}
#endif /* ! defined(__amigaos__) || defined(QT_GUI_LIB) */
return(RetVal);
}
/* Written: Saturday 10-Jul-2010 12:43 pm */
void RClipboard::AppendData(const char *a_pcData, TInt a_iOffset, size_t a_stLength)
{
ASSERTM((m_pcSetData != NULL), "RClipboard::AppendData() => SetDataStart() must be called first");
memcpy((m_pcSetData + a_iOffset), a_pcData, a_stLength);
}
/* Written: Saturday 10-Jul-2010 1:34 pm */
void RClipboard::SetDataEnd()
{
ASSERTM((m_pcSetData != NULL), "RClipboard::SetDataEnd() => SetDataStart() must be called first");
#ifdef __amigaos__
/* Write the block of data to the clipboard */
#ifdef __amigaos4__
DEBUGCHECK(WriteClipVector(m_pcSetData, m_stDataSize), "RClipboard::SetDataEnd() => Unable to write clipboard data");
#else /* ! __amigaos4__ */
ASSERTM((m_poHandle != NULL), "RClipboard::SetDataEnd() => open() must be called first");
if (OpenIFF(m_poHandle, IFFF_WRITE) == 0)
{
if (PushChunk(m_poHandle, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN) == 0)
{
if (PushChunk(m_poHandle, 0, ID_CHRS, IFFSIZE_UNKNOWN) == 0)
{
DEBUGCHECK((WriteChunkBytes(m_poHandle, m_pcSetData, m_stDataSize) == (LONG) m_stDataSize),
"RClipboard::SetDataEnd() => Unable to write clipboard data");
}
}
CloseIFF(m_poHandle);
}
#endif /* ! __amigaos4__ */
/* And free the temporary buffer */
delete [] m_pcSetData;
m_pcSetData = NULL;
#elif defined(QT_GUI_LIB)
ASSERTM((m_pcSetData[m_stDataSize] == '\0'), "RClipboard::SetDataEnd() => End of clipboard buffer has been overwritten");
/* Write the block of data to the clipboard */
QApplication::clipboard()->setText(m_pcSetData);
/* And free the temporary buffer */
delete [] m_pcSetData;
m_pcSetData = NULL;
#else /* ! QT_GUI_LIB */
ASSERTM((m_poHandle != NULL), "RClipboard::SetDataEnd() => SetDataStart() must be called first");
/* Unlock the block of memory we have been writing to */
DEBUGCHECK(GlobalUnlock(m_pcSetData), "RClipboard::SetDataEnd() => Unable to unlock global clipboard data");
/* And assign ownership of the memory block to the clipboard */
if (SetClipboardData(CF_TEXT, m_poHandle) != NULL)
{
m_poHandle = NULL;
}
else
{
Utils::info("RClipboard::SetDataEnd() => Unable to set clipboard data");
}
#endif /* ! QT_GUI_LIB */
}
/* Written: Tuesday 06-Jul-2010 7:47 am */
const char *RClipboard::GetDataStart(TEncoding a_eEncoding)
{
const char *RetVal;
/* Assume failure */
RetVal = NULL;
#ifdef __amigaos4__
(void) a_eEncoding;
ULONG Size;
/* Check to see if there is any plain text available on the clipboard and if so, get a ptr to it */
if (ReadClipVector((STRPTR *) &RetVal, &Size))
{
m_pccGetData = m_pccCurrentGetData = RetVal;
}
#elif defined(__amigaos__)
(void) a_eEncoding;
char *GetData;
LONG Result, Size;
ContextNode *Chunk;
ASSERTM((m_poHandle != NULL), "RClipboard::GetDataStart() => open() must be called first");
if (OpenIFF(m_poHandle, IFFF_READ) == 0)
{
if (StopChunk(m_poHandle, ID_FTXT, ID_CHRS) == 0)
{
if ((Result = ParseIFF(m_poHandle, IFFPARSE_SCAN)) == 0)
{
if ((Chunk = CurrentChunk(m_poHandle)) != NULL)
{
if ((Chunk->cn_Type == ID_FTXT) && (Chunk->cn_ID == ID_CHRS))
{
if ((GetData = AllocVec((Chunk->cn_Size + 1), 0)) != NULL)
{
if ((Size = ReadChunkBytes(m_poHandle, GetData, Chunk->cn_Size)) == Chunk->cn_Size)
{
GetData[Size] = '\0';
RetVal = m_pccGetData = m_pccCurrentGetData = GetData;
}
else
{
FreeVec(GetData);
}
}
}
}
}
}
if (!RetVal)
{
CloseIFF(m_poHandle);
}
}
#elif defined(QT_GUI_LIB)
/* The data returned by clipboard()->text() needs to be persistent for the life of the RClipboard class, */
/* so copy it into a temporary QByteArray. Also, the data must be returned in a format appropriate for */
/* the currently used encoding */
if (a_eEncoding == EEncoding8859)
{
m_oGetData = QApplication::clipboard()->text().toLatin1();
}
else
{
m_oGetData = QApplication::clipboard()->text().toLocal8Bit();
}
/* Now return a ptr to the start of the clipboard data */
RetVal = m_pccGetData = m_pccCurrentGetData = m_oGetData.constData();
#else /* ! QT_GUI_LIB */
(void) a_eEncoding;
HANDLE Handle;
/* Check to see if there is any plain text available on the clipboard and if so, get a handle to it */
if (IsClipboardFormatAvailable(CF_TEXT))
{
if ((Handle = GetClipboardData(CF_TEXT)) != NULL)
{
/* Lock the handle into memory and return a ptr to it */
if ((RetVal = m_pccGetData = m_pccCurrentGetData = (const char *) GlobalLock(Handle)) == NULL)
{
Utils::info("RClipboard::GetDataStart() => Unable to lock keyboard data into memory");
}
}
else
{
Utils::info("RClipboard::GetDataStart() => Unable to get handle to clipboard data");
}
}
else
{
Utils::info("RClipboard::GetDataStart() => No clipboard data available");
}
#endif /* ! __unix__ */
return(RetVal);
}
/* Written: Tuesday 06-Jul-2010 7:49 am */
void RClipboard::GetDataEnd()
{
ASSERTM((m_pccGetData != NULL), "RClipboard::GetDataEnd() => GetDataStart() must be called first");
#ifdef __amigaos4__
DisposeClipVector((STRPTR) m_pccGetData);
#elif defined(__amigaos__)
ASSERTM((m_poHandle != NULL), "RClipboard::GetDataEnd() => close() must be called first");
CloseIFF(m_poHandle);
#elif defined(WIN32) && !defined(QT_GUI_LIB)
GlobalUnlock((void *) m_pccGetData);
#endif /* defined(WIN32) && !defined(QT_GUI_LIB) */
m_pccGetData = NULL;
}