Fix for a crash which happened when a document couldn't be opened.
[AROS-Contrib.git] / vpdf / clipboard.c
blobdc1d29fde06c5b1c51e202a20ac9bb523689e58c
1 /*
2 * Multiview 3
4 * Copyright © 2007-2011 Ilkka Lehtoranta <ilkleht@yahoo.com>
5 * All rights reserved.
6 *
7 * $Id$
8 */
10 #warning "!!!!!!!REPLACE THIS WITH SOME SYSTEM SOLUTION!!!!!!!"
11 #define USE_INLINE_STDARG 1
13 #include <memory.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <devices/clipboard.h>
17 #if defined(__AROS__)
18 // FIXMDE: AROS
19 #define CODESET_UTF8 1
20 #include <clib/arossupport_protos.h>
21 #else
22 #include <libraries/charsets.h>
23 #endif
24 #include <libraries/locale.h>
25 #include <proto/alib.h>
26 #if !defined(__AROS__)
27 #include <proto/charsets.h>
28 #endif
29 #include <proto/datatypes.h>
30 #include <proto/dos.h>
31 #include <proto/exec.h>
32 #include <proto/iffparse.h>
33 #include <proto/intuition.h>
35 #define ID_FTXT MAKE_ID('F','T','X','T')
36 #define ID_CHRS MAKE_ID('C','H','R','S')
37 #define ID_UTF8 MAKE_ID('U','T','F','8')
40 STATIC APTR clipboard_open(void)
42 struct IOClipReq *io;
43 struct MsgPort *mp;
45 mp = CreateMsgPort();
47 if ((io = (struct IOClipReq *)CreateIORequest(mp,sizeof(struct IOClipReq))))
49 if (!(OpenDevice("clipboard.device", 0, (struct IORequest *)io, 0)))
51 return io;
53 DeleteIORequest((struct IORequest *)io);
56 DeleteMsgPort(mp);
57 return NULL;
61 STATIC void clipboard_close(struct IOClipReq *io)
63 if (io)
65 struct MsgPort *mp;
67 mp = io->io_Message.mn_ReplyPort;
69 CloseDevice((struct IORequest *)io);
70 DeleteIORequest((struct IORequest *)io);
71 DeleteMsgPort(mp);
76 STATIC ULONG clipboard_write_data(struct IOClipReq *io, CONST_APTR data, ULONG len)
78 LONG rc;
80 io->io_Command = CMD_WRITE;
81 io->io_Data = (APTR)data;
82 io->io_Length = len;
83 DoIO( (struct IORequest *)io);
85 if (io->io_Actual != len)
87 io->io_Error = 1;
90 rc = io->io_Error ? FALSE : TRUE;
91 return rc;
95 STATIC VOID clipboard_pad_text(struct IOClipReq *io, ULONG textlen)
97 if (textlen & 1) clipboard_write_data(io, "", 1);
101 STATIC ULONG clipboard_write_header_and_text(struct IOClipReq *io, CONST_STRPTR string, ULONG slen, ULONG ulen)
103 ULONG rc;
105 struct
107 ULONG form;
108 ULONG totalsize;
109 ULONG ftxt;
110 ULONG type;
111 ULONG strlen;
112 } iffheader;
114 io->io_Offset = 0;
115 io->io_Error = 0;
116 // io->io_ClipID = 0;
118 /* FIXME: For correct operation we should also store font name. Used font
119 * is relevant with guides written in Japanese for example.
122 iffheader.form = ID_FORM;
123 iffheader.totalsize = (slen & 1 ? slen + 1 : slen) + (ulen & 1 ? ulen + 1 : ulen) + 12 + 8;
124 iffheader.ftxt = ID_FTXT;
125 iffheader.type = ID_CHRS;
126 iffheader.strlen = slen;
128 rc = FALSE;
130 if (clipboard_write_data(io, &iffheader, sizeof(iffheader)))
132 if (clipboard_write_data(io, string, slen))
134 clipboard_pad_text(io, slen);
135 rc = TRUE;
139 return rc;
143 STATIC ULONG clipboard_write_utf8(struct IOClipReq *io, CONST_STRPTR utext, ULONG ulen)
145 ULONG rc;
147 struct
149 ULONG type;
150 ULONG strlen;
151 } utf8_header;
153 /* FIXME: For correct operation we should also store font name. Used font
154 * is relevant with guides written in Japanese for example.
157 utf8_header.type = ID_UTF8;
158 utf8_header.strlen = ulen;
160 rc = FALSE;
162 if (clipboard_write_data(io, &utf8_header, sizeof(utf8_header)))
164 if (clipboard_write_data(io, utext, ulen))
166 clipboard_pad_text(io, ulen);
167 rc = TRUE;
171 return rc;
174 STATIC VOID clipboard_finalize(struct IOClipReq *io)
176 io->io_Command = CMD_UPDATE;
177 DoIO((struct IORequest *)io);
180 static void clips_write(CONST_STRPTR stext, LONG slen, CONST_STRPTR utext, LONG ulen)
182 APTR ctx;
184 if ((ctx = clipboard_open()))
186 if (clipboard_write_header_and_text(ctx, stext, slen, ulen))
188 if (clipboard_write_utf8(ctx, utext, ulen))
193 clipboard_finalize(ctx);
194 clipboard_close(ctx);
198 //==============================================================================
199 // This function is fully automatic and is used for writing a single
200 // null-terminated buffer of text.
202 // codeset is either CODESET_LATIN1 or CODESET_UTF8
204 VOID clipboard_write_text(CONST_STRPTR string, ULONG codeset)
206 #if defined(__AROS__)
207 kprintf("[clipboard_write_text] not implemented\n");
208 // FIXME: AROS (maybe codesets.library)
209 #else
210 if (string)
212 struct Library *CharsetsBase = OpenLibrary("charsets.library", 52);
214 if (CharsetsBase)
216 CONST_STRPTR stext = stext, utext = utext;
217 STRPTR buf;
218 LONG slen = slen, ulen = ulen, buflen, srcmib, dstmib;
220 buflen = strlen(string) + 1;
222 if (codeset == CODESET_UTF8)
224 srcmib = MIBENUM_UTF_8;
225 dstmib = MIBENUM_SYSTEM;
226 ulen = buflen;
227 utext = string;
229 else // Some system default maybe, who knows
231 srcmib = MIBENUM_SYSTEM;
232 dstmib = MIBENUM_UTF_8;
233 slen = buflen;
234 stext = string;
237 ConvertTags((STRPTR)string, -1, NULL, -1, srcmib, dstmib, CST_GetDestBytes, (IPTR)&buflen, TAG_DONE);
238 buf = AllocTaskPooled(buflen);
240 if (buf)
242 if (codeset == CODESET_UTF8)
244 slen = buflen;
245 stext = buf;
247 else
249 ulen = buflen;
250 utext = buf;
253 ConvertTags((STRPTR)string, -1, buf, buflen, srcmib, dstmib, TAG_DONE);
255 clips_write(stext, slen - 1, utext, ulen - 1); // do not write terminating NULL
257 FreeTaskPooled(buf, buflen);
260 CloseLibrary(CharsetsBase);
263 #endif