1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2009, 2010 Nedko Arnaudov <nedko@arnaudov.name>
7 **************************************************************************
8 * This file contains implementation of graph canvas object
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.
29 #include "graph_canvas.h"
30 #include "../dbus_constants.h"
31 #include "../common/catdup.h"
35 graph_proxy_handle graph
;
37 struct list_head clients
;
42 struct list_head siblings
;
44 canvas_module_handle canvas_module
;
45 struct list_head ports
;
46 struct graph_canvas
* owner_ptr
;
51 struct list_head siblings
;
53 canvas_port_handle canvas_port
;
54 struct graph_canvas
* graph_canvas
;
60 struct graph_canvas
* graph_canvas_ptr
,
63 struct list_head
* node_ptr
;
64 struct client
* client_ptr
;
66 list_for_each(node_ptr
, &graph_canvas_ptr
->clients
)
68 client_ptr
= list_entry(node_ptr
, struct client
, siblings
);
69 if (client_ptr
->id
== id
)
81 struct client
* client_ptr
,
84 struct list_head
* node_ptr
;
85 struct port
* port_ptr
;
87 list_for_each(node_ptr
, &client_ptr
->ports
)
89 port_ptr
= list_entry(node_ptr
, struct port
, siblings
);
90 if (port_ptr
->id
== id
)
99 #define port1_ptr ((struct port *)port1_context)
100 #define port2_ptr ((struct port *)port2_context)
105 void * port1_context
,
106 void * port2_context
)
108 log_info("connect request(%"PRIu64
", %"PRIu64
")", port1_ptr
->id
, port2_ptr
->id
);
110 ASSERT(port1_ptr
->graph_canvas
== port2_ptr
->graph_canvas
);
112 graph_proxy_connect_ports(port1_ptr
->graph_canvas
->graph
, port1_ptr
->id
, port2_ptr
->id
);
117 void * port1_context
,
118 void * port2_context
)
120 log_info("disconnect request(%"PRIu64
", %"PRIu64
")", port1_ptr
->id
, port2_ptr
->id
);
122 ASSERT(port1_ptr
->graph_canvas
== port2_ptr
->graph_canvas
);
124 graph_proxy_disconnect_ports(port1_ptr
->graph_canvas
->graph
, port1_ptr
->id
, port2_ptr
->id
);
130 #define client_ptr ((struct client *)module_context)
133 module_location_changed(
134 void * module_context
,
142 log_info("module_location_changed(id = %3llu, x = %6.1f, y = %6.1f)", (unsigned long long)client_ptr
->id
, x
, y
);
144 locale
= strdup(setlocale(LC_NUMERIC
, NULL
));
147 log_error("strdup() failed for locale string");
151 setlocale(LC_NUMERIC
, "POSIX");
152 sprintf(x_str
, "%f", x
);
153 sprintf(y_str
, "%f", y
);
154 setlocale(LC_NUMERIC
, locale
);
157 graph_proxy_dict_entry_set(
158 client_ptr
->owner_ptr
->graph
,
159 GRAPH_DICT_OBJECT_TYPE_CLIENT
,
164 graph_proxy_dict_entry_set(
165 client_ptr
->owner_ptr
->graph
,
166 GRAPH_DICT_OBJECT_TYPE_CLIENT
,
178 void (* fill_canvas_menu
)(GtkMenu
* menu
),
179 graph_canvas_handle
* graph_canvas_handle_ptr
)
181 struct graph_canvas
* graph_canvas_ptr
;
183 graph_canvas_ptr
= malloc(sizeof(struct graph_canvas
));
184 if (graph_canvas_ptr
== NULL
)
194 module_location_changed
,
198 &graph_canvas_ptr
->canvas
))
200 free(graph_canvas_ptr
);
204 graph_canvas_ptr
->graph
= NULL
;
205 INIT_LIST_HEAD(&graph_canvas_ptr
->clients
);
207 *graph_canvas_handle_ptr
= (graph_canvas_handle
)graph_canvas_ptr
;
212 #define graph_canvas_ptr ((struct graph_canvas *)graph_canvas)
219 log_info("canvas::clear()");
220 canvas_clear(graph_canvas_ptr
->canvas
);
230 struct client
* client_ptr
;
239 log_info("canvas::client_appeared(%"PRIu64
", \"%s\")", id
, name
);
241 canvas_get_size(graph_canvas_ptr
->canvas
, &width
, &height
);
242 //log_debug("width %f, height %f", width, height);
244 client_ptr
= malloc(sizeof(struct client
));
245 if (client_ptr
== NULL
)
247 log_error("allocation of memory for struct client failed");
252 INIT_LIST_HEAD(&client_ptr
->ports
);
253 client_ptr
->owner_ptr
= graph_canvas_ptr
;
258 if (!graph_proxy_dict_entry_get(
259 client_ptr
->owner_ptr
->graph
,
260 GRAPH_DICT_OBJECT_TYPE_CLIENT
,
266 x
= width
/ 2 - 200 + rand() % 300;
269 if (!graph_proxy_dict_entry_get(
270 client_ptr
->owner_ptr
->graph
,
271 GRAPH_DICT_OBJECT_TYPE_CLIENT
,
277 y
= height
/ 2 - 200 + rand() % 300;
280 if (x_str
!= NULL
|| y_str
!= NULL
)
282 locale
= strdup(setlocale(LC_NUMERIC
, NULL
));
285 log_error("strdup() failed for locale string");
289 setlocale(LC_NUMERIC
, "POSIX");
292 //log_info("converting %s", x_str);
293 sscanf(x_str
, "%lf", &x
);
297 //log_info("converting %s", y_str);
298 sscanf(y_str
, "%lf", &y
);
300 setlocale(LC_NUMERIC
, locale
);
315 if (!canvas_create_module(graph_canvas_ptr
->canvas
, name
, x
, y
, true, true, client_ptr
, &client_ptr
->canvas_module
))
317 log_error("canvas_create_module(\"%s\") failed", name
);
322 if (x_str
== NULL
|| y_str
== NULL
)
323 { /* we have generated random value, store it */
324 module_location_changed(client_ptr
, x
, y
);
327 list_add_tail(&client_ptr
->siblings
, &graph_canvas_ptr
->clients
);
336 struct client
* client_ptr
;
338 log_info("canvas::client_disappeared(%"PRIu64
")", id
);
340 client_ptr
= find_client(graph_canvas_ptr
, id
);
341 if (client_ptr
== NULL
)
343 log_error("cannot find disappearing client %"PRIu64
"", id
);
347 list_del(&client_ptr
->siblings
);
348 canvas_destroy_module(graph_canvas_ptr
->canvas
, client_ptr
->canvas_module
);
352 static void client_renamed(void * graph_canvas
, uint64_t id
, const char * old_name
, const char * new_name
)
354 struct client
* client_ptr
;
356 log_info("canvas::client_renamed(%"PRIu64
", '%s', '%s')", id
, old_name
, new_name
);
358 client_ptr
= find_client(graph_canvas_ptr
, id
);
359 if (client_ptr
== NULL
)
361 log_error("cannot find renamed client %"PRIu64
, id
);
365 canvas_set_module_name(client_ptr
->canvas_module
, new_name
);
374 const char * port_name
,
380 struct client
* client_ptr
;
381 struct port
* port_ptr
;
383 char * name_override
;
385 log_info("canvas::port_appeared(%"PRIu64
", %"PRIu64
", \"%s\")", client_id
, port_id
, port_name
);
387 client_ptr
= find_client(graph_canvas_ptr
, client_id
);
388 if (client_ptr
== NULL
)
390 log_error("cannot find client %"PRIu64
" of appearing port %"PRIu64
" \"%s\"", client_id
, port_id
, port_name
);
394 port_ptr
= malloc(sizeof(struct port
));
395 if (port_ptr
== NULL
)
397 log_error("allocation of memory for struct port failed");
401 port_ptr
->id
= port_id
;
402 port_ptr
->graph_canvas
= graph_canvas_ptr
;
404 // Darkest tango palette colour, with S -= 6, V -= 6, w/ transparency
414 if (!graph_proxy_dict_entry_get(
415 client_ptr
->owner_ptr
->graph
,
416 GRAPH_DICT_OBJECT_TYPE_PORT
,
421 name_override
= NULL
;
425 if (strcmp(value
, "yes") == 0)
427 name_override
= catdup(port_name
, " (a2j)");
428 if (name_override
!= NULL
)
430 port_name
= name_override
;
435 name_override
= NULL
;
441 if (!canvas_create_port(graph_canvas_ptr
->canvas
, client_ptr
->canvas_module
, port_name
, is_input
, color
, port_ptr
, &port_ptr
->canvas_port
))
443 log_error("canvas_create_port(\"%s\") failed", port_name
);
449 list_add_tail(&port_ptr
->siblings
, &client_ptr
->ports
);
461 struct client
* client_ptr
;
462 struct port
* port_ptr
;
464 log_info("canvas::port_disappeared(%"PRIu64
", %"PRIu64
")", client_id
, port_id
);
466 client_ptr
= find_client(graph_canvas_ptr
, client_id
);
467 if (client_ptr
== NULL
)
469 log_error("cannot find client %"PRIu64
" of disappearing port %"PRIu64
"", client_id
, port_id
);
473 port_ptr
= find_port(client_ptr
, port_id
);
474 if (client_ptr
== NULL
)
476 log_error("cannot find disappearing port %"PRIu64
" of client %"PRIu64
"", port_id
, client_id
);
480 list_del(&port_ptr
->siblings
);
481 canvas_destroy_port(graph_canvas_ptr
->canvas
, port_ptr
->canvas_port
);
491 const char * old_port_name
,
492 const char * new_port_name
)
494 struct client
* client_ptr
;
495 struct port
* port_ptr
;
497 log_info("canvas::port_renamed(%"PRIu64
", %"PRIu64
", '%s', '%s')", client_id
, port_id
, old_port_name
, new_port_name
);
499 client_ptr
= find_client(graph_canvas_ptr
, client_id
);
500 if (client_ptr
== NULL
)
502 log_error("cannot find client %"PRIu64
" of renamed port %"PRIu64
"", client_id
, port_id
);
506 port_ptr
= find_port(client_ptr
, port_id
);
507 if (client_ptr
== NULL
)
509 log_error("cannot find renamed port %"PRIu64
" of client %"PRIu64
"", port_id
, client_id
);
513 canvas_set_port_name(port_ptr
->canvas_port
, new_port_name
);
525 struct client
* client1_ptr
;
526 struct port
* port1_ptr
;
527 struct client
* client2_ptr
;
528 struct port
* port2_ptr
;
530 log_info("canvas::ports_connected(%"PRIu64
", %"PRIu64
", %"PRIu64
", %"PRIu64
")", client1_id
, port1_id
, client2_id
, port2_id
);
532 client1_ptr
= find_client(graph_canvas_ptr
, client1_id
);
533 if (client1_ptr
== NULL
)
535 log_error("cannot find client %"PRIu64
" of connected port %"PRIu64
"", client1_id
, port1_id
);
539 port1_ptr
= find_port(client1_ptr
, port1_id
);
540 if (client1_ptr
== NULL
)
542 log_error("cannot find connected port %"PRIu64
" of client %"PRIu64
"", port1_id
, client1_id
);
546 client2_ptr
= find_client(graph_canvas_ptr
, client2_id
);
547 if (client2_ptr
== NULL
)
549 log_error("cannot find client %"PRIu64
" of connected port %"PRIu64
"", client2_id
, port2_id
);
553 port2_ptr
= find_port(client2_ptr
, port2_id
);
554 if (client2_ptr
== NULL
)
556 log_error("cannot find connected port %"PRIu64
" of client %"PRIu64
"", port2_id
, client2_id
);
560 canvas_add_connection(
561 graph_canvas_ptr
->canvas
,
562 port1_ptr
->canvas_port
,
563 port2_ptr
->canvas_port
,
564 canvas_get_port_color(port1_ptr
->canvas_port
) + 0x22222200);
576 struct client
* client1_ptr
;
577 struct port
* port1_ptr
;
578 struct client
* client2_ptr
;
579 struct port
* port2_ptr
;
581 log_info("canvas::ports_disconnected(%"PRIu64
", %"PRIu64
", %"PRIu64
", %"PRIu64
")", client1_id
, port1_id
, client2_id
, port2_id
);
583 client1_ptr
= find_client(graph_canvas_ptr
, client1_id
);
584 if (client1_ptr
== NULL
)
586 log_error("cannot find client %"PRIu64
" of disconnected port %"PRIu64
"", client1_id
, port1_id
);
590 port1_ptr
= find_port(client1_ptr
, port1_id
);
591 if (client1_ptr
== NULL
)
593 log_error("cannot find disconnected port %"PRIu64
" of client %"PRIu64
"", port1_id
, client1_id
);
597 client2_ptr
= find_client(graph_canvas_ptr
, client2_id
);
598 if (client2_ptr
== NULL
)
600 log_error("cannot find client %"PRIu64
" of disconnected port %"PRIu64
"", client2_id
, port2_id
);
604 port2_ptr
= find_port(client2_ptr
, port2_id
);
605 if (client2_ptr
== NULL
)
607 log_error("cannot find disconnected port %"PRIu64
" of client %"PRIu64
"", port2_id
, client2_id
);
611 canvas_remove_connection(
612 graph_canvas_ptr
->canvas
,
613 port1_ptr
->canvas_port
,
614 port2_ptr
->canvas_port
);
618 graph_canvas_destroy(
619 graph_canvas_handle graph_canvas
)
621 if (graph_canvas_ptr
->graph
!= NULL
)
623 graph_canvas_detach(graph_canvas
);
626 free(graph_canvas_ptr
);
631 graph_canvas_handle graph_canvas
,
632 graph_proxy_handle graph
)
634 ASSERT(graph_canvas_ptr
->graph
== NULL
);
636 if (!graph_proxy_attach(
652 graph_canvas_ptr
->graph
= graph
;
659 graph_canvas_handle graph_canvas
)
661 ASSERT(graph_canvas_ptr
->graph
!= NULL
);
662 graph_proxy_detach(graph_canvas_ptr
->graph
, graph_canvas
);
663 graph_canvas_ptr
->graph
= NULL
;
667 graph_canvas_get_canvas(
668 graph_canvas_handle graph_canvas
)
670 return graph_canvas_ptr
->canvas
;