1 /* GSequencer - Advanced GTK Sequencer
2  * Copyright (C) 2005-2019 Joël Krähemann
3  *
4  * This file is part of GSequencer.
5  *
6  * GSequencer is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GSequencer is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSequencer.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <ags/audio/osc/ags_osc_response.h>
21 
22 #include <ags/audio/osc/ags_osc_message.h>
23 
24 #include <stdlib.h>
25 
26 #include <ags/i18n.h>
27 
28 void ags_osc_response_class_init(AgsOscResponseClass *osc_response);
29 void ags_osc_response_init(AgsOscResponse *osc_response);
30 void ags_osc_response_set_property(GObject *gobject,
31 				   guint prop_id,
32 				   const GValue *value,
33 				   GParamSpec *param_spec);
34 void ags_osc_response_get_property(GObject *gobject,
35 				   guint prop_id,
36 				   GValue *value,
37 				   GParamSpec *param_spec);
38 void ags_osc_response_dispose(GObject *gobject);
39 void ags_osc_response_finalize(GObject *gobject);
40 
41 /**
42  * SECTION:ags_osc_response
43  * @short_description: the OSC server side response
44  * @title: AgsOscResponse
45  * @section_id:
46  * @include: ags/audio/osc/ags_osc_response.h
47  *
48  * #AgsOscResponse your OSC server side response.
49  */
50 
51 enum{
52   PROP_0,
53   PROP_PACKET,
54   PROP_PACKET_SIZE,
55   PROP_ERROR_MESSAGE,
56   PROP_OSC_MESSAGE,
57 };
58 
59 static gpointer ags_osc_response_parent_class = NULL;
60 
61 GType
ags_osc_response_get_type(void)62 ags_osc_response_get_type(void)
63 {
64   static volatile gsize g_define_type_id__volatile = 0;
65 
66   if(g_once_init_enter (&g_define_type_id__volatile)){
67     GType ags_type_osc_response = 0;
68 
69     static const GTypeInfo ags_osc_response_info = {
70       sizeof (AgsOscResponseClass),
71       NULL, /* base_init */
72       NULL, /* base_finalize */
73       (GClassInitFunc) ags_osc_response_class_init,
74       NULL, /* class_finalize */
75       NULL, /* class_data */
76       sizeof (AgsOscResponse),
77       0,    /* n_preallocs */
78       (GInstanceInitFunc) ags_osc_response_init,
79     };
80 
81     ags_type_osc_response = g_type_register_static(G_TYPE_OBJECT,
82 						   "AgsOscResponse", &ags_osc_response_info,
83 						   0);
84 
85     g_once_init_leave(&g_define_type_id__volatile, ags_type_osc_response);
86   }
87 
88   return g_define_type_id__volatile;
89 }
90 
91 void
ags_osc_response_class_init(AgsOscResponseClass * osc_response)92 ags_osc_response_class_init(AgsOscResponseClass *osc_response)
93 {
94   GObjectClass *gobject;
95 
96   GParamSpec *param_spec;
97 
98   ags_osc_response_parent_class = g_type_class_peek_parent(osc_response);
99 
100   /* GObjectClass */
101   gobject = (GObjectClass *) osc_response;
102 
103   gobject->set_property = ags_osc_response_set_property;
104   gobject->get_property = ags_osc_response_get_property;
105 
106   gobject->dispose = ags_osc_response_dispose;
107   gobject->finalize = ags_osc_response_finalize;
108 
109   /* properties */
110   /**
111    * AgsOscResponse:packet:
112    *
113    * The response packet.
114    *
115    * Since: 3.0.0
116    */
117   param_spec = g_param_spec_pointer("packet",
118 				    i18n_pspec("response packet"),
119 				    i18n_pspec("The response packet"),
120 				    G_PARAM_READABLE | G_PARAM_WRITABLE);
121   g_object_class_install_property(gobject,
122 				  PROP_PACKET,
123 				  param_spec);
124 
125   /**
126    * AgsOscResponse:packet-size:
127    *
128    * The response packet's size.
129    *
130    * Since: 3.0.0
131    */
132   param_spec = g_param_spec_uint("packet-size",
133 				 i18n_pspec("response packet size"),
134 				 i18n_pspec("The response packet size"),
135 				 0,
136 				 G_MAXUINT,
137 				 0,
138 				 G_PARAM_READABLE | G_PARAM_WRITABLE);
139   g_object_class_install_property(gobject,
140 				  PROP_PACKET_SIZE,
141 				  param_spec);
142 
143   /**
144    * AgsOscResponse:error-message:
145    *
146    * The error message.
147    *
148    * Since: 3.0.0
149    */
150   param_spec = g_param_spec_string("error-message",
151 				   i18n_pspec("error message"),
152 				   i18n_pspec("The error message"),
153 				   NULL,
154 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
155   g_object_class_install_property(gobject,
156 				  PROP_ERROR_MESSAGE,
157 				  param_spec);
158 
159   /**
160    * AgsOscResponse:osc-message:
161    *
162    * The assigned #AgsOscMessage
163    *
164    * Since: 3.0.0
165    */
166   param_spec = g_param_spec_object("osc-message",
167 				   i18n("assigned OSC message"),
168 				   i18n("The assigned OSC message"),
169 				   AGS_TYPE_OSC_MESSAGE,
170 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
171   g_object_class_install_property(gobject,
172 				  PROP_OSC_MESSAGE,
173 				  param_spec);
174 }
175 
176 void
ags_osc_response_init(AgsOscResponse * osc_response)177 ags_osc_response_init(AgsOscResponse *osc_response)
178 {
179   osc_response->flags = 0;
180 
181   /* osc response mutex */
182   g_rec_mutex_init(&(osc_response->obj_mutex));
183 
184   osc_response->packet = NULL;
185   osc_response->packet_size = 0;
186 
187   osc_response->error_message = NULL;
188 
189   osc_response->osc_message = NULL;
190 
191   osc_response->creation_time = NULL;
192 }
193 
194 void
ags_osc_response_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)195 ags_osc_response_set_property(GObject *gobject,
196 			      guint prop_id,
197 			      const GValue *value,
198 			      GParamSpec *param_spec)
199 {
200   AgsOscResponse *osc_response;
201 
202   GRecMutex *osc_response_mutex;
203 
204   osc_response = AGS_OSC_RESPONSE(gobject);
205 
206   /* get osc response mutex */
207   osc_response_mutex = AGS_OSC_RESPONSE_GET_OBJ_MUTEX(osc_response);
208 
209   switch(prop_id){
210   case PROP_PACKET:
211     {
212       gpointer packet;
213 
214       packet = g_value_get_pointer(value);
215 
216       g_rec_mutex_lock(osc_response_mutex);
217 
218       if(osc_response->packet == packet){
219 	g_rec_mutex_unlock(osc_response_mutex);
220 
221 	return;
222       }
223 
224       osc_response->packet = packet;
225 
226       g_rec_mutex_unlock(osc_response_mutex);
227     }
228     break;
229   case PROP_PACKET_SIZE:
230     {
231       guint packet_size;
232 
233       packet_size = g_value_get_uint(value);
234 
235       g_rec_mutex_lock(osc_response_mutex);
236 
237       osc_response->packet_size = packet_size;
238 
239       g_rec_mutex_unlock(osc_response_mutex);
240     }
241     break;
242   case PROP_ERROR_MESSAGE:
243     {
244       gchar *error_message;
245 
246       error_message = g_value_get_string(value);
247 
248       g_rec_mutex_lock(osc_response_mutex);
249 
250       if(osc_response->error_message == error_message){
251 	g_rec_mutex_unlock(osc_response_mutex);
252 
253 	return;
254       }
255 
256       g_free(osc_response->error_message);
257 
258       osc_response->error_message = g_strdup(error_message);
259 
260       g_rec_mutex_unlock(osc_response_mutex);
261     }
262     break;
263   case PROP_OSC_MESSAGE:
264   {
265     AgsOscMessage *osc_message;
266 
267     osc_message = (AgsOscMessage *) g_value_get_object(value);
268 
269     g_rec_mutex_lock(osc_response_mutex);
270 
271     if(osc_response->osc_message == (GObject *) osc_message){
272       g_rec_mutex_unlock(osc_response_mutex);
273 
274       return;
275     }
276 
277     if(osc_response->osc_message != NULL){
278       g_object_unref(G_OBJECT(osc_response->osc_message));
279     }
280 
281     if(osc_message != NULL){
282       g_object_ref(G_OBJECT(osc_message));
283     }
284 
285     osc_response->osc_message = (GObject *) osc_message;
286 
287     g_rec_mutex_unlock(osc_response_mutex);
288   }
289   break;
290   default:
291     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
292     break;
293   }
294 }
295 
296 void
ags_osc_response_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)297 ags_osc_response_get_property(GObject *gobject,
298 			      guint prop_id,
299 			      GValue *value,
300 			      GParamSpec *param_spec)
301 {
302   AgsOscResponse *osc_response;
303 
304   GRecMutex *osc_response_mutex;
305 
306   osc_response = AGS_OSC_RESPONSE(gobject);
307 
308   /* get osc response mutex */
309   osc_response_mutex = AGS_OSC_RESPONSE_GET_OBJ_MUTEX(osc_response);
310 
311   switch(prop_id){
312   case PROP_PACKET:
313     {
314       g_rec_mutex_lock(osc_response_mutex);
315 
316       g_value_set_pointer(value, osc_response->packet);
317 
318       g_rec_mutex_unlock(osc_response_mutex);
319     }
320     break;
321   case PROP_PACKET_SIZE:
322     {
323       g_rec_mutex_lock(osc_response_mutex);
324 
325       g_value_set_uint(value,
326 		       osc_response->packet_size);
327 
328       g_rec_mutex_unlock(osc_response_mutex);
329     }
330     break;
331   case PROP_ERROR_MESSAGE:
332     {
333       g_rec_mutex_lock(osc_response_mutex);
334 
335       g_value_set_pointer(value, osc_response->error_message);
336 
337       g_rec_mutex_unlock(osc_response_mutex);
338     }
339     break;
340   case PROP_OSC_MESSAGE:
341   {
342     g_rec_mutex_lock(osc_response_mutex);
343 
344     g_value_set_object(value, osc_response->osc_message);
345 
346     g_rec_mutex_unlock(osc_response_mutex);
347   }
348   break;
349   default:
350     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
351     break;
352   }
353 }
354 
355 void
ags_osc_response_dispose(GObject * gobject)356 ags_osc_response_dispose(GObject *gobject)
357 {
358   AgsOscResponse *osc_response;
359 
360   osc_response = (AgsOscResponse *) gobject;
361 
362   if(osc_response->osc_message != NULL){
363     g_object_unref(osc_response->osc_message);
364 
365     osc_response->osc_message = NULL;
366   }
367 
368   /* call parent */
369   G_OBJECT_CLASS(ags_osc_response_parent_class)->dispose(gobject);
370 }
371 
372 void
ags_osc_response_finalize(GObject * gobject)373 ags_osc_response_finalize(GObject *gobject)
374 {
375   AgsOscResponse *osc_response;
376 
377   osc_response = (AgsOscResponse *) gobject;
378 
379   if(osc_response->packet != NULL){
380     free(osc_response->packet);
381   }
382 
383   g_free(osc_response->error_message);
384 
385   if(osc_response->osc_message != NULL){
386     g_object_unref(osc_response->osc_message);
387   }
388 
389   /* call parent */
390   G_OBJECT_CLASS(ags_osc_response_parent_class)->finalize(gobject);
391 }
392 
393 /**
394  * ags_osc_response_test_flags:
395  * @osc_response: the #AgsOscResponse
396  * @flags: the flags
397  *
398  * Test @flags to be set on @osc_response.
399  *
400  * Returns: %TRUE if flags are set, else %FALSE
401  *
402  * Since: 3.0.0
403  */
404 gboolean
ags_osc_response_test_flags(AgsOscResponse * osc_response,guint flags)405 ags_osc_response_test_flags(AgsOscResponse *osc_response, guint flags)
406 {
407   gboolean retval;
408 
409   GRecMutex *osc_response_mutex;
410 
411   if(!AGS_IS_OSC_RESPONSE(osc_response)){
412     return(FALSE);
413   }
414 
415   /* get osc_response mutex */
416   osc_response_mutex = AGS_OSC_RESPONSE_GET_OBJ_MUTEX(osc_response);
417 
418   /* test */
419   g_rec_mutex_lock(osc_response_mutex);
420 
421   retval = (flags & (osc_response->flags)) ? TRUE: FALSE;
422 
423   g_rec_mutex_unlock(osc_response_mutex);
424 
425   return(retval);
426 }
427 
428 /**
429  * ags_osc_response_set_flags:
430  * @osc_response: the #AgsOscResponse
431  * @flags: the flags
432  *
433  * Set flags.
434  *
435  * Since: 3.0.0
436  */
437 void
ags_osc_response_set_flags(AgsOscResponse * osc_response,guint flags)438 ags_osc_response_set_flags(AgsOscResponse *osc_response, guint flags)
439 {
440   GRecMutex *osc_response_mutex;
441 
442   if(!AGS_IS_OSC_RESPONSE(osc_response)){
443     return;
444   }
445 
446   /* get osc_response mutex */
447   osc_response_mutex = AGS_OSC_RESPONSE_GET_OBJ_MUTEX(osc_response);
448 
449   /* set flags */
450   g_rec_mutex_lock(osc_response_mutex);
451 
452   osc_response->flags |= flags;
453 
454   g_rec_mutex_unlock(osc_response_mutex);
455 }
456 
457 /**
458  * ags_osc_response_unset_flags:
459  * @osc_response: the #AgsOscResponse
460  * @flags: the flags
461  *
462  * Unset flags.
463  *
464  * Since: 3.0.0
465  */
466 void
ags_osc_response_unset_flags(AgsOscResponse * osc_response,guint flags)467 ags_osc_response_unset_flags(AgsOscResponse *osc_response, guint flags)
468 {
469   GRecMutex *osc_response_mutex;
470 
471   if(!AGS_IS_OSC_RESPONSE(osc_response)){
472     return;
473   }
474 
475   /* get osc_response mutex */
476   osc_response_mutex = AGS_OSC_RESPONSE_GET_OBJ_MUTEX(osc_response);
477 
478   /* set flags */
479   g_rec_mutex_lock(osc_response_mutex);
480 
481   osc_response->flags &= (~flags);
482 
483   g_rec_mutex_unlock(osc_response_mutex);
484 }
485 
486 /**
487  * ags_osc_response_new:
488  *
489  * Creates a new instance of #AgsOscResponse
490  *
491  * Returns: the new #AgsOscResponse
492  *
493  * Since: 3.0.0
494  */
495 AgsOscResponse*
ags_osc_response_new()496 ags_osc_response_new()
497 {
498   AgsOscResponse *osc_response;
499 
500   osc_response = (AgsOscResponse *) g_object_new(AGS_TYPE_OSC_RESPONSE,
501 						 NULL);
502 
503   return(osc_response);
504 }
505