Move dbus constants to separate header
[ladish.git] / gui / lash_proxy.cpp
blob4715cdc9e6fe7ad6e205fda4946533154ba568fc
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2008, 2009 Nedko Arnaudov <nedko@arnaudov.name>
7 **************************************************************************
8 * This file contains code that communicates with ladishd through D-Bus
9 **************************************************************************
11 * LADI Session Handler is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * LADI Session Handler is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
23 * or write to the Free Software Foundation, Inc.,
24 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "common.h"
29 #include <string.h>
30 #include <dbus/dbus.h>
32 #include "lash_proxy.hpp"
33 #include "session.hpp"
34 #include "project.hpp"
35 #include "lash_client.hpp"
36 #include "globals.hpp"
37 #include "dbus_helpers.h"
39 struct lash_proxy_impl
41 void init();
43 void fetch_loaded_projects();
44 void fetch_project_clients(boost::shared_ptr<project> project_ptr);
45 bool is_studio_loaded();
47 static void error_msg(const std::string& msg);
48 static void info_msg(const std::string& msg);
50 static
51 DBusHandlerResult
52 dbus_message_hook(
53 DBusConnection * connection,
54 DBusMessage * message,
55 void * proxy);
57 bool
58 call(
59 bool response_expected,
60 const char* iface,
61 const char* method,
62 DBusMessage ** reply_ptr_ptr,
63 int in_type,
64 ...);
66 boost::shared_ptr<project>
67 on_project_added(
68 std::string name);
70 boost::shared_ptr<lash_client>
71 on_client_added(
72 boost::shared_ptr<project> project_ptr,
73 std::string id,
74 std::string name);
76 void exit();
78 bool _server_responding;
79 session * _session_ptr;
80 lash_proxy * _interface_ptr;
83 lash_proxy::lash_proxy(session * session_ptr)
85 _impl_ptr = new lash_proxy_impl;
86 _impl_ptr->_interface_ptr = this;
87 _impl_ptr->_session_ptr = session_ptr;
88 _impl_ptr->init();
91 lash_proxy::~lash_proxy()
93 delete _impl_ptr;
96 void
97 lash_proxy_impl::init()
99 _server_responding = false;
101 patchage_dbus_add_match("type='signal',interface='" DBUS_INTERFACE_DBUS "',member=NameOwnerChanged,arg0='" LASH_SERVICE "'");
102 patchage_dbus_add_match("type='signal',interface='" LASH_IFACE_CONTROL "',member=StudioAppeared");
103 patchage_dbus_add_match("type='signal',interface='" LASH_IFACE_CONTROL "',member=StudioDisappeared");
104 patchage_dbus_add_match("type='signal',interface='" LASH_IFACE_CONTROL "',member=ProjectAppeared");
105 patchage_dbus_add_match("type='signal',interface='" LASH_IFACE_CONTROL "',member=ProjectDisappeared");
106 patchage_dbus_add_match("type='signal',interface='" LASH_IFACE_CONTROL "',member=ProjectNameChanged");
107 patchage_dbus_add_match("type='signal',interface='" LASH_IFACE_CONTROL "',member=ProjectModifiedStatusChanged");
108 patchage_dbus_add_match("type='signal',interface='" LASH_IFACE_CONTROL "',member=ProjectDescriptionChanged");
109 patchage_dbus_add_match("type='signal',interface='" LASH_IFACE_CONTROL "',member=ProjectNotesChanged");
110 patchage_dbus_add_match("type='signal',interface='" LASH_IFACE_CONTROL "',member=ClientAppeared");
111 patchage_dbus_add_match("type='signal',interface='" LASH_IFACE_CONTROL "',member=ClientDisappeared");
112 patchage_dbus_add_match("type='signal',interface='" LASH_IFACE_CONTROL "',member=ClientNameChanged");
114 patchage_dbus_add_filter(dbus_message_hook, this);
116 // get initial list of projects
117 // calling any method to updates server responding status
118 // this also actiavtes lash object if it not activated already
119 //fetch_loaded_projects();
121 g_app->set_studio_availability(is_studio_loaded());
124 bool
125 lash_proxy::is_active()
127 return _impl_ptr->_server_responding;
130 void
131 lash_proxy::try_activate()
133 std::list<lash_project_info> projects;
134 get_available_projects(projects);
137 void
138 lash_proxy::deactivate()
140 _impl_ptr->exit();
143 void
144 lash_proxy_impl::error_msg(const std::string& msg)
146 g_app->error_msg((std::string)"[LASH] " + msg);
149 void
150 lash_proxy_impl::info_msg(const std::string& msg)
152 g_app->info_msg((std::string)"[LASH] " + msg);
155 DBusHandlerResult
156 lash_proxy_impl::dbus_message_hook(
157 DBusConnection * connection,
158 DBusMessage * message,
159 void * proxy)
161 const char * project_name;
162 const char * new_project_name;
163 const char * object_name;
164 const char * old_owner;
165 const char * new_owner;
166 const char * value_string;
167 const char * client_id;
168 const char * client_name;
169 dbus_bool_t modified_status;
170 boost::shared_ptr<project> project_ptr;
171 boost::shared_ptr<lash_client> client_ptr;
173 assert(proxy);
174 lash_proxy_impl * me = reinterpret_cast<lash_proxy_impl *>(proxy);
176 //info_msg("dbus_message_hook() called.");
178 // Handle signals we have subscribed for in attach()
180 if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
182 if (!dbus_message_get_args(
183 message, &g_dbus_error,
184 DBUS_TYPE_STRING, &object_name,
185 DBUS_TYPE_STRING, &old_owner,
186 DBUS_TYPE_STRING, &new_owner,
187 DBUS_TYPE_INVALID))
189 error_msg(str(boost::format("dbus_message_get_args() failed to extract NameOwnerChanged signal arguments (%s)") % g_dbus_error.message));
190 dbus_error_free(&g_dbus_error);
191 return DBUS_HANDLER_RESULT_HANDLED;
194 if ((std::string)object_name != LASH_SERVICE)
196 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
199 if (old_owner[0] == '\0')
201 info_msg((std::string)"LASH activated.");
203 else if (new_owner[0] == '\0')
205 info_msg((std::string)"LASH deactivated.");
206 g_app->set_studio_availability(false);
207 me->_server_responding = false;
210 return DBUS_HANDLER_RESULT_HANDLED;
213 if (dbus_message_is_signal(message, LASH_IFACE_CONTROL, "StudioAppeared"))
215 info_msg((std::string)"Studio appeared.");
216 g_app->set_studio_availability(true);
218 return DBUS_HANDLER_RESULT_HANDLED;
221 if (dbus_message_is_signal(message, LASH_IFACE_CONTROL, "StudioDisappeared"))
223 info_msg((std::string)"Studio disappeared.");
224 g_app->set_studio_availability(false);
226 return DBUS_HANDLER_RESULT_HANDLED;
229 if (dbus_message_is_signal(message, LASH_IFACE_CONTROL, "ProjectAppeared"))
231 if (!dbus_message_get_args( message, &g_dbus_error,
232 DBUS_TYPE_STRING, &project_name,
233 DBUS_TYPE_INVALID))
235 error_msg(str(boost::format("dbus_message_get_args() failed to extract ProjectAppeared signal arguments (%s)") % g_dbus_error.message));
236 dbus_error_free(&g_dbus_error);
237 return DBUS_HANDLER_RESULT_HANDLED;
240 info_msg((std::string)"Project '" + project_name + "' appeared.");
241 me->on_project_added(project_name);
243 return DBUS_HANDLER_RESULT_HANDLED;
246 if (dbus_message_is_signal(message, LASH_IFACE_CONTROL, "ProjectDisappeared"))
248 if (!dbus_message_get_args(
249 message, &g_dbus_error,
250 DBUS_TYPE_STRING, &project_name,
251 DBUS_TYPE_INVALID))
253 error_msg(str(boost::format("dbus_message_get_args() failed to extract ProjectDisappeared signal arguments (%s)") % g_dbus_error.message));
254 dbus_error_free(&g_dbus_error);
255 return DBUS_HANDLER_RESULT_HANDLED;
258 info_msg((std::string)"Project '" + project_name + "' disappeared.");
259 me->_session_ptr->project_close(project_name);
261 return DBUS_HANDLER_RESULT_HANDLED;
265 if (dbus_message_is_signal(message, LASH_IFACE_CONTROL, "ProjectNameChanged"))
267 if (!dbus_message_get_args(
268 message, &g_dbus_error,
269 DBUS_TYPE_STRING, &project_name,
270 DBUS_TYPE_STRING, &new_project_name,
271 DBUS_TYPE_INVALID))
273 error_msg(str(boost::format("dbus_message_get_args() failed to extract ProjectNameChanged signal arguments (%s)") % g_dbus_error.message));
274 dbus_error_free(&g_dbus_error);
275 return DBUS_HANDLER_RESULT_HANDLED;
278 info_msg((std::string)"Project '" + project_name + "' renamed to '" + new_project_name + "'.");
280 project_ptr = me->_session_ptr->find_project_by_name(project_name);
281 if (project_ptr)
283 project_ptr->on_name_changed(new_project_name);
286 return DBUS_HANDLER_RESULT_HANDLED;
289 if (dbus_message_is_signal(message, LASH_IFACE_CONTROL, "ProjectModifiedStatusChanged"))
291 if (!dbus_message_get_args(
292 message, &g_dbus_error,
293 DBUS_TYPE_STRING, &project_name,
294 DBUS_TYPE_BOOLEAN, &modified_status,
295 DBUS_TYPE_INVALID))
297 error_msg(str(boost::format("dbus_message_get_args() failed to extract ProjectModifiedStatusChanged signal arguments (%s)") % g_dbus_error.message));
298 dbus_error_free(&g_dbus_error);
299 return DBUS_HANDLER_RESULT_HANDLED;
302 info_msg((std::string)"Project '" + project_name + "' modified status changed to '" + (modified_status ? "true" : "false") + "'.");
304 project_ptr = me->_session_ptr->find_project_by_name(project_name);
305 if (project_ptr)
307 project_ptr->on_modified_status_changed(modified_status);
310 return DBUS_HANDLER_RESULT_HANDLED;
313 if (dbus_message_is_signal(message, LASH_IFACE_CONTROL, "ProjectDescriptionChanged"))
315 if (!dbus_message_get_args(
316 message, &g_dbus_error,
317 DBUS_TYPE_STRING, &project_name,
318 DBUS_TYPE_STRING, &value_string,
319 DBUS_TYPE_INVALID))
321 error_msg(str(boost::format("dbus_message_get_args() failed to extract ProjectDescriptionChanged signal arguments (%s)") % g_dbus_error.message));
322 dbus_error_free(&g_dbus_error);
323 return DBUS_HANDLER_RESULT_HANDLED;
326 info_msg((std::string)"Project '" + project_name + "' description changed.");
328 project_ptr = me->_session_ptr->find_project_by_name(project_name);
329 if (project_ptr)
331 project_ptr->on_description_changed(value_string);
334 return DBUS_HANDLER_RESULT_HANDLED;
337 if (dbus_message_is_signal(message, LASH_IFACE_CONTROL, "ProjectNotesChanged"))
339 if (!dbus_message_get_args(
340 message, &g_dbus_error,
341 DBUS_TYPE_STRING, &project_name,
342 DBUS_TYPE_STRING, &value_string,
343 DBUS_TYPE_INVALID))
345 error_msg(str(boost::format("dbus_message_get_args() failed to extract ProjectNotesChanged signal arguments (%s)") % g_dbus_error.message));
346 dbus_error_free(&g_dbus_error);
347 return DBUS_HANDLER_RESULT_HANDLED;
350 info_msg((std::string)"Project '" + project_name + "' notes changed.");
352 project_ptr = me->_session_ptr->find_project_by_name(project_name);
353 if (project_ptr)
355 project_ptr->on_notes_changed(value_string);
358 return DBUS_HANDLER_RESULT_HANDLED;
361 if (dbus_message_is_signal(message, LASH_IFACE_CONTROL, "ClientAppeared"))
363 if (!dbus_message_get_args(
364 message, &g_dbus_error,
365 DBUS_TYPE_STRING, &client_id,
366 DBUS_TYPE_STRING, &project_name,
367 DBUS_TYPE_STRING, &client_name,
368 DBUS_TYPE_INVALID))
370 error_msg(str(boost::format("dbus_message_get_args() failed to extract ClientAppeared signal arguments (%s)") % g_dbus_error.message));
371 dbus_error_free(&g_dbus_error);
372 return DBUS_HANDLER_RESULT_HANDLED;
375 info_msg((std::string)"Client '" + client_id + "':'" + client_name + "' appeared in project '" + project_name + "'.");
377 project_ptr = me->_session_ptr->find_project_by_name(project_name);
378 if (project_ptr)
380 me->on_client_added(project_ptr, client_id, client_name);
383 return DBUS_HANDLER_RESULT_HANDLED;
386 if (dbus_message_is_signal(message, LASH_IFACE_CONTROL, "ClientDisappeared"))
388 if (!dbus_message_get_args(
389 message, &g_dbus_error,
390 DBUS_TYPE_STRING, &client_id,
391 DBUS_TYPE_STRING, &project_name,
392 DBUS_TYPE_INVALID))
394 error_msg(str(boost::format("dbus_message_get_args() failed to extract ClientDisappeared signal arguments (%s)") % g_dbus_error.message));
395 dbus_error_free(&g_dbus_error);
396 return DBUS_HANDLER_RESULT_HANDLED;
399 info_msg((std::string)"Client '" + client_id + "' of project '" + project_name + "' disappeared.");
401 client_ptr = me->_session_ptr->find_client_by_id(client_id);
402 if (client_ptr)
404 client_ptr->get_project()->on_client_removed(client_id);
405 me->_session_ptr->client_remove(client_id);
408 return DBUS_HANDLER_RESULT_HANDLED;
411 if (dbus_message_is_signal(message, LASH_IFACE_CONTROL, "ClientNameChanged"))
413 if (!dbus_message_get_args(
414 message, &g_dbus_error,
415 DBUS_TYPE_STRING, &client_id,
416 DBUS_TYPE_STRING, &client_name,
417 DBUS_TYPE_INVALID))
419 error_msg(str(boost::format("dbus_message_get_args() failed to extract ClientNameChanged signal arguments (%s)") % g_dbus_error.message));
420 dbus_error_free(&g_dbus_error);
421 return DBUS_HANDLER_RESULT_HANDLED;
424 info_msg((std::string)"Client '" + client_id + "' name changed to '" + client_name + "'.");
426 client_ptr = me->_session_ptr->find_client_by_id(client_id);
427 if (client_ptr)
429 client_ptr->on_name_changed(client_name);
432 return DBUS_HANDLER_RESULT_HANDLED;
435 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
438 bool
439 lash_proxy_impl::call(
440 bool response_expected,
441 const char* iface,
442 const char* method,
443 DBusMessage ** reply_ptr_ptr,
444 int in_type,
445 ...)
447 va_list ap;
449 va_start(ap, in_type);
451 _server_responding = patchage_dbus_call_valist(
452 response_expected,
453 LASH_SERVICE,
454 LASH_OBJECT,
455 iface,
456 method,
457 reply_ptr_ptr,
458 in_type,
459 ap);
461 va_end(ap);
463 return _server_responding;
466 void
467 lash_proxy_impl::fetch_loaded_projects()
469 DBusMessage* reply_ptr;
470 const char * reply_signature;
471 DBusMessageIter iter;
472 DBusMessageIter array_iter;
473 const char * project_name;
474 boost::shared_ptr<project> project_ptr;
476 if (!call(true, LASH_IFACE_CONTROL, "ProjectsGet", &reply_ptr, DBUS_TYPE_INVALID)) {
477 return;
480 reply_signature = dbus_message_get_signature(reply_ptr);
482 if (strcmp(reply_signature, "as") != 0)
484 error_msg((std::string)"ProjectsGet() reply signature mismatch. " + reply_signature);
485 goto unref;
488 dbus_message_iter_init(reply_ptr, &iter);
490 for (dbus_message_iter_recurse(&iter, &array_iter);
491 dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID;
492 dbus_message_iter_next(&array_iter))
494 dbus_message_iter_get_basic(&array_iter, &project_name);
495 project_ptr = on_project_added(project_name);
496 fetch_project_clients(project_ptr);
499 unref:
500 dbus_message_unref(reply_ptr);
503 void
504 lash_proxy_impl::fetch_project_clients(
505 boost::shared_ptr<project> project_ptr)
507 DBusMessage* reply_ptr;
508 const char * reply_signature;
509 DBusMessageIter iter;
510 DBusMessageIter array_iter;
511 DBusMessageIter struct_iter;
512 const char * client_id;
513 const char * client_name;
514 std::string project_name;
515 const char * project_name_cstr;
517 project_ptr->get_name(project_name);
518 project_name_cstr = project_name.c_str();
520 if (!call(
521 true,
522 LASH_IFACE_CONTROL,
523 "ProjectGetClients",
524 &reply_ptr,
525 DBUS_TYPE_STRING, &project_name_cstr,
526 DBUS_TYPE_INVALID))
528 return;
531 reply_signature = dbus_message_get_signature(reply_ptr);
533 if (strcmp(reply_signature, "a(ss)") != 0)
535 error_msg((std::string)"ProjectGetClients() reply signature mismatch. " + reply_signature);
536 goto unref;
539 dbus_message_iter_init(reply_ptr, &iter);
541 for (dbus_message_iter_recurse(&iter, &array_iter);
542 dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID;
543 dbus_message_iter_next(&array_iter))
545 dbus_message_iter_recurse(&array_iter, &struct_iter);
547 dbus_message_iter_get_basic(&struct_iter, &client_id);
548 dbus_message_iter_next(&struct_iter);
549 dbus_message_iter_get_basic(&struct_iter, &client_name);
550 dbus_message_iter_next(&struct_iter);
552 on_client_added(project_ptr, client_id, client_name);
555 unref:
556 dbus_message_unref(reply_ptr);
559 boost::shared_ptr<project>
560 lash_proxy_impl::on_project_added(
561 std::string name)
563 boost::shared_ptr<project> project_ptr(new project(_interface_ptr, name));
565 _session_ptr->project_add(project_ptr);
567 return project_ptr;
570 boost::shared_ptr<lash_client>
571 lash_proxy_impl::on_client_added(
572 boost::shared_ptr<project> project_ptr,
573 std::string id,
574 std::string name)
576 boost::shared_ptr<lash_client> client_ptr(
577 new lash_client(
578 _interface_ptr,
579 project_ptr.get(),
581 name));
583 project_ptr->on_client_added(client_ptr);
584 _session_ptr->client_add(client_ptr);
586 return client_ptr;
589 void
590 lash_proxy::get_available_projects(
591 std::list<lash_project_info>& projects)
593 DBusMessage * reply_ptr;
594 const char * reply_signature;
595 DBusMessageIter iter;
596 DBusMessageIter array_iter;
597 DBusMessageIter struct_iter;
598 DBusMessageIter dict_iter;
599 DBusMessageIter dict_entry_iter;
600 DBusMessageIter variant_iter;
601 const char * project_name;
602 const char * key;
603 const char * value_type;
604 dbus_uint32_t value_uint32;
605 const char * value_string;
606 lash_project_info project_info;
608 if (!_impl_ptr->call(true, LASH_IFACE_CONTROL, "ProjectsGetAvailable", &reply_ptr, DBUS_TYPE_INVALID))
610 return;
613 reply_signature = dbus_message_get_signature(reply_ptr);
615 if (strcmp(reply_signature, "a(sa{sv})") != 0)
617 lash_proxy_impl::error_msg((std::string)"ProjectsGetAvailable() reply signature mismatch. " + reply_signature);
618 goto unref;
621 dbus_message_iter_init(reply_ptr, &iter);
623 for (dbus_message_iter_recurse(&iter, &array_iter);
624 dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID;
625 dbus_message_iter_next(&array_iter))
627 dbus_message_iter_recurse(&array_iter, &struct_iter);
629 dbus_message_iter_get_basic(&struct_iter, &project_name);
631 project_info.name = project_name;
632 project_info.modification_time = 0;
633 project_info.description.erase();
635 dbus_message_iter_next(&struct_iter);
637 for (dbus_message_iter_recurse(&struct_iter, &dict_iter);
638 dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_INVALID;
639 dbus_message_iter_next(&dict_iter))
641 dbus_message_iter_recurse(&dict_iter, &dict_entry_iter);
642 dbus_message_iter_get_basic(&dict_entry_iter, &key);
643 dbus_message_iter_next(&dict_entry_iter);
644 dbus_message_iter_recurse(&dict_entry_iter, &variant_iter);
645 value_type = dbus_message_iter_get_signature(&variant_iter);
646 if (value_type[0] != 0 && value_type[1] == 0)
648 switch (*value_type)
650 case DBUS_TYPE_UINT32:
651 if (strcmp(key, "Modification Time") == 0)
653 dbus_message_iter_get_basic(&variant_iter, &value_uint32);
654 project_info.modification_time = value_uint32;
656 break;
657 case DBUS_TYPE_STRING:
658 if (strcmp(key, "Description") == 0)
660 dbus_message_iter_get_basic(&variant_iter, &value_string);
661 project_info.description = value_string;
663 break;
668 projects.push_back(project_info);
671 unref:
672 dbus_message_unref(reply_ptr);
675 void
676 lash_proxy::load_project(
677 const std::string& project_name)
679 DBusMessage * reply_ptr;
680 const char * project_name_cstr;
682 project_name_cstr = project_name.c_str();
684 if (!_impl_ptr->call(true, LASH_IFACE_CONTROL, "ProjectOpen", &reply_ptr, DBUS_TYPE_STRING, &project_name_cstr, DBUS_TYPE_INVALID))
686 return;
689 dbus_message_unref(reply_ptr);
692 void
693 lash_proxy::save_all_projects()
695 DBusMessage * reply_ptr;
697 if (!_impl_ptr->call(true, LASH_IFACE_CONTROL, "ProjectsSaveAll", &reply_ptr, DBUS_TYPE_INVALID))
699 return;
702 dbus_message_unref(reply_ptr);
705 void
706 lash_proxy::save_project(
707 const std::string& project_name)
709 DBusMessage * reply_ptr;
710 const char * project_name_cstr;
712 project_name_cstr = project_name.c_str();
714 if (!_impl_ptr->call(true, LASH_IFACE_CONTROL, "ProjectSave", &reply_ptr, DBUS_TYPE_STRING, &project_name_cstr, DBUS_TYPE_INVALID))
716 return;
719 dbus_message_unref(reply_ptr);
722 void
723 lash_proxy::close_project(
724 const std::string& project_name)
726 DBusMessage * reply_ptr;
727 const char * project_name_cstr;
729 project_name_cstr = project_name.c_str();
731 if (!_impl_ptr->call(true, LASH_IFACE_CONTROL, "ProjectClose", &reply_ptr, DBUS_TYPE_STRING, &project_name_cstr, DBUS_TYPE_INVALID))
733 return;
736 dbus_message_unref(reply_ptr);
739 void
740 lash_proxy::close_all_projects()
742 DBusMessage * reply_ptr;
744 if (!_impl_ptr->call(true, LASH_IFACE_CONTROL, "ProjectsCloseAll", &reply_ptr, DBUS_TYPE_INVALID))
746 return;
749 dbus_message_unref(reply_ptr);
752 void
753 lash_proxy::project_rename(
754 const std::string& old_name,
755 const std::string& new_name)
757 DBusMessage * reply_ptr;
758 const char * old_name_cstr;
759 const char * new_name_cstr;
761 old_name_cstr = old_name.c_str();
762 new_name_cstr = new_name.c_str();
764 if (!_impl_ptr->call(
765 true,
766 LASH_IFACE_CONTROL,
767 "ProjectRename",
768 &reply_ptr,
769 DBUS_TYPE_STRING, &old_name_cstr,
770 DBUS_TYPE_STRING, &new_name_cstr,
771 DBUS_TYPE_INVALID))
773 return;
776 dbus_message_unref(reply_ptr);
779 void
780 lash_proxy::get_loaded_project_properties(
781 const std::string& name,
782 lash_loaded_project_properties& properties)
784 DBusMessage * reply_ptr;
785 const char * reply_signature;
786 DBusMessageIter iter;
787 DBusMessageIter dict_iter;
788 DBusMessageIter dict_entry_iter;
789 DBusMessageIter variant_iter;
790 const char * key;
791 const char * value_type;
792 dbus_bool_t value_bool;
793 const char * value_string;
794 const char * project_name_cstr;
796 project_name_cstr = name.c_str();
798 if (!_impl_ptr->call(
799 true,
800 LASH_IFACE_CONTROL,
801 "ProjectGetProperties",
802 &reply_ptr,
803 DBUS_TYPE_STRING, &project_name_cstr,
804 DBUS_TYPE_INVALID))
806 return;
809 reply_signature = dbus_message_get_signature(reply_ptr);
811 if (strcmp(reply_signature, "a{sv}") != 0)
813 lash_proxy_impl::error_msg((std::string)"ProjectGetProperties() reply signature mismatch. " + reply_signature);
814 goto unref;
817 dbus_message_iter_init(reply_ptr, &iter);
819 for (dbus_message_iter_recurse(&iter, &dict_iter);
820 dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_INVALID;
821 dbus_message_iter_next(&dict_iter))
823 dbus_message_iter_recurse(&dict_iter, &dict_entry_iter);
824 dbus_message_iter_get_basic(&dict_entry_iter, &key);
825 dbus_message_iter_next(&dict_entry_iter);
826 dbus_message_iter_recurse(&dict_entry_iter, &variant_iter);
827 value_type = dbus_message_iter_get_signature(&variant_iter);
828 if (value_type[0] != 0 && value_type[1] == 0)
830 switch (*value_type)
832 case DBUS_TYPE_BOOLEAN:
833 if (strcmp(key, "Modified Status") == 0)
835 dbus_message_iter_get_basic(&variant_iter, &value_bool);
836 properties.modified_status = value_bool;
838 break;
839 case DBUS_TYPE_STRING:
840 if (strcmp(key, "Description") == 0)
842 dbus_message_iter_get_basic(&variant_iter, &value_string);
843 properties.description = value_string;
845 else if (strcmp(key, "Notes") == 0)
847 dbus_message_iter_get_basic(&variant_iter, &value_string);
848 properties.notes = value_string;
850 break;
855 unref:
856 dbus_message_unref(reply_ptr);
859 void
860 lash_proxy::project_set_description(
861 const std::string& project_name,
862 const std::string& description)
864 DBusMessage * reply_ptr;
865 const char * project_name_cstr;
866 const char * description_cstr;
868 project_name_cstr = project_name.c_str();
869 description_cstr = description.c_str();
871 if (!_impl_ptr->call(
872 true,
873 LASH_IFACE_CONTROL,
874 "ProjectSetDescription",
875 &reply_ptr,
876 DBUS_TYPE_STRING, &project_name_cstr,
877 DBUS_TYPE_STRING, &description_cstr,
878 DBUS_TYPE_INVALID))
880 return;
883 dbus_message_unref(reply_ptr);
886 void
887 lash_proxy::project_set_notes(
888 const std::string& project_name,
889 const std::string& notes)
891 DBusMessage * reply_ptr;
892 const char * project_name_cstr;
893 const char * notes_cstr;
895 project_name_cstr = project_name.c_str();
896 notes_cstr = notes.c_str();
898 if (!_impl_ptr->call(
899 true,
900 LASH_IFACE_CONTROL,
901 "ProjectSetNotes",
902 &reply_ptr,
903 DBUS_TYPE_STRING, &project_name_cstr,
904 DBUS_TYPE_STRING, &notes_cstr,
905 DBUS_TYPE_INVALID))
907 return;
910 dbus_message_unref(reply_ptr);
913 void
914 lash_proxy_impl::exit()
916 DBusMessage * reply_ptr;
918 if (!call(
919 true,
920 LASH_IFACE_CONTROL,
921 "Exit",
922 &reply_ptr,
923 DBUS_TYPE_INVALID))
925 return;
928 dbus_message_unref(reply_ptr);
931 bool
932 lash_proxy_impl::is_studio_loaded()
934 DBusMessage* reply_ptr;
935 const char * reply_signature;
936 DBusMessageIter iter;
937 dbus_bool_t is_loaded;
939 if (!call(true, LASH_IFACE_CONTROL, "IsStudioLoaded", &reply_ptr, DBUS_TYPE_INVALID))
941 error_msg("IsStudioLoaded() call failed.");
942 return false;
945 reply_signature = dbus_message_get_signature(reply_ptr);
947 if (strcmp(reply_signature, "b") != 0)
949 error_msg((std::string)"IsStudioLoaded() reply signature mismatch. " + reply_signature);
950 dbus_message_unref(reply_ptr);
951 return false;
954 dbus_message_iter_init(reply_ptr, &iter);
956 dbus_message_iter_get_basic(&iter, &is_loaded);
958 dbus_message_unref(reply_ptr);
959 return is_loaded;