2 * GNOME Camera - Access camera devices on a system via D-Bus
3 * Copyright (C) 2014 Red Hat, Inc.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "gc-camera-client.h"
22 #include "cheese-avatar-chooser.h"
26 GDBusConnection
*connection
;
30 } GcCameraClientPrivate
;
32 static void gc_camera_client_client_iface_init (GcClientIface
*iface
);
33 static void gc_camera_client_initable_iface_init (GInitableIface
*iface
);
35 G_DEFINE_TYPE_WITH_CODE (GcCameraClient
, gc_camera_client
,
36 GC_TYPE_CLIENT_SKELETON
,
37 G_ADD_PRIVATE (GcCameraClient
)
38 G_IMPLEMENT_INTERFACE (GC_TYPE_CLIENT
, gc_camera_client_client_iface_init
)
39 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE
, gc_camera_client_initable_iface_init
))
50 static GParamSpec
*properties
[N_PROPERTIES
] = { NULL
, };
53 gc_camera_client_set_image_data_from_pixbuf (GcCameraClient
*self
,
56 GcCameraClientPrivate
*priv
;
60 priv
= gc_camera_client_get_instance_private (self
);
62 /* FIXME: Check for errors. */
63 if (!gdk_pixbuf_save_to_buffer (pixbuf
, &buffer
, &length
, "png", NULL
, NULL
))
65 g_error ("%s", "GdkPixbuf could not be saved to PNG format");
68 g_free (priv
->image_data
);
69 priv
->image_data
= g_base64_encode ((const guchar
*)buffer
, length
);
72 g_object_notify_by_pspec (G_OBJECT (self
), properties
[PROP_IMAGE_DATA
]);
76 on_chooser_response (CheeseAvatarChooser
*chooser
,
80 GcCameraClientPrivate
*priv
;
82 priv
= gc_camera_client_get_instance_private (self
);
84 if (response
== GTK_RESPONSE_ACCEPT
)
86 gc_camera_client_set_image_data_from_pixbuf (self
,
87 cheese_avatar_chooser_get_picture (chooser
));
88 gc_client_emit_user_done (GC_CLIENT (self
), TRUE
, priv
->image_data
);
92 gc_client_emit_user_done (GC_CLIENT (self
), FALSE
, priv
->image_data
);
95 /* FIXME: Destroy the chooser, as there is no way to stop the webcam
97 gtk_widget_hide (GTK_WIDGET (chooser
));
101 gc_camera_client_handle_show_chooser (GcClient
*client
,
102 GDBusMethodInvocation
*invocation
)
104 GcCameraClientPrivate
*priv
;
106 priv
= gc_camera_client_get_instance_private (GC_CAMERA_CLIENT (client
));
108 gtk_widget_show (priv
->chooser
);
110 gc_client_complete_show_chooser (client
, invocation
);
116 gc_camera_client_get_image_data (GcClient
*client
)
118 GcCameraClient
*self
;
119 GcCameraClientPrivate
*priv
;
121 self
= GC_CAMERA_CLIENT (client
);
122 priv
= gc_camera_client_get_instance_private (self
);
124 return priv
->image_data
;
128 gc_camera_client_get_path (GcCameraClient
*client
)
130 GcCameraClientPrivate
*priv
;
132 g_return_val_if_fail (GC_CAMERA_CLIENT (client
), NULL
);
134 priv
= gc_camera_client_get_instance_private (client
);
140 gc_camera_client_finalize (GObject
*object
)
142 GcCameraClientPrivate
*priv
;
144 priv
= gc_camera_client_get_instance_private (GC_CAMERA_CLIENT (object
));
146 g_clear_object (&priv
->chooser
);
147 g_clear_pointer (&priv
->image_data
, g_free
);
151 G_OBJECT_CLASS (gc_camera_client_parent_class
)->finalize (object
);
155 gc_camera_client_get_property (GObject
*object
,
160 GcCameraClientPrivate
*priv
;
162 priv
= gc_camera_client_get_instance_private (GC_CAMERA_CLIENT (object
));
166 case PROP_CONNECTION
:
167 g_value_set_object (value
, priv
->connection
);
170 g_value_set_string (value
, priv
->path
);
172 case PROP_IMAGE_DATA
:
173 g_value_set_string (value
, priv
->image_data
);
176 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
181 gc_camera_client_set_property (GObject
*object
,
186 GcCameraClientPrivate
*priv
;
188 priv
= gc_camera_client_get_instance_private (GC_CAMERA_CLIENT (object
));
192 case PROP_CONNECTION
:
193 priv
->connection
= g_value_dup_object (value
);
197 priv
->path
= g_value_dup_string (value
);
199 case PROP_IMAGE_DATA
:
200 g_free (priv
->image_data
);
201 priv
->image_data
= g_value_dup_string (value
);
204 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
209 gc_camera_client_class_init (GcCameraClientClass
*klass
)
211 GObjectClass
*object_class
;
213 object_class
= G_OBJECT_CLASS (klass
);
215 object_class
->finalize
= gc_camera_client_finalize
;
216 object_class
->get_property
= gc_camera_client_get_property
;
217 object_class
->set_property
= gc_camera_client_set_property
;
219 properties
[PROP_CONNECTION
] = g_param_spec_object ("connection",
222 G_TYPE_DBUS_CONNECTION
,
224 G_PARAM_CONSTRUCT_ONLY
|
225 G_PARAM_STATIC_STRINGS
);
226 g_object_class_install_property (object_class
, PROP_CONNECTION
,
227 properties
[PROP_CONNECTION
]);
229 properties
[PROP_PATH
] = g_param_spec_string ("path",
234 G_PARAM_CONSTRUCT_ONLY
|
235 G_PARAM_STATIC_STRINGS
);
236 g_object_class_install_property (object_class
, PROP_PATH
,
237 properties
[PROP_PATH
]);
239 properties
[PROP_IMAGE_DATA
] = g_param_spec_string ("image-data",
241 "PNG image data, Base64-encoded",
244 G_PARAM_STATIC_STRINGS
);
245 g_object_class_install_property (object_class
, PROP_IMAGE_DATA
,
246 properties
[PROP_IMAGE_DATA
]);
250 gc_camera_client_init (GcCameraClient
*self
)
252 GcCameraClientPrivate
*priv
;
254 priv
= gc_camera_client_get_instance_private (self
);
256 priv
->chooser
= cheese_avatar_chooser_new ();
258 g_signal_connect (priv
->chooser
, "response",
259 G_CALLBACK (on_chooser_response
), self
);
263 gc_camera_client_initable_init (GInitable
*initable
,
264 GCancellable
*cancellable
,
267 GcCameraClientPrivate
*priv
;
269 priv
= gc_camera_client_get_instance_private (GC_CAMERA_CLIENT (initable
));
271 return g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (initable
),
278 gc_camera_client_client_iface_init (GcClientIface
*iface
)
280 iface
->handle_show_chooser
= gc_camera_client_handle_show_chooser
;
281 iface
->get_image_data
= gc_camera_client_get_image_data
;
285 gc_camera_client_initable_iface_init (GInitableIface
*iface
)
287 iface
->init
= gc_camera_client_initable_init
;
291 gc_camera_client_new (GDBusConnection
*connection
,
295 return g_initable_new (GC_TYPE_CAMERA_CLIENT
, NULL
, error
, "connection",
296 connection
, "path", path
, NULL
);