1/*
2 * Copyright (C) 2011 Igalia S.L.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "ArgumentCodersGtk.h"
28
29#include "DataReference.h"
30#include "ShareableBitmap.h"
31#include "WebCoreArgumentCoders.h"
32#include <WebCore/GraphicsContext.h>
33#include <WebCore/Image.h>
34#include <WebCore/SelectionData.h>
35#include <gtk/gtk.h>
36#include <wtf/glib/GUniquePtr.h>
37
38namespace IPC {
39using namespace WebCore;
40using namespace WebKit;
41
42static void encodeImage(Encoder& encoder, Image& image)
43{
44 RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(IntSize(image.size()), { });
45 bitmap->createGraphicsContext()->drawImage(image, IntPoint());
46
47 ShareableBitmap::Handle handle;
48 bitmap->createHandle(handle);
49
50 encoder << handle;
51}
52
53static bool decodeImage(Decoder& decoder, RefPtr<Image>& image)
54{
55 ShareableBitmap::Handle handle;
56 if (!decoder.decode(handle))
57 return false;
58
59 RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle);
60 if (!bitmap)
61 return false;
62 image = bitmap->createImage();
63 if (!image)
64 return false;
65 return true;
66}
67
68void ArgumentCoder<SelectionData>::encode(Encoder& encoder, const SelectionData& selection)
69{
70 bool hasText = selection.hasText();
71 encoder << hasText;
72 if (hasText)
73 encoder << selection.text();
74
75 bool hasMarkup = selection.hasMarkup();
76 encoder << hasMarkup;
77 if (hasMarkup)
78 encoder << selection.markup();
79
80 bool hasURL = selection.hasURL();
81 encoder << hasURL;
82 if (hasURL)
83 encoder << selection.url().string();
84
85 bool hasURIList = selection.hasURIList();
86 encoder << hasURIList;
87 if (hasURIList)
88 encoder << selection.uriList();
89
90 bool hasImage = selection.hasImage();
91 encoder << hasImage;
92 if (hasImage)
93 encodeImage(encoder, *selection.image());
94
95 bool hasUnknownTypeData = selection.hasUnknownTypeData();
96 encoder << hasUnknownTypeData;
97 if (hasUnknownTypeData)
98 encoder << selection.unknownTypes();
99
100 bool canSmartReplace = selection.canSmartReplace();
101 encoder << canSmartReplace;
102}
103
104bool ArgumentCoder<SelectionData>::decode(Decoder& decoder, SelectionData& selection)
105{
106 selection.clearAll();
107
108 bool hasText;
109 if (!decoder.decode(hasText))
110 return false;
111 if (hasText) {
112 String text;
113 if (!decoder.decode(text))
114 return false;
115 selection.setText(text);
116 }
117
118 bool hasMarkup;
119 if (!decoder.decode(hasMarkup))
120 return false;
121 if (hasMarkup) {
122 String markup;
123 if (!decoder.decode(markup))
124 return false;
125 selection.setMarkup(markup);
126 }
127
128 bool hasURL;
129 if (!decoder.decode(hasURL))
130 return false;
131 if (hasURL) {
132 String url;
133 if (!decoder.decode(url))
134 return false;
135 selection.setURL(URL(URL(), url), String());
136 }
137
138 bool hasURIList;
139 if (!decoder.decode(hasURIList))
140 return false;
141 if (hasURIList) {
142 String uriList;
143 if (!decoder.decode(uriList))
144 return false;
145 selection.setURIList(uriList);
146 }
147
148 bool hasImage;
149 if (!decoder.decode(hasImage))
150 return false;
151 if (hasImage) {
152 RefPtr<Image> image;
153 if (!decodeImage(decoder, image))
154 return false;
155 selection.setImage(image.get());
156 }
157
158 bool hasUnknownTypeData;
159 if (!decoder.decode(hasUnknownTypeData))
160 return false;
161 if (hasUnknownTypeData) {
162 HashMap<String, String> unknownTypes;
163 if (!decoder.decode(unknownTypes))
164 return false;
165
166 auto end = unknownTypes.end();
167 for (auto it = unknownTypes.begin(); it != end; ++it)
168 selection.setUnknownTypeData(it->key, it->value);
169 }
170
171 bool canSmartReplace;
172 if (!decoder.decode(canSmartReplace))
173 return false;
174 selection.setCanSmartReplace(canSmartReplace);
175
176 return true;
177}
178
179static void encodeGKeyFile(Encoder& encoder, GKeyFile* keyFile)
180{
181 gsize dataSize;
182 GUniquePtr<char> data(g_key_file_to_data(keyFile, &dataSize, 0));
183 encoder << DataReference(reinterpret_cast<uint8_t*>(data.get()), dataSize);
184}
185
186static bool decodeGKeyFile(Decoder& decoder, GUniquePtr<GKeyFile>& keyFile)
187{
188 DataReference dataReference;
189 if (!decoder.decode(dataReference))
190 return false;
191
192 if (!dataReference.size())
193 return true;
194
195 keyFile.reset(g_key_file_new());
196 if (!g_key_file_load_from_data(keyFile.get(), reinterpret_cast<const gchar*>(dataReference.data()), dataReference.size(), G_KEY_FILE_NONE, 0)) {
197 keyFile.reset();
198 return false;
199 }
200
201 return true;
202}
203
204void encode(Encoder& encoder, GtkPrintSettings* printSettings)
205{
206 GUniquePtr<GKeyFile> keyFile(g_key_file_new());
207 gtk_print_settings_to_key_file(printSettings, keyFile.get(), "Print Settings");
208 encodeGKeyFile(encoder, keyFile.get());
209}
210
211bool decode(Decoder& decoder, GRefPtr<GtkPrintSettings>& printSettings)
212{
213 GUniquePtr<GKeyFile> keyFile;
214 if (!decodeGKeyFile(decoder, keyFile))
215 return false;
216
217 printSettings = adoptGRef(gtk_print_settings_new());
218 if (!keyFile)
219 return true;
220
221 if (!gtk_print_settings_load_key_file(printSettings.get(), keyFile.get(), "Print Settings", 0))
222 printSettings = 0;
223
224 return printSettings;
225}
226
227void encode(Encoder& encoder, GtkPageSetup* pageSetup)
228{
229 GUniquePtr<GKeyFile> keyFile(g_key_file_new());
230 gtk_page_setup_to_key_file(pageSetup, keyFile.get(), "Page Setup");
231 encodeGKeyFile(encoder, keyFile.get());
232}
233
234bool decode(Decoder& decoder, GRefPtr<GtkPageSetup>& pageSetup)
235{
236 GUniquePtr<GKeyFile> keyFile;
237 if (!decodeGKeyFile(decoder, keyFile))
238 return false;
239
240 pageSetup = adoptGRef(gtk_page_setup_new());
241 if (!keyFile)
242 return true;
243
244 if (!gtk_page_setup_load_key_file(pageSetup.get(), keyFile.get(), "Page Setup", 0))
245 pageSetup = 0;
246
247 return pageSetup;
248}
249
250}
251