1
// DBus-client-template.hh --- DBUS template
3
// Copyright (C) 2007, 2008 Rob Caelers <robc@krandor.nl>
4
// All rights reserved.
6
// This program 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.
11
// This program 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.
16
// You should have received a copy of the GNU General Public License
17
// along with this program. If not, see <http://www.gnu.org/licenses/>.
29
\#include "DBusBinding.hh"
30
\#include "DBusException.hh"
31
\#include "${model.include_filename}"
34
using namespace workrave;
36
#for interface in $model.interfaces
38
#if interface.condition != ''
39
\#if $interface.condition
42
#for imp in interface.imports
43
#for ns in imp.namespaces
48
#for imp in interface.imports
49
#for include in imp.includes
50
\#include "${include}"
54
class ${interface.qname}_Impl : public ${interface.qname}, public DBusBaseTypes
57
${interface.qname}_Impl(DBus *dbus, const string &service, const string &path);
59
#for $method in interface.methods
61
$interface.type2csymbol(method.return_type()) ${method.qname}(#slurp
63
#for p in method.params
64
#if p.direction != 'out' or (not 'return' in p.hint)
68
$comma $interface.type2csymbol(p.type) #slurp
71
#if p.direction == 'out'
72
#if 'return' in p.hint
75
#else if 'ptr' in p.hint
80
#else if p.direction == 'in'
83
#else if 'ptr' in p.hint
92
void ${method.qname}_async(#slurp
94
#for p in method.params
95
#if p.direction == 'in'
99
$comma $interface.type2csymbol(p.type) #slurp
102
#else if 'ptr' in p.hint
110
$comma ${method.name}_slot slot #slurp
118
#for $method in interface.methods
119
typedef sigc::signal<void, DBusError * #slurp
121
#for p in method.params
122
#if p.direction == 'out'
123
#if 'const' in p.hint
126
$comma $interface.type2csymbol(p.type) #slurp
129
#else if 'ptr' in p.hint
135
> ${method.qname}_signal;
137
struct ${method.qname}_async_closure
139
class ${interface.qname}_Impl *impl;
140
${method.qname}_signal signal;
142
static void ${method.qname}_async_closure_free(void *mem)
144
delete (${method.qname}_async_closure *)mem;
147
static void ${method.qname}_fcn_static(DBusPendingCall *pending, void *user_data);
148
void ${method.qname}_fcn(DBusPendingCall *pending, void *user_data);
152
#for enum in $interface.enums
153
void get_${enum.qname}(DBusMessageIter *reader, ${enum.csymbol} *result);
154
void put_${enum.qname}(DBusMessageIter *writer, const ${enum.csymbol} *result);
157
#for struct in $interface.structs
158
void get_${struct.qname}(DBusMessageIter *reader, ${struct.csymbol} *result);
159
void put_${struct.qname}(DBusMessageIter *writer, const ${struct.csymbol} *result);
162
#for seq in $interface.sequences
163
void get_${seq.qname}(DBusMessageIter *reader, ${seq.csymbol} *result);
164
void put_${seq.qname}(DBusMessageIter *writer, const ${seq.csymbol} *result);
167
#for dict in $interface.dictionaries
168
void get_${dict.qname}(DBusMessageIter *reader, ${dict.csymbol} *result);
169
void put_${dict.qname}(DBusMessageIter *writer, const ${dict.csymbol} *result);
178
${interface.qname}_Impl::${interface.qname}_Impl(DBus *dbus, const string &service, const string &path)
179
: dbus(dbus), service(service), path(path)
183
${interface.qname} *${interface.qname}::instance(DBus *dbus, const string &service, const string &path)
185
return new ${interface.qname}_Impl(dbus, service, path);
189
#for enum in $interface.enums
192
${interface.qname}::get_${enum.qname}(DBusMessageIter *reader, ${enum.csymbol} *result)
195
int argtype = dbus_message_iter_get_arg_type(reader);
197
if (argtype != DBUS_TYPE_STRING)
198
throw DBusTypeException("Type mismatch. Excepted string");
200
get_string(reader, &value);
203
#for e in enum.values
204
$ifs ("$e.name" == value)
206
*result = $e.csymbol;
208
#set $ifs = 'else if'
212
throw DBusTypeException("Illegal enum value");
217
${interface.qname}::put_${enum.qname}(DBusMessageIter *writer, const ${enum.csymbol} *result)
222
#for e in enum.values
228
throw DBusTypeException("Illegal enum value");
231
put_string(writer, &value);
236
#for struct in $interface.structs
239
${interface.qname}::get_${struct.qname}(DBusMessageIter *reader, ${struct.csymbol} *result)
242
dbus_message_iter_recurse(reader, &it);
244
#for p in struct.fields
245
get_${p.type}(&it, ($interface.type2csymbol(p.type) *) &(result->${p.name}));
248
dbus_message_iter_next(reader);
252
${interface.qname}::put_${struct.qname}(DBusMessageIter *writer, const ${struct.csymbol} *result)
257
ok = dbus_message_iter_open_container(writer, DBUS_TYPE_STRUCT, NULL, &it);
260
throw DBusSystemException("Internal error");
263
#for p in struct.fields
264
put_${p.type}(&it, ($interface.type2csymbol(p.type) *) &(result->${p.name}));
267
ok = dbus_message_iter_close_container(writer, &it);
270
throw DBusSystemException("Internal error");
276
#for seq in $interface.sequences
279
${interface.qname}::get_${seq.qname}(DBusMessageIter *reader, ${seq.csymbol} *result)
283
dbus_message_iter_recurse(reader, &it);
284
while (dbus_message_iter_has_next(&it))
286
$interface.type2csymbol(seq.data_type) tmp;
287
get_${seq.data_type}(&it, &tmp);
288
result->push_back(tmp);
291
dbus_message_iter_next(reader);
295
${interface.qname}::put_${seq.qname}(DBusMessageIter *writer, const ${seq.csymbol} *result)
298
${seq.csymbol}::const_iterator it;
301
ok = dbus_message_iter_open_container(writer, DBUS_TYPE_ARRAY, "$interface.type2sig(seq.data_type)", &arr);
304
throw DBusSystemException("Internal error");
307
for(it = result->begin(); it != result->end(); it++)
309
put_${seq.data_type}(&arr, &(*it));
312
ok = dbus_message_iter_close_container(writer, &arr);
315
throw DBusSystemException("Internal error");
321
#for dict in $interface.dictionaries
324
${interface.qname}::get_${dict.qname}(DBusMessageIter *reader, ${dict.csymbol} *result)
326
DBusMessageIter arr_it;
327
DBusMessageIter dict_it;
329
dbus_message_iter_recurse(reader, &arr_it);
330
while (dbus_message_iter_has_next(&arr_it))
332
$interface.type2csymbol(dict.key_type) key;
333
$interface.type2csymbol(dict.value_type) value;
335
dbus_message_iter_recurse(&arr_it, &dict_it);
337
get_${dict.key_type}(&dict_it, &key);
338
get_${dict.value_type}(&dict_it, &value);
340
(*result)[key] = value;
342
dbus_message_iter_next(&arr_it);
345
dbus_message_iter_next(reader);
350
${interface.qname}::put_${dict.qname}(DBusMessageIter *writer, const ${dict.csymbol} *result)
352
DBusMessageIter arr_it;
353
DBusMessageIter dict_it;
354
${dict.csymbol}::const_iterator it;
357
ok = dbus_message_iter_open_container(writer, DBUS_TYPE_ARRAY,
358
"$interface.type2sig(dict.value_type)", &arr_it);
361
throw DBusSystemException("Internal error");
364
for (it = result->begin(); it != result->end(); it++)
366
ok = dbus_message_iter_open_container(&arr_it, DBUS_TYPE_DICT_ENTRY, NULL, &dict_it);
369
throw DBusSystemException("Internal error");
372
put_${dict.key_type}(&dict_it, &(it->first));
373
put_${dict.value_type}(&dict_it, &(it->second));
375
ok = dbus_message_iter_close_container(&arr_it, &dict_it);
378
throw DBusSystemException("Internal error");
382
ok = dbus_message_iter_close_container(writer, &arr_it);
385
throw DBusSystemException("Internal error");
392
#for method in $interface.methods
394
$interface.type2csymbol(method.return_type()) ${interface.qname}_Impl::${method.qname}(#slurp
396
#for p in method.params
397
#if p.direction != 'out' or (not 'return' in p.hint)
398
#if 'const' in p.hint
401
$comma $interface.type2csymbol(p.type) #slurp
404
#if p.direction == 'out'
405
#if 'return' in p.hint
408
#else if 'ptr' in p.hint
413
#else if p.direction == 'in'
416
#else if 'ptr' in p.hint
425
#if method.condition != ''
426
\#if $method.condition
429
DBusMessage *message = NULL;
430
DBusMessage *reply = NULL;
431
DBusPendingCall *pending = NULL;
433
DBusMessageIter reader;
434
DBusMessageIter writer;
437
#set have_in_args = False
438
#for p in method.params
439
#if p.direction == 'in'
440
#set have_in_args = True
442
#if 'return' in p.hint
443
#if 'ptrtr' in p.hint
444
$interface.type2csymbol(p.type) *${p.name} = NULL;
446
$interface.type2csymbol(p.type) ${p.name};
453
message = dbus_message_new_method_call(service.c_str(),
455
"$interface.name", "$method.name");
457
dbus_message_iter_init_append(message, &writer);
459
#for arg in method.params:
460
#if arg.direction == 'in'
461
#if 'ptrptr' in p.hint
462
put_${arg.type}(&writer, ${arg.name});
464
put_${arg.type}(&writer, &${arg.name});
469
if (!dbus_connection_send_with_reply(dbus->conn(), message, &pending, -1))
471
throw DBusSystemException("Cannot send");
476
throw DBusSystemException("No pending reply");
479
dbus_connection_flush(dbus->conn());
482
dbus_message_unref(message);
485
// block until we receive a reply
486
dbus_pending_call_block(pending);
488
// get the reply message
489
reply = dbus_pending_call_steal_reply(pending);
492
throw DBusSystemException("No reply");
495
// free the pending message handle
496
dbus_pending_call_unref(pending);
499
ok = dbus_message_iter_init(reply, &reader);
503
throw DBusSystemException("No parameters");
507
#for arg in method.params:
508
#if $arg.direction == 'out'
509
get_${arg.type}(&reader, &${arg.name});
514
catch (DBusException)
518
dbus_message_unref(reply);
523
dbus_message_unref(message);
528
dbus_pending_call_unref(pending);
534
#if method.return_type() != 'void'
535
return $method.return_name();
538
#if method.condition != ''
542
reply = dbus_message_new_error(message,
543
"org.workrave.NotImplemented",
544
"This method is unavailable in current configuration");
550
void ${interface.qname}_Impl::${method.qname}_async(#slurp
552
#for p in method.params
553
#if p.direction == 'in'
554
#if 'const' in p.hint
557
$comma $interface.type2csymbol(p.type) #slurp
560
#else if 'ptr' in p.hint
568
$comma ${method.name}_slot slot
571
#if method.condition != ''
572
\#if $method.condition
575
DBusMessage *message = NULL;
576
DBusPendingCall *pending = NULL;
578
DBusMessageIter writer;
582
message = dbus_message_new_method_call(service.c_str(),
584
"$interface.name", "$method.name");
586
dbus_message_iter_init(message, &writer);
588
#for arg in method.params:
589
#if arg.direction == 'in'
590
#if 'ptrptr' in p.hint
591
put_${arg.type}(&writer, ${arg.name});
593
put_${arg.type}(&writer, &${arg.name});
598
if (!dbus_connection_send_with_reply(dbus->conn(), message, &pending, -1))
600
throw DBusSystemException("Cannot send");
605
throw DBusSystemException("No pending reply");
608
${method.qname}_async_closure *closure = new ${method.qname}_async_closure;
609
closure->impl = this;
610
closure->signal.connect(slot);
612
if (!dbus_pending_call_set_notify(pending,
613
${interface.qname}_Impl::${method.qname}_fcn_static,
614
closure, ${method.qname}_async_closure_free))
616
throw DBusSystemException("Cannot set notifier");
620
dbus_message_unref(message);
623
catch (DBusException)
627
dbus_message_unref(message);
632
dbus_pending_call_unref(pending);
638
#if method.condition != ''
642
reply = dbus_message_new_error(message,
643
"org.workrave.NotImplemented",
644
"This method is unavailable in current configuration");
649
void ${interface.qname}_Impl::${method.qname}_fcn_static(DBusPendingCall *pending, void *user_data)
651
${method.qname}_async_closure *closure = (${method.qname}_async_closure *)user_data;
653
closure->impl->${method.qname}_fcn(pending, user_data);
656
void ${interface.qname}_Impl::${method.qname}_fcn(DBusPendingCall *pending, void *user_data)
658
#if method.condition != ''
659
\#if $method.condition
661
${method.qname}_async_closure *closure = (${method.qname}_async_closure *)user_data;
662
DBusMessage *reply = NULL;
663
DBusMessageIter reader;
667
#set have_out_args = False
668
#for p in method.params
669
#if p.direction == 'out'
670
#set have_out_args = True
671
#if 'ptrtr' in p.hint
672
$interface.type2csymbol(p.type) *${p.name} = NULL;
674
$interface.type2csymbol(p.type) ${p.name};
679
dbus_error_init(&error);
683
reply = dbus_pending_call_steal_reply(pending);
686
throw DBusSystemException("Cannot get reply");
689
ok = dbus_message_iter_init(reply, &reader);
693
throw DBusSystemException("No parameters");
697
#for arg in method.params:
698
#if $arg.direction == 'out'
699
get_${arg.type}(&reader, &${arg.name});
703
closure->signal.emit((DBusError *)NULL #slurp
704
#for p in method.params
705
#if p.direction == 'out'
711
catch (DBusException)
715
dbus_message_unref(reply);
720
dbus_pending_call_unref(pending);
725
#if method.condition != ''
737
#if interface.condition != ''