1 | /* graphene-gobject.c: Shared GObject types |
2 | * |
3 | * SPDX-License-Identifier: MIT |
4 | * |
5 | * Copyright 2014 Emmanuele Bassi |
6 | * |
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
8 | * of this software and associated documentation files (the "Software"), to deal |
9 | * in the Software without restriction, including without limitation the rights |
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
11 | * copies of the Software, and to permit persons to whom the Software is |
12 | * furnished to do so, subject to the following conditions: |
13 | * |
14 | * The above copyright notice and this permission notice shall be included in |
15 | * all copies or substantial portions of the Software. |
16 | * |
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
23 | * THE SOFTWARE. |
24 | */ |
25 | |
26 | /** |
27 | * SECTION:graphene-gobject |
28 | * @Title: GObject integration |
29 | * @short_description: Types for GObject properties and signals |
30 | * @Include: graphene-gobject.h |
31 | * |
32 | * Graphene optionally provides information for using its own types with |
33 | * GObject properties and signals. |
34 | * |
35 | * ## Using Graphene with GObject |
36 | * |
37 | * In order to discover at compile time if Graphene exposes type information |
38 | * for the GType type system, you need to check if the `graphene-gobject-1.0` |
39 | * pkg-config file exists. |
40 | * |
41 | * If you're using Meson to build your project, you can use a typical |
42 | * `dependency()` object, for instance: |
43 | * |
44 | * |[<!-- language="plain" --> |
45 | * graphene_dep = dependency('graphene-gobject-1.0') |
46 | * ]| |
47 | * |
48 | * If you're using Autotools to build your project, you can use the |
49 | * `PKG_CHECK_EXISTS` m4 macro, for instance: |
50 | * |
51 | * |[<!-- language="plain" --> |
52 | * PKG_CHECK_EXISTS([graphene-gobject-1.0], |
53 | * [action-if-found], |
54 | * [action-if-not-found] |
55 | * ]| |
56 | * |
57 | * All the types provided by Graphene are boxed types, which means you |
58 | * will have to use the #GBoxed API when dealing with #GValue, #GParamSpec, |
59 | * and signal marshallers. For instance, to install a property in a #GObject |
60 | * class that uses #graphene_rect_t, you can use: |
61 | * |
62 | * |[<!-- language="C" --> |
63 | * g_object_class_install_property (object_class, PROP_BOUNDS, |
64 | * g_param_spec_boxed ("bounds", "Bounds", "Bounds of an object", |
65 | * GRAPHENE_TYPE_RECT, |
66 | * G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); |
67 | * ]| |
68 | * |
69 | * You'll then need to use g_value_set_boxed() and g_value_get_boxed() |
70 | * in order to access the #graphene_rect_t pointer from the #GValue data |
71 | * structure. |
72 | * |
73 | * Whereas for creating a new signal that has a #graphene_point_t parameter |
74 | * you can use: |
75 | * |
76 | * |[<!-- language="C" --> |
77 | * signals[HIT_TEST] = |
78 | * g_signal_new ("hit-test", |
79 | * G_TYPE_FROM_CLASS (object_class), |
80 | * G_SIGNAL_RUN_LAST, |
81 | * 0, |
82 | * g_signal_accumulator_true_handled, NULL, |
83 | * marshal_BOOLEAN__BOXED, |
84 | * G_TYPE_BOOLEAN, 1, |
85 | * GRAPHENE_TYPE_POINT); |
86 | * ]| |
87 | * |
88 | * ## Using Graphene via GObject introspection |
89 | * |
90 | * When using Graphene with another language than C, the GObject Introspection |
91 | * bindings change the type names to the CamelCase version of the C name, minus |
92 | * the `_t` suffix; for instance: |
93 | * |
94 | * * #graphene_point_t becomes `GraphenePoint` |
95 | * * #graphene_point3d_t becomes `GraphenePoint3D` |
96 | * * #graphene_rect_t becomes `GrapheneRect` |
97 | * * #graphene_matrix_t becomes `GrapheneMatrix` |
98 | * |
99 | * There is no direct access for the low level #graphene_simd4f_t and |
100 | * #graphene_simd4x4f_t SIMD types. |
101 | */ |
102 | |
103 | #include "config.h" |
104 | |
105 | #include "graphene-gobject.h" |
106 | |
107 | #define GRAPHENE_ENUM_VALUE(EnumValue, EnumNick) { EnumValue, #EnumValue, EnumNick }, |
108 | |
109 | #define GRAPHENE_DEFINE_ENUM_TYPE(TypeName, type_name, values) \ |
110 | GType \ |
111 | type_name ## _get_type (void) \ |
112 | { \ |
113 | static volatile gsize graphene_define_id__volatile = 0; \ |
114 | if (g_once_init_enter (&graphene_define_id__volatile)) \ |
115 | { \ |
116 | static const GEnumValue v[] = { \ |
117 | values \ |
118 | { 0, NULL, NULL }, \ |
119 | }; \ |
120 | GType graphene_define_id = \ |
121 | g_enum_register_static (g_intern_static_string (#TypeName), v); \ |
122 | g_once_init_leave (&graphene_define_id__volatile, graphene_define_id); \ |
123 | } \ |
124 | return graphene_define_id__volatile; \ |
125 | } |
126 | |
127 | #define GRAPHENE_DEFINE_BOXED_TYPE(TypeName, type_name) \ |
128 | static type_name ## _t * \ |
129 | type_name ## _copy_internal (type_name ## _t * v) \ |
130 | { \ |
131 | type_name ## _t * res = NULL; \ |
132 | if (G_LIKELY (v != NULL)) \ |
133 | { \ |
134 | res = type_name ## _alloc (); \ |
135 | *res = *v; \ |
136 | } \ |
137 | return res; \ |
138 | } \ |
139 | \ |
140 | GType \ |
141 | type_name ## _get_type (void) \ |
142 | { \ |
143 | static volatile gsize graphene_define_id__volatile = 0; \ |
144 | if (g_once_init_enter (&graphene_define_id__volatile)) \ |
145 | { \ |
146 | GType graphene_define_id = \ |
147 | g_boxed_type_register_static (g_intern_static_string (#TypeName), \ |
148 | (GBoxedCopyFunc) type_name ## _copy_internal, \ |
149 | (GBoxedFreeFunc) type_name ## _free); \ |
150 | g_once_init_leave (&graphene_define_id__volatile, graphene_define_id); \ |
151 | } \ |
152 | return graphene_define_id__volatile; \ |
153 | } |
154 | |
155 | GRAPHENE_DEFINE_BOXED_TYPE (GraphenePoint, graphene_point) |
156 | |
157 | GRAPHENE_DEFINE_BOXED_TYPE (GraphenePoint3D, graphene_point3d) |
158 | |
159 | GRAPHENE_DEFINE_BOXED_TYPE (GrapheneSize, graphene_size) |
160 | |
161 | GRAPHENE_DEFINE_BOXED_TYPE (GrapheneRect, graphene_rect) |
162 | |
163 | GRAPHENE_DEFINE_BOXED_TYPE (GrapheneVec2, graphene_vec2) |
164 | |
165 | GRAPHENE_DEFINE_BOXED_TYPE (GrapheneVec3, graphene_vec3) |
166 | |
167 | GRAPHENE_DEFINE_BOXED_TYPE (GrapheneVec4, graphene_vec4) |
168 | |
169 | GRAPHENE_DEFINE_BOXED_TYPE (GrapheneQuad, graphene_quad) |
170 | |
171 | GRAPHENE_DEFINE_BOXED_TYPE (GrapheneQuaternion, graphene_quaternion) |
172 | |
173 | GRAPHENE_DEFINE_BOXED_TYPE (GrapheneMatrix, graphene_matrix) |
174 | |
175 | GRAPHENE_DEFINE_BOXED_TYPE (GraphenePlane, graphene_plane) |
176 | |
177 | GRAPHENE_DEFINE_BOXED_TYPE (GrapheneFrustum, graphene_frustum) |
178 | |
179 | GRAPHENE_DEFINE_BOXED_TYPE (GrapheneSphere, graphene_sphere) |
180 | |
181 | GRAPHENE_DEFINE_BOXED_TYPE (GrapheneBox, graphene_box) |
182 | |
183 | GRAPHENE_DEFINE_BOXED_TYPE (GrapheneTriangle, graphene_triangle) |
184 | |
185 | GRAPHENE_DEFINE_BOXED_TYPE (GrapheneEuler, graphene_euler) |
186 | |
187 | GRAPHENE_DEFINE_BOXED_TYPE (GrapheneRay, graphene_ray) |
188 | |