1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
3 * Copyright (c) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27 #if PY_VERSION_HEX < 0x03000000
29 static Pycairo_CAPI_t
*Pycairo_CAPI
;
34 #include <cairo-gobject.h>
36 /* Limit includes from PyGI to APIs which do not have link dependencies
37 * (pygobject.h and pygi-foreign-api.h) since _gi_cairo is built as a separate
38 * shared library that interacts with PyGI through a PyCapsule API at runtime.
40 #include <pygi-foreign-api.h>
41 #include "pygi-python-compat.h"
48 cairo_context_to_arg (PyObject
*value
,
49 GIInterfaceInfo
*interface_info
,
55 if (!PyObject_TypeCheck (value
, &PycairoContext_Type
)) {
56 PyErr_SetString (PyExc_TypeError
, "Expected cairo.Context");
60 cr
= PycairoContext_GET (value
);
65 if (transfer
!= GI_TRANSFER_NOTHING
)
66 cr
= cairo_reference (cr
);
73 cairo_context_from_arg (GIInterfaceInfo
*interface_info
,
77 cairo_t
*context
= (cairo_t
*) data
;
79 if (transfer
== GI_TRANSFER_NOTHING
)
80 cairo_reference (context
);
82 return PycairoContext_FromContext (context
, &PycairoContext_Type
, NULL
);
87 cairo_context_release (GIBaseInfo
*base_info
,
90 cairo_destroy ( (cairo_t
*) struct_
);
95 cairo_context_to_gvalue (GValue
*value
, PyObject
*obj
)
99 if (!PyObject_TypeCheck (obj
, &PycairoContext_Type
)) {
100 PyErr_SetString (PyExc_TypeError
, "Expected cairo.Context");
104 cr
= PycairoContext_GET (obj
);
109 /* PycairoContext_GET returns a borrowed reference, use set_boxed
110 * to add new ref to the context which will be managed by the GValue. */
111 g_value_set_boxed (value
, cr
);
116 cairo_context_from_gvalue (const GValue
*value
)
118 /* PycairoContext_FromContext steals a ref, so we dup it out of the GValue. */
119 cairo_t
*cr
= g_value_dup_boxed (value
);
124 return PycairoContext_FromContext (cr
, &PycairoContext_Type
, NULL
);
129 * cairo_surface_t marshaling
133 cairo_surface_to_arg (PyObject
*value
,
134 GIInterfaceInfo
*interface_info
,
138 cairo_surface_t
*surface
;
140 if (!PyObject_TypeCheck (value
, &PycairoSurface_Type
)) {
141 PyErr_SetString (PyExc_TypeError
, "Expected cairo.Surface");
145 surface
= ( (PycairoSurface
*) value
)->surface
;
147 PyErr_SetString (PyExc_ValueError
, "Surface instance wrapping a NULL surface");
151 if (transfer
!= GI_TRANSFER_NOTHING
)
152 surface
= cairo_surface_reference (surface
);
154 arg
->v_pointer
= surface
;
159 cairo_surface_from_arg (GIInterfaceInfo
*interface_info
,
163 cairo_surface_t
*surface
= (cairo_surface_t
*) data
;
165 if (transfer
== GI_TRANSFER_NOTHING
)
166 cairo_surface_reference (surface
);
168 return PycairoSurface_FromSurface (surface
, NULL
);
172 cairo_surface_release (GIBaseInfo
*base_info
,
175 cairo_surface_destroy ( (cairo_surface_t
*) struct_
);
180 cairo_surface_to_gvalue (GValue
*value
, PyObject
*obj
)
182 cairo_surface_t
*surface
;
184 if (!PyObject_TypeCheck (obj
, &PycairoSurface_Type
)) {
185 PyErr_SetString (PyExc_TypeError
, "Expected cairo.Surface");
189 surface
= ((PycairoSurface
*) obj
)->surface
;
194 /* surface is a borrowed reference, use set_boxed
195 * to add new ref to the context which will be managed by the GValue. */
196 g_value_set_boxed (value
, surface
);
201 cairo_surface_from_gvalue (const GValue
*value
)
203 /* PycairoSurface_FromSurface steals a ref, so we dup it out of the GValue. */
204 cairo_surface_t
*surface
= g_value_dup_boxed (value
);
209 return PycairoSurface_FromSurface (surface
, NULL
);
214 * cairo_path_t marshaling
217 static cairo_path_t
*
218 _cairo_path_copy (cairo_path_t
*path
) {
220 cairo_surface_t
*surface
;
223 surface
= cairo_image_surface_create (CAIRO_FORMAT_ARGB32
, 0, 0);
224 cr
= cairo_create (surface
);
225 cairo_append_path (cr
, path
);
226 copy
= cairo_copy_path (cr
);
228 cairo_surface_destroy (surface
);
234 cairo_path_to_arg (PyObject
*value
,
235 GIInterfaceInfo
*interface_info
,
241 if (!PyObject_TypeCheck (value
, &PycairoPath_Type
)) {
242 PyErr_SetString (PyExc_TypeError
, "Expected cairo.Path");
246 path
= ( (PycairoPath
*) value
)->path
;
248 PyErr_SetString (PyExc_ValueError
, "Path instance wrapping a NULL path");
252 if (transfer
!= GI_TRANSFER_NOTHING
)
253 path
= _cairo_path_copy (path
);
255 arg
->v_pointer
= path
;
260 cairo_path_from_arg (GIInterfaceInfo
*interface_info
,
264 cairo_path_t
*path
= (cairo_path_t
*) data
;
266 if (transfer
== GI_TRANSFER_NOTHING
) {
267 PyErr_SetString(PyExc_TypeError
, "Unsupported annotation (transfer none) for cairo.Path return");
271 return PycairoPath_FromPath (path
);
275 cairo_path_release (GIBaseInfo
*base_info
,
278 cairo_path_destroy ( (cairo_path_t
*) struct_
);
284 * cairo_font_face_t marshaling
288 cairo_font_face_to_gvalue (GValue
*value
, PyObject
*obj
)
290 cairo_font_face_t
*font_face
;
292 if (!PyObject_TypeCheck (obj
, &PycairoFontFace_Type
)) {
293 PyErr_SetString (PyExc_TypeError
, "Expected cairo.FontFace");
297 font_face
= ((PycairoFontFace
*) obj
)->font_face
;
302 g_value_set_boxed (value
, font_face
);
307 cairo_font_face_from_gvalue (const GValue
*value
)
309 cairo_font_face_t
*font_face
= g_value_dup_boxed (value
);
314 return PycairoFontFace_FromFontFace (font_face
);
319 * cairo_font_options_t marshaling
323 cairo_font_options_to_arg (PyObject
*value
,
324 GIInterfaceInfo
*interface_info
,
328 cairo_font_options_t
*font_options
;
330 if (!PyObject_TypeCheck (value
, &PycairoFontOptions_Type
)) {
331 PyErr_SetString (PyExc_TypeError
, "Expected cairo.FontOptions");
335 font_options
= ( (PycairoFontOptions
*) value
)->font_options
;
337 PyErr_SetString (PyExc_ValueError
, "FontOptions instance wrapping a NULL font_options");
341 if (transfer
!= GI_TRANSFER_NOTHING
)
342 font_options
= cairo_font_options_copy (font_options
);
344 arg
->v_pointer
= font_options
;
349 cairo_font_options_from_arg (GIInterfaceInfo
*interface_info
,
353 cairo_font_options_t
*font_options
= (cairo_font_options_t
*) data
;
355 if (transfer
== GI_TRANSFER_NOTHING
)
356 font_options
= cairo_font_options_copy (font_options
);
358 return PycairoFontOptions_FromFontOptions (font_options
);
362 cairo_font_options_release (GIBaseInfo
*base_info
,
365 cairo_font_options_destroy ( (cairo_font_options_t
*) struct_
);
371 * scaled_font_t marshaling
375 cairo_scaled_font_to_gvalue (GValue
*value
, PyObject
*obj
)
377 cairo_scaled_font_t
*scaled_font
;
379 if (!PyObject_TypeCheck (obj
, &PycairoScaledFont_Type
)) {
380 PyErr_SetString (PyExc_TypeError
, "Expected cairo.ScaledFont");
384 scaled_font
= ((PycairoScaledFont
*) obj
)->scaled_font
;
389 /* scaled_font is a borrowed reference, use set_boxed
390 * to add new ref to the context which will be managed by the GValue. */
391 g_value_set_boxed (value
, scaled_font
);
396 cairo_scaled_font_from_gvalue (const GValue
*value
)
398 /* PycairoScaledFont_FromScaledFont steals a ref, so we dup it out of the GValue. */
399 cairo_scaled_font_t
*scaled_font
= g_value_dup_boxed (value
);
404 return PycairoScaledFont_FromScaledFont (scaled_font
);
409 * cairo_pattern_t marshaling
413 cairo_pattern_to_gvalue (GValue
*value
, PyObject
*obj
)
415 cairo_pattern_t
*pattern
;
417 if (!PyObject_TypeCheck (obj
, &PycairoPattern_Type
)) {
418 PyErr_SetString (PyExc_TypeError
, "Expected cairo.Pattern");
422 pattern
= ((PycairoPattern
*) obj
)->pattern
;
427 /* pattern is a borrowed reference, use set_boxed
428 * to add new ref to the context which will be managed by the GValue. */
429 g_value_set_boxed (value
, pattern
);
434 cairo_pattern_from_gvalue (const GValue
*value
)
436 /* PycairoPattern_FromPattern steals a ref, so we dup it out of the GValue. */
437 cairo_pattern_t
*pattern
= g_value_dup_boxed (value
);
442 return PycairoPattern_FromPattern (pattern
, NULL
);
446 cairo_region_to_arg (PyObject
*value
,
447 GIInterfaceInfo
*interface_info
,
451 cairo_region_t
*region
;
453 if (!PyObject_TypeCheck (value
, &PycairoRegion_Type
)) {
454 PyErr_SetString (PyExc_TypeError
, "Expected cairo.Region");
458 region
= ( (PycairoRegion
*) value
)->region
;
460 PyErr_SetString (PyExc_ValueError
, "Region instance wrapping a NULL region");
464 if (transfer
!= GI_TRANSFER_NOTHING
)
465 region
= cairo_region_copy (region
);
467 arg
->v_pointer
= region
;
472 cairo_region_from_arg (GIInterfaceInfo
*interface_info
,
476 cairo_region_t
*region
= (cairo_region_t
*) data
;
478 if (transfer
== GI_TRANSFER_NOTHING
)
479 cairo_region_reference (region
);
481 return PycairoRegion_FromRegion (region
);
485 cairo_region_release (GIBaseInfo
*base_info
,
488 cairo_region_destroy ( (cairo_region_t
*) struct_
);
493 cairo_matrix_from_arg (GIInterfaceInfo
*interface_info
,
497 cairo_matrix_t
*matrix
= (cairo_matrix_t
*) data
;
499 if (transfer
!= GI_TRANSFER_NOTHING
) {
500 PyErr_SetString(PyExc_TypeError
, "Unsupported annotation (transfer full) for cairo.Matrix");
504 if (matrix
== NULL
) {
505 /* NULL in case of caller-allocates */
506 cairo_matrix_t temp
= {0};
507 return PycairoMatrix_FromMatrix (&temp
);
510 return PycairoMatrix_FromMatrix (matrix
);
514 cairo_matrix_to_arg (PyObject
*value
,
515 GIInterfaceInfo
*interface_info
,
519 cairo_matrix_t
*matrix
;
521 if (!PyObject_TypeCheck (value
, &PycairoMatrix_Type
)) {
522 PyErr_SetString (PyExc_TypeError
, "Expected cairo.Matrix");
526 matrix
= &(( (PycairoMatrix
*) value
)->matrix
);
528 arg
->v_pointer
= matrix
;
533 cairo_matrix_release (GIBaseInfo
*base_info
,
539 static PyMethodDef _gi_cairo_functions
[] = { {0,} };
540 PYGLIB_MODULE_START(_gi_cairo
, "_gi_cairo")
542 #if PY_VERSION_HEX < 0x03000000
548 if (Pycairo_CAPI
== NULL
)
549 return PYGLIB_MODULE_ERROR_RETURN
;
551 pygobject_init (3, 13, 2);
553 pygi_register_foreign_struct ("cairo",
556 cairo_matrix_from_arg
,
557 cairo_matrix_release
);
559 pygi_register_foreign_struct ("cairo",
561 cairo_context_to_arg
,
562 cairo_context_from_arg
,
563 cairo_context_release
);
565 pygi_register_foreign_struct ("cairo",
567 cairo_surface_to_arg
,
568 cairo_surface_from_arg
,
569 cairo_surface_release
);
571 pygi_register_foreign_struct ("cairo",
577 pygi_register_foreign_struct ("cairo",
579 cairo_font_options_to_arg
,
580 cairo_font_options_from_arg
,
581 cairo_font_options_release
);
583 pygi_register_foreign_struct ("cairo",
586 cairo_region_from_arg
,
587 cairo_region_release
);
589 pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_CONTEXT
,
590 cairo_context_from_gvalue
,
591 cairo_context_to_gvalue
);
593 pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_SURFACE
,
594 cairo_surface_from_gvalue
,
595 cairo_surface_to_gvalue
);
597 pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_FONT_FACE
,
598 cairo_font_face_from_gvalue
,
599 cairo_font_face_to_gvalue
);
601 pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_SCALED_FONT
,
602 cairo_scaled_font_from_gvalue
,
603 cairo_scaled_font_to_gvalue
);
605 pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_PATTERN
,
606 cairo_pattern_from_gvalue
,
607 cairo_pattern_to_gvalue
);