[GTK] Add a GKeyFile especialization to GOwnPtr
[WebKit-https.git] / Source / WebKit2 / Shared / gtk / ArgumentCodersGtk.cpp
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/DataObjectGtk.h>
33 #include <WebCore/DragData.h>
34 #include <WebCore/GraphicsContext.h>
35 #include <WebCore/GtkVersioning.h>
36 #include <WebCore/PlatformContextCairo.h>
37 #include <wtf/gobject/GOwnPtr.h>
38
39 using namespace WebCore;
40 using namespace WebKit;
41
42 namespace CoreIPC {
43
44 static void encodeImage(ArgumentEncoder* encoder, const GdkPixbuf* pixbuf)
45 {
46     IntSize imageSize(gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf));
47     RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(imageSize, ShareableBitmap::SupportsAlpha);
48     OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext();
49
50     cairo_t* cr = graphicsContext->platformContext()->cr();
51     gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
52     cairo_paint(cr);
53
54     ShareableBitmap::Handle handle;
55     bitmap->createHandle(handle);
56
57     encoder->encode(handle);
58 }
59
60 static bool decodeImage(ArgumentDecoder* decoder, GRefPtr<GdkPixbuf>& pixbuf)
61 {
62     ShareableBitmap::Handle handle;
63     if (!decoder->decode(handle))
64         return false;
65
66     RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle);
67     if (!bitmap)
68         return false;
69
70     RefPtr<Image> image = bitmap->createImage();
71     if (!image)
72         return false;
73
74     cairo_surface_t* surface = image->nativeImageForCurrentFrame();
75     if (!surface)
76         return false;
77
78     pixbuf = adoptGRef(gdk_pixbuf_get_from_surface(surface, 0, 0,
79                                                    cairo_image_surface_get_width(surface),
80                                                    cairo_image_surface_get_height(surface)));
81     if (!pixbuf)
82         return false;
83
84     return true;
85 }
86
87 static void encodeDataObject(ArgumentEncoder* encoder, const DataObjectGtk* dataObject)
88 {
89     bool hasText = dataObject->hasText();
90     encoder->encode(hasText);
91     if (hasText)
92         encoder->encode(dataObject->text());
93
94     bool hasMarkup = dataObject->hasMarkup();
95     encoder->encode(hasMarkup);
96     if (hasMarkup)
97         encoder->encode(dataObject->markup());
98
99     bool hasURL = dataObject->hasURL();
100     encoder->encode(hasURL);
101     if (hasURL)
102         encoder->encode(dataObject->url().string());
103
104     bool hasURIList = dataObject->hasURIList();
105     encoder->encode(hasURIList);
106     if (hasURIList)
107         encoder->encode(dataObject->uriList());
108
109     bool hasImage = dataObject->hasImage();
110     encoder->encode(hasImage);
111     if (hasImage)
112         encodeImage(encoder, dataObject->image());
113 }
114
115 static bool decodeDataObject(ArgumentDecoder* decoder, RefPtr<DataObjectGtk>& dataObject)
116 {
117     RefPtr<DataObjectGtk> data = DataObjectGtk::create();
118
119     bool hasText;
120     if (!decoder->decode(hasText))
121         return false;
122     if (hasText) {
123         String text;
124         if (!decoder->decode(text))
125             return false;
126         data->setText(text);
127     }
128
129     bool hasMarkup;
130     if (!decoder->decode(hasMarkup))
131         return false;
132     if (hasMarkup) {
133         String markup;
134         if (!decoder->decode(markup))
135             return false;
136         data->setMarkup(markup);
137     }
138
139     bool hasURL;
140     if (!decoder->decode(hasURL))
141         return false;
142     if (hasURL) {
143         String url;
144         if (!decoder->decode(url))
145             return false;
146         data->setURL(KURL(KURL(), url), String());
147     }
148
149     bool hasURIList;
150     if (!decoder->decode(hasURIList))
151         return false;
152     if (hasURIList) {
153         String uriList;
154         if (!decoder->decode(uriList))
155             return false;
156         data->setURIList(uriList);
157     }
158
159     bool hasImage;
160     if (!decoder->decode(hasImage))
161         return false;
162     if (hasImage) {
163         GRefPtr<GdkPixbuf> image;
164         if (!decodeImage(decoder, image))
165             return false;
166         data->setImage(image.get());
167     }
168
169     dataObject = data;
170
171     return true;
172 }
173
174 void ArgumentCoder<DragData>::encode(ArgumentEncoder* encoder, const DragData& dragData)
175 {
176     encoder->encode(dragData.clientPosition());
177     encoder->encode(dragData.globalPosition());
178     encoder->encode(static_cast<uint64_t>(dragData.draggingSourceOperationMask()));
179     encoder->encode(static_cast<uint64_t>(dragData.flags()));
180
181     DataObjectGtk* platformData = dragData.platformData();
182     encoder->encode(static_cast<bool>(platformData));
183     if (platformData)
184         encodeDataObject(encoder, platformData);
185 }
186
187 bool ArgumentCoder<DragData>::decode(ArgumentDecoder* decoder, DragData& dragData)
188 {
189     IntPoint clientPosition;
190     if (!decoder->decode(clientPosition))
191         return false;
192
193     IntPoint globalPosition;
194     if (!decoder->decode(globalPosition))
195         return false;
196
197     uint64_t sourceOperationMask;
198     if (!decoder->decode(sourceOperationMask))
199         return false;
200
201     uint64_t flags;
202     if (!decoder->decode(flags))
203         return false;
204
205     bool hasPlatformData;
206     if (!decoder->decode(hasPlatformData))
207         return false;
208
209     RefPtr<DataObjectGtk> platformData;
210     if (hasPlatformData) {
211         if (!decodeDataObject(decoder, platformData))
212             return false;
213     }
214
215     dragData = DragData(platformData.release().leakRef(), clientPosition, globalPosition, static_cast<DragOperation>(sourceOperationMask),
216                         static_cast<DragApplicationFlags>(flags));
217
218     return true;
219 }
220
221 static void encodeGKeyFile(ArgumentEncoder* encoder, GKeyFile* keyFile)
222 {
223     gsize dataSize;
224     GOwnPtr<char> data(g_key_file_to_data(keyFile, &dataSize, 0));
225     DataReference dataReference(reinterpret_cast<uint8_t*>(data.get()), dataSize);
226     encoder->encode(dataReference);
227 }
228
229 static bool decodeGKeyFile(ArgumentDecoder* decoder, GOwnPtr<GKeyFile>& keyFile)
230 {
231     DataReference dataReference;
232     if (!decoder->decode(dataReference))
233         return false;
234
235     if (!dataReference.size())
236         return true;
237
238     keyFile.set(g_key_file_new());
239     if (!g_key_file_load_from_data(keyFile.get(), reinterpret_cast<const gchar*>(dataReference.data()), dataReference.size(), G_KEY_FILE_NONE, 0)) {
240         keyFile.clear();
241         return false;
242     }
243
244     return true;
245 }
246
247 void encode(ArgumentEncoder* encoder, GtkPrintSettings* printSettings)
248 {
249     GOwnPtr<GKeyFile> keyFile(g_key_file_new());
250     gtk_print_settings_to_key_file(printSettings, keyFile.get(), "Print Settings");
251     encodeGKeyFile(encoder, keyFile.get());
252 }
253
254 bool decode(ArgumentDecoder* decoder, GRefPtr<GtkPrintSettings>& printSettings)
255 {
256     GOwnPtr<GKeyFile> keyFile;
257     if (!decodeGKeyFile(decoder, keyFile))
258         return false;
259
260     printSettings = adoptGRef(gtk_print_settings_new());
261     if (!keyFile)
262         return true;
263
264     if (!gtk_print_settings_load_key_file(printSettings.get(), keyFile.get(), "Print Settings", 0))
265         printSettings = 0;
266
267     return printSettings;
268 }
269
270 void encode(ArgumentEncoder* encoder, GtkPageSetup* pageSetup)
271 {
272     GOwnPtr<GKeyFile> keyFile(g_key_file_new());
273     gtk_page_setup_to_key_file(pageSetup, keyFile.get(), "Page Setup");
274     encodeGKeyFile(encoder, keyFile.get());
275 }
276
277 bool decode(ArgumentDecoder* decoder, GRefPtr<GtkPageSetup>& pageSetup)
278 {
279     GOwnPtr<GKeyFile> keyFile;
280     if (!decodeGKeyFile(decoder, keyFile))
281         return false;
282
283     pageSetup = adoptGRef(gtk_page_setup_new());
284     if (!keyFile)
285         return true;
286
287     if (!gtk_page_setup_load_key_file(pageSetup.get(), keyFile.get(), "Page Setup", 0))
288         pageSetup = 0;
289
290     return pageSetup;
291 }
292
293 }