Cleanup current studio before loading new one
[ladish.git] / gui / graph_canvas.c
blob37038449d156dec16312c69f7054dd5c7021326d
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2009 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.
27 #include <stdlib.h>
28 #include <inttypes.h>
30 #include "graph_canvas.h"
31 #include "../common/debug.h"
32 #include "../common/klist.h"
34 struct graph_canvas
36 graph_handle graph;
37 canvas_handle canvas;
38 struct list_head clients;
41 struct client
43 struct list_head siblings;
44 uint64_t id;
45 canvas_module_handle canvas_module;
46 struct list_head ports;
49 struct port
51 struct list_head siblings;
52 uint64_t id;
53 canvas_port_handle canvas_port;
54 struct graph_canvas * graph_canvas;
57 static
58 struct client *
59 find_client(
60 struct graph_canvas * graph_canvas_ptr,
61 uint64_t id)
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)
71 return client_ptr;
75 return NULL;
78 static
79 struct port *
80 find_port(
81 struct client * client_ptr,
82 uint64_t id)
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)
92 return port_ptr;
96 return NULL;
99 #define port1_ptr ((struct port *)port1_context)
100 #define port2_ptr ((struct port *)port2_context)
102 static
103 void
104 connect_request(
105 void * port1_context,
106 void * port2_context)
108 lash_info("connect request(%"PRIu64", %"PRIu64")", port1_ptr->id, port2_ptr->id);
110 assert(port1_ptr->graph_canvas == port2_ptr->graph_canvas);
112 graph_connect_ports(port1_ptr->graph_canvas->graph, port1_ptr->id, port2_ptr->id);
115 void
116 disconnect_request(
117 void * port1_context,
118 void * port2_context)
120 lash_info("disconnect request(%"PRIu64", %"PRIu64")", port1_ptr->id, port2_ptr->id);
122 assert(port1_ptr->graph_canvas == port2_ptr->graph_canvas);
124 graph_disconnect_ports(port1_ptr->graph_canvas->graph, port1_ptr->id, port2_ptr->id);
127 #undef port1_ptr
128 #undef port2_ptr
130 bool
131 graph_canvas_create(
132 int width,
133 int height,
134 graph_canvas_handle * graph_canvas_handle_ptr)
136 struct graph_canvas * graph_canvas_ptr;
138 graph_canvas_ptr = malloc(sizeof(struct graph_canvas));
139 if (graph_canvas_ptr == NULL)
141 return false;
144 if (!canvas_create(width, height, connect_request, disconnect_request, &graph_canvas_ptr->canvas))
146 free(graph_canvas_ptr);
147 return false;
150 graph_canvas_ptr->graph = NULL;
151 INIT_LIST_HEAD(&graph_canvas_ptr->clients);
153 *graph_canvas_handle_ptr = (graph_canvas_handle)graph_canvas_ptr;
155 return true;
158 #define graph_canvas_ptr ((struct graph_canvas *)graph_canvas)
160 static
161 void
162 clear(
163 void * graph_canvas)
165 lash_info("canvas::clear()");
166 canvas_clear(graph_canvas_ptr->canvas);
169 static
170 void
171 client_appeared(
172 void * graph_canvas,
173 uint64_t id,
174 const char * name)
176 struct client * client_ptr;
178 lash_info("canvas::client_appeared(%"PRIu64", \"%s\")", id, name);
180 client_ptr = malloc(sizeof(struct client));
181 if (client_ptr == NULL)
183 lash_error("allocation of memory for struct client failed");
184 return;
187 client_ptr->id = id;
188 INIT_LIST_HEAD(&client_ptr->ports);
190 if (!canvas_create_module(graph_canvas_ptr->canvas, name, 0, 0, true, true, &client_ptr->canvas_module))
192 lash_error("canvas_create_module(\"%s\") failed", name);
193 free(client_ptr);
194 return;
197 list_add_tail(&client_ptr->siblings, &graph_canvas_ptr->clients);
200 static
201 void
202 client_disappeared(
203 void * graph_canvas,
204 uint64_t id)
206 struct client * client_ptr;
208 lash_info("canvas::client_disappeared(%"PRIu64")", id);
210 client_ptr = find_client(graph_canvas_ptr, id);
211 if (client_ptr == NULL)
213 lash_error("cannot find disappearing client %"PRIu64"", id);
214 return;
217 list_del(&client_ptr->siblings);
218 canvas_destroy_module(graph_canvas_ptr->canvas, client_ptr->canvas_module);
219 free(client_ptr);
222 static
223 void
224 port_appeared(
225 void * graph_canvas,
226 uint64_t client_id,
227 uint64_t port_id,
228 const char * port_name,
229 bool is_input,
230 bool is_terminal,
231 bool is_midi)
233 int color;
234 struct client * client_ptr;
235 struct port * port_ptr;
237 lash_info("canvas::port_appeared(%"PRIu64", %"PRIu64", \"%s\")", client_id, port_id, port_name);
239 client_ptr = find_client(graph_canvas_ptr, client_id);
240 if (client_ptr == NULL)
242 lash_error("cannot find client %"PRIu64" of appearing port %"PRIu64" \"%s\"", client_id, port_id, port_name);
243 return;
246 port_ptr = malloc(sizeof(struct port));
247 if (port_ptr == NULL)
249 lash_error("allocation of memory for struct port failed");
250 return;
253 port_ptr->id = port_id;
254 port_ptr->graph_canvas = graph_canvas_ptr;
256 // Darkest tango palette colour, with S -= 6, V -= 6, w/ transparency
257 if (is_midi)
259 color = 0x960909C0;
261 else
263 color = 0x244678C0;
266 if (!canvas_create_port(graph_canvas_ptr->canvas, client_ptr->canvas_module, port_name, is_input, color, port_ptr, &port_ptr->canvas_port))
268 lash_error("canvas_create_port(\"%s\") failed", port_name);
269 free(client_ptr);
270 return;
273 list_add_tail(&port_ptr->siblings, &client_ptr->ports);
276 static
277 void
278 port_disappeared(
279 void * graph_canvas,
280 uint64_t client_id,
281 uint64_t port_id)
283 struct client * client_ptr;
284 struct port * port_ptr;
286 lash_info("canvas::port_disappeared(%"PRIu64", %"PRIu64")", client_id, port_id);
288 client_ptr = find_client(graph_canvas_ptr, client_id);
289 if (client_ptr == NULL)
291 lash_error("cannot find client %"PRIu64" of disappearing port %"PRIu64"", client_id, port_id);
292 return;
295 port_ptr = find_port(client_ptr, port_id);
296 if (client_ptr == NULL)
298 lash_error("cannot find disappearing port %"PRIu64" of client %"PRIu64"", port_id, client_id);
299 return;
302 list_del(&port_ptr->siblings);
303 canvas_destroy_port(graph_canvas_ptr->canvas, port_ptr->canvas_port);
304 free(port_ptr);
307 static
308 void
309 ports_connected(
310 void * graph_canvas,
311 uint64_t client1_id,
312 uint64_t port1_id,
313 uint64_t client2_id,
314 uint64_t port2_id)
316 struct client * client1_ptr;
317 struct port * port1_ptr;
318 struct client * client2_ptr;
319 struct port * port2_ptr;
321 lash_info("canvas::ports_connected(%"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64")", client1_id, port1_id, client2_id, port2_id);
323 client1_ptr = find_client(graph_canvas_ptr, client1_id);
324 if (client1_ptr == NULL)
326 lash_error("cannot find client %"PRIu64" of connected port %"PRIu64"", client1_id, port1_id);
327 return;
330 port1_ptr = find_port(client1_ptr, port1_id);
331 if (client1_ptr == NULL)
333 lash_error("cannot find connected port %"PRIu64" of client %"PRIu64"", port1_id, client1_id);
334 return;
337 client2_ptr = find_client(graph_canvas_ptr, client2_id);
338 if (client2_ptr == NULL)
340 lash_error("cannot find client %"PRIu64" of connected port %"PRIu64"", client2_id, port2_id);
341 return;
344 port2_ptr = find_port(client2_ptr, port2_id);
345 if (client2_ptr == NULL)
347 lash_error("cannot find connected port %"PRIu64" of client %"PRIu64"", port2_id, client2_id);
348 return;
351 canvas_add_connection(
352 graph_canvas_ptr->canvas,
353 port1_ptr->canvas_port,
354 port2_ptr->canvas_port,
355 canvas_get_port_color(port1_ptr->canvas_port) + 0x22222200);
358 static
359 void
360 ports_disconnected(
361 void * graph_canvas,
362 uint64_t client1_id,
363 uint64_t port1_id,
364 uint64_t client2_id,
365 uint64_t port2_id)
367 struct client * client1_ptr;
368 struct port * port1_ptr;
369 struct client * client2_ptr;
370 struct port * port2_ptr;
372 lash_info("canvas::ports_disconnected(%"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64")", client1_id, port1_id, client2_id, port2_id);
374 client1_ptr = find_client(graph_canvas_ptr, client1_id);
375 if (client1_ptr == NULL)
377 lash_error("cannot find client %"PRIu64" of disconnected port %"PRIu64"", client1_id, port1_id);
378 return;
381 port1_ptr = find_port(client1_ptr, port1_id);
382 if (client1_ptr == NULL)
384 lash_error("cannot find disconnected port %"PRIu64" of client %"PRIu64"", port1_id, client1_id);
385 return;
388 client2_ptr = find_client(graph_canvas_ptr, client2_id);
389 if (client2_ptr == NULL)
391 lash_error("cannot find client %"PRIu64" of disconnected port %"PRIu64"", client2_id, port2_id);
392 return;
395 port2_ptr = find_port(client2_ptr, port2_id);
396 if (client2_ptr == NULL)
398 lash_error("cannot find disconnected port %"PRIu64" of client %"PRIu64"", port2_id, client2_id);
399 return;
402 canvas_remove_connection(
403 graph_canvas_ptr->canvas,
404 port1_ptr->canvas_port,
405 port2_ptr->canvas_port);
408 void
409 graph_canvas_destroy(
410 graph_canvas_handle graph_canvas)
412 if (graph_canvas_ptr->graph != NULL)
414 graph_canvas_detach(graph_canvas);
417 free(graph_canvas_ptr);
420 bool
421 graph_canvas_attach(
422 graph_canvas_handle graph_canvas,
423 graph_handle graph)
425 assert(graph_canvas_ptr->graph == NULL);
427 if (!graph_attach(
428 graph,
429 graph_canvas,
430 clear,
431 client_appeared,
432 client_disappeared,
433 port_appeared,
434 port_disappeared,
435 ports_connected,
436 ports_disconnected))
438 return false;
441 graph_canvas_ptr->graph = graph;
443 return true;
446 void
447 graph_canvas_detach(
448 graph_canvas_handle graph_canvas)
450 assert(graph_canvas_ptr->graph != NULL);
451 graph_detach(graph_canvas_ptr->graph, graph_canvas);
452 graph_canvas_ptr->graph = NULL;
455 canvas_handle
456 graph_canvas_get_canvas(
457 graph_canvas_handle graph_canvas)
459 return graph_canvas_ptr->canvas;